aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorGrant Grundler <grundler@chromium.org>2011-10-04 05:55:17 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-04 16:25:31 -0400
commit610d885d3176bd807b582401e8990898ae25bed2 (patch)
tree89ce0b6233dd195c4728586b6702e683fbb9aea8 /drivers/net/usb
parent4ad1438f025ed8d1e4e95a796ca7f0ad5a22c378 (diff)
NET: fix phy init for Asix AX88178 USB (GigE)
Asix provided this patch and I've confirmed "Plugable USB2-E1000" and "Shenzhen Winstars NWU220G" USB dongles can get a link and TX/RX data. Signed-off-by: "Freddy Xin" <freddy@asix.com.tw> Signed-off-by: Grant Grundler <grundler@chromium.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/asix.c163
1 files changed, 101 insertions, 62 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 9e0b3776b80a..8d48affb65fd 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -164,6 +164,8 @@ static const char driver_name [] = "asix";
164#define MARVELL_CTRL_TXDELAY 0x0002 164#define MARVELL_CTRL_TXDELAY 0x0002
165#define MARVELL_CTRL_RXDELAY 0x0080 165#define MARVELL_CTRL_RXDELAY 0x0080
166 166
167#define PHY_MODE_RTL8211CL 0x0004
168
167/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ 169/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
168struct asix_data { 170struct asix_data {
169 u8 multi_filter[AX_MCAST_FILTER_SIZE]; 171 u8 multi_filter[AX_MCAST_FILTER_SIZE];
@@ -1149,6 +1151,27 @@ static int marvell_phy_init(struct usbnet *dev)
1149 return 0; 1151 return 0;
1150} 1152}
1151 1153
1154static int rtl8211cl_phy_init(struct usbnet *dev)
1155{
1156 struct asix_data *data = (struct asix_data *)&dev->data;
1157
1158 netdev_dbg(dev->net, "rtl8211cl_phy_init()\n");
1159
1160 asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0005);
1161 asix_mdio_write (dev->net, dev->mii.phy_id, 0x0c, 0);
1162 asix_mdio_write (dev->net, dev->mii.phy_id, 0x01,
1163 asix_mdio_read (dev->net, dev->mii.phy_id, 0x01) | 0x0080);
1164 asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0);
1165
1166 if (data->ledmode == 12) {
1167 asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0002);
1168 asix_mdio_write (dev->net, dev->mii.phy_id, 0x1a, 0x00cb);
1169 asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0);
1170 }
1171
1172 return 0;
1173}
1174
1152static int marvell_led_status(struct usbnet *dev, u16 speed) 1175static int marvell_led_status(struct usbnet *dev, u16 speed)
1153{ 1176{
1154 u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL); 1177 u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL);
@@ -1175,6 +1198,81 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
1175 return 0; 1198 return 0;
1176} 1199}
1177 1200
1201static int ax88178_reset(struct usbnet *dev)
1202{
1203 struct asix_data *data = (struct asix_data *)&dev->data;
1204 int ret;
1205 __le16 eeprom;
1206 u8 status;
1207 int gpio0 = 0;
1208
1209 asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
1210 dbg("GPIO Status: 0x%04x", status);
1211
1212 asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
1213 asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
1214 asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);
1215
1216 dbg("EEPROM index 0x17 is 0x%04x", eeprom);
1217
1218 if (eeprom == cpu_to_le16(0xffff)) {
1219 data->phymode = PHY_MODE_MARVELL;
1220 data->ledmode = 0;
1221 gpio0 = 1;
1222 } else {
1223 data->phymode = le16_to_cpu(eeprom) & 7;
1224 data->ledmode = le16_to_cpu(eeprom) >> 8;
1225 gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
1226 }
1227 dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
1228
1229 asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
1230 if ((le16_to_cpu(eeprom) >> 8) != 1) {
1231 asix_write_gpio(dev, 0x003c, 30);
1232 asix_write_gpio(dev, 0x001c, 300);
1233 asix_write_gpio(dev, 0x003c, 30);
1234 } else {
1235 dbg("gpio phymode == 1 path");
1236 asix_write_gpio(dev, AX_GPIO_GPO1EN, 30);
1237 asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
1238 }
1239
1240 asix_sw_reset(dev, 0);
1241 msleep(150);
1242
1243 asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
1244 msleep(150);
1245
1246 asix_write_rx_ctl(dev, 0);
1247
1248 if (data->phymode == PHY_MODE_MARVELL) {
1249 marvell_phy_init(dev);
1250 msleep(60);
1251 } else if (data->phymode == PHY_MODE_RTL8211CL)
1252 rtl8211cl_phy_init(dev);
1253
1254 asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
1255 BMCR_RESET | BMCR_ANENABLE);
1256 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
1257 ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
1258 asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
1259 ADVERTISE_1000FULL);
1260
1261 mii_nway_restart(&dev->mii);
1262
1263 if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0)
1264 goto out;
1265
1266 if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
1267 goto out;
1268
1269 return 0;
1270
1271out:
1272 return ret;
1273
1274}
1275
1178static int ax88178_link_reset(struct usbnet *dev) 1276static int ax88178_link_reset(struct usbnet *dev)
1179{ 1277{
1180 u16 mode; 1278 u16 mode;
@@ -1283,55 +1381,12 @@ static const struct net_device_ops ax88178_netdev_ops = {
1283 1381
1284static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) 1382static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
1285{ 1383{
1286 struct asix_data *data = (struct asix_data *)&dev->data;
1287 int ret; 1384 int ret;
1288 u8 buf[ETH_ALEN]; 1385 u8 buf[ETH_ALEN];
1289 __le16 eeprom;
1290 u8 status;
1291 int gpio0 = 0;
1292 u32 phyid; 1386 u32 phyid;
1293 1387
1294 usbnet_get_endpoints(dev,intf); 1388 usbnet_get_endpoints(dev,intf);
1295 1389
1296 asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
1297 dbg("GPIO Status: 0x%04x", status);
1298
1299 asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
1300 asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
1301 asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);
1302
1303 dbg("EEPROM index 0x17 is 0x%04x", eeprom);
1304
1305 if (eeprom == cpu_to_le16(0xffff)) {
1306 data->phymode = PHY_MODE_MARVELL;
1307 data->ledmode = 0;
1308 gpio0 = 1;
1309 } else {
1310 data->phymode = le16_to_cpu(eeprom) & 7;
1311 data->ledmode = le16_to_cpu(eeprom) >> 8;
1312 gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
1313 }
1314 dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
1315
1316 asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
1317 if ((le16_to_cpu(eeprom) >> 8) != 1) {
1318 asix_write_gpio(dev, 0x003c, 30);
1319 asix_write_gpio(dev, 0x001c, 300);
1320 asix_write_gpio(dev, 0x003c, 30);
1321 } else {
1322 dbg("gpio phymode == 1 path");
1323 asix_write_gpio(dev, AX_GPIO_GPO1EN, 30);
1324 asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
1325 }
1326
1327 asix_sw_reset(dev, 0);
1328 msleep(150);
1329
1330 asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
1331 msleep(150);
1332
1333 asix_write_rx_ctl(dev, 0);
1334
1335 /* Get the MAC address */ 1390 /* Get the MAC address */
1336 if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 1391 if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
1337 0, 0, ETH_ALEN, buf)) < 0) { 1392 0, 0, ETH_ALEN, buf)) < 0) {
@@ -1355,24 +1410,8 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
1355 phyid = asix_get_phyid(dev); 1410 phyid = asix_get_phyid(dev);
1356 dbg("PHYID=0x%08x", phyid); 1411 dbg("PHYID=0x%08x", phyid);
1357 1412
1358 if (data->phymode == PHY_MODE_MARVELL) { 1413 ret = ax88178_reset(dev);
1359 marvell_phy_init(dev); 1414 if (ret < 0)
1360 msleep(60);
1361 }
1362
1363 asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
1364 BMCR_RESET | BMCR_ANENABLE);
1365 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
1366 ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
1367 asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
1368 ADVERTISE_1000FULL);
1369
1370 mii_nway_restart(&dev->mii);
1371
1372 if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0)
1373 goto out;
1374
1375 if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
1376 goto out; 1415 goto out;
1377 1416
1378 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ 1417 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
@@ -1443,7 +1482,7 @@ static const struct driver_info ax88178_info = {
1443 .bind = ax88178_bind, 1482 .bind = ax88178_bind,
1444 .status = asix_status, 1483 .status = asix_status,
1445 .link_reset = ax88178_link_reset, 1484 .link_reset = ax88178_link_reset,
1446 .reset = ax88178_link_reset, 1485 .reset = ax88178_reset,
1447 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, 1486 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
1448 .rx_fixup = asix_rx_fixup, 1487 .rx_fixup = asix_rx_fixup,
1449 .tx_fixup = asix_tx_fixup, 1488 .tx_fixup = asix_tx_fixup,