diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/asix.h | 40 | ||||
-rw-r--r-- | drivers/net/usb/asix_common.c | 212 | ||||
-rw-r--r-- | drivers/net/usb/asix_devices.c | 450 | ||||
-rw-r--r-- | drivers/net/usb/ax88172a.c | 29 | ||||
-rw-r--r-- | drivers/net/usb/hso.c | 138 | ||||
-rw-r--r-- | drivers/net/usb/kaweth.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/lan78xx.c | 28 | ||||
-rw-r--r-- | drivers/net/usb/pegasus.c | 3 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 294 | ||||
-rw-r--r-- | drivers/net/usb/smsc95xx.c | 109 | ||||
-rw-r--r-- | drivers/net/usb/smsc95xx.h | 8 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 5 |
12 files changed, 918 insertions, 413 deletions
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h index a2d3ea6efb20..d1092421aaa7 100644 --- a/drivers/net/usb/asix.h +++ b/drivers/net/usb/asix.h @@ -46,6 +46,7 @@ #define AX_CMD_SET_SW_MII 0x06 #define AX_CMD_READ_MII_REG 0x07 #define AX_CMD_WRITE_MII_REG 0x08 +#define AX_CMD_STATMNGSTS_REG 0x09 #define AX_CMD_SET_HW_MII 0x0a #define AX_CMD_READ_EEPROM 0x0b #define AX_CMD_WRITE_EEPROM 0x0c @@ -71,6 +72,17 @@ #define AX_CMD_SW_RESET 0x20 #define AX_CMD_SW_PHY_STATUS 0x21 #define AX_CMD_SW_PHY_SELECT 0x22 +#define AX_QCTCTRL 0x2A + +#define AX_CHIPCODE_MASK 0x70 +#define AX_AX88772_CHIPCODE 0x00 +#define AX_AX88772A_CHIPCODE 0x10 +#define AX_AX88772B_CHIPCODE 0x20 +#define AX_HOST_EN 0x01 + +#define AX_PHYSEL_PSEL 0x01 +#define AX_PHYSEL_SSMII 0 +#define AX_PHYSEL_SSEN 0x10 #define AX_PHY_SELECT_MASK (BIT(3) | BIT(2)) #define AX_PHY_SELECT_INTERNAL 0 @@ -173,6 +185,10 @@ struct asix_rx_fixup_info { }; struct asix_common_private { + void (*resume)(struct usbnet *dev); + void (*suspend)(struct usbnet *dev); + u16 presvd_phy_advertise; + u16 presvd_phy_bmcr; struct asix_rx_fixup_info rx_fixup_info; }; @@ -182,10 +198,10 @@ extern const struct driver_info ax88172a_info; #define FLAG_EEPROM_MAC (1UL << 0) /* init device MAC from eeprom */ int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data); + u16 size, void *data, int in_pm); int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data); + u16 size, void *data, int in_pm); void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data); @@ -197,27 +213,31 @@ int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb); struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags); -int asix_set_sw_mii(struct usbnet *dev); -int asix_set_hw_mii(struct usbnet *dev); +int asix_set_sw_mii(struct usbnet *dev, int in_pm); +int asix_set_hw_mii(struct usbnet *dev, int in_pm); int asix_read_phy_addr(struct usbnet *dev, int internal); int asix_get_phy_addr(struct usbnet *dev); -int asix_sw_reset(struct usbnet *dev, u8 flags); +int asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm); -u16 asix_read_rx_ctl(struct usbnet *dev); -int asix_write_rx_ctl(struct usbnet *dev, u16 mode); +u16 asix_read_rx_ctl(struct usbnet *dev, int in_pm); +int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm); -u16 asix_read_medium_status(struct usbnet *dev); -int asix_write_medium_mode(struct usbnet *dev, u16 mode); +u16 asix_read_medium_status(struct usbnet *dev, int in_pm); +int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm); -int asix_write_gpio(struct usbnet *dev, u16 value, int sleep); +int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm); void asix_set_multicast(struct net_device *net); int asix_mdio_read(struct net_device *netdev, int phy_id, int loc); void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val); +int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc); +void asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, + int val); + void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 7de5ab589e4e..f79eb12c326a 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -22,24 +22,49 @@ #include "asix.h" int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) + u16 size, void *data, int in_pm) { int ret; - ret = usbnet_read_cmd(dev, cmd, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); + int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); + + BUG_ON(!dev); + + if (!in_pm) + fn = usbnet_read_cmd; + else + fn = usbnet_read_cmd_nopm; + + ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, data, size); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n", + index, ret); - if (ret != size && ret >= 0) - return -EINVAL; return ret; } int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) + u16 size, void *data, int in_pm) { - return usbnet_write_cmd(dev, cmd, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); + int ret; + int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); + + BUG_ON(!dev); + + if (!in_pm) + fn = usbnet_write_cmd; + else + fn = usbnet_write_cmd_nopm; + + ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, data, size); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n", + index, ret); + + return ret; } void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, @@ -225,19 +250,20 @@ struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, return skb; } -int asix_set_sw_mii(struct usbnet *dev) +int asix_set_sw_mii(struct usbnet *dev, int in_pm) { int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL, in_pm); + if (ret < 0) netdev_err(dev->net, "Failed to enable software MII access\n"); return ret; } -int asix_set_hw_mii(struct usbnet *dev) +int asix_set_hw_mii(struct usbnet *dev, int in_pm) { int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL, in_pm); if (ret < 0) netdev_err(dev->net, "Failed to enable hardware MII access\n"); return ret; @@ -247,7 +273,7 @@ int asix_read_phy_addr(struct usbnet *dev, int internal) { int offset = (internal ? 1 : 0); u8 buf[2]; - int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); + int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf, 0); netdev_dbg(dev->net, "asix_get_phy_addr()\n"); @@ -270,21 +296,21 @@ int asix_get_phy_addr(struct usbnet *dev) } -int asix_sw_reset(struct usbnet *dev, u8 flags) +int asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm) { int ret; - ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL, in_pm); if (ret < 0) netdev_err(dev->net, "Failed to send software reset: %02x\n", ret); return ret; } -u16 asix_read_rx_ctl(struct usbnet *dev) +u16 asix_read_rx_ctl(struct usbnet *dev, int in_pm) { __le16 v; - int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); + int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v, in_pm); if (ret < 0) { netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret); @@ -295,12 +321,12 @@ out: return ret; } -int asix_write_rx_ctl(struct usbnet *dev, u16 mode) +int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm) { int ret; netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); - ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL, in_pm); if (ret < 0) netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n", mode, ret); @@ -308,10 +334,11 @@ int asix_write_rx_ctl(struct usbnet *dev, u16 mode) return ret; } -u16 asix_read_medium_status(struct usbnet *dev) +u16 asix_read_medium_status(struct usbnet *dev, int in_pm) { __le16 v; - int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); + int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, + 0, 0, 2, &v, in_pm); if (ret < 0) { netdev_err(dev->net, "Error reading Medium Status register: %02x\n", @@ -323,12 +350,13 @@ u16 asix_read_medium_status(struct usbnet *dev) } -int asix_write_medium_mode(struct usbnet *dev, u16 mode) +int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm) { int ret; netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode); - ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, + mode, 0, 0, NULL, in_pm); if (ret < 0) netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n", mode, ret); @@ -336,12 +364,12 @@ int asix_write_medium_mode(struct usbnet *dev, u16 mode) return ret; } -int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) +int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm) { int ret; netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value); - ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL, in_pm); if (ret < 0) netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n", value, ret); @@ -398,16 +426,31 @@ int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); __le16 res; + u8 smsr; + int i = 0; + int ret; mutex_lock(&dev->phy_mutex); - asix_set_sw_mii(dev); + do { + ret = asix_set_sw_mii(dev, 0); + if (ret == -ENODEV) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, 0); + } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + if (ret == -ENODEV) { + mutex_unlock(&dev->phy_mutex); + return ret; + } + asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, - (__u16)loc, 2, &res); - asix_set_hw_mii(dev); + (__u16)loc, 2, &res, 0); + asix_set_hw_mii(dev, 0); mutex_unlock(&dev->phy_mutex); netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", - phy_id, loc, le16_to_cpu(res)); + phy_id, loc, le16_to_cpu(res)); return le16_to_cpu(res); } @@ -416,13 +459,95 @@ void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); __le16 res = cpu_to_le16(val); + u8 smsr; + int i = 0; + int ret; netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", - phy_id, loc, val); + phy_id, loc, val); + mutex_lock(&dev->phy_mutex); - asix_set_sw_mii(dev); - asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); - asix_set_hw_mii(dev); + do { + ret = asix_set_sw_mii(dev, 0); + if (ret == -ENODEV) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, 0); + } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + if (ret == -ENODEV) { + mutex_unlock(&dev->phy_mutex); + return; + } + + asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, + (__u16)loc, 2, &res, 0); + asix_set_hw_mii(dev, 0); + mutex_unlock(&dev->phy_mutex); +} + +int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res; + u8 smsr; + int i = 0; + int ret; + + mutex_lock(&dev->phy_mutex); + do { + ret = asix_set_sw_mii(dev, 1); + if (ret == -ENODEV) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, 1); + } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + if (ret == -ENODEV) { + mutex_unlock(&dev->phy_mutex); + return ret; + } + + asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, + (__u16)loc, 2, &res, 1); + asix_set_hw_mii(dev, 1); + mutex_unlock(&dev->phy_mutex); + + netdev_dbg(dev->net, "asix_mdio_read_nopm() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", + phy_id, loc, le16_to_cpu(res)); + + return le16_to_cpu(res); +} + +void +asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res = cpu_to_le16(val); + u8 smsr; + int i = 0; + int ret; + + netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", + phy_id, loc, val); + + mutex_lock(&dev->phy_mutex); + do { + ret = asix_set_sw_mii(dev, 1); + if (ret == -ENODEV) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, 1); + } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + if (ret == -ENODEV) { + mutex_unlock(&dev->phy_mutex); + return; + } + + asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, + (__u16)loc, 2, &res, 1); + asix_set_hw_mii(dev, 1); mutex_unlock(&dev->phy_mutex); } @@ -431,7 +556,8 @@ void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) struct usbnet *dev = netdev_priv(net); u8 opt; - if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { + if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, + 0, 0, 1, &opt, 0) < 0) { wolinfo->supported = 0; wolinfo->wolopts = 0; return; @@ -455,7 +581,7 @@ int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) opt |= AX_MONITOR_MAGIC; if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, - opt, 0, 0, NULL) < 0) + opt, 0, 0, NULL, 0) < 0) return -EINVAL; return 0; @@ -490,7 +616,7 @@ int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, /* ax8817x returns 2 bytes from eeprom on read */ for (i = first_word; i <= last_word; i++) { if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, i, 0, 2, - &(eeprom_buff[i - first_word])) < 0) { + &eeprom_buff[i - first_word], 0) < 0) { kfree(eeprom_buff); return -EIO; } @@ -531,7 +657,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, the EEPROM */ if (eeprom->offset & 1) { ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, first_word, 0, 2, - &(eeprom_buff[0])); + &eeprom_buff[0], 0); if (ret < 0) { netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", first_word); goto free; @@ -540,7 +666,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, if ((eeprom->offset + eeprom->len) & 1) { ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, last_word, 0, 2, - &(eeprom_buff[last_word - first_word])); + &eeprom_buff[last_word - first_word], 0); if (ret < 0) { netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", last_word); goto free; @@ -550,7 +676,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, memcpy((u8 *)eeprom_buff + (eeprom->offset & 1), data, eeprom->len); /* write data to EEPROM */ - ret = asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0x0000, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0x0000, 0, 0, NULL, 0); if (ret < 0) { netdev_err(net, "Failed to enable EEPROM write\n"); goto free; @@ -561,7 +687,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, netdev_dbg(net, "write to EEPROM at offset 0x%02x, data 0x%04x\n", i, eeprom_buff[i - first_word]); ret = asix_write_cmd(dev, AX_CMD_WRITE_EEPROM, i, - eeprom_buff[i - first_word], 0, NULL); + eeprom_buff[i - first_word], 0, NULL, 0); if (ret < 0) { netdev_err(net, "Failed to write EEPROM at offset 0x%02x.\n", i); @@ -570,7 +696,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, msleep(20); } - ret = asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0x0000, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0x0000, 0, 0, NULL, 0); if (ret < 0) { netdev_err(net, "Failed to disable EEPROM write\n"); goto free; diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 5cabefc23494..cce24950a0ab 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -35,6 +35,15 @@ #define PHY_MODE_RTL8211CL 0x000C +#define AX88772A_PHY14H 0x14 +#define AX88772A_PHY14H_DEFAULT 0x442C + +#define AX88772A_PHY15H 0x15 +#define AX88772A_PHY15H_DEFAULT 0x03C8 + +#define AX88772A_PHY16H 0x16 +#define AX88772A_PHY16H_DEFAULT 0x4044 + struct ax88172_int_data { __le16 res1; u8 link; @@ -79,6 +88,8 @@ static u32 asix_get_phyid(struct usbnet *dev) /* Poll for the rare case the FW or phy isn't ready yet. */ for (i = 0; i < 100; i++) { phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); + if (phy_reg < 0) + return 0; if (phy_reg != 0 && phy_reg != 0xFFFF) break; mdelay(1); @@ -184,7 +195,7 @@ static int ax88172_link_reset(struct usbnet *dev) netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); - asix_write_medium_mode(dev, mode); + asix_write_medium_mode(dev, mode, 0); return 0; } @@ -201,6 +212,28 @@ static const struct net_device_ops ax88172_netdev_ops = { .ndo_set_rx_mode = ax88172_set_multicast, }; +static void asix_phy_reset(struct usbnet *dev, unsigned int reset_bits) +{ + unsigned int timeout = 5000; + + asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, reset_bits); + + /* give phy_id a chance to process reset */ + udelay(500); + + /* See IEEE 802.3 "22.2.4.1.1 Reset": 500ms max */ + while (timeout--) { + if (asix_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR) + & BMCR_RESET) + udelay(100); + else + return; + } + + netdev_err(dev->net, "BMCR_RESET timeout on phy_id %d\n", + dev->mii.phy_id); +} + static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) { int ret = 0; @@ -213,18 +246,19 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) /* Toggle the GPIOs in a manufacturer/model specific way */ for (i = 2; i >= 0; i--) { ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, - (gpio_bits >> (i * 8)) & 0xff, 0, 0, NULL); + (gpio_bits >> (i * 8)) & 0xff, 0, 0, NULL, 0); if (ret < 0) goto out; msleep(5); } - ret = asix_write_rx_ctl(dev, 0x80); + ret = asix_write_rx_ctl(dev, 0x80, 0); if (ret < 0) goto out; /* Get the MAC address */ - ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); + ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, + 0, 0, ETH_ALEN, buf, 0); if (ret < 0) { netdev_dbg(dev->net, "read AX_CMD_READ_NODE_ID failed: %d\n", ret); @@ -246,7 +280,7 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ - asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + asix_phy_reset(dev, BMCR_RESET); asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); mii_nway_restart(&dev->mii); @@ -290,7 +324,7 @@ static int ax88772_link_reset(struct usbnet *dev) netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); - asix_write_medium_mode(dev, mode); + asix_write_medium_mode(dev, mode, 0); return 0; } @@ -298,78 +332,218 @@ static int ax88772_link_reset(struct usbnet *dev) static int ax88772_reset(struct usbnet *dev) { struct asix_data *data = (struct asix_data *)&dev->data; + int ret; + + /* Rewrite MAC address */ + ether_addr_copy(data->mac_addr, dev->net->dev_addr); + ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, + ETH_ALEN, data->mac_addr, 0); + if (ret < 0) + goto out; + + /* Set RX_CTL to default values with 2k buffer, and enable cactus */ + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, 0); + if (ret < 0) + goto out; + + asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT, 0); + if (ret < 0) + goto out; + + return 0; + +out: + return ret; +} + +static int ax88772_hw_reset(struct usbnet *dev, int in_pm) +{ + struct asix_data *data = (struct asix_data *)&dev->data; int ret, embd_phy; u16 rx_ctl; - ret = asix_write_gpio(dev, - AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5); + ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | + AX_GPIO_GPO2EN, 5, in_pm); if (ret < 0) goto out; - embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); + embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); - ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); + ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, + 0, 0, NULL, in_pm); if (ret < 0) { netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); goto out; } - ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL); - if (ret < 0) - goto out; + if (embd_phy) { + ret = asix_sw_reset(dev, AX_SWRESET_IPPD, in_pm); + if (ret < 0) + goto out; - msleep(150); + usleep_range(10000, 11000); - ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); - if (ret < 0) - goto out; + ret = asix_sw_reset(dev, AX_SWRESET_CLEAR, in_pm); + if (ret < 0) + goto out; - msleep(150); + msleep(60); - if (embd_phy) { - ret = asix_sw_reset(dev, AX_SWRESET_IPRL); + ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL, + in_pm); if (ret < 0) goto out; } else { - ret = asix_sw_reset(dev, AX_SWRESET_PRTE); + ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL, + in_pm); if (ret < 0) goto out; } msleep(150); - rx_ctl = asix_read_rx_ctl(dev); - netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); - ret = asix_write_rx_ctl(dev, 0x0000); + + if (in_pm && (!asix_mdio_read_nopm(dev->net, dev->mii.phy_id, + MII_PHYSID1))){ + ret = -EIO; + goto out; + } + + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, in_pm); if (ret < 0) goto out; - rx_ctl = asix_read_rx_ctl(dev); - netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); + ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT, in_pm); + if (ret < 0) + goto out; + + ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, + AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, + AX88772_IPG2_DEFAULT, 0, NULL, in_pm); + if (ret < 0) { + netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); + goto out; + } + + /* Rewrite MAC address */ + ether_addr_copy(data->mac_addr, dev->net->dev_addr); + ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, + ETH_ALEN, data->mac_addr, in_pm); + if (ret < 0) + goto out; - ret = asix_sw_reset(dev, AX_SWRESET_PRL); + /* Set RX_CTL to default values with 2k buffer, and enable cactus */ + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, in_pm); if (ret < 0) goto out; - msleep(150); + rx_ctl = asix_read_rx_ctl(dev, in_pm); + netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", + rx_ctl); - ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL); + rx_ctl = asix_read_medium_status(dev, in_pm); + netdev_dbg(dev->net, + "Medium Status is 0x%04x after all initializations\n", + rx_ctl); + + return 0; + +out: + return ret; +} + +static int ax88772a_hw_reset(struct usbnet *dev, int in_pm) +{ + struct asix_data *data = (struct asix_data *)&dev->data; + int ret, embd_phy; + u16 rx_ctl, phy14h, phy15h, phy16h; + u8 chipcode = 0; + + ret = asix_write_gpio(dev, AX_GPIO_RSE, 5, in_pm); if (ret < 0) goto out; - msleep(150); + embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); - asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, - ADVERTISE_ALL | ADVERTISE_CSMA); - mii_nway_restart(&dev->mii); + ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy | + AX_PHYSEL_SSEN, 0, 0, NULL, in_pm); + if (ret < 0) { + netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); + goto out; + } + usleep_range(10000, 11000); + + ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_IPRL, in_pm); + if (ret < 0) + goto out; + + usleep_range(10000, 11000); + + ret = asix_sw_reset(dev, AX_SWRESET_IPRL, in_pm); + if (ret < 0) + goto out; + + msleep(160); + + ret = asix_sw_reset(dev, AX_SWRESET_CLEAR, in_pm); + if (ret < 0) + goto out; - ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT); + ret = asix_sw_reset(dev, AX_SWRESET_IPRL, in_pm); if (ret < 0) goto out; + msleep(200); + + if (in_pm && (!asix_mdio_read_nopm(dev->net, dev->mii.phy_id, + MII_PHYSID1))) { + ret = -1; + goto out; + } + + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, + 0, 1, &chipcode, in_pm); + if (ret < 0) + goto out; + + if ((chipcode & AX_CHIPCODE_MASK) == AX_AX88772B_CHIPCODE) { + ret = asix_write_cmd(dev, AX_QCTCTRL, 0x8000, 0x8001, + 0, NULL, in_pm); + if (ret < 0) { + netdev_dbg(dev->net, "Write BQ setting failed: %d\n", + ret); + goto out; + } + } else if ((chipcode & AX_CHIPCODE_MASK) == AX_AX88772A_CHIPCODE) { + /* Check if the PHY registers have default settings */ + phy14h = asix_mdio_read_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY14H); + phy15h = asix_mdio_read_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY15H); + phy16h = asix_mdio_read_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY16H); + + netdev_dbg(dev->net, + "772a_hw_reset: MR20=0x%x MR21=0x%x MR22=0x%x\n", + phy14h, phy15h, phy16h); + + /* Restore PHY registers default setting if not */ + if (phy14h != AX88772A_PHY14H_DEFAULT) + asix_mdio_write_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY14H, + AX88772A_PHY14H_DEFAULT); + if (phy15h != AX88772A_PHY15H_DEFAULT) + asix_mdio_write_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY15H, + AX88772A_PHY15H_DEFAULT); + if (phy16h != AX88772A_PHY16H_DEFAULT) + asix_mdio_write_nopm(dev->net, dev->mii.phy_id, + AX88772A_PHY16H, + AX88772A_PHY16H_DEFAULT); + } + ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, - AX88772_IPG2_DEFAULT, 0, NULL); + AX88772_IPG2_DEFAULT, 0, NULL, in_pm); if (ret < 0) { netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); goto out; @@ -378,20 +552,29 @@ static int ax88772_reset(struct usbnet *dev) /* Rewrite MAC address */ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, - data->mac_addr); + data->mac_addr, in_pm); if (ret < 0) goto out; /* Set RX_CTL to default values with 2k buffer, and enable cactus */ - ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, in_pm); if (ret < 0) goto out; - rx_ctl = asix_read_rx_ctl(dev); + ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT, in_pm); + if (ret < 0) + return ret; + + /* Set RX_CTL to default values with 2k buffer, and enable cactus */ + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, in_pm); + if (ret < 0) + goto out; + + rx_ctl = asix_read_rx_ctl(dev, in_pm); netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", rx_ctl); - rx_ctl = asix_read_medium_status(dev); + rx_ctl = asix_read_medium_status(dev, in_pm); netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n", rx_ctl); @@ -400,7 +583,6 @@ static int ax88772_reset(struct usbnet *dev) out: return ret; - } static const struct net_device_ops ax88772_netdev_ops = { @@ -415,11 +597,97 @@ static const struct net_device_ops ax88772_netdev_ops = { .ndo_set_rx_mode = asix_set_multicast, }; +static void ax88772_suspend(struct usbnet *dev) +{ + struct asix_common_private *priv = dev->driver_priv; + u16 medium; + + /* Stop MAC operation */ + medium = asix_read_medium_status(dev, 0); + medium &= ~AX_MEDIUM_RE; + asix_write_medium_mode(dev, medium, 0); + + netdev_dbg(dev->net, "ax88772_suspend: medium=0x%04x\n", + asix_read_medium_status(dev, 0)); + + /* Preserve BMCR for restoring */ + priv->presvd_phy_bmcr = + asix_mdio_read_nopm(dev->net, dev->mii.phy_id, MII_BMCR); + + /* Preserve ANAR for restoring */ + priv->presvd_phy_advertise = + asix_mdio_read_nopm(dev->net, dev->mii.phy_id, MII_ADVERTISE); +} + +static int asix_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usbnet *dev = usb_get_intfdata(intf); + struct asix_common_private *priv = dev->driver_priv; + + if (priv->suspend) + priv->suspend(dev); + + return usbnet_suspend(intf, message); +} + +static void ax88772_restore_phy(struct usbnet *dev) +{ + struct asix_common_private *priv = dev->driver_priv; + + if (priv->presvd_phy_advertise) { + /* Restore Advertisement control reg */ + asix_mdio_write_nopm(dev->net, dev->mii.phy_id, MII_ADVERTISE, + priv->presvd_phy_advertise); + + /* Restore BMCR */ + asix_mdio_write_nopm(dev->net, dev->mii.phy_id, MII_BMCR, + priv->presvd_phy_bmcr); + + mii_nway_restart(&dev->mii); + priv->presvd_phy_advertise = 0; + priv->presvd_phy_bmcr = 0; + } +} + +static void ax88772_resume(struct usbnet *dev) +{ + int i; + + for (i = 0; i < 3; i++) + if (!ax88772_hw_reset(dev, 1)) + break; + ax88772_restore_phy(dev); +} + +static void ax88772a_resume(struct usbnet *dev) +{ + int i; + + for (i = 0; i < 3; i++) { + if (!ax88772a_hw_reset(dev, 1)) + break; + } + + ax88772_restore_phy(dev); +} + +static int asix_resume(struct usb_interface *intf) +{ + struct usbnet *dev = usb_get_intfdata(intf); + struct asix_common_private *priv = dev->driver_priv; + + if (priv->resume) + priv->resume(dev); + + return usbnet_resume(intf); +} + static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) { - int ret, embd_phy, i; - u8 buf[ETH_ALEN]; + int ret, i; + u8 buf[ETH_ALEN], chipcode = 0; u32 phyid; + struct asix_common_private *priv; usbnet_get_endpoints(dev,intf); @@ -427,13 +695,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) if (dev->driver_info->data & FLAG_EEPROM_MAC) { for (i = 0; i < (ETH_ALEN >> 1); i++) { ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x04 + i, - 0, 2, buf + i * 2); + 0, 2, buf + i * 2, 0); if (ret < 0) break; } } else { ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, - 0, 0, ETH_ALEN, buf); + 0, 0, ETH_ALEN, buf, 0); } if (ret < 0) { @@ -456,16 +724,11 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ - embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); - - /* Reset the PHY to normal operation mode */ - ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); - if (ret < 0) { - netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); - return ret; - } + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0); + chipcode &= AX_CHIPCODE_MASK; - ax88772_reset(dev); + (chipcode == AX_AX88772_CHIPCODE) ? ax88772_hw_reset(dev, 0) : + ax88772a_hw_reset(dev, 0); /* Read PHYID register *AFTER* the PHY was reset properly */ phyid = asix_get_phyid(dev); @@ -482,6 +745,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) if (!dev->driver_priv) return -ENOMEM; + priv = dev->driver_priv; + + priv->presvd_phy_bmcr = 0; + priv->presvd_phy_advertise = 0; + if (chipcode == AX_AX88772_CHIPCODE) { + priv->resume = ax88772_resume; + priv->suspend = ax88772_suspend; + } else { + priv->resume = ax88772a_resume; + priv->suspend = ax88772_suspend; + } + return 0; } @@ -593,12 +868,12 @@ static int ax88178_reset(struct usbnet *dev) int gpio0 = 0; u32 phyid; - asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status); + asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status, 0); netdev_dbg(dev->net, "GPIO Status: 0x%04x\n", status); - asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); - asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); - asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL); + asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL, 0); + asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom, 0); + asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL, 0); netdev_dbg(dev->net, "EEPROM index 0x17 is 0x%04x\n", eeprom); @@ -614,15 +889,16 @@ static int ax88178_reset(struct usbnet *dev) netdev_dbg(dev->net, "GPIO0: %d, PhyMode: %d\n", gpio0, data->phymode); /* Power up external GigaPHY through AX88178 GPIO pin */ - asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); + asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | + AX_GPIO_GPO1EN, 40, 0); if ((le16_to_cpu(eeprom) >> 8) != 1) { - asix_write_gpio(dev, 0x003c, 30); - asix_write_gpio(dev, 0x001c, 300); - asix_write_gpio(dev, 0x003c, 30); + asix_write_gpio(dev, 0x003c, 30, 0); + asix_write_gpio(dev, 0x001c, 300, 0); + asix_write_gpio(dev, 0x003c, 30, 0); } else { netdev_dbg(dev->net, "gpio phymode == 1 path\n"); - asix_write_gpio(dev, AX_GPIO_GPO1EN, 30); - asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30); + asix_write_gpio(dev, AX_GPIO_GPO1EN, 30, 0); + asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30, 0); } /* Read PHYID register *AFTER* powering up PHY */ @@ -630,15 +906,15 @@ static int ax88178_reset(struct usbnet *dev) netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */ - asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL); + asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL, 0); - asix_sw_reset(dev, 0); + asix_sw_reset(dev, 0, 0); msleep(150); - asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); + asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD, 0); msleep(150); - asix_write_rx_ctl(dev, 0); + asix_write_rx_ctl(dev, 0, 0); if (data->phymode == PHY_MODE_MARVELL) { marvell_phy_init(dev); @@ -646,27 +922,23 @@ static int ax88178_reset(struct usbnet *dev) } else if (data->phymode == PHY_MODE_RTL8211CL) rtl8211cl_phy_init(dev); - asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, - BMCR_RESET | BMCR_ANENABLE); + asix_phy_reset(dev, BMCR_RESET | BMCR_ANENABLE); asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, ADVERTISE_1000FULL); + asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT, 0); mii_nway_restart(&dev->mii); - ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT); - if (ret < 0) - return ret; - /* Rewrite MAC address */ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, - data->mac_addr); + data->mac_addr, 0); if (ret < 0) return ret; - ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, 0); if (ret < 0) return ret; @@ -704,7 +976,7 @@ static int ax88178_link_reset(struct usbnet *dev) netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", speed, ecmd.duplex, mode); - asix_write_medium_mode(dev, mode); + asix_write_medium_mode(dev, mode, 0); if (data->phymode == PHY_MODE_MARVELL && data->ledmode) marvell_led_status(dev, speed); @@ -733,15 +1005,15 @@ static void ax88178_set_mfb(struct usbnet *dev) mfb = AX_RX_CTL_MFB_16384; } - rxctl = asix_read_rx_ctl(dev); - asix_write_rx_ctl(dev, (rxctl & ~AX_RX_CTL_MFB_16384) | mfb); + rxctl = asix_read_rx_ctl(dev, 0); + asix_write_rx_ctl(dev, (rxctl & ~AX_RX_CTL_MFB_16384) | mfb, 0); - medium = asix_read_medium_status(dev); + medium = asix_read_medium_status(dev, 0); if (dev->net->mtu > 1500) medium |= AX_MEDIUM_JFE; else medium &= ~AX_MEDIUM_JFE; - asix_write_medium_mode(dev, medium); + asix_write_medium_mode(dev, medium, 0); if (dev->rx_urb_size > old_rx_urb_size) usbnet_unlink_rx_urbs(dev); @@ -790,7 +1062,7 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) usbnet_get_endpoints(dev,intf); /* Get the MAC address */ - ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); + ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); if (ret < 0) { netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); return ret; @@ -811,10 +1083,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &ax88178_ethtool_ops; /* Blink LEDS so users know driver saw dongle */ - asix_sw_reset(dev, 0); + asix_sw_reset(dev, 0, 0); msleep(150); - asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); + asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD, 0); msleep(150); /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ @@ -877,7 +1149,7 @@ static const struct driver_info ax88772_info = { .unbind = ax88772_unbind, .status = asix_status, .link_reset = ax88772_link_reset, - .reset = ax88772_link_reset, + .reset = ax88772_reset, .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, @@ -1005,7 +1277,7 @@ static const struct usb_device_id products [] = { }, { // Lenovo U2L100P 10/100 USB_DEVICE (0x17ef, 0x7203), - .driver_info = (unsigned long) &ax88772_info, + .driver_info = (unsigned long)&ax88772b_info, }, { // ASIX AX88772B 10/100 USB_DEVICE (0x0b95, 0x772b), @@ -1073,7 +1345,7 @@ static const struct usb_device_id products [] = { }, { // Asus USB Ethernet Adapter USB_DEVICE (0x0b95, 0x7e2b), - .driver_info = (unsigned long) &ax88772_info, + .driver_info = (unsigned long)&ax88772b_info, }, { /* ASIX 88172a demo board */ USB_DEVICE(0x0b95, 0x172a), @@ -1095,8 +1367,8 @@ static struct usb_driver asix_driver = { .name = DRIVER_NAME, .id_table = products, .probe = usbnet_probe, - .suspend = usbnet_suspend, - .resume = usbnet_resume, + .suspend = asix_suspend, + .resume = asix_resume, .disconnect = usbnet_disconnect, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c index 163a2c576e69..49a3bc107d05 100644 --- a/drivers/net/usb/ax88172a.c +++ b/drivers/net/usb/ax88172a.c @@ -81,7 +81,7 @@ static void ax88172a_adjust_link(struct net_device *netdev) } if (mode != priv->oldmode) { - asix_write_medium_mode(dev, mode); + asix_write_medium_mode(dev, mode, 0); priv->oldmode = mode; netdev_dbg(netdev, "speed %u duplex %d, setting mode to 0x%04x\n", phydev->speed, phydev->duplex, mode); @@ -176,18 +176,19 @@ static int ax88172a_reset_phy(struct usbnet *dev, int embd_phy) { int ret; - ret = asix_sw_reset(dev, AX_SWRESET_IPPD); + ret = asix_sw_reset(dev, AX_SWRESET_IPPD, 0); if (ret < 0) goto err; msleep(150); - ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); + ret = asix_sw_reset(dev, AX_SWRESET_CLEAR, 0); if (ret < 0) goto err; msleep(150); - ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD); + ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD, + 0); if (ret < 0) goto err; @@ -213,7 +214,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) dev->driver_priv = priv; /* Get the MAC address */ - ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); + ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); if (ret < 0) { netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); goto free; @@ -224,7 +225,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &ax88172a_ethtool_ops; /* are we using the internal or the external phy? */ - ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf); + ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf, 0); if (ret < 0) { netdev_err(dev->net, "Failed to read software interface selection register: %d\n", ret); @@ -303,20 +304,20 @@ static int ax88172a_reset(struct usbnet *dev) ax88172a_reset_phy(dev, priv->use_embdphy); msleep(150); - rx_ctl = asix_read_rx_ctl(dev); + rx_ctl = asix_read_rx_ctl(dev, 0); netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); - ret = asix_write_rx_ctl(dev, 0x0000); + ret = asix_write_rx_ctl(dev, 0x0000, 0); if (ret < 0) goto out; - rx_ctl = asix_read_rx_ctl(dev); + rx_ctl = asix_read_rx_ctl(dev, 0); netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); msleep(150); ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, - AX88772_IPG2_DEFAULT, 0, NULL); + AX88772_IPG2_DEFAULT, 0, NULL, 0); if (ret < 0) { netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); goto out; @@ -325,20 +326,20 @@ static int ax88172a_reset(struct usbnet *dev) /* Rewrite MAC address */ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, - data->mac_addr); + data->mac_addr, 0); if (ret < 0) goto out; /* Set RX_CTL to default values with 2k buffer, and enable cactus */ - ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, 0); if (ret < 0) goto out; - rx_ctl = asix_read_rx_ctl(dev); + rx_ctl = asix_read_rx_ctl(dev, 0); netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", rx_ctl); - rx_ctl = asix_read_medium_status(dev); + rx_ctl = asix_read_medium_status(dev, 0); netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n", rx_ctl); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 4b4458616693..e7b516342678 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -50,6 +50,8 @@ * *****************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/sched.h> #include <linux/slab.h> #include <linux/init.h> @@ -108,23 +110,12 @@ /*****************************************************************************/ /* Debugging functions */ /*****************************************************************************/ -#define D__(lvl_, fmt, arg...) \ - do { \ - printk(lvl_ "[%d:%s]: " fmt "\n", \ - __LINE__, __func__, ## arg); \ - } while (0) - -#define D_(lvl, args...) \ - do { \ - if (lvl & debug) \ - D__(KERN_INFO, args); \ - } while (0) - -#define D1(args...) D_(0x01, ##args) -#define D2(args...) D_(0x02, ##args) -#define D3(args...) D_(0x04, ##args) -#define D4(args...) D_(0x08, ##args) -#define D5(args...) D_(0x10, ##args) +#define hso_dbg(lvl, fmt, ...) \ +do { \ + if ((lvl) & debug) \ + pr_info("[%d:%s] " fmt, \ + __LINE__, __func__, ##__VA_ARGS__); \ +} while (0) /*****************************************************************************/ /* Enumerators */ @@ -649,7 +640,7 @@ static int get_free_serial_index(void) } spin_unlock_irqrestore(&serial_table_lock, flags); - printk(KERN_ERR "%s: no free serial devices in table\n", __func__); + pr_err("%s: no free serial devices in table\n", __func__); return -1; } @@ -709,7 +700,8 @@ static void handle_usb_error(int status, const char *function, } /* log a meaningful explanation of an USB status */ - D1("%s: received USB status - %s (%d)", function, explanation, status); + hso_dbg(0x1, "%s: received USB status - %s (%d)\n", + function, explanation, status); } /* Network interface functions */ @@ -808,7 +800,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, DUMP1(skb->data, skb->len); /* Copy it from kernel memory to OUR memory */ memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len); - D1("len: %d/%d", skb->len, MUX_BULK_TX_BUF_SIZE); + hso_dbg(0x1, "len: %d/%d\n", skb->len, MUX_BULK_TX_BUF_SIZE); /* Fill in the URB for shipping it out. */ usb_fill_bulk_urb(odev->mux_bulk_tx_urb, @@ -872,7 +864,7 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, unsigned char *tmp_rx_buf; /* log if needed */ - D1("Rx %d bytes", count); + hso_dbg(0x1, "Rx %d bytes\n", count); DUMP(ip_pkt, min(128, (int)count)); while (count) { @@ -912,7 +904,7 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, frame_len); if (!odev->skb_rx_buf) { /* We got no receive buffer. */ - D1("could not allocate memory"); + hso_dbg(0x1, "could not allocate memory\n"); odev->rx_parse_state = WAIT_SYNC; continue; } @@ -972,11 +964,11 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, break; case WAIT_SYNC: - D1(" W_S"); + hso_dbg(0x1, " W_S\n"); count = 0; break; default: - D1(" "); + hso_dbg(0x1, "\n"); count--; break; } @@ -1020,7 +1012,7 @@ static void read_bulk_callback(struct urb *urb) /* Sanity check */ if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) { - D1("BULK IN callback but driver is not active!"); + hso_dbg(0x1, "BULK IN callback but driver is not active!\n"); return; } usb_mark_last_busy(urb->dev); @@ -1112,11 +1104,11 @@ static void _hso_serial_set_termios(struct tty_struct *tty, struct hso_serial *serial = tty->driver_data; if (!serial) { - printk(KERN_ERR "%s: no tty structures", __func__); + pr_err("%s: no tty structures", __func__); return; } - D4("port %d", serial->minor); + hso_dbg(0x8, "port %d\n", serial->minor); /* * Fix up unsupported bits @@ -1205,11 +1197,11 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) struct hso_serial *serial = urb->context; int status = urb->status; - D4("\n--- Got serial_read_bulk callback %02x ---", status); + hso_dbg(0x8, "--- Got serial_read_bulk callback %02x ---\n", status); /* sanity check */ if (!serial) { - D1("serial == NULL"); + hso_dbg(0x1, "serial == NULL\n"); return; } if (status) { @@ -1217,7 +1209,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) return; } - D1("Actual length = %d\n", urb->actual_length); + hso_dbg(0x1, "Actual length = %d\n", urb->actual_length); DUMP1(urb->transfer_buffer, urb->actual_length); /* Anyone listening? */ @@ -1266,7 +1258,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) { WARN_ON(1); tty->driver_data = NULL; - D1("Failed to open port"); + hso_dbg(0x1, "Failed to open port\n"); return -ENODEV; } @@ -1275,7 +1267,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) if (result < 0) goto err_out; - D1("Opening %d", serial->minor); + hso_dbg(0x1, "Opening %d\n", serial->minor); /* setup */ tty->driver_data = serial; @@ -1298,7 +1290,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) kref_get(&serial->parent->ref); } } else { - D1("Port was already open"); + hso_dbg(0x1, "Port was already open\n"); } usb_autopm_put_interface(serial->parent->interface); @@ -1317,7 +1309,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) struct hso_serial *serial = tty->driver_data; u8 usb_gone; - D1("Closing serial port"); + hso_dbg(0x1, "Closing serial port\n"); /* Open failed, no close cleanup required */ if (serial == NULL) @@ -1357,7 +1349,7 @@ static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, /* sanity check */ if (serial == NULL) { - printk(KERN_ERR "%s: serial is NULL\n", __func__); + pr_err("%s: serial is NULL\n", __func__); return -ENODEV; } @@ -1412,8 +1404,8 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) unsigned long flags; if (old) - D5("Termios called with: cflags new[%d] - old[%d]", - tty->termios.c_cflag, old->c_cflag); + hso_dbg(0x16, "Termios called with: cflags new[%d] - old[%d]\n", + tty->termios.c_cflag, old->c_cflag); /* the actual setup */ spin_lock_irqsave(&serial->serial_lock, flags); @@ -1649,7 +1641,7 @@ static int hso_serial_tiocmget(struct tty_struct *tty) /* sanity check */ if (!serial) { - D1("no tty structures"); + hso_dbg(0x1, "no tty structures\n"); return -EINVAL; } spin_lock_irq(&serial->serial_lock); @@ -1682,7 +1674,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, /* sanity check */ if (!serial) { - D1("no tty structures"); + hso_dbg(0x1, "no tty structures\n"); return -EINVAL; } @@ -1721,7 +1713,7 @@ static int hso_serial_ioctl(struct tty_struct *tty, { struct hso_serial *serial = tty->driver_data; int ret = 0; - D4("IOCTL cmd: %d, arg: %ld", cmd, arg); + hso_dbg(0x8, "IOCTL cmd: %d, arg: %ld\n", cmd, arg); if (!serial) return -ENODEV; @@ -1783,7 +1775,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, /* Sanity check */ if (!serial || !ctrl_urb || !ctrl_req) { - printk(KERN_ERR "%s: Wrong arguments\n", __func__); + pr_err("%s: Wrong arguments\n", __func__); return -EINVAL; } @@ -1808,9 +1800,9 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, pipe = usb_sndctrlpipe(serial->parent->usb, 0); } /* syslog */ - D2("%s command (%02x) len: %d, port: %d", - type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write", - ctrl_req->bRequestType, ctrl_req->wLength, port); + hso_dbg(0x2, "%s command (%02x) len: %d, port: %d\n", + type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write", + ctrl_req->bRequestType, ctrl_req->wLength, port); /* Load ctrl urb */ ctrl_urb->transfer_flags = 0; @@ -1876,11 +1868,11 @@ static void intr_callback(struct urb *urb) handle_usb_error(status, __func__, NULL); return; } - D4("\n--- Got intr callback 0x%02X ---", status); + hso_dbg(0x8, "--- Got intr callback 0x%02X ---\n", status); /* what request? */ port_req = urb->transfer_buffer; - D4(" port_req = 0x%.2X\n", *port_req); + hso_dbg(0x8, "port_req = 0x%.2X\n", *port_req); /* loop over all muxed ports to find the one sending this */ for (i = 0; i < 8; i++) { /* max 8 channels on MUX */ @@ -1888,7 +1880,8 @@ static void intr_callback(struct urb *urb) serial = get_serial_by_shared_int_and_type(shared_int, (1 << i)); if (serial != NULL) { - D1("Pending read interrupt on port %d\n", i); + hso_dbg(0x1, "Pending read interrupt on port %d\n", + i); spin_lock(&serial->serial_lock); if (serial->rx_state == RX_IDLE && serial->port.count > 0) { @@ -1900,8 +1893,8 @@ static void intr_callback(struct urb *urb) } else serial->rx_state = RX_PENDING; } else { - D1("Already a read pending on " - "port %d or port not open\n", i); + hso_dbg(0x1, "Already a read pending on port %d or port not open\n", + i); } spin_unlock(&serial->serial_lock); } @@ -1933,7 +1926,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) /* sanity check */ if (!serial) { - D1("serial == NULL"); + hso_dbg(0x1, "serial == NULL\n"); return; } @@ -1948,7 +1941,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) tty_port_tty_wakeup(&serial->port); hso_kick_transmit(serial); - D1(" "); + hso_dbg(0x1, "\n"); } /* called for writing diag or CS serial port */ @@ -1996,8 +1989,8 @@ static void ctrl_callback(struct urb *urb) /* what request? */ req = (struct usb_ctrlrequest *)(urb->setup_packet); - D4("\n--- Got muxed ctrl callback 0x%02X ---", status); - D4("Actual length of urb = %d\n", urb->actual_length); + hso_dbg(0x8, "--- Got muxed ctrl callback 0x%02X ---\n", status); + hso_dbg(0x8, "Actual length of urb = %d\n", urb->actual_length); DUMP1(urb->transfer_buffer, urb->actual_length); if (req->bRequestType == @@ -2023,7 +2016,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) /* Sanity check */ if (urb == NULL || serial == NULL) { - D1("serial = NULL"); + hso_dbg(0x1, "serial = NULL\n"); return -2; } @@ -2035,7 +2028,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) } /* Push data to tty */ - D1("data to push to tty"); + hso_dbg(0x1, "data to push to tty\n"); count = tty_buffer_request_room(&serial->port, urb->actual_length); if (count >= urb->actual_length) { tty_insert_flip_string(&serial->port, urb->transfer_buffer, @@ -2300,10 +2293,8 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, serial->rx_data_length = rx_size; for (i = 0; i < serial->num_rx_urbs; i++) { serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!serial->rx_urb[i]) { - dev_err(dev, "Could not allocate urb?\n"); + if (!serial->rx_urb[i]) goto exit; - } serial->rx_urb[i]->transfer_buffer = NULL; serial->rx_urb[i]->transfer_buffer_length = 0; serial->rx_data[i] = kzalloc(serial->rx_data_length, @@ -2314,10 +2305,8 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, /* TX, allocate urb and initialize */ serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!serial->tx_urb) { - dev_err(dev, "Could not allocate urb?\n"); + if (!serial->tx_urb) goto exit; - } serial->tx_urb->transfer_buffer = NULL; serial->tx_urb->transfer_buffer_length = 0; /* prepare our TX buffer */ @@ -2419,7 +2408,7 @@ static void hso_net_init(struct net_device *net) { struct hso_net *hso_net = netdev_priv(net); - D1("sizeof hso_net is %d", (int)sizeof(*hso_net)); + hso_dbg(0x1, "sizeof hso_net is %zu\n", sizeof(*hso_net)); /* fill in the other fields */ net->netdev_ops = &hso_netdev_ops; @@ -2555,20 +2544,16 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, /* start allocating */ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!hso_net->mux_bulk_rx_urb_pool[i]) { - dev_err(&interface->dev, "Could not allocate rx urb\n"); + if (!hso_net->mux_bulk_rx_urb_pool[i]) goto exit; - } hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_rx_buf_pool[i]) goto exit; } hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!hso_net->mux_bulk_tx_urb) { - dev_err(&interface->dev, "Could not allocate tx urb\n"); + if (!hso_net->mux_bulk_tx_urb) goto exit; - } hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_tx_buf) goto exit; @@ -2787,10 +2772,8 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) } mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mux->shared_intr_urb) { - dev_err(&interface->dev, "Could not allocate intr urb?\n"); + if (!mux->shared_intr_urb) goto exit; - } mux->shared_intr_buf = kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), GFP_KERNEL); @@ -3239,7 +3222,7 @@ static int __init hso_init(void) int result; /* put it in the log */ - printk(KERN_INFO "hso: %s\n", version); + pr_info("%s\n", version); /* Initialise the serial table semaphore and table */ spin_lock_init(&serial_table_lock); @@ -3270,16 +3253,15 @@ static int __init hso_init(void) /* register the tty driver */ result = tty_register_driver(tty_drv); if (result) { - printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", - __func__, result); + pr_err("%s - tty_register_driver failed(%d)\n", + __func__, result); goto err_free_tty; } /* register this module as an usb driver */ result = usb_register(&hso_driver); if (result) { - printk(KERN_ERR "Could not register hso driver? error: %d\n", - result); + pr_err("Could not register hso driver - error: %d\n", result); goto err_unreg_tty; } @@ -3294,7 +3276,7 @@ err_free_tty: static void __exit hso_exit(void) { - printk(KERN_INFO "hso: unloaded\n"); + pr_info("unloaded\n"); tty_unregister_driver(tty_drv); put_tty_driver(tty_drv); @@ -3311,7 +3293,7 @@ MODULE_DESCRIPTION(MOD_DESCRIPTION); MODULE_LICENSE(MOD_LICENSE); /* change the debug level (eg: insmod hso.ko debug=0x04) */ -MODULE_PARM_DESC(debug, "Level of debug [0x01 | 0x02 | 0x04 | 0x08 | 0x10]"); +MODULE_PARM_DESC(debug, "debug level mask [0x01 | 0x02 | 0x04 | 0x08 | 0x10]"); module_param(debug, int, S_IRUGO | S_IWUSR); /* set the major tty number (eg: insmod hso.ko tty_major=245) */ diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 528b9c9c4e60..66b34ddbe216 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -265,8 +265,6 @@ static int kaweth_control(struct kaweth_device *kaweth, struct usb_ctrlrequest *dr; int retval; - netdev_dbg(kaweth->net, "kaweth_control()\n"); - if(in_interrupt()) { netdev_dbg(kaweth->net, "in_interrupt()\n"); return -EBUSY; @@ -300,8 +298,6 @@ static int kaweth_read_configuration(struct kaweth_device *kaweth) { int retval; - netdev_dbg(kaweth->net, "Reading kaweth configuration\n"); - retval = kaweth_control(kaweth, usb_rcvctrlpipe(kaweth->dev, 0), KAWETH_COMMAND_GET_ETHERNET_DESC, @@ -451,8 +447,6 @@ static int kaweth_trigger_firmware(struct kaweth_device *kaweth, kaweth->firmware_buf[6] = 0x00; kaweth->firmware_buf[7] = 0x00; - netdev_dbg(kaweth->net, "Triggering firmware\n"); - return kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), KAWETH_COMMAND_SCAN, @@ -471,7 +465,6 @@ static int kaweth_reset(struct kaweth_device *kaweth) { int result; - netdev_dbg(kaweth->net, "kaweth_reset(%p)\n", kaweth); result = usb_reset_configuration(kaweth->dev); mdelay(10); @@ -685,8 +678,6 @@ static int kaweth_open(struct net_device *net) struct kaweth_device *kaweth = netdev_priv(net); int res; - netdev_dbg(kaweth->net, "Opening network device.\n"); - res = usb_autopm_get_interface(kaweth->intf); if (res) { dev_err(&kaweth->intf->dev, "Interface cannot be resumed.\n"); @@ -951,7 +942,6 @@ static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) struct kaweth_device *kaweth = usb_get_intfdata(intf); unsigned long flags; - dev_dbg(&intf->dev, "Suspending device\n"); spin_lock_irqsave(&kaweth->device_lock, flags); kaweth->status |= KAWETH_STATUS_SUSPENDING; spin_unlock_irqrestore(&kaweth->device_lock, flags); @@ -968,7 +958,6 @@ static int kaweth_resume(struct usb_interface *intf) struct kaweth_device *kaweth = usb_get_intfdata(intf); unsigned long flags; - dev_dbg(&intf->dev, "Resuming device\n"); spin_lock_irqsave(&kaweth->device_lock, flags); kaweth->status &= ~KAWETH_STATUS_SUSPENDING; spin_unlock_irqrestore(&kaweth->device_lock, flags); @@ -1190,8 +1179,6 @@ err_fw: dev_info(dev, "kaweth interface created at %s\n", kaweth->net->name); - dev_dbg(dev, "Kaweth probe returning.\n"); - return 0; err_intfdata: @@ -1219,8 +1206,6 @@ static void kaweth_disconnect(struct usb_interface *intf) struct kaweth_device *kaweth = usb_get_intfdata(intf); struct net_device *netdev; - dev_info(&intf->dev, "Unregistering\n"); - usb_set_intfdata(intf, NULL); if (!kaweth) { dev_warn(&intf->dev, "unregistering non-existent device\n"); diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 6a9d474b08b2..db558b8b32fe 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1179,7 +1179,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) * NOTE: annoying asymmetry: if it's active, schedule_work() fails, * but tasklet_schedule() doesn't. hope the failure is rare. */ -void lan78xx_defer_kevent(struct lan78xx_net *dev, int work) +static void lan78xx_defer_kevent(struct lan78xx_net *dev, int work) { set_bit(work, &dev->flags); if (!schedule_delayed_work(&dev->wq, 0)) @@ -1406,7 +1406,7 @@ static u32 lan78xx_get_link(struct net_device *net) return net->phydev->link; } -int lan78xx_nway_reset(struct net_device *net) +static int lan78xx_nway_reset(struct net_device *net) { return phy_start_aneg(net->phydev); } @@ -1997,7 +1997,7 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu) return 0; } -int lan78xx_set_mac_addr(struct net_device *netdev, void *p) +static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) { struct lan78xx_net *dev = netdev_priv(netdev); struct sockaddr *addr = p; @@ -2371,7 +2371,7 @@ static void lan78xx_terminate_urbs(struct lan78xx_net *dev) remove_wait_queue(&unlink_wakeup, &wait); } -int lan78xx_stop(struct net_device *net) +static int lan78xx_stop(struct net_device *net) { struct lan78xx_net *dev = netdev_priv(net); @@ -2533,7 +2533,8 @@ static void lan78xx_queue_skb(struct sk_buff_head *list, entry->state = state; } -netdev_tx_t lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) +static netdev_tx_t +lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) { struct lan78xx_net *dev = netdev_priv(net); struct sk_buff *skb2 = NULL; @@ -2562,7 +2563,8 @@ netdev_tx_t lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) return NETDEV_TX_OK; } -int lan78xx_get_endpoints(struct lan78xx_net *dev, struct usb_interface *intf) +static int +lan78xx_get_endpoints(struct lan78xx_net *dev, struct usb_interface *intf) { int tmp; struct usb_host_interface *alt = NULL; @@ -2700,7 +2702,7 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev, } } -void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) +static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) { int status; @@ -3002,10 +3004,8 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) gso_skb: urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - netif_dbg(dev, tx_err, dev->net, "no urb\n"); + if (!urb) goto drop; - } entry = (struct skb_data *)skb->cb; entry->urb = urb; @@ -3285,7 +3285,7 @@ static void lan78xx_disconnect(struct usb_interface *intf) usb_put_dev(udev); } -void lan78xx_tx_timeout(struct net_device *net) +static void lan78xx_tx_timeout(struct net_device *net) { struct lan78xx_net *dev = netdev_priv(net); @@ -3605,7 +3605,7 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) return 0; } -int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) +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]); @@ -3701,7 +3701,7 @@ out: return ret; } -int lan78xx_resume(struct usb_interface *intf) +static int lan78xx_resume(struct usb_interface *intf) { struct lan78xx_net *dev = usb_get_intfdata(intf); struct sk_buff *skb; @@ -3768,7 +3768,7 @@ int lan78xx_resume(struct usb_interface *intf) return 0; } -int lan78xx_reset_resume(struct usb_interface *intf) +static int lan78xx_reset_resume(struct usb_interface *intf) { struct lan78xx_net *dev = usb_get_intfdata(intf); diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 9bbe0161a2f4..1434e5dd5f9c 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1129,7 +1129,8 @@ static int pegasus_probe(struct usb_interface *intf, return -ENODEV; if (pegasus_count == 0) { - pegasus_workqueue = create_singlethread_workqueue("pegasus"); + pegasus_workqueue = alloc_workqueue("pegasus", WQ_MEM_RECLAIM, + 0); if (!pegasus_workqueue) return -ENOMEM; } diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f41a8ad4740e..44d439f50961 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -32,7 +32,7 @@ #define NETNEXT_VERSION "08" /* Information for net */ -#define NET_VERSION "5" +#define NET_VERSION "6" #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" @@ -1076,8 +1076,7 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) return -ENODEV; if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { netif_warn(tp, probe, tp->netdev, - "Invalid buffer when reading pass-thru MAC addr: " - "(%d, %d)\n", + "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", obj->type, obj->string.length); goto amacout; } @@ -1090,8 +1089,8 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) ret = hex2bin(buf, obj->string.pointer + 9, 6); if (!(ret == 0 && is_valid_ether_addr(buf))) { netif_warn(tp, probe, tp->netdev, - "Invalid MAC when reading pass-thru MAC addr: " - "%d, %pM\n", ret, buf); + "Invalid MAC for pass-thru MAC addr: %d, %pM\n", + ret, buf); ret = -EINVAL; goto amacout; } @@ -1111,9 +1110,9 @@ static int set_ethernet_addr(struct r8152 *tp) struct sockaddr sa; int ret; - if (tp->version == RTL_VER_01) + if (tp->version == RTL_VER_01) { ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); - else { + } else { /* if this is not an RTL8153-AD, no eFuse mac pass thru set, * or system doesn't provide valid _SB.AMAC this will be * be expected to non-zero @@ -2552,6 +2551,77 @@ static void r8152_aldps_en(struct r8152 *tp, bool enable) } } +static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) +{ + ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); + ocp_reg_write(tp, OCP_EEE_DATA, reg); + ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); +} + +static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) +{ + u16 data; + + r8152_mmd_indirect(tp, dev, reg); + data = ocp_reg_read(tp, OCP_EEE_DATA); + ocp_reg_write(tp, OCP_EEE_AR, 0x0000); + + return data; +} + +static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) +{ + r8152_mmd_indirect(tp, dev, reg); + ocp_reg_write(tp, OCP_EEE_DATA, data); + ocp_reg_write(tp, OCP_EEE_AR, 0x0000); +} + +static void r8152_eee_en(struct r8152 *tp, bool enable) +{ + u16 config1, config2, config3; + u32 ocp_data; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; + config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); + config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; + + if (enable) { + ocp_data |= EEE_RX_EN | EEE_TX_EN; + config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; + config1 |= sd_rise_time(1); + config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; + config3 |= fast_snr(42); + } else { + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); + config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | + RX_QUIET_EN); + config1 |= sd_rise_time(7); + config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); + config3 |= fast_snr(511); + } + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); + ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); + ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); +} + +static void r8152b_enable_eee(struct r8152 *tp) +{ + r8152_eee_en(tp, true); + r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); +} + +static void r8152b_enable_fc(struct r8152 *tp) +{ + u16 anar; + + anar = r8152_mdio_read(tp, MII_ADVERTISE); + anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + r8152_mdio_write(tp, MII_ADVERTISE, anar); +} + static void rtl8152_disable(struct r8152 *tp) { r8152_aldps_en(tp, false); @@ -2561,13 +2631,9 @@ static void rtl8152_disable(struct r8152 *tp) static void r8152b_hw_phy_cfg(struct r8152 *tp) { - u16 data; - - data = r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { - data &= ~BMCR_PDOWN; - r8152_mdio_write(tp, MII_BMCR, data); - } + r8152b_enable_eee(tp); + r8152_aldps_en(tp, true); + r8152b_enable_fc(tp); set_bit(PHY_RESET, &tp->flags); } @@ -2701,20 +2767,52 @@ static void r8152b_enter_oob(struct r8152 *tp) ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); } +static void r8153_aldps_en(struct r8152 *tp, bool enable) +{ + u16 data; + + data = ocp_reg_read(tp, OCP_POWER_CFG); + if (enable) { + data |= EN_ALDPS; + ocp_reg_write(tp, OCP_POWER_CFG, data); + } else { + data &= ~EN_ALDPS; + ocp_reg_write(tp, OCP_POWER_CFG, data); + msleep(20); + } +} + +static void r8153_eee_en(struct r8152 *tp, bool enable) +{ + u32 ocp_data; + u16 config; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config = ocp_reg_read(tp, OCP_EEE_CFG); + + if (enable) { + ocp_data |= EEE_RX_EN | EEE_TX_EN; + config |= EEE10_EN; + } else { + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); + config &= ~EEE10_EN; + } + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CFG, config); +} + static void r8153_hw_phy_cfg(struct r8152 *tp) { u32 ocp_data; u16 data; - if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || - tp->version == RTL_VER_05) - ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); - data = r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { - data &= ~BMCR_PDOWN; - r8152_mdio_write(tp, MII_BMCR, data); - } + /* disable EEE before updating the PHY parameters */ + r8153_eee_en(tp, false); + ocp_reg_write(tp, OCP_EEE_ADV, 0); if (tp->version == RTL_VER_03) { data = ocp_reg_read(tp, OCP_EEE_CFG); @@ -2745,6 +2843,12 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) sram_write(tp, SRAM_10M_AMP1, 0x00af); sram_write(tp, SRAM_10M_AMP2, 0x0208); + r8153_eee_en(tp, true); + ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); + + r8153_aldps_en(tp, true); + r8152b_enable_fc(tp); + set_bit(PHY_RESET, &tp->flags); } @@ -2866,21 +2970,6 @@ static void r8153_enter_oob(struct r8152 *tp) ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); } -static void r8153_aldps_en(struct r8152 *tp, bool enable) -{ - u16 data; - - data = ocp_reg_read(tp, OCP_POWER_CFG); - if (enable) { - data |= EN_ALDPS; - ocp_reg_write(tp, OCP_POWER_CFG, data); - } else { - data &= ~EN_ALDPS; - ocp_reg_write(tp, OCP_POWER_CFG, data); - msleep(20); - } -} - static void rtl8153_disable(struct r8152 *tp) { r8153_aldps_en(tp, false); @@ -3246,103 +3335,6 @@ static int rtl8152_close(struct net_device *netdev) return res; } -static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) -{ - ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); - ocp_reg_write(tp, OCP_EEE_DATA, reg); - ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); -} - -static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) -{ - u16 data; - - r8152_mmd_indirect(tp, dev, reg); - data = ocp_reg_read(tp, OCP_EEE_DATA); - ocp_reg_write(tp, OCP_EEE_AR, 0x0000); - - return data; -} - -static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) -{ - r8152_mmd_indirect(tp, dev, reg); - ocp_reg_write(tp, OCP_EEE_DATA, data); - ocp_reg_write(tp, OCP_EEE_AR, 0x0000); -} - -static void r8152_eee_en(struct r8152 *tp, bool enable) -{ - u16 config1, config2, config3; - u32 ocp_data; - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); - config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; - config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); - config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; - - if (enable) { - ocp_data |= EEE_RX_EN | EEE_TX_EN; - config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; - config1 |= sd_rise_time(1); - config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; - config3 |= fast_snr(42); - } else { - ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); - config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | - RX_QUIET_EN); - config1 |= sd_rise_time(7); - config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); - config3 |= fast_snr(511); - } - - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); - ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); - ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); - ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); -} - -static void r8152b_enable_eee(struct r8152 *tp) -{ - r8152_eee_en(tp, true); - r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); -} - -static void r8153_eee_en(struct r8152 *tp, bool enable) -{ - u32 ocp_data; - u16 config; - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); - config = ocp_reg_read(tp, OCP_EEE_CFG); - - if (enable) { - ocp_data |= EEE_RX_EN | EEE_TX_EN; - config |= EEE10_EN; - } else { - ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); - config &= ~EEE10_EN; - } - - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); - ocp_reg_write(tp, OCP_EEE_CFG, config); -} - -static void r8153_enable_eee(struct r8152 *tp) -{ - r8153_eee_en(tp, true); - ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); -} - -static void r8152b_enable_fc(struct r8152 *tp) -{ - u16 anar; - - anar = r8152_mdio_read(tp, MII_ADVERTISE); - anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; - r8152_mdio_write(tp, MII_ADVERTISE, anar); -} - static void rtl_tally_reset(struct r8152 *tp) { u32 ocp_data; @@ -3355,10 +3347,17 @@ static void rtl_tally_reset(struct r8152 *tp) static void r8152b_init(struct r8152 *tp) { u32 ocp_data; + u16 data; if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; + data = r8152_mdio_read(tp, MII_BMCR); + if (data & BMCR_PDOWN) { + data &= ~BMCR_PDOWN; + r8152_mdio_write(tp, MII_BMCR, data); + } + r8152_aldps_en(tp, false); if (tp->version == RTL_VER_01) { @@ -3380,9 +3379,6 @@ static void r8152b_init(struct r8152 *tp) SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); - r8152b_enable_eee(tp); - r8152_aldps_en(tp, true); - r8152b_enable_fc(tp); rtl_tally_reset(tp); /* enable rx aggregation */ @@ -3394,12 +3390,12 @@ static void r8152b_init(struct r8152 *tp) static void r8153_init(struct r8152 *tp) { u32 ocp_data; + u16 data; int i; if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; - r8153_aldps_en(tp, false); r8153_u1u2en(tp, false); for (i = 0; i < 500; i++) { @@ -3416,6 +3412,23 @@ static void r8153_init(struct r8152 *tp) msleep(20); } + if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || + tp->version == RTL_VER_05) + ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); + + data = r8152_mdio_read(tp, MII_BMCR); + if (data & BMCR_PDOWN) { + data &= ~BMCR_PDOWN; + r8152_mdio_write(tp, MII_BMCR, data); + } + + for (i = 0; i < 500; i++) { + ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; + if (ocp_data == PHY_STAT_LAN_ON) + break; + msleep(20); + } + usb_disable_lpm(tp->udev); r8153_u2p3en(tp, false); @@ -3483,9 +3496,6 @@ static void r8153_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); - r8153_enable_eee(tp); - r8153_aldps_en(tp, true); - r8152b_enable_fc(tp); rtl_tally_reset(tp); r8153_u2p3en(tp, true); } @@ -4032,7 +4042,7 @@ static int rtl8152_set_coalesce(struct net_device *netdev, return ret; } -static struct ethtool_ops ops = { +static const struct ethtool_ops ops = { .get_drvinfo = rtl8152_get_drvinfo, .get_settings = rtl8152_get_settings, .set_settings = rtl8152_set_settings, diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index dc989a8b5afb..831aa33d078a 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -33,7 +33,7 @@ #include "smsc95xx.h" #define SMSC_CHIPNAME "smsc95xx" -#define SMSC_DRIVER_VERSION "1.0.4" +#define SMSC_DRIVER_VERSION "1.0.5" #define HS_USB_PKT_SIZE (512) #define FS_USB_PKT_SIZE (64) #define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) @@ -64,6 +64,7 @@ #define CARRIER_CHECK_DELAY (2 * HZ) struct smsc95xx_priv { + u32 chip_id; u32 mac_cr; u32 hash_hi; u32 hash_lo; @@ -71,6 +72,7 @@ struct smsc95xx_priv { spinlock_t mac_cr_lock; u8 features; u8 suspend_flags; + u8 mdix_ctrl; bool link_ok; struct delayed_work carrier_check; struct usbnet *dev; @@ -782,14 +784,113 @@ static int smsc95xx_ethtool_set_wol(struct net_device *net, return ret; } +static int get_mdix_status(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + u32 val; + int buf; + + buf = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, SPECIAL_CTRL_STS); + if (buf & SPECIAL_CTRL_STS_OVRRD_AMDIX_) { + if (buf & SPECIAL_CTRL_STS_AMDIX_ENABLE_) + return ETH_TP_MDI_AUTO; + else if (buf & SPECIAL_CTRL_STS_AMDIX_STATE_) + return ETH_TP_MDI_X; + } else { + buf = smsc95xx_read_reg(dev, STRAP_STATUS, &val); + if (val & STRAP_STATUS_AMDIX_EN_) + return ETH_TP_MDI_AUTO; + } + + return ETH_TP_MDI; +} + +static void set_mdix_status(struct net_device *net, __u8 mdix_ctrl) +{ + struct usbnet *dev = netdev_priv(net); + struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + int buf; + + if ((pdata->chip_id == ID_REV_CHIP_ID_9500A_) || + (pdata->chip_id == ID_REV_CHIP_ID_9530_) || + (pdata->chip_id == ID_REV_CHIP_ID_89530_) || + (pdata->chip_id == ID_REV_CHIP_ID_9730_)) { + /* Extend Manual AutoMDIX timer for 9500A/9500Ai */ + buf = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, + PHY_EDPD_CONFIG); + buf |= PHY_EDPD_CONFIG_EXT_CROSSOVER_; + smsc95xx_mdio_write(dev->net, dev->mii.phy_id, + PHY_EDPD_CONFIG, buf); + } + + if (mdix_ctrl == ETH_TP_MDI) { + buf = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS); + buf |= SPECIAL_CTRL_STS_OVRRD_AMDIX_; + buf &= ~(SPECIAL_CTRL_STS_AMDIX_ENABLE_ | + SPECIAL_CTRL_STS_AMDIX_STATE_); + smsc95xx_mdio_write(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS, buf); + } else if (mdix_ctrl == ETH_TP_MDI_X) { + buf = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS); + buf |= SPECIAL_CTRL_STS_OVRRD_AMDIX_; + buf &= ~(SPECIAL_CTRL_STS_AMDIX_ENABLE_ | + SPECIAL_CTRL_STS_AMDIX_STATE_); + buf |= SPECIAL_CTRL_STS_AMDIX_STATE_; + smsc95xx_mdio_write(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS, buf); + } else if (mdix_ctrl == ETH_TP_MDI_AUTO) { + buf = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS); + buf &= ~SPECIAL_CTRL_STS_OVRRD_AMDIX_; + buf &= ~(SPECIAL_CTRL_STS_AMDIX_ENABLE_ | + SPECIAL_CTRL_STS_AMDIX_STATE_); + buf |= SPECIAL_CTRL_STS_AMDIX_ENABLE_; + smsc95xx_mdio_write(dev->net, dev->mii.phy_id, + SPECIAL_CTRL_STS, buf); + } + pdata->mdix_ctrl = mdix_ctrl; +} + +static int smsc95xx_get_settings(struct net_device *net, + struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + int retval; + + retval = usbnet_get_settings(net, cmd); + + cmd->eth_tp_mdix = pdata->mdix_ctrl; + cmd->eth_tp_mdix_ctrl = pdata->mdix_ctrl; + + return retval; +} + +static int smsc95xx_set_settings(struct net_device *net, + struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + int retval; + + if (pdata->mdix_ctrl != cmd->eth_tp_mdix_ctrl) + set_mdix_status(net, cmd->eth_tp_mdix_ctrl); + + retval = usbnet_set_settings(net, cmd); + + return retval; +} + static const struct ethtool_ops smsc95xx_ethtool_ops = { .get_link = usbnet_get_link, .nway_reset = usbnet_nway_reset, .get_drvinfo = usbnet_get_drvinfo, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, + .get_settings = smsc95xx_get_settings, + .set_settings = smsc95xx_set_settings, .get_eeprom_len = smsc95xx_ethtool_get_eeprom_len, .get_eeprom = smsc95xx_ethtool_get_eeprom, .set_eeprom = smsc95xx_ethtool_set_eeprom, @@ -1194,6 +1295,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) if (ret < 0) return ret; val >>= 16; + pdata->chip_id = val; + pdata->mdix_ctrl = get_mdix_status(dev->net); if ((val == ID_REV_CHIP_ID_9500A_) || (val == ID_REV_CHIP_ID_9530_) || (val == ID_REV_CHIP_ID_89530_) || (val == ID_REV_CHIP_ID_9730_)) diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h index 526faa0c44e6..29a4d9efce7c 100644 --- a/drivers/net/usb/smsc95xx.h +++ b/drivers/net/usb/smsc95xx.h @@ -144,6 +144,14 @@ #define BURST_CAP (0x38) +#define STRAP_STATUS (0x3C) +#define STRAP_STATUS_PWR_SEL_ (0x00000020) +#define STRAP_STATUS_AMDIX_EN_ (0x00000010) +#define STRAP_STATUS_PORT_SWAP_ (0x00000008) +#define STRAP_STATUS_EEP_SIZE_ (0x00000004) +#define STRAP_STATUS_RMT_WKP_ (0x00000002) +#define STRAP_STATUS_EEP_DISABLE_ (0x00000001) + #define GPIO_WAKE (0x64) #define INT_EP_CTL (0x68) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3bfb59209326..d5071e364d40 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -2062,11 +2062,8 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, cmd, reqtype, value, index, size); urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - netdev_err(dev->net, "Error allocating URB in" - " %s!\n", __func__); + if (!urb) goto fail; - } if (data) { buf = kmemdup(data, size, GFP_ATOMIC); |