Skip to content

Commit

Permalink
NET: fix phy init for AX88772 USB ethernet
Browse files Browse the repository at this point in the history
Fix phy initialization for AX88772 (USB 2.0 100BT). Failure was
occasionally DHCP wouldn't work after reboot or suspend/resume cycle.

Remove MONITOR_MODE. In this mode, Received packets are not buffered when
the remote wakeup is enabled.

Signed-off-by: "Freddy Xin" <freddy@asix.com.tw>
Signed-off-by: Grant Grundler <grundler@chromium.org>
Acked-by: Olof Johansson <olofj@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Grant Grundler authored and David S. Miller committed Oct 4, 2011
1 parent 349d289 commit 4ad1438
Showing 1 changed file with 61 additions and 54 deletions.
115 changes: 61 additions & 54 deletions drivers/net/usb/asix.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include <linux/usb/usbnet.h>
#include <linux/slab.h>

#define DRIVER_VERSION "14-Jun-2006"
#define DRIVER_VERSION "26-Sep-2011"
static const char driver_name [] = "asix";

/* ASIX AX8817X based USB 2.0 Ethernet Devices */
Expand Down Expand Up @@ -676,12 +676,6 @@ asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
}
wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
wolinfo->wolopts = 0;
if (opt & AX_MONITOR_MODE) {
if (opt & AX_MONITOR_LINK)
wolinfo->wolopts |= WAKE_PHY;
if (opt & AX_MONITOR_MAGIC)
wolinfo->wolopts |= WAKE_MAGIC;
}
}

static int
Expand All @@ -694,8 +688,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
opt |= AX_MONITOR_LINK;
if (wolinfo->wolopts & WAKE_MAGIC)
opt |= AX_MONITOR_MAGIC;
if (opt != 0)
opt |= AX_MONITOR_MODE;

if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
opt, 0, 0, NULL) < 0)
Expand Down Expand Up @@ -966,36 +958,17 @@ static int ax88772_link_reset(struct usbnet *dev)
return 0;
}

static const struct net_device_ops ax88772_netdev_ops = {
.ndo_open = usbnet_open,
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_change_mtu = usbnet_change_mtu,
.ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = asix_ioctl,
.ndo_set_rx_mode = asix_set_multicast,
};

static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
static int ax88772_reset(struct usbnet *dev)
{
int ret, embd_phy;
u16 rx_ctl;
struct asix_data *data = (struct asix_data *)&dev->data;
u8 buf[ETH_ALEN];
u32 phyid;

data->eeprom_len = AX88772_EEPROM_LEN;

usbnet_get_endpoints(dev,intf);

if ((ret = asix_write_gpio(dev,
AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
goto out;

/* 0x10 is the phy id of the embedded 10/100 ethernet phy */
embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);

if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
embd_phy, 0, 0, NULL)) < 0) {
dbg("Select PHY #1 failed: %d", ret);
Expand All @@ -1010,6 +983,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out;

msleep(150);

if (embd_phy) {
if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0)
goto out;
Expand All @@ -1028,25 +1002,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
rx_ctl = asix_read_rx_ctl(dev);
dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);

/* Get the MAC address */
if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
0, 0, ETH_ALEN, buf)) < 0) {
dbg("Failed to read MAC address: %d", ret);
goto out;
}
memcpy(dev->net->dev_addr, buf, ETH_ALEN);

/* 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);

phyid = asix_get_phyid(dev);
dbg("PHYID=0x%08x", phyid);

if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0)
goto out;

Expand All @@ -1057,9 +1012,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)

msleep(150);

dev->net->netdev_ops = &ax88772_netdev_ops;
dev->net->ethtool_ops = &ax88772_ethtool_ops;

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);
Expand All @@ -1085,14 +1037,68 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
rx_ctl = asix_read_medium_status(dev);
dbg("Medium Status is 0x%04x after all initializations", rx_ctl);

return 0;

out:
return ret;

}

static const struct net_device_ops ax88772_netdev_ops = {
.ndo_open = usbnet_open,
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_change_mtu = usbnet_change_mtu,
.ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = asix_ioctl,
.ndo_set_rx_mode = asix_set_multicast,
};

static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
struct asix_data *data = (struct asix_data *)&dev->data;
u8 buf[ETH_ALEN];
u32 phyid;

data->eeprom_len = AX88772_EEPROM_LEN;

usbnet_get_endpoints(dev,intf);

/* Get the MAC address */
if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
0, 0, ETH_ALEN, buf)) < 0) {
dbg("Failed to read MAC address: %d", ret);
goto out;
}
memcpy(dev->net->dev_addr, buf, ETH_ALEN);

/* 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);

phyid = asix_get_phyid(dev);
dbg("PHYID=0x%08x", phyid);

dev->net->netdev_ops = &ax88772_netdev_ops;
dev->net->ethtool_ops = &ax88772_ethtool_ops;

if ((ret = ax88772_reset(dev)) < 0)
goto out;

/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
/* hard_mtu is still the default - the device does not support
jumbo eth frames */
dev->rx_urb_size = 2048;
}
return 0;

out:
return ret;
}
Expand Down Expand Up @@ -1426,7 +1432,7 @@ static const struct driver_info ax88772_info = {
.bind = ax88772_bind,
.status = asix_status,
.link_reset = ax88772_link_reset,
.reset = ax88772_link_reset,
.reset = ax88772_reset,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
.rx_fixup = asix_rx_fixup,
.tx_fixup = asix_tx_fixup,
Expand Down Expand Up @@ -1588,6 +1594,7 @@ static void __exit asix_exit(void)
module_exit(asix_exit);

MODULE_AUTHOR("David Hollis");
MODULE_VERSION(DRIVER_VERSION);
MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
MODULE_LICENSE("GPL");

0 comments on commit 4ad1438

Please sign in to comment.