diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Kconfig | 12 | ||||
-rw-r--r-- | drivers/net/usb/asix.h | 13 | ||||
-rw-r--r-- | drivers/net/usb/asix_common.c | 106 | ||||
-rw-r--r-- | drivers/net/usb/asix_devices.c | 203 | ||||
-rw-r--r-- | drivers/net/usb/ax88172a.c | 21 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/cdc_mbim.c | 7 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 40 | ||||
-rw-r--r-- | drivers/net/usb/hso.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/huawei_cdc_ncm.c | 1 | ||||
-rw-r--r-- | drivers/net/usb/int51x1.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/lan78xx.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/lg-vl600.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/mcs7830.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 3 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 97 | ||||
-rw-r--r-- | drivers/net/usb/rndis_host.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 27 |
18 files changed, 387 insertions, 172 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index fbbe78643631..4c5d69732a7e 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -164,12 +164,14 @@ config USB_NET_AX8817X depends on USB_USBNET select CRC32 select PHYLIB + select AX88796B_PHY + imply NET_SELFTESTS default y help This option adds support for ASIX AX88xxx based USB 2.0 10/100 Ethernet adapters. - This driver should work with at least the following devices: + This driver should work with at least the following devices: * Aten UC210T * ASIX AX88172 * Billionton Systems, USB2AR @@ -220,13 +222,13 @@ config USB_NET_CDCETHER CDC Ethernet is an implementation option for DOCSIS cable modems that support USB connectivity, used for non-Microsoft USB hosts. The Linux-USB CDC Ethernet Gadget driver is an open implementation. - This driver should work with at least the following devices: + This driver should work with at least the following devices: * Dell Wireless 5530 HSPA - * Ericsson PipeRider (all variants) + * Ericsson PipeRider (all variants) * Ericsson Mobile Broadband Module (all variants) - * Motorola (DM100 and SB4100) - * Broadcom Cable Modem (reference design) + * Motorola (DM100 and SB4100) + * Broadcom Cable Modem (reference design) * Toshiba (PCX1100U and F3507g/F3607gw) * ... diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h index 3b53685301de..e1994a246122 100644 --- a/drivers/net/usb/asix.h +++ b/drivers/net/usb/asix.h @@ -25,6 +25,8 @@ #include <linux/usb/usbnet.h> #include <linux/slab.h> #include <linux/if_vlan.h> +#include <linux/phy.h> +#include <net/selftests.h> #define DRIVER_VERSION "22-Dec-2011" #define DRIVER_NAME "asix" @@ -178,6 +180,10 @@ struct asix_common_private { u16 presvd_phy_advertise; u16 presvd_phy_bmcr; struct asix_rx_fixup_info rx_fixup_info; + struct mii_bus *mdio; + struct phy_device *phydev; + u16 phy_addr; + char phy_name[20]; }; extern const struct driver_info ax88172a_info; @@ -205,8 +211,7 @@ struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 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_read_phy_addr(struct usbnet *dev, bool internal); int asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm); @@ -215,6 +220,7 @@ int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm); u16 asix_read_medium_status(struct usbnet *dev, int in_pm); int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm); +void asix_adjust_link(struct net_device *netdev); int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm); @@ -223,6 +229,9 @@ 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_bus_read(struct mii_bus *bus, int phy_id, int regnum); +int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 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); diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 7bc6e8f856fe..ac92bc52a85e 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -288,32 +288,33 @@ int asix_set_hw_mii(struct usbnet *dev, int in_pm) return ret; } -int asix_read_phy_addr(struct usbnet *dev, int internal) +int asix_read_phy_addr(struct usbnet *dev, bool internal) { - int offset = (internal ? 1 : 0); + int ret, offset; u8 buf[2]; - 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"); + ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf, 0); + if (ret < 0) + goto error; if (ret < 2) { - netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); - goto out; + ret = -EIO; + goto error; } - netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n", - *((__le16 *)buf)); + + offset = (internal ? 1 : 0); ret = buf[offset]; -out: + netdev_dbg(dev->net, "%s PHY address 0x%x\n", + internal ? "internal" : "external", ret); + return ret; -} -int asix_get_phy_addr(struct usbnet *dev) -{ - /* return the address of the internal phy */ - return asix_read_phy_addr(dev, 1); -} +error: + netdev_err(dev->net, "Error reading PHY_ID register: %02x\n", ret); + return ret; +} int asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm) { @@ -383,6 +384,27 @@ int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm) return ret; } +/* set MAC link settings according to information from phylib */ +void asix_adjust_link(struct net_device *netdev) +{ + struct phy_device *phydev = netdev->phydev; + struct usbnet *dev = netdev_priv(netdev); + u16 mode = 0; + + if (phydev->link) { + mode = AX88772_MEDIUM_DEFAULT; + + if (phydev->duplex == DUPLEX_HALF) + mode &= ~AX_MEDIUM_FD; + + if (phydev->speed != SPEED_100) + mode &= ~AX_MEDIUM_PS; + } + + asix_write_medium_mode(dev, mode, 0); + phy_print_status(phydev); +} + int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm) { int ret; @@ -463,18 +485,23 @@ int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) return ret; } - asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, - (__u16)loc, 2, &res, 0); - asix_set_hw_mii(dev, 0); + ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, + &res, 0); + if (ret < 0) + goto out; + + ret = asix_set_hw_mii(dev, 0); +out: 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)); - return le16_to_cpu(res); + return ret < 0 ? ret : le16_to_cpu(res); } -void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +static int __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); @@ -494,15 +521,40 @@ void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) 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); + if (ret == -ENODEV) + goto out; + + ret = asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, + &res, 0); + if (ret < 0) + goto out; + + ret = asix_set_hw_mii(dev, 0); +out: mutex_unlock(&dev->phy_mutex); + + return ret < 0 ? ret : 0; +} + +void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +{ + __asix_mdio_write(netdev, phy_id, loc, val); +} + +/* MDIO read and write wrappers for phylib */ +int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum) +{ + struct usbnet *priv = bus->priv; + + return asix_mdio_read(priv->net, phy_id, regnum); +} + +int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val) +{ + struct usbnet *priv = bus->priv; + + return __asix_mdio_write(priv->net, phy_id, regnum, val); } int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc) diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 19a8fafb8f04..2c115216420a 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -262,7 +262,10 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.mdio_write = asix_mdio_write; dev->mii.phy_id_mask = 0x3f; dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = asix_get_phy_addr(dev); + + dev->mii.phy_id = asix_read_phy_addr(dev, true); + if (dev->mii.phy_id < 0) + return dev->mii.phy_id; dev->net->netdev_ops = &ax88172_netdev_ops; dev->net->ethtool_ops = &ax88172_ethtool_ops; @@ -280,9 +283,29 @@ out: return ret; } +static void ax88772_ethtool_get_strings(struct net_device *netdev, u32 sset, + u8 *data) +{ + switch (sset) { + case ETH_SS_TEST: + net_selftest_get_strings(data); + break; + } +} + +static int ax88772_ethtool_get_sset_count(struct net_device *ndev, int sset) +{ + switch (sset) { + case ETH_SS_TEST: + return net_selftest_get_count(); + default: + return -EOPNOTSUPP; + } +} + static const struct ethtool_ops ax88772_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, - .get_link = asix_get_link, + .get_link = usbnet_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, .get_wol = asix_get_wol, @@ -290,37 +313,18 @@ static const struct ethtool_ops ax88772_ethtool_ops = { .get_eeprom_len = asix_get_eeprom_len, .get_eeprom = asix_get_eeprom, .set_eeprom = asix_set_eeprom, - .nway_reset = usbnet_nway_reset, - .get_link_ksettings = usbnet_get_link_ksettings_mii, - .set_link_ksettings = usbnet_set_link_ksettings_mii, + .nway_reset = phy_ethtool_nway_reset, + .get_link_ksettings = phy_ethtool_get_link_ksettings, + .set_link_ksettings = phy_ethtool_set_link_ksettings, + .self_test = net_selftest, + .get_strings = ax88772_ethtool_get_strings, + .get_sset_count = ax88772_ethtool_get_sset_count, }; -static int ax88772_link_reset(struct usbnet *dev) -{ - u16 mode; - struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; - - mii_check_media(&dev->mii, 1, 1); - mii_ethtool_gset(&dev->mii, &ecmd); - mode = AX88772_MEDIUM_DEFAULT; - - if (ethtool_cmd_speed(&ecmd) != SPEED_100) - mode &= ~AX_MEDIUM_PS; - - if (ecmd.duplex != DUPLEX_FULL) - mode &= ~AX_MEDIUM_FD; - - 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, 0); - - return 0; -} - static int ax88772_reset(struct usbnet *dev) { struct asix_data *data = (struct asix_data *)&dev->data; + struct asix_common_private *priv = dev->driver_priv; int ret; /* Rewrite MAC address */ @@ -339,6 +343,8 @@ static int ax88772_reset(struct usbnet *dev) if (ret < 0) goto out; + phy_start(priv->phydev); + return 0; out: @@ -583,7 +589,7 @@ static const struct net_device_ops ax88772_netdev_ops = { .ndo_get_stats64 = dev_get_tstats64, .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, - .ndo_do_ioctl = asix_ioctl, + .ndo_do_ioctl = phy_do_ioctl_running, .ndo_set_rx_mode = asix_set_multicast, }; @@ -592,6 +598,9 @@ static void ax88772_suspend(struct usbnet *dev) struct asix_common_private *priv = dev->driver_priv; u16 medium; + if (netif_running(dev->net)) + phy_stop(priv->phydev); + /* Stop MAC operation */ medium = asix_read_medium_status(dev, 1); medium &= ~AX_MEDIUM_RE; @@ -599,14 +608,6 @@ static void ax88772_suspend(struct usbnet *dev) netdev_dbg(dev->net, "ax88772_suspend: medium=0x%04x\n", asix_read_medium_status(dev, 1)); - - /* 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) @@ -620,39 +621,22 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message) 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 */ - if (priv->presvd_phy_bmcr & BMCR_ANENABLE) - priv->presvd_phy_bmcr |= BMCR_ANRESTART; - - asix_mdio_write_nopm(dev->net, dev->mii.phy_id, MII_BMCR, - priv->presvd_phy_bmcr); - - priv->presvd_phy_advertise = 0; - priv->presvd_phy_bmcr = 0; - } -} - static void ax88772_resume(struct usbnet *dev) { + struct asix_common_private *priv = dev->driver_priv; int i; for (i = 0; i < 3; i++) if (!ax88772_hw_reset(dev, 1)) break; - ax88772_restore_phy(dev); + + if (netif_running(dev->net)) + phy_start(priv->phydev); } static void ax88772a_resume(struct usbnet *dev) { + struct asix_common_private *priv = dev->driver_priv; int i; for (i = 0; i < 3; i++) { @@ -660,7 +644,8 @@ static void ax88772a_resume(struct usbnet *dev) break; } - ax88772_restore_phy(dev); + if (netif_running(dev->net)) + phy_start(priv->phydev); } static int asix_resume(struct usb_interface *intf) @@ -674,12 +659,62 @@ static int asix_resume(struct usb_interface *intf) return usbnet_resume(intf); } +static int ax88772_init_mdio(struct usbnet *dev) +{ + struct asix_common_private *priv = dev->driver_priv; + + priv->mdio = devm_mdiobus_alloc(&dev->udev->dev); + if (!priv->mdio) + return -ENOMEM; + + priv->mdio->priv = dev; + priv->mdio->read = &asix_mdio_bus_read; + priv->mdio->write = &asix_mdio_bus_write; + priv->mdio->name = "Asix MDIO Bus"; + /* mii bus name is usb-<usb bus number>-<usb device number> */ + snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", + dev->udev->bus->busnum, dev->udev->devnum); + + return devm_mdiobus_register(&dev->udev->dev, priv->mdio); +} + +static int ax88772_init_phy(struct usbnet *dev) +{ + struct asix_common_private *priv = dev->driver_priv; + int ret; + + ret = asix_read_phy_addr(dev, true); + if (ret < 0) + return ret; + + priv->phy_addr = ret; + + snprintf(priv->phy_name, sizeof(priv->phy_name), PHY_ID_FMT, + priv->mdio->id, priv->phy_addr); + + priv->phydev = phy_connect(dev->net, priv->phy_name, &asix_adjust_link, + PHY_INTERFACE_MODE_INTERNAL); + if (IS_ERR(priv->phydev)) { + netdev_err(dev->net, "Could not connect to PHY device %s\n", + priv->phy_name); + ret = PTR_ERR(priv->phydev); + return ret; + } + + phy_suspend(priv->phydev); + priv->phydev->mac_managed_pm = 1; + + phy_attached_info(priv->phydev); + + return 0; +} + static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) { - int ret, i; u8 buf[ETH_ALEN] = {0}, chipcode = 0; - u32 phyid; struct asix_common_private *priv; + int ret, i; + u32 phyid; usbnet_get_endpoints(dev, intf); @@ -711,14 +746,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) asix_set_netdev_dev_addr(dev, buf); - /* Initialize MII structure */ - dev->mii.dev = dev->net; - dev->mii.mdio_read = asix_mdio_read; - dev->mii.mdio_write = asix_mdio_write; - dev->mii.phy_id_mask = 0x1f; - dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = asix_get_phy_addr(dev); - dev->net->netdev_ops = &ax88772_netdev_ops; dev->net->ethtool_ops = &ax88772_ethtool_ops; dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ @@ -746,11 +773,11 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) dev->rx_urb_size = 2048; } - dev->driver_priv = kzalloc(sizeof(struct asix_common_private), GFP_KERNEL); - if (!dev->driver_priv) + priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = dev->driver_priv; + dev->driver_priv = priv; priv->presvd_phy_bmcr = 0; priv->presvd_phy_advertise = 0; @@ -762,13 +789,32 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) priv->suspend = ax88772_suspend; } + ret = ax88772_init_mdio(dev); + if (ret) + return ret; + + return ax88772_init_phy(dev); +} + +static int ax88772_stop(struct usbnet *dev) +{ + struct asix_common_private *priv = dev->driver_priv; + + /* On unplugged USB, we will get MDIO communication errors and the + * PHY will be set in to PHY_HALTED state. + */ + if (priv->phydev->state != PHY_HALTED) + phy_stop(priv->phydev); + return 0; } static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) { + struct asix_common_private *priv = dev->driver_priv; + + phy_disconnect(priv->phydev); asix_rx_fixup_common_free(dev->driver_priv); - kfree(dev->driver_priv); } static const struct ethtool_ops ax88178_ethtool_ops = { @@ -1081,7 +1127,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.phy_id_mask = 0x1f; dev->mii.reg_num_mask = 0xff; dev->mii.supports_gmii = 1; - dev->mii.phy_id = asix_get_phy_addr(dev); + + dev->mii.phy_id = asix_read_phy_addr(dev, true); + if (dev->mii.phy_id < 0) + return dev->mii.phy_id; dev->net->netdev_ops = &ax88178_netdev_ops; dev->net->ethtool_ops = &ax88178_ethtool_ops; @@ -1153,8 +1202,8 @@ static const struct driver_info ax88772_info = { .bind = ax88772_bind, .unbind = ax88772_unbind, .status = asix_status, - .link_reset = ax88772_link_reset, .reset = ax88772_reset, + .stop = ax88772_stop, .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, @@ -1165,7 +1214,6 @@ static const struct driver_info ax88772b_info = { .bind = ax88772_bind, .unbind = ax88772_unbind, .status = asix_status, - .link_reset = ax88772_link_reset, .reset = ax88772_reset, .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, @@ -1201,7 +1249,6 @@ static const struct driver_info hg20f9_info = { .bind = ax88772_bind, .unbind = ax88772_unbind, .status = asix_status, - .link_reset = ax88772_link_reset, .reset = ax88772_reset, .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c index b404c9462dce..530947d7477b 100644 --- a/drivers/net/usb/ax88172a.c +++ b/drivers/net/usb/ax88172a.c @@ -25,20 +25,6 @@ struct ax88172a_private { struct asix_rx_fixup_info rx_fixup_info; }; -/* MDIO read and write wrappers for phylib */ -static int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum) -{ - return asix_mdio_read(((struct usbnet *)bus->priv)->net, phy_id, - regnum); -} - -static int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, - u16 val) -{ - asix_mdio_write(((struct usbnet *)bus->priv)->net, phy_id, regnum, val); - return 0; -} - /* set MAC link settings according to information from phylib */ static void ax88172a_adjust_link(struct net_device *netdev) { @@ -219,7 +205,12 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) goto free; } - priv->phy_addr = asix_read_phy_addr(dev, priv->use_embdphy); + ret = asix_read_phy_addr(dev, priv->use_embdphy); + if (ret < 0) + goto free; + + priv->phy_addr = ret; + ax88172a_reset_phy(dev, priv->use_embdphy); /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 7eb0109e9baa..eb3817d70f2b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -217,7 +217,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) goto bad_desc; } skip: - /* Communcation class functions with bmCapabilities are not + /* Communication class functions with bmCapabilities are not * RNDIS. But some Wireless class RNDIS functions use * bmCapabilities for their own purpose. The failsafe is * therefore applied only to Communication class RNDIS diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 5db66272fc82..4c4ab7b38d78 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -168,6 +168,7 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) subdriver = usb_cdc_wdm_register(ctx->control, &dev->status->desc, le16_to_cpu(ctx->mbim_desc->wMaxControlMessage), + WWAN_PORT_MBIM, cdc_mbim_wdm_manage_power); if (IS_ERR(subdriver)) { ret = PTR_ERR(subdriver); @@ -300,8 +301,8 @@ error: return NULL; } -/* Some devices are known to send Neigbor Solicitation messages and - * require Neigbor Advertisement replies. The IPv6 core will not +/* Some devices are known to send Neighbor Solicitation messages and + * require Neighbor Advertisement replies. The IPv6 core will not * respond since IFF_NOARP is set, so we must handle them ourselves. */ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci) @@ -588,7 +589,7 @@ static const struct driver_info cdc_mbim_info_zlp = { * * Note: The current implementation of this feature restricts each NTB * to a single NDP, implying that multiplexed sessions cannot share an - * NTB. This might affect performace for multiplexed sessions. + * NTB. This might affect performance for multiplexed sessions. */ static const struct driver_info cdc_mbim_info_ndp_to_end = { .description = "CDC MBIM", diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index df0d1837e4ed..24753a4da7e6 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -192,7 +192,8 @@ static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx) return val; } -static ssize_t cdc_ncm_show_min_tx_pkt(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t min_tx_pkt_show(struct device *d, + struct device_attribute *attr, char *buf) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -200,7 +201,8 @@ static ssize_t cdc_ncm_show_min_tx_pkt(struct device *d, struct device_attribute return sprintf(buf, "%u\n", ctx->min_tx_pkt); } -static ssize_t cdc_ncm_show_rx_max(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t rx_max_show(struct device *d, + struct device_attribute *attr, char *buf) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -208,7 +210,8 @@ static ssize_t cdc_ncm_show_rx_max(struct device *d, struct device_attribute *at return sprintf(buf, "%u\n", ctx->rx_max); } -static ssize_t cdc_ncm_show_tx_max(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t tx_max_show(struct device *d, + struct device_attribute *attr, char *buf) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -216,7 +219,8 @@ static ssize_t cdc_ncm_show_tx_max(struct device *d, struct device_attribute *at return sprintf(buf, "%u\n", ctx->tx_max); } -static ssize_t cdc_ncm_show_tx_timer_usecs(struct device *d, struct device_attribute *attr, char *buf) +static ssize_t tx_timer_usecs_show(struct device *d, + struct device_attribute *attr, char *buf) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -224,7 +228,9 @@ static ssize_t cdc_ncm_show_tx_timer_usecs(struct device *d, struct device_attri return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC); } -static ssize_t cdc_ncm_store_min_tx_pkt(struct device *d, struct device_attribute *attr, const char *buf, size_t len) +static ssize_t min_tx_pkt_store(struct device *d, + struct device_attribute *attr, + const char *buf, size_t len) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -238,7 +244,9 @@ static ssize_t cdc_ncm_store_min_tx_pkt(struct device *d, struct device_attribu return len; } -static ssize_t cdc_ncm_store_rx_max(struct device *d, struct device_attribute *attr, const char *buf, size_t len) +static ssize_t rx_max_store(struct device *d, + struct device_attribute *attr, + const char *buf, size_t len) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -251,7 +259,9 @@ static ssize_t cdc_ncm_store_rx_max(struct device *d, struct device_attribute * return len; } -static ssize_t cdc_ncm_store_tx_max(struct device *d, struct device_attribute *attr, const char *buf, size_t len) +static ssize_t tx_max_store(struct device *d, + struct device_attribute *attr, + const char *buf, size_t len) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -264,7 +274,9 @@ static ssize_t cdc_ncm_store_tx_max(struct device *d, struct device_attribute * return len; } -static ssize_t cdc_ncm_store_tx_timer_usecs(struct device *d, struct device_attribute *attr, const char *buf, size_t len) +static ssize_t tx_timer_usecs_store(struct device *d, + struct device_attribute *attr, + const char *buf, size_t len) { struct usbnet *dev = netdev_priv(to_net_dev(d)); struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; @@ -285,10 +297,10 @@ static ssize_t cdc_ncm_store_tx_timer_usecs(struct device *d, struct device_att return len; } -static DEVICE_ATTR(min_tx_pkt, 0644, cdc_ncm_show_min_tx_pkt, cdc_ncm_store_min_tx_pkt); -static DEVICE_ATTR(rx_max, 0644, cdc_ncm_show_rx_max, cdc_ncm_store_rx_max); -static DEVICE_ATTR(tx_max, 0644, cdc_ncm_show_tx_max, cdc_ncm_store_tx_max); -static DEVICE_ATTR(tx_timer_usecs, 0644, cdc_ncm_show_tx_timer_usecs, cdc_ncm_store_tx_timer_usecs); +static DEVICE_ATTR_RW(min_tx_pkt); +static DEVICE_ATTR_RW(rx_max); +static DEVICE_ATTR_RW(tx_max); +static DEVICE_ATTR_RW(tx_timer_usecs); static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr, char *buf) { @@ -628,7 +640,7 @@ out: /* set MTU to max supported by the device if necessary */ dev->net->mtu = min_t(int, dev->net->mtu, ctx->max_datagram_size - cdc_ncm_eth_hlen(dev)); - /* do not exceed operater preferred MTU */ + /* do not exceed operator preferred MTU */ if (ctx->mbim_extended_desc) { mbim_mtu = le16_to_cpu(ctx->mbim_extended_desc->wMTU); if (mbim_mtu != 0 && mbim_mtu < dev->net->mtu) @@ -685,7 +697,7 @@ static int cdc_ncm_setup(struct usbnet *dev) struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; u32 def_rx, def_tx; - /* be conservative when selecting intial buffer size to + /* be conservative when selecting initial buffer size to * increase the number of hosts this will work for */ def_rx = min_t(u32, CDC_NCM_NTB_DEF_SIZE_RX, diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 5c779cc0ea11..63006838bdcc 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -457,9 +457,8 @@ static const struct usb_device_id hso_ids[] = { MODULE_DEVICE_TABLE(usb, hso_ids); /* Sysfs attribute */ -static ssize_t hso_sysfs_show_porttype(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t hsotype_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct hso_device *hso_dev = dev_get_drvdata(dev); char *port_name; @@ -505,7 +504,7 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev, return sprintf(buf, "%s\n", port_name); } -static DEVICE_ATTR(hsotype, 0444, hso_sysfs_show_porttype, NULL); +static DEVICE_ATTR_RO(hsotype); static struct attribute *hso_serial_dev_attrs[] = { &dev_attr_hsotype.attr, @@ -1357,10 +1356,10 @@ out: } /* how much room is there for writing */ -static int hso_serial_write_room(struct tty_struct *tty) +static unsigned int hso_serial_write_room(struct tty_struct *tty) { struct hso_serial *serial = tty->driver_data; - int room; + unsigned int room; unsigned long flags; spin_lock_irqsave(&serial->serial_lock, flags); @@ -1404,11 +1403,11 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) } /* how many characters in the buffer */ -static int hso_serial_chars_in_buffer(struct tty_struct *tty) +static unsigned int hso_serial_chars_in_buffer(struct tty_struct *tty) { struct hso_serial *serial = tty->driver_data; - int chars; unsigned long flags; + unsigned int chars; /* sanity check */ if (serial == NULL) diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c index a87f0dabcdb7..849b77330bf2 100644 --- a/drivers/net/usb/huawei_cdc_ncm.c +++ b/drivers/net/usb/huawei_cdc_ncm.c @@ -96,6 +96,7 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev, subdriver = usb_cdc_wdm_register(ctx->control, &usbnet_dev->status->desc, 1024, /* wMaxCommand */ + WWAN_PORT_AT, huawei_cdc_ncm_wdm_manage_power); if (IS_ERR(subdriver)) { ret = PTR_ERR(subdriver); diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index ed05f992c612..6fde41550de1 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c @@ -61,7 +61,7 @@ static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev, int need_tail = 0; __le16 *len; - /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */ + /* if packet and our header is smaller than 64 pad to 64 (+ ZLP) */ if ((pack_with_header_len) < dev->maxpacket) need_tail = dev->maxpacket - pack_with_header_len + 1; /* diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 02bce40a67e5..25489389ea49 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -298,7 +298,7 @@ struct lan78xx_net; struct lan78xx_priv { struct lan78xx_net *dev; u32 rfe_ctl; - u32 mchash_table[DP_SEL_VHF_HASH_LEN]; /* multicat hash table */ + u32 mchash_table[DP_SEL_VHF_HASH_LEN]; /* multicast hash table */ u32 pfilter_table[NUM_OF_MAF][2]; /* perfect filter table */ u32 vlan_table[DP_SEL_VHF_VLAN_LEN]; struct mutex dataport_mutex; /* for dataport access */ diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c index 217a2d8fa47b..b2495fa80171 100644 --- a/drivers/net/usb/lg-vl600.c +++ b/drivers/net/usb/lg-vl600.c @@ -31,7 +31,7 @@ * Windows/Mac drivers do send a couple of such frames to the device * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what * seems to be) a flag in the .dummy_flags. This doesn't seem necessary - * for modem operation but can possibly be used for GPS or other funcitons. + * for modem operation but can possibly be used for GPS or other functions. */ struct vl600_frame_hdr { @@ -72,7 +72,7 @@ static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) /* ARP packets don't go through, but they're also of no use. The * subnet has only two hosts anyway: us and the gateway / DHCP * server (probably simulated by modem firmware or network operator) - * whose address changes everytime we connect to the intarwebz and + * whose address changes every time we connect to the intarwebz and * who doesn't bother answering ARP requests either. So hardware * addresses have no meaning, the destination and the source of every * packet depend only on whether it is on the IN or OUT endpoint. */ diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 9f9352a4522f..2469bdcb1a04 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -601,7 +601,7 @@ MODULE_DEVICE_TABLE(usb, products); static int mcs7830_reset_resume (struct usb_interface *intf) { - /* YES, this function is successful enough that ethtool -d + /* YES, this function is successful enough that ethtool -d does show same output pre-/post-suspend */ struct usbnet *dev = usb_get_intfdata(intf); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index bc55ec739af9..6a2e4f884b12 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -710,7 +710,8 @@ static int qmi_wwan_register_subdriver(struct usbnet *dev) /* register subdriver */ subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, - 4096, &qmi_wwan_cdc_wdm_manage_power); + 4096, WWAN_PORT_QMI, + &qmi_wwan_cdc_wdm_manage_power); if (IS_ERR(subdriver)) { dev_err(&info->control->dev, "subdriver registration failed\n"); rv = PTR_ERR(subdriver); diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e25bfb7021ed..1692d3b1b6e1 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -931,6 +931,8 @@ struct r8152 { u32 rx_pending; u32 fc_pause_on, fc_pause_off; + unsigned int pipe_in, pipe_out, pipe_intr, pipe_ctrl_in, pipe_ctrl_out; + u32 support_2500full:1; u32 lenovo_macpassthru:1; u32 dell_tb_rx_agg_bug:1; @@ -1198,7 +1200,7 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) if (!tmp) return -ENOMEM; - ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), + ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, value, index, tmp, size, 500); if (ret < 0) @@ -1221,7 +1223,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) if (!tmp) return -ENOMEM; - ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), + ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out, RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, value, index, tmp, size, 500); @@ -2041,7 +2043,7 @@ static int alloc_all_mem(struct r8152 *tp) goto err1; tp->intr_interval = (int)ep_intr->desc.bInterval; - usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3), + usb_fill_int_urb(tp->intr_urb, tp->udev, tp->pipe_intr, tp->intr_buff, INTBUFSIZE, intr_callback, tp, tp->intr_interval); @@ -2305,7 +2307,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) if (ret < 0) goto out_tx_fill; - usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), + usb_fill_bulk_urb(agg->urb, tp->udev, tp->pipe_out, agg->head, (int)(tx_data - (u8 *)agg->head), (usb_complete_t)write_bulk_callback, agg); @@ -2445,7 +2447,7 @@ static int rx_bottom(struct r8152 *tp, int budget) unsigned int pkt_len, rx_frag_head_sz; struct sk_buff *skb; - /* limite the skb numbers for rx_queue */ + /* limit the skb numbers for rx_queue */ if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) break; @@ -2620,7 +2622,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) !test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev)) return 0; - usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), + usb_fill_bulk_urb(agg->urb, tp->udev, tp->pipe_in, agg->buffer, tp->rx_buf_sz, (usb_complete_t)read_bulk_callback, agg); @@ -8211,7 +8213,7 @@ static int rtl8152_post_reset(struct usb_interface *intf) if (!tp) return 0; - /* reset the MAC adddress in case of policy change */ + /* reset the MAC address in case of policy change */ if (determine_ethernet_addr(tp, &sa) >= 0) { rtnl_lock(); dev_set_mac_address (tp->netdev, &sa, NULL); @@ -8967,6 +8969,79 @@ static int rtl8152_set_ringparam(struct net_device *netdev, return 0; } +static void rtl8152_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) +{ + struct r8152 *tp = netdev_priv(netdev); + u16 bmcr, lcladv, rmtadv; + u8 cap; + + if (usb_autopm_get_interface(tp->intf) < 0) + return; + + mutex_lock(&tp->control); + + bmcr = r8152_mdio_read(tp, MII_BMCR); + lcladv = r8152_mdio_read(tp, MII_ADVERTISE); + rmtadv = r8152_mdio_read(tp, MII_LPA); + + mutex_unlock(&tp->control); + + usb_autopm_put_interface(tp->intf); + + if (!(bmcr & BMCR_ANENABLE)) { + pause->autoneg = 0; + pause->rx_pause = 0; + pause->tx_pause = 0; + return; + } + + pause->autoneg = 1; + + cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); + + if (cap & FLOW_CTRL_RX) + pause->rx_pause = 1; + + if (cap & FLOW_CTRL_TX) + pause->tx_pause = 1; +} + +static int rtl8152_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) +{ + struct r8152 *tp = netdev_priv(netdev); + u16 old, new1; + u8 cap = 0; + int ret; + + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + return ret; + + mutex_lock(&tp->control); + + if (pause->autoneg && !(r8152_mdio_read(tp, MII_BMCR) & BMCR_ANENABLE)) { + ret = -EINVAL; + goto out; + } + + if (pause->rx_pause) + cap |= FLOW_CTRL_RX; + + if (pause->tx_pause) + cap |= FLOW_CTRL_TX; + + old = r8152_mdio_read(tp, MII_ADVERTISE); + new1 = (old & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) | mii_advertise_flowctrl(cap); + if (old != new1) + r8152_mdio_write(tp, MII_ADVERTISE, new1); + +out: + mutex_unlock(&tp->control); + usb_autopm_put_interface(tp->intf); + + return ret; +} + static const struct ethtool_ops ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS, .get_drvinfo = rtl8152_get_drvinfo, @@ -8989,6 +9064,8 @@ static const struct ethtool_ops ops = { .set_tunable = rtl8152_set_tunable, .get_ringparam = rtl8152_get_ringparam, .set_ringparam = rtl8152_set_ringparam, + .get_pauseparam = rtl8152_get_pauseparam, + .set_pauseparam = rtl8152_set_pauseparam, }; static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) @@ -9432,6 +9509,12 @@ static int rtl8152_probe(struct usb_interface *intf, tp->intf = intf; tp->version = version; + tp->pipe_ctrl_in = usb_rcvctrlpipe(udev, 0); + tp->pipe_ctrl_out = usb_sndctrlpipe(udev, 0); + tp->pipe_in = usb_rcvbulkpipe(udev, 1); + tp->pipe_out = usb_sndbulkpipe(udev, 2); + tp->pipe_intr = usb_rcvintpipe(udev, 3); + switch (version) { case RTL_VER_01: case RTL_VER_02: diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index f813ca9dec53..85a8b96e39a6 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -324,7 +324,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) * For RX we handle drivers that zero-pad to end-of-packet. * Don't let userspace change these settings. * - * NOTE: there still seems to be wierdness here, as if we need + * NOTE: there still seems to be weirdness here, as if we need * to do some more things to make sure WinCE targets accept this. * They default to jumbograms of 8KB or 16KB, which is absurd * for such low data rates and which is also more than Linux diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ecf62849f4c1..470e1c1e6353 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -74,6 +74,23 @@ MODULE_PARM_DESC (msg_level, "Override default message level"); /*-------------------------------------------------------------------------*/ +static const char * const usbnet_event_names[] = { + [EVENT_TX_HALT] = "EVENT_TX_HALT", + [EVENT_RX_HALT] = "EVENT_RX_HALT", + [EVENT_RX_MEMORY] = "EVENT_RX_MEMORY", + [EVENT_STS_SPLIT] = "EVENT_STS_SPLIT", + [EVENT_LINK_RESET] = "EVENT_LINK_RESET", + [EVENT_RX_PAUSED] = "EVENT_RX_PAUSED", + [EVENT_DEV_ASLEEP] = "EVENT_DEV_ASLEEP", + [EVENT_DEV_OPEN] = "EVENT_DEV_OPEN", + [EVENT_DEVICE_REPORT_IDLE] = "EVENT_DEVICE_REPORT_IDLE", + [EVENT_NO_RUNTIME_PM] = "EVENT_NO_RUNTIME_PM", + [EVENT_RX_KILL] = "EVENT_RX_KILL", + [EVENT_LINK_CHANGE] = "EVENT_LINK_CHANGE", + [EVENT_SET_RX_MODE] = "EVENT_SET_RX_MODE", + [EVENT_NO_IP_ALIGN] = "EVENT_NO_IP_ALIGN", +}; + /* handles CDC Ethernet and many other network "bulk data" interfaces */ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) { @@ -452,9 +469,9 @@ void usbnet_defer_kevent (struct usbnet *dev, int work) { set_bit (work, &dev->flags); if (!schedule_work (&dev->kevent)) - netdev_dbg(dev->net, "kevent %d may have been dropped\n", work); + netdev_dbg(dev->net, "kevent %s may have been dropped\n", usbnet_event_names[work]); else - netdev_dbg(dev->net, "kevent %d scheduled\n", work); + netdev_dbg(dev->net, "kevent %s scheduled\n", usbnet_event_names[work]); } EXPORT_SYMBOL_GPL(usbnet_defer_kevent); @@ -1597,6 +1614,9 @@ void usbnet_disconnect (struct usb_interface *intf) xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); + if (dev->driver_info->unbind) + dev->driver_info->unbind(dev, intf); + net = dev->net; unregister_netdev (net); @@ -1604,9 +1624,6 @@ void usbnet_disconnect (struct usb_interface *intf) usb_scuttle_anchored_urbs(&dev->deferred); - if (dev->driver_info->unbind) - dev->driver_info->unbind (dev, intf); - usb_kill_urb(dev->interrupt); usb_free_urb(dev->interrupt); kfree(dev->padding_pkt); |