aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/asix.c
diff options
context:
space:
mode:
authorGrant Grundler <grundler@chromium.org>2011-10-04 05:55:16 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-04 16:25:31 -0400
commit4ad1438f025ed8d1e4e95a796ca7f0ad5a22c378 (patch)
tree532dd31a2132dcd346e2011a84fdc75912bfb98a /drivers/net/usb/asix.c
parent349d2895cc8b7db1f5be677cd685209a3805d2ed (diff)
NET: fix phy init for AX88772 USB ethernet
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>
Diffstat (limited to 'drivers/net/usb/asix.c')
-rw-r--r--drivers/net/usb/asix.c115
1 files changed, 61 insertions, 54 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index b843eedd409d..9e0b3776b80a 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -36,7 +36,7 @@
36#include <linux/usb/usbnet.h> 36#include <linux/usb/usbnet.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38 38
39#define DRIVER_VERSION "14-Jun-2006" 39#define DRIVER_VERSION "26-Sep-2011"
40static const char driver_name [] = "asix"; 40static const char driver_name [] = "asix";
41 41
42/* ASIX AX8817X based USB 2.0 Ethernet Devices */ 42/* ASIX AX8817X based USB 2.0 Ethernet Devices */
@@ -676,12 +676,6 @@ asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
676 } 676 }
677 wolinfo->supported = WAKE_PHY | WAKE_MAGIC; 677 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
678 wolinfo->wolopts = 0; 678 wolinfo->wolopts = 0;
679 if (opt & AX_MONITOR_MODE) {
680 if (opt & AX_MONITOR_LINK)
681 wolinfo->wolopts |= WAKE_PHY;
682 if (opt & AX_MONITOR_MAGIC)
683 wolinfo->wolopts |= WAKE_MAGIC;
684 }
685} 679}
686 680
687static int 681static int
@@ -694,8 +688,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
694 opt |= AX_MONITOR_LINK; 688 opt |= AX_MONITOR_LINK;
695 if (wolinfo->wolopts & WAKE_MAGIC) 689 if (wolinfo->wolopts & WAKE_MAGIC)
696 opt |= AX_MONITOR_MAGIC; 690 opt |= AX_MONITOR_MAGIC;
697 if (opt != 0)
698 opt |= AX_MONITOR_MODE;
699 691
700 if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, 692 if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
701 opt, 0, 0, NULL) < 0) 693 opt, 0, 0, NULL) < 0)
@@ -966,36 +958,17 @@ static int ax88772_link_reset(struct usbnet *dev)
966 return 0; 958 return 0;
967} 959}
968 960
969static const struct net_device_ops ax88772_netdev_ops = { 961static int ax88772_reset(struct usbnet *dev)
970 .ndo_open = usbnet_open,
971 .ndo_stop = usbnet_stop,
972 .ndo_start_xmit = usbnet_start_xmit,
973 .ndo_tx_timeout = usbnet_tx_timeout,
974 .ndo_change_mtu = usbnet_change_mtu,
975 .ndo_set_mac_address = asix_set_mac_address,
976 .ndo_validate_addr = eth_validate_addr,
977 .ndo_do_ioctl = asix_ioctl,
978 .ndo_set_rx_mode = asix_set_multicast,
979};
980
981static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
982{ 962{
983 int ret, embd_phy; 963 int ret, embd_phy;
984 u16 rx_ctl; 964 u16 rx_ctl;
985 struct asix_data *data = (struct asix_data *)&dev->data;
986 u8 buf[ETH_ALEN];
987 u32 phyid;
988
989 data->eeprom_len = AX88772_EEPROM_LEN;
990
991 usbnet_get_endpoints(dev,intf);
992 965
993 if ((ret = asix_write_gpio(dev, 966 if ((ret = asix_write_gpio(dev,
994 AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) 967 AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
995 goto out; 968 goto out;
996 969
997 /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
998 embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); 970 embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
971
999 if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 972 if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
1000 embd_phy, 0, 0, NULL)) < 0) { 973 embd_phy, 0, 0, NULL)) < 0) {
1001 dbg("Select PHY #1 failed: %d", ret); 974 dbg("Select PHY #1 failed: %d", ret);
@@ -1010,6 +983,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1010 goto out; 983 goto out;
1011 984
1012 msleep(150); 985 msleep(150);
986
1013 if (embd_phy) { 987 if (embd_phy) {
1014 if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) 988 if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0)
1015 goto out; 989 goto out;
@@ -1028,25 +1002,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1028 rx_ctl = asix_read_rx_ctl(dev); 1002 rx_ctl = asix_read_rx_ctl(dev);
1029 dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); 1003 dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
1030 1004
1031 /* Get the MAC address */
1032 if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
1033 0, 0, ETH_ALEN, buf)) < 0) {
1034 dbg("Failed to read MAC address: %d", ret);
1035 goto out;
1036 }
1037 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
1038
1039 /* Initialize MII structure */
1040 dev->mii.dev = dev->net;
1041 dev->mii.mdio_read = asix_mdio_read;
1042 dev->mii.mdio_write = asix_mdio_write;
1043 dev->mii.phy_id_mask = 0x1f;
1044 dev->mii.reg_num_mask = 0x1f;
1045 dev->mii.phy_id = asix_get_phy_addr(dev);
1046
1047 phyid = asix_get_phyid(dev);
1048 dbg("PHYID=0x%08x", phyid);
1049
1050 if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) 1005 if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0)
1051 goto out; 1006 goto out;
1052 1007
@@ -1057,9 +1012,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1057 1012
1058 msleep(150); 1013 msleep(150);
1059 1014
1060 dev->net->netdev_ops = &ax88772_netdev_ops;
1061 dev->net->ethtool_ops = &ax88772_ethtool_ops;
1062
1063 asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); 1015 asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
1064 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, 1016 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
1065 ADVERTISE_ALL | ADVERTISE_CSMA); 1017 ADVERTISE_ALL | ADVERTISE_CSMA);
@@ -1085,6 +1037,61 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1085 rx_ctl = asix_read_medium_status(dev); 1037 rx_ctl = asix_read_medium_status(dev);
1086 dbg("Medium Status is 0x%04x after all initializations", rx_ctl); 1038 dbg("Medium Status is 0x%04x after all initializations", rx_ctl);
1087 1039
1040 return 0;
1041
1042out:
1043 return ret;
1044
1045}
1046
1047static const struct net_device_ops ax88772_netdev_ops = {
1048 .ndo_open = usbnet_open,
1049 .ndo_stop = usbnet_stop,
1050 .ndo_start_xmit = usbnet_start_xmit,
1051 .ndo_tx_timeout = usbnet_tx_timeout,
1052 .ndo_change_mtu = usbnet_change_mtu,
1053 .ndo_set_mac_address = asix_set_mac_address,
1054 .ndo_validate_addr = eth_validate_addr,
1055 .ndo_do_ioctl = asix_ioctl,
1056 .ndo_set_rx_mode = asix_set_multicast,
1057};
1058
1059static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1060{
1061 int ret;
1062 struct asix_data *data = (struct asix_data *)&dev->data;
1063 u8 buf[ETH_ALEN];
1064 u32 phyid;
1065
1066 data->eeprom_len = AX88772_EEPROM_LEN;
1067
1068 usbnet_get_endpoints(dev,intf);
1069
1070 /* Get the MAC address */
1071 if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
1072 0, 0, ETH_ALEN, buf)) < 0) {
1073 dbg("Failed to read MAC address: %d", ret);
1074 goto out;
1075 }
1076 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
1077
1078 /* Initialize MII structure */
1079 dev->mii.dev = dev->net;
1080 dev->mii.mdio_read = asix_mdio_read;
1081 dev->mii.mdio_write = asix_mdio_write;
1082 dev->mii.phy_id_mask = 0x1f;
1083 dev->mii.reg_num_mask = 0x1f;
1084 dev->mii.phy_id = asix_get_phy_addr(dev);
1085
1086 phyid = asix_get_phyid(dev);
1087 dbg("PHYID=0x%08x", phyid);
1088
1089 dev->net->netdev_ops = &ax88772_netdev_ops;
1090 dev->net->ethtool_ops = &ax88772_ethtool_ops;
1091
1092 if ((ret = ax88772_reset(dev)) < 0)
1093 goto out;
1094
1088 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ 1095 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
1089 if (dev->driver_info->flags & FLAG_FRAMING_AX) { 1096 if (dev->driver_info->flags & FLAG_FRAMING_AX) {
1090 /* hard_mtu is still the default - the device does not support 1097 /* hard_mtu is still the default - the device does not support
@@ -1092,7 +1099,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
1092 dev->rx_urb_size = 2048; 1099 dev->rx_urb_size = 2048;
1093 } 1100 }
1094 return 0; 1101 return 0;
1095
1096out: 1102out:
1097 return ret; 1103 return ret;
1098} 1104}
@@ -1426,7 +1432,7 @@ static const struct driver_info ax88772_info = {
1426 .bind = ax88772_bind, 1432 .bind = ax88772_bind,
1427 .status = asix_status, 1433 .status = asix_status,
1428 .link_reset = ax88772_link_reset, 1434 .link_reset = ax88772_link_reset,
1429 .reset = ax88772_link_reset, 1435 .reset = ax88772_reset,
1430 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, 1436 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
1431 .rx_fixup = asix_rx_fixup, 1437 .rx_fixup = asix_rx_fixup,
1432 .tx_fixup = asix_tx_fixup, 1438 .tx_fixup = asix_tx_fixup,
@@ -1588,6 +1594,7 @@ static void __exit asix_exit(void)
1588module_exit(asix_exit); 1594module_exit(asix_exit);
1589 1595
1590MODULE_AUTHOR("David Hollis"); 1596MODULE_AUTHOR("David Hollis");
1597MODULE_VERSION(DRIVER_VERSION);
1591MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices"); 1598MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
1592MODULE_LICENSE("GPL"); 1599MODULE_LICENSE("GPL");
1593 1600