/* clear LAN78xx interrupt status */
ret = lan78xx_write_reg(dev, INT_STS, INT_STS_PHY_INT_);
if (unlikely(ret < 0))
- return -EIO;
+ return ret;
mutex_lock(&phydev->lock);
phy_read_status(phydev);
/* reset MAC */
ret = lan78xx_read_reg(dev, MAC_CR, &buf);
if (unlikely(ret < 0))
- return -EIO;
+ return ret;
buf |= MAC_CR_RST_;
ret = lan78xx_write_reg(dev, MAC_CR, buf);
if (unlikely(ret < 0))
- return -EIO;
+ return ret;
del_timer(&dev->stat_monitor);
} else if (link && !dev->link_on) {
if (ecmd.base.speed == 1000) {
/* disable U2 */
ret = lan78xx_read_reg(dev, USB_CFG1, &buf);
+ if (ret < 0)
+ return ret;
buf &= ~USB_CFG1_DEV_U2_INIT_EN_;
ret = lan78xx_write_reg(dev, USB_CFG1, buf);
+ if (ret < 0)
+ return ret;
/* enable U1 */
ret = lan78xx_read_reg(dev, USB_CFG1, &buf);
+ if (ret < 0)
+ return ret;
buf |= USB_CFG1_DEV_U1_INIT_EN_;
ret = lan78xx_write_reg(dev, USB_CFG1, buf);
+ if (ret < 0)
+ return ret;
} else {
/* enable U1 & U2 */
ret = lan78xx_read_reg(dev, USB_CFG1, &buf);
+ if (ret < 0)
+ return ret;
buf |= USB_CFG1_DEV_U2_INIT_EN_;
buf |= USB_CFG1_DEV_U1_INIT_EN_;
ret = lan78xx_write_reg(dev, USB_CFG1, buf);
+ if (ret < 0)
+ return ret;
}
}
ret = lan78xx_update_flowcontrol(dev, ecmd.base.duplex, ladv,
radv);
+ if (ret < 0)
+ return ret;
if (!timer_pending(&dev->stat_monitor)) {
dev->delta = 1;
tasklet_schedule(&dev->bh);
}
- return ret;
+ return 0;
}
/* some work can't be done in tasklets, so we use keventd
static int lan78xx_reset(struct lan78xx_net *dev)
{
struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
- u32 buf;
- int ret = 0;
unsigned long timeout;
+ int ret;
+ u32 buf;
u8 sig;
ret = lan78xx_read_reg(dev, HW_CFG, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= HW_CFG_LRST_;
+
ret = lan78xx_write_reg(dev, HW_CFG, buf);
+ if (ret < 0)
+ return ret;
timeout = jiffies + HZ;
do {
mdelay(1);
ret = lan78xx_read_reg(dev, HW_CFG, &buf);
+ if (ret < 0)
+ return ret;
+
if (time_after(jiffies, timeout)) {
netdev_warn(dev->net,
"timeout on completion of LiteReset");
- return -EIO;
+ ret = -ETIMEDOUT;
+ return ret;
}
} while (buf & HW_CFG_LRST_);
/* save DEVID for later usage */
ret = lan78xx_read_reg(dev, ID_REV, &buf);
+ if (ret < 0)
+ return ret;
+
dev->chipid = (buf & ID_REV_CHIP_ID_MASK_) >> 16;
dev->chiprev = buf & ID_REV_CHIP_REV_MASK_;
/* Respond to the IN token with a NAK */
ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= USB_CFG_BIR_;
+
ret = lan78xx_write_reg(dev, USB_CFG0, buf);
+ if (ret < 0)
+ return ret;
/* Init LTM */
lan78xx_init_ltm(dev);
}
ret = lan78xx_write_reg(dev, BURST_CAP, buf);
+ if (ret < 0)
+ return ret;
+
ret = lan78xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, HW_CFG, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= HW_CFG_MEF_;
+
ret = lan78xx_write_reg(dev, HW_CFG, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= USB_CFG_BCE_;
+
ret = lan78xx_write_reg(dev, USB_CFG0, buf);
+ if (ret < 0)
+ return ret;
/* set FIFO sizes */
buf = (MAX_RX_FIFO_SIZE - 512) / 512;
+
ret = lan78xx_write_reg(dev, FCT_RX_FIFO_END, buf);
+ if (ret < 0)
+ return ret;
buf = (MAX_TX_FIFO_SIZE - 512) / 512;
+
ret = lan78xx_write_reg(dev, FCT_TX_FIFO_END, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
+ if (ret < 0)
+ return ret;
+
ret = lan78xx_write_reg(dev, FLOW, 0);
+ if (ret < 0)
+ return ret;
+
ret = lan78xx_write_reg(dev, FCT_FLOW, 0);
+ if (ret < 0)
+ return ret;
/* Don't need rfe_ctl_lock during initialisation */
ret = lan78xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+ if (ret < 0)
+ return ret;
+
pdata->rfe_ctl |= RFE_CTL_BCAST_EN_ | RFE_CTL_DA_PERFECT_;
+
ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+ if (ret < 0)
+ return ret;
/* Enable or disable checksum offload engines */
- lan78xx_set_features(dev->net, dev->net->features);
+ ret = lan78xx_set_features(dev->net, dev->net->features);
+ if (ret < 0)
+ return ret;
lan78xx_set_multicast(dev->net);
/* reset PHY */
ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= PMT_CTL_PHY_RST_;
+
ret = lan78xx_write_reg(dev, PMT_CTL, buf);
+ if (ret < 0)
+ return ret;
timeout = jiffies + HZ;
do {
mdelay(1);
ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0)
+ return ret;
+
if (time_after(jiffies, timeout)) {
netdev_warn(dev->net, "timeout waiting for PHY Reset");
- return -EIO;
+ ret = -ETIMEDOUT;
+ return ret;
}
} while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_));
ret = lan78xx_read_reg(dev, MAC_CR, &buf);
+ if (ret < 0)
+ return ret;
+
/* LAN7801 only has RGMII mode */
if (dev->chipid == ID_REV_CHIP_ID_7801_)
buf &= ~MAC_CR_GMII_EN_;
}
}
ret = lan78xx_write_reg(dev, MAC_CR, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= MAC_TX_TXEN_;
+
ret = lan78xx_write_reg(dev, MAC_TX, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= FCT_TX_CTL_EN_;
+
ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_set_rx_max_frame_length(dev,
dev->net->mtu + VLAN_ETH_HLEN);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= MAC_RX_RXEN_;
+
ret = lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= FCT_RX_CTL_EN_;
+
ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf);
+ if (ret < 0)
+ return ret;
return 0;
}
ret = usb_autopm_get_interface(dev->intf);
if (ret < 0)
- goto out;
+ return ret;
phy_start(net->phydev);
done:
usb_autopm_put_interface(dev->intf);
-out:
return ret;
}
static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
{
- u32 buf;
- int mask_index;
- u16 crc;
- u32 temp_wucsr;
- u32 temp_pmt_ctl;
const u8 ipv4_multicast[3] = { 0x01, 0x00, 0x5E };
const u8 ipv6_multicast[3] = { 0x33, 0x33 };
const u8 arp_type[2] = { 0x08, 0x06 };
+ u32 temp_pmt_ctl;
+ int mask_index;
+ u32 temp_wucsr;
+ u32 buf;
+ u16 crc;
+ int ret;
+
+ ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+ if (ret < 0)
+ return ret;
- lan78xx_read_reg(dev, MAC_TX, &buf);
buf &= ~MAC_TX_TXEN_;
- lan78xx_write_reg(dev, MAC_TX, buf);
- lan78xx_read_reg(dev, MAC_RX, &buf);
+
+ ret = lan78xx_write_reg(dev, MAC_TX, buf);
+ if (ret < 0)
+ return ret;
+
+ ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf &= ~MAC_RX_RXEN_;
- lan78xx_write_reg(dev, MAC_RX, buf);
- lan78xx_write_reg(dev, WUCSR, 0);
- lan78xx_write_reg(dev, WUCSR2, 0);
- lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
+ ret = lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
+
+ ret = lan78xx_write_reg(dev, WUCSR, 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUCSR2, 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
+ if (ret < 0)
+ return ret;
temp_wucsr = 0;
temp_pmt_ctl = 0;
- lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl);
+
+ ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl);
+ if (ret < 0)
+ return ret;
+
temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_;
temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_;
- for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++)
- lan78xx_write_reg(dev, WUF_CFG(mask_index), 0);
+ for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) {
+ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ }
mask_index = 0;
if (wol & WAKE_PHY) {
/* set WUF_CFG & WUF_MASK for IPv4 Multicast */
crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3);
- lan78xx_write_reg(dev, WUF_CFG(mask_index),
- WUF_CFGX_EN_ |
- WUF_CFGX_TYPE_MCAST_ |
- (0 << WUF_CFGX_OFFSET_SHIFT_) |
- (crc & WUF_CFGX_CRC16_MASK_));
-
- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7);
- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+ WUF_CFGX_EN_ |
+ WUF_CFGX_TYPE_MCAST_ |
+ (0 << WUF_CFGX_OFFSET_SHIFT_) |
+ (crc & WUF_CFGX_CRC16_MASK_));
+ if (ret < 0)
+ return ret;
+
+ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ if (ret < 0)
+ return ret;
+
mask_index++;
/* for IPv6 Multicast */
crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2);
- lan78xx_write_reg(dev, WUF_CFG(mask_index),
- WUF_CFGX_EN_ |
- WUF_CFGX_TYPE_MCAST_ |
- (0 << WUF_CFGX_OFFSET_SHIFT_) |
- (crc & WUF_CFGX_CRC16_MASK_));
-
- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3);
- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+ WUF_CFGX_EN_ |
+ WUF_CFGX_TYPE_MCAST_ |
+ (0 << WUF_CFGX_OFFSET_SHIFT_) |
+ (crc & WUF_CFGX_CRC16_MASK_));
+ if (ret < 0)
+ return ret;
+
+ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ if (ret < 0)
+ return ret;
+
mask_index++;
temp_pmt_ctl |= PMT_CTL_WOL_EN_;
* for packettype (offset 12,13) = ARP (0x0806)
*/
crc = lan78xx_wakeframe_crc16(arp_type, 2);
- lan78xx_write_reg(dev, WUF_CFG(mask_index),
- WUF_CFGX_EN_ |
- WUF_CFGX_TYPE_ALL_ |
- (0 << WUF_CFGX_OFFSET_SHIFT_) |
- (crc & WUF_CFGX_CRC16_MASK_));
-
- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000);
- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+ WUF_CFGX_EN_ |
+ WUF_CFGX_TYPE_ALL_ |
+ (0 << WUF_CFGX_OFFSET_SHIFT_) |
+ (crc & WUF_CFGX_CRC16_MASK_));
+ if (ret < 0)
+ return ret;
+
+ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+ if (ret < 0)
+ return ret;
+ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+ if (ret < 0)
+ return ret;
+
mask_index++;
temp_pmt_ctl |= PMT_CTL_WOL_EN_;
temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_;
}
- lan78xx_write_reg(dev, WUCSR, temp_wucsr);
+ ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr);
+ if (ret < 0)
+ return ret;
/* when multiple WOL bits are set */
if (hweight_long((unsigned long)wol) > 1) {
temp_pmt_ctl &= ~PMT_CTL_SUS_MODE_MASK_;
temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_;
}
- lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl);
+ ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl);
+ if (ret < 0)
+ return ret;
/* clear WUPS */
- lan78xx_read_reg(dev, PMT_CTL, &buf);
+ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= PMT_CTL_WUPS_MASK_;
- lan78xx_write_reg(dev, PMT_CTL, buf);
+
+ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
+ if (ret < 0)
+ return ret;
lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= MAC_RX_RXEN_;
+
lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
return 0;
}
static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct lan78xx_net *dev = usb_get_intfdata(intf);
- struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
u32 buf;
int ret;
/* stop TX & RX */
ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+ if (ret < 0)
+ return ret;
+
buf &= ~MAC_TX_TXEN_;
+
ret = lan78xx_write_reg(dev, MAC_TX, buf);
+ if (ret < 0)
+ return ret;
+
ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf &= ~MAC_RX_RXEN_;
+
ret = lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
/* empty out the rx and queues */
netif_device_detach(dev->net);
if (PMSG_IS_AUTO(message)) {
/* auto suspend (selective suspend) */
ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+ if (ret < 0)
+ return ret;
+
buf &= ~MAC_TX_TXEN_;
+
ret = lan78xx_write_reg(dev, MAC_TX, buf);
+ if (ret < 0)
+ return ret;
+
ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf &= ~MAC_RX_RXEN_;
+
ret = lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WUCSR, 0);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WUCSR2, 0);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
+ if (ret < 0)
+ return ret;
/* set goodframe wakeup */
ret = lan78xx_read_reg(dev, WUCSR, &buf);
+ if (ret < 0)
+ return ret;
buf |= WUCSR_RFE_WAKE_EN_;
buf |= WUCSR_STORE_WAKE_;
ret = lan78xx_write_reg(dev, WUCSR, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0)
+ return ret;
buf &= ~PMT_CTL_RES_CLR_WKP_EN_;
buf |= PMT_CTL_RES_CLR_WKP_STS_;
buf |= PMT_CTL_SUS_MODE_3_;
ret = lan78xx_write_reg(dev, PMT_CTL, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0)
+ return ret;
buf |= PMT_CTL_WUPS_MASK_;
ret = lan78xx_write_reg(dev, PMT_CTL, buf);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= MAC_RX_RXEN_;
+
ret = lan78xx_write_reg(dev, MAC_RX, buf);
+ if (ret < 0)
+ return ret;
} else {
- lan78xx_set_suspend(dev, pdata->wol);
+ struct lan78xx_priv *pdata;
+
+ pdata = (struct lan78xx_priv *)(dev->data[0]);
+
+ ret = lan78xx_set_suspend(dev, pdata->wol);
+ if (ret < 0)
+ return ret;
}
}
if (!--dev->suspend_count) {
/* resume interrupt URBs */
- if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags))
- usb_submit_urb(dev->urb_intr, GFP_NOIO);
+ if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) {
+ ret = usb_submit_urb(dev->urb_intr, GFP_NOIO);
+ if (ret < 0)
+ return ret;
+ }
spin_lock_irq(&dev->txq.lock);
while ((res = usb_get_from_anchor(&dev->deferred))) {
}
ret = lan78xx_write_reg(dev, WUCSR2, 0);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WUCSR, 0);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WUCSR2, WUCSR2_NS_RCD_ |
WUCSR2_ARP_RCD_ |
WUCSR2_IPV6_TCPSYN_RCD_ |
WUCSR2_IPV4_TCPSYN_RCD_);
+ if (ret < 0)
+ return ret;
ret = lan78xx_write_reg(dev, WUCSR, WUCSR_EEE_TX_WAKE_ |
WUCSR_EEE_RX_WAKE_ |
WUCSR_WUFR_ |
WUCSR_MPR_ |
WUCSR_BCST_FR_);
+ if (ret < 0)
+ return ret;
ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+ if (ret < 0)
+ return ret;
+
buf |= MAC_TX_TXEN_;
+
ret = lan78xx_write_reg(dev, MAC_TX, buf);
+ if (ret < 0)
+ return ret;
return 0;
}
static int lan78xx_reset_resume(struct usb_interface *intf)
{
struct lan78xx_net *dev = usb_get_intfdata(intf);
+ int ret;
- lan78xx_reset(dev);
+ ret = lan78xx_reset(dev);
+ if (ret < 0)
+ return ret;
phy_start(dev->net->phydev);
- return lan78xx_resume(intf);
+ ret = lan78xx_resume(intf);
+
+ return ret;
}
static const struct usb_device_id products[] = {