[as plain text this time...] Robert, On Mon, Jul 25, 2016 at 10:40 AM, <robert.foss@xxxxxxxxxxxxx> wrote: > From: Grant Grundler <grundler@xxxxxxxxxxxx> For the record, I believe I am not the author of these patches. I believe the original author is Signed-off-by: Freddy Xin <freddy@xxxxxxxxxxx> as recorded in the following code reviews (and testing) that I was responsible for: https://chromium-review.googlesource.com/#/q/owner:%22Grant+Grundler%22+status:merged+asix+in_pm And I would certainly be happy to see this code go upstream and expected ASIX would submit this change upstream. > In order to R/W registers in suspend/resume functions, in_pm flags are > added to some functions to determine whether the nopm version of usb > functions is called. FTR, current drivers/net/usb/ax88179_178a.c uses "in_pm" as well. > Save BMCR and ANAR PHY registers in suspend function and restore them > in resume function. > > Reset HW in resume function to ensure the PHY works correctly. > > Signed-off-by: Grant Grundler <grundler@xxxxxxxxxxxx> BTW, I have two additional changes for AX88772x support sitting in my "needs more work" queue (for quite a while already): https://chromium-review.googlesource.com/#/c/229620/ "asix: autoneg will set WRITE_MEDIUM reg" https://chromium-review.googlesource.com/#/c/231162/ "net: asix: see 802.3 spec for phy reset" I would certainly approve if _anyone_ picked these up, tested them, and then submitted them to netdev. cheers, grant > --- > drivers/net/usb/asix.h | 40 +++-- > drivers/net/usb/asix_common.c | 180 +++++++++++++++----- > drivers/net/usb/asix_devices.c | 373 ++++++++++++++++++++++++++++++++--------- > drivers/net/usb/ax88172a.c | 29 ++-- > 4 files changed, 472 insertions(+), 150 deletions(-) > > diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h > index a2d3ea6..d109242 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 bd9acff..f0ccf76 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,23 @@ 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; > > mutex_lock(&dev->phy_mutex); > - asix_set_sw_mii(dev); > + do { > + asix_set_sw_mii(dev, 0); > + usleep_range(1000, 1100); > + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 0); > + } while (!(smsr & AX_HOST_EN) && (i++ < 30)); > + > 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 +451,71 @@ 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; > > 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); > + do { > + asix_set_sw_mii(dev, 0); > + usleep_range(1000, 1100); > + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 0); > + } while (!(smsr & AX_HOST_EN) && (i++ < 30)); > + > + 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; > + > + mutex_lock(&dev->phy_mutex); > + do { > + asix_set_sw_mii(dev, 1); > + usleep_range(1000, 1100); > + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 1); > + } while (!(smsr & AX_HOST_EN) && (i++ < 30)); > + > + 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; > + > + 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); > - 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 { > + asix_set_sw_mii(dev, 1); > + usleep_range(1000, 1100); > + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &smsr, 1); > + } while (!(smsr & AX_HOST_EN) && (i++ < 30)); > + > + 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 +524,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 +549,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 +584,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 +625,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 +634,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 +644,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 +655,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 +664,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 5cabefc..aaa4290 100644 > --- a/drivers/net/usb/asix_devices.c > +++ b/drivers/net/usb/asix_devices.c > @@ -184,7 +184,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; > } > @@ -213,18 +213,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); > @@ -290,7 +291,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 +299,192 @@ 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; > + > + ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT, 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_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; > + } > > - ret = asix_sw_reset(dev, AX_SWRESET_PRL); > + /* 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; > > - msleep(150); > + /* 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, 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; > + u8 chipcode = 0; > > - ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL); > + 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_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT); > + 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_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; > + } > + } > + > 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 +493,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, in_pm); > if (ret < 0) > goto out; > > + 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); > + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, in_pm); > if (ret < 0) > goto out; > > - rx_ctl = asix_read_rx_ctl(dev); > + 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 +524,6 @@ static int ax88772_reset(struct usbnet *dev) > > out: > return ret; > - > } > > static const struct net_device_ops ax88772_netdev_ops = { > @@ -415,11 +538,87 @@ 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; > + > + /* 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); > + > + 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 +626,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 +655,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); > + asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0); > + chipcode &= AX_CHIPCODE_MASK; > > - /* 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; > - } > - > - 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 +676,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 +799,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 +820,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 +837,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); > @@ -655,18 +862,18 @@ static int ax88178_reset(struct usbnet *dev) > > mii_nway_restart(&dev->mii); > > - ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT); > + ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT, 0); > 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 +911,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 +940,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 +997,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 +1018,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 +1084,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 +1212,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 +1280,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 +1302,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 5f18fcb..c2394f1 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); > @@ -205,18 +205,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; > > @@ -242,7 +243,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; > @@ -253,7 +254,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); > @@ -332,20 +333,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; > @@ -354,20 +355,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); > > -- > 2.7.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html