aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-09-24 00:25:28 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-25 20:04:29 -0400
commit64f6b64dfb8cdda21652f24a0fb0a68e2f0b0022 (patch)
treee1706db57e1a1b4c65884c9b79a7f9d4e0e2ae7c /drivers/net
parent46798c897e235e71e1e9c46a5e6e9adfffd8b85d (diff)
[PATCH] skge: fiber support
Add support for older fiber versions of the SysKonnect board. These chipsets use an internal PHY so they require special handling. The older sk98lin driver already supported these Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/skge.c357
-rw-r--r--drivers/net/skge.h37
2 files changed, 301 insertions, 93 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 9142d91355bc..705e9a8fa30f 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -58,6 +58,7 @@
58#define TX_WATCHDOG (5 * HZ) 58#define TX_WATCHDOG (5 * HZ)
59#define NAPI_WEIGHT 64 59#define NAPI_WEIGHT 64
60#define BLINK_MS 250 60#define BLINK_MS 250
61#define LINK_HZ (HZ/2)
61 62
62MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); 63MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
63MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); 64MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -605,7 +606,12 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
605 if (hw->chip_id == CHIP_ID_GENESIS) { 606 if (hw->chip_id == CHIP_ID_GENESIS) {
606 switch (mode) { 607 switch (mode) {
607 case LED_MODE_OFF: 608 case LED_MODE_OFF:
608 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); 609 if (hw->phy_type == SK_PHY_BCOM)
610 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
611 else {
612 skge_write32(hw, SK_REG(port, TX_LED_VAL), 0);
613 skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF);
614 }
609 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); 615 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
610 skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); 616 skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
611 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); 617 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
@@ -625,8 +631,14 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
625 skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); 631 skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
626 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); 632 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
627 633
628 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); 634 if (hw->phy_type == SK_PHY_BCOM)
629 break; 635 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
636 else {
637 skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON);
638 skge_write32(hw, SK_REG(port, TX_LED_VAL), 100);
639 skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
640 }
641
630 } 642 }
631 } else { 643 } else {
632 switch (mode) { 644 switch (mode) {
@@ -879,6 +891,9 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
879 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
880 *val = xm_read16(hw, port, XM_PHY_DATA); 892 *val = xm_read16(hw, port, XM_PHY_DATA);
881 893
894 if (hw->phy_type == SK_PHY_XMAC)
895 goto ready;
896
882 for (i = 0; i < PHY_RETRIES; i++) { 897 for (i = 0; i < PHY_RETRIES; i++) {
883 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) 898 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
884 goto ready; 899 goto ready;
@@ -965,7 +980,8 @@ static void genesis_reset(struct skge_hw *hw, int port)
965 xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ 980 xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
966 981
967 /* disable Broadcom PHY IRQ */ 982 /* disable Broadcom PHY IRQ */
968 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); 983 if (hw->phy_type == SK_PHY_BCOM)
984 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
969 985
970 xm_outhash(hw, port, XM_HSM, zero); 986 xm_outhash(hw, port, XM_HSM, zero);
971} 987}
@@ -1000,60 +1016,64 @@ static void bcom_check_link(struct skge_hw *hw, int port)
1000 1016
1001 if (netif_carrier_ok(dev)) 1017 if (netif_carrier_ok(dev))
1002 skge_link_down(skge); 1018 skge_link_down(skge);
1003 } else { 1019 return;
1004 if (skge->autoneg == AUTONEG_ENABLE && 1020 }
1005 (status & PHY_ST_AN_OVER)) {
1006 u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
1007 u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1008
1009 if (lpa & PHY_B_AN_RF) {
1010 printk(KERN_NOTICE PFX "%s: remote fault\n",
1011 dev->name);
1012 return;
1013 }
1014 1021
1015 /* Check Duplex mismatch */ 1022 if (skge->autoneg == AUTONEG_ENABLE) {
1016 switch (aux & PHY_B_AS_AN_RES_MSK) { 1023 u16 lpa, aux;
1017 case PHY_B_RES_1000FD:
1018 skge->duplex = DUPLEX_FULL;
1019 break;
1020 case PHY_B_RES_1000HD:
1021 skge->duplex = DUPLEX_HALF;
1022 break;
1023 default:
1024 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1025 dev->name);
1026 return;
1027 }
1028 1024
1025 if (!(status & PHY_ST_AN_OVER))
1026 return;
1029 1027
1030 /* We are using IEEE 802.3z/D5.0 Table 37-4 */ 1028 lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
1031 switch (aux & PHY_B_AS_PAUSE_MSK) { 1029 if (lpa & PHY_B_AN_RF) {
1032 case PHY_B_AS_PAUSE_MSK: 1030 printk(KERN_NOTICE PFX "%s: remote fault\n",
1033 skge->flow_control = FLOW_MODE_SYMMETRIC; 1031 dev->name);
1034 break; 1032 return;
1035 case PHY_B_AS_PRR: 1033 }
1036 skge->flow_control = FLOW_MODE_REM_SEND;
1037 break;
1038 case PHY_B_AS_PRT:
1039 skge->flow_control = FLOW_MODE_LOC_SEND;
1040 break;
1041 default:
1042 skge->flow_control = FLOW_MODE_NONE;
1043 }
1044 1034
1045 skge->speed = SPEED_1000; 1035 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1036
1037 /* Check Duplex mismatch */
1038 switch (aux & PHY_B_AS_AN_RES_MSK) {
1039 case PHY_B_RES_1000FD:
1040 skge->duplex = DUPLEX_FULL;
1041 break;
1042 case PHY_B_RES_1000HD:
1043 skge->duplex = DUPLEX_HALF;
1044 break;
1045 default:
1046 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1047 dev->name);
1048 return;
1046 } 1049 }
1047 1050
1048 if (!netif_carrier_ok(dev)) 1051
1049 genesis_link_up(skge); 1052 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
1053 switch (aux & PHY_B_AS_PAUSE_MSK) {
1054 case PHY_B_AS_PAUSE_MSK:
1055 skge->flow_control = FLOW_MODE_SYMMETRIC;
1056 break;
1057 case PHY_B_AS_PRR:
1058 skge->flow_control = FLOW_MODE_REM_SEND;
1059 break;
1060 case PHY_B_AS_PRT:
1061 skge->flow_control = FLOW_MODE_LOC_SEND;
1062 break;
1063 default:
1064 skge->flow_control = FLOW_MODE_NONE;
1065 }
1066 skge->speed = SPEED_1000;
1050 } 1067 }
1068
1069 if (!netif_carrier_ok(dev))
1070 genesis_link_up(skge);
1051} 1071}
1052 1072
1053/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional 1073/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
1054 * Phy on for 100 or 10Mbit operation 1074 * Phy on for 100 or 10Mbit operation
1055 */ 1075 */
1056static void bcom_phy_init(struct skge_port *skge, int jumbo) 1076static void bcom_phy_init(struct skge_port *skge)
1057{ 1077{
1058 struct skge_hw *hw = skge->hw; 1078 struct skge_hw *hw = skge->hw;
1059 int port = skge->port; 1079 int port = skge->port;
@@ -1144,7 +1164,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1144 phy_pause_map[skge->flow_control] | PHY_AN_CSMA); 1164 phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
1145 1165
1146 /* Handle Jumbo frames */ 1166 /* Handle Jumbo frames */
1147 if (jumbo) { 1167 if (hw->dev[port]->mtu > ETH_DATA_LEN) {
1148 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, 1168 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
1149 PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); 1169 PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
1150 1170
@@ -1157,8 +1177,154 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1157 1177
1158 /* Use link status change interrupt */ 1178 /* Use link status change interrupt */
1159 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1179 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1180}
1160 1181
1161 bcom_check_link(hw, port); 1182static void xm_phy_init(struct skge_port *skge)
1183{
1184 struct skge_hw *hw = skge->hw;
1185 int port = skge->port;
1186 u16 ctrl = 0;
1187
1188 if (skge->autoneg == AUTONEG_ENABLE) {
1189 if (skge->advertising & ADVERTISED_1000baseT_Half)
1190 ctrl |= PHY_X_AN_HD;
1191 if (skge->advertising & ADVERTISED_1000baseT_Full)
1192 ctrl |= PHY_X_AN_FD;
1193
1194 switch(skge->flow_control) {
1195 case FLOW_MODE_NONE:
1196 ctrl |= PHY_X_P_NO_PAUSE;
1197 break;
1198 case FLOW_MODE_LOC_SEND:
1199 ctrl |= PHY_X_P_ASYM_MD;
1200 break;
1201 case FLOW_MODE_SYMMETRIC:
1202 ctrl |= PHY_X_P_BOTH_MD;
1203 break;
1204 }
1205
1206 xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);
1207
1208 /* Restart Auto-negotiation */
1209 ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1210 } else {
1211 /* Set DuplexMode in Config register */
1212 if (skge->duplex == DUPLEX_FULL)
1213 ctrl |= PHY_CT_DUP_MD;
1214 /*
1215 * Do NOT enable Auto-negotiation here. This would hold
1216 * the link down because no IDLEs are transmitted
1217 */
1218 }
1219
1220 xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
1221
1222 /* Poll PHY for status changes */
1223 schedule_delayed_work(&skge->link_thread, LINK_HZ);
1224}
1225
1226static void xm_check_link(struct net_device *dev)
1227{
1228 struct skge_port *skge = netdev_priv(dev);
1229 struct skge_hw *hw = skge->hw;
1230 int port = skge->port;
1231 u16 status;
1232
1233 /* read twice because of latch */
1234 (void) xm_phy_read(hw, port, PHY_XMAC_STAT);
1235 status = xm_phy_read(hw, port, PHY_XMAC_STAT);
1236
1237 if ((status & PHY_ST_LSYNC) == 0) {
1238 u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
1239 cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
1240 xm_write16(hw, port, XM_MMU_CMD, cmd);
1241 /* dummy read to ensure writing */
1242 (void) xm_read16(hw, port, XM_MMU_CMD);
1243
1244 if (netif_carrier_ok(dev))
1245 skge_link_down(skge);
1246 return;
1247 }
1248
1249 if (skge->autoneg == AUTONEG_ENABLE) {
1250 u16 lpa, res;
1251
1252 if (!(status & PHY_ST_AN_OVER))
1253 return;
1254
1255 lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
1256 if (lpa & PHY_B_AN_RF) {
1257 printk(KERN_NOTICE PFX "%s: remote fault\n",
1258 dev->name);
1259 return;
1260 }
1261
1262 res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);
1263
1264 /* Check Duplex mismatch */
1265 switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) {
1266 case PHY_X_RS_FD:
1267 skge->duplex = DUPLEX_FULL;
1268 break;
1269 case PHY_X_RS_HD:
1270 skge->duplex = DUPLEX_HALF;
1271 break;
1272 default:
1273 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1274 dev->name);
1275 return;
1276 }
1277
1278 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
1279 if (lpa & PHY_X_P_SYM_MD)
1280 skge->flow_control = FLOW_MODE_SYMMETRIC;
1281 else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
1282 skge->flow_control = FLOW_MODE_REM_SEND;
1283 else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
1284 skge->flow_control = FLOW_MODE_LOC_SEND;
1285 else
1286 skge->flow_control = FLOW_MODE_NONE;
1287
1288
1289 skge->speed = SPEED_1000;
1290 }
1291
1292 if (!netif_carrier_ok(dev))
1293 genesis_link_up(skge);
1294}
1295
1296/* Poll to check for link coming up.
1297 * Since internal PHY is wired to a level triggered pin, can't
1298 * get an interrupt when carrier is detected.
1299 */
1300static void xm_link_timer(void *arg)
1301{
1302 struct net_device *dev = arg;
1303 struct skge_port *skge = netdev_priv(arg);
1304 struct skge_hw *hw = skge->hw;
1305 int port = skge->port;
1306
1307 if (!netif_running(dev))
1308 return;
1309
1310 if (netif_carrier_ok(dev)) {
1311 xm_read16(hw, port, XM_ISRC);
1312 if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS))
1313 goto nochange;
1314 } else {
1315 if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
1316 goto nochange;
1317 xm_read16(hw, port, XM_ISRC);
1318 if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
1319 goto nochange;
1320 }
1321
1322 mutex_lock(&hw->phy_mutex);
1323 xm_check_link(dev);
1324 mutex_unlock(&hw->phy_mutex);
1325
1326nochange:
1327 schedule_delayed_work(&skge->link_thread, LINK_HZ);
1162} 1328}
1163 1329
1164static void genesis_mac_init(struct skge_hw *hw, int port) 1330static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -1189,20 +1355,29 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1189 * namely for the 1000baseTX cards that use the XMAC's 1355 * namely for the 1000baseTX cards that use the XMAC's
1190 * GMII mode. 1356 * GMII mode.
1191 */ 1357 */
1192 /* Take external Phy out of reset */ 1358 if (hw->phy_type != SK_PHY_XMAC) {
1193 r = skge_read32(hw, B2_GP_IO); 1359 /* Take external Phy out of reset */
1194 if (port == 0) 1360 r = skge_read32(hw, B2_GP_IO);
1195 r |= GP_DIR_0|GP_IO_0; 1361 if (port == 0)
1196 else 1362 r |= GP_DIR_0|GP_IO_0;
1197 r |= GP_DIR_2|GP_IO_2; 1363 else
1364 r |= GP_DIR_2|GP_IO_2;
1198 1365
1199 skge_write32(hw, B2_GP_IO, r); 1366 skge_write32(hw, B2_GP_IO, r);
1200 1367
1368 /* Enable GMII interface */
1369 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1370 }
1201 1371
1202 /* Enable GMII interface */
1203 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1204 1372
1205 bcom_phy_init(skge, jumbo); 1373 switch(hw->phy_type) {
1374 case SK_PHY_XMAC:
1375 xm_phy_init(skge);
1376 break;
1377 case SK_PHY_BCOM:
1378 bcom_phy_init(skge);
1379 bcom_check_link(hw, port);
1380 }
1206 1381
1207 /* Set Station Address */ 1382 /* Set Station Address */
1208 xm_outaddr(hw, port, XM_SA, dev->dev_addr); 1383 xm_outaddr(hw, port, XM_SA, dev->dev_addr);
@@ -1335,16 +1510,18 @@ static void genesis_stop(struct skge_port *skge)
1335 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); 1510 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
1336 1511
1337 /* For external PHYs there must be special handling */ 1512 /* For external PHYs there must be special handling */
1338 reg = skge_read32(hw, B2_GP_IO); 1513 if (hw->phy_type != SK_PHY_XMAC) {
1339 if (port == 0) { 1514 reg = skge_read32(hw, B2_GP_IO);
1340 reg |= GP_DIR_0; 1515 if (port == 0) {
1341 reg &= ~GP_IO_0; 1516 reg |= GP_DIR_0;
1342 } else { 1517 reg &= ~GP_IO_0;
1343 reg |= GP_DIR_2; 1518 } else {
1344 reg &= ~GP_IO_2; 1519 reg |= GP_DIR_2;
1520 reg &= ~GP_IO_2;
1521 }
1522 skge_write32(hw, B2_GP_IO, reg);
1523 skge_read32(hw, B2_GP_IO);
1345 } 1524 }
1346 skge_write32(hw, B2_GP_IO, reg);
1347 skge_read32(hw, B2_GP_IO);
1348 1525
1349 xm_write16(hw, port, XM_MMU_CMD, 1526 xm_write16(hw, port, XM_MMU_CMD,
1350 xm_read16(hw, port, XM_MMU_CMD) 1527 xm_read16(hw, port, XM_MMU_CMD)
@@ -1406,7 +1583,7 @@ static void genesis_link_up(struct skge_port *skge)
1406 struct skge_hw *hw = skge->hw; 1583 struct skge_hw *hw = skge->hw;
1407 int port = skge->port; 1584 int port = skge->port;
1408 u16 cmd; 1585 u16 cmd;
1409 u32 mode, msk; 1586 u32 mode;
1410 1587
1411 cmd = xm_read16(hw, port, XM_MMU_CMD); 1588 cmd = xm_read16(hw, port, XM_MMU_CMD);
1412 1589
@@ -1454,27 +1631,24 @@ static void genesis_link_up(struct skge_port *skge)
1454 } 1631 }
1455 1632
1456 xm_write32(hw, port, XM_MODE, mode); 1633 xm_write32(hw, port, XM_MODE, mode);
1457 1634 xm_write16(hw, port, XM_IMSK, XM_DEF_MSK);
1458 msk = XM_DEF_MSK;
1459 /* disable GP0 interrupt bit for external Phy */
1460 msk |= XM_IS_INP_ASS;
1461
1462 xm_write16(hw, port, XM_IMSK, msk);
1463 xm_read16(hw, port, XM_ISRC); 1635 xm_read16(hw, port, XM_ISRC);
1464 1636
1465 /* get MMU Command Reg. */ 1637 /* get MMU Command Reg. */
1466 cmd = xm_read16(hw, port, XM_MMU_CMD); 1638 cmd = xm_read16(hw, port, XM_MMU_CMD);
1467 if (skge->duplex == DUPLEX_FULL) 1639 if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
1468 cmd |= XM_MMU_GMII_FD; 1640 cmd |= XM_MMU_GMII_FD;
1469 1641
1470 /* 1642 /*
1471 * Workaround BCOM Errata (#10523) for all BCom Phys 1643 * Workaround BCOM Errata (#10523) for all BCom Phys
1472 * Enable Power Management after link up 1644 * Enable Power Management after link up
1473 */ 1645 */
1474 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, 1646 if (hw->phy_type == SK_PHY_BCOM) {
1475 xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) 1647 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
1476 & ~PHY_B_AC_DIS_PM); 1648 xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
1477 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1649 & ~PHY_B_AC_DIS_PM);
1650 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1651 }
1478 1652
1479 /* enable Rx/Tx */ 1653 /* enable Rx/Tx */
1480 xm_write16(hw, port, XM_MMU_CMD, 1654 xm_write16(hw, port, XM_MMU_CMD,
@@ -2240,6 +2414,8 @@ static int skge_down(struct net_device *dev)
2240 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 2414 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
2241 2415
2242 netif_stop_queue(dev); 2416 netif_stop_queue(dev);
2417 if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
2418 cancel_rearming_delayed_work(&skge->link_thread);
2243 2419
2244 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); 2420 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
2245 if (hw->chip_id == CHIP_ID_GENESIS) 2421 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2862,7 +3038,7 @@ static void skge_extirq(void *arg)
2862 if (netif_running(dev)) { 3038 if (netif_running(dev)) {
2863 if (hw->chip_id != CHIP_ID_GENESIS) 3039 if (hw->chip_id != CHIP_ID_GENESIS)
2864 yukon_phy_intr(skge); 3040 yukon_phy_intr(skge);
2865 else 3041 else if (hw->phy_type == SK_PHY_BCOM)
2866 bcom_phy_intr(skge); 3042 bcom_phy_intr(skge);
2867 } 3043 }
2868 } 3044 }
@@ -3014,7 +3190,7 @@ static int skge_reset(struct skge_hw *hw)
3014{ 3190{
3015 u32 reg; 3191 u32 reg;
3016 u16 ctst, pci_status; 3192 u16 ctst, pci_status;
3017 u8 t8, mac_cfg, pmd_type, phy_type; 3193 u8 t8, mac_cfg, pmd_type;
3018 int i; 3194 int i;
3019 3195
3020 ctst = skge_read16(hw, B0_CTST); 3196 ctst = skge_read16(hw, B0_CTST);
@@ -3038,19 +3214,22 @@ static int skge_reset(struct skge_hw *hw)
3038 ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); 3214 ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));
3039 3215
3040 hw->chip_id = skge_read8(hw, B2_CHIP_ID); 3216 hw->chip_id = skge_read8(hw, B2_CHIP_ID);
3041 phy_type = skge_read8(hw, B2_E_1) & 0xf; 3217 hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
3042 pmd_type = skge_read8(hw, B2_PMD_TYP); 3218 pmd_type = skge_read8(hw, B2_PMD_TYP);
3043 hw->copper = (pmd_type == 'T' || pmd_type == '1'); 3219 hw->copper = (pmd_type == 'T' || pmd_type == '1');
3044 3220
3045 switch (hw->chip_id) { 3221 switch (hw->chip_id) {
3046 case CHIP_ID_GENESIS: 3222 case CHIP_ID_GENESIS:
3047 switch (phy_type) { 3223 switch (hw->phy_type) {
3224 case SK_PHY_XMAC:
3225 hw->phy_addr = PHY_ADDR_XMAC;
3226 break;
3048 case SK_PHY_BCOM: 3227 case SK_PHY_BCOM:
3049 hw->phy_addr = PHY_ADDR_BCOM; 3228 hw->phy_addr = PHY_ADDR_BCOM;
3050 break; 3229 break;
3051 default: 3230 default:
3052 printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", 3231 printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n",
3053 pci_name(hw->pdev), phy_type); 3232 pci_name(hw->pdev), hw->phy_type);
3054 return -EOPNOTSUPP; 3233 return -EOPNOTSUPP;
3055 } 3234 }
3056 break; 3235 break;
@@ -3058,7 +3237,7 @@ static int skge_reset(struct skge_hw *hw)
3058 case CHIP_ID_YUKON: 3237 case CHIP_ID_YUKON:
3059 case CHIP_ID_YUKON_LITE: 3238 case CHIP_ID_YUKON_LITE:
3060 case CHIP_ID_YUKON_LP: 3239 case CHIP_ID_YUKON_LP:
3061 if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') 3240 if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
3062 hw->copper = 1; 3241 hw->copper = 1;
3063 3242
3064 hw->phy_addr = PHY_ADDR_MARV; 3243 hw->phy_addr = PHY_ADDR_MARV;
@@ -3089,10 +3268,13 @@ static int skge_reset(struct skge_hw *hw)
3089 else 3268 else
3090 hw->ram_size = t8 * 4096; 3269 hw->ram_size = t8 * 4096;
3091 3270
3092 hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; 3271 hw->intr_mask = IS_HW_ERR | IS_PORT_1;
3093 if (hw->ports > 1) 3272 if (hw->ports > 1)
3094 hw->intr_mask |= IS_PORT_2; 3273 hw->intr_mask |= IS_PORT_2;
3095 3274
3275 if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
3276 hw->intr_mask |= IS_EXT_REG;
3277
3096 if (hw->chip_id == CHIP_ID_GENESIS) 3278 if (hw->chip_id == CHIP_ID_GENESIS)
3097 genesis_init(hw); 3279 genesis_init(hw);
3098 else { 3280 else {
@@ -3226,6 +3408,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3226 3408
3227 skge->port = port; 3409 skge->port = port;
3228 3410
3411 /* Only used for Genesis XMAC */
3412 INIT_WORK(&skge->link_thread, xm_link_timer, dev);
3413
3229 if (hw->chip_id != CHIP_ID_GENESIS) { 3414 if (hw->chip_id != CHIP_ID_GENESIS) {
3230 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; 3415 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
3231 skge->rx_csum = 1; 3416 skge->rx_csum = 1;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 79e09271bcf9..d0b47d46cf9d 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -934,7 +934,7 @@ enum {
934 PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ 934 PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
935 PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */ 935 PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */
936 PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ 936 PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
937 PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */ 937 PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */
938 PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ 938 PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */
939 939
940 PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */ 940 PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */
@@ -1097,13 +1097,36 @@ enum {
1097 1097
1098/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ 1098/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
1099enum { 1099enum {
1100 PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ 1100 PHY_X_P_NO_PAUSE= 0<<7,/* Bit 8..7: no Pause Mode */
1101 PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */ 1101 PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */
1102 PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */ 1102 PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */
1103 PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */ 1103 PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */
1104}; 1104};
1105 1105
1106 1106
1107/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
1108enum {
1109 PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */
1110 PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */
1111};
1112
1113/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
1114enum {
1115 PHY_X_RS_PAUSE = 3<<7, /* Bit 8..7: selected Pause Mode */
1116 PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */
1117 PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */
1118 PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */
1119 PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */
1120};
1121
1122/* Remote Fault Bits (PHY_X_AN_RFB) encoding */
1123enum {
1124 X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */
1125 X_RFB_LF = 1<<12,/* Bit 13..12 Link Failure */
1126 X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */
1127 X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */
1128};
1129
1107/* Broadcom-Specific */ 1130/* Broadcom-Specific */
1108/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ 1131/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1109enum { 1132enum {
@@ -2158,8 +2181,8 @@ enum {
2158 XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */ 2181 XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */
2159 XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */ 2182 XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */
2160 XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */ 2183 XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */
2161 XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */ 2184 XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */
2162 XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */ 2185 XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */
2163 XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */ 2186 XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */
2164 XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */ 2187 XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */
2165 XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */ 2188 XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */
@@ -2172,9 +2195,7 @@ enum {
2172 XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ 2195 XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */
2173}; 2196};
2174 2197
2175#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | \ 2198#define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR))
2176 XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | \
2177 XM_IS_RXF_OV | XM_IS_TXF_UR))
2178 2199
2179 2200
2180/* XM_HW_CFG 16 bit r/w Hardware Config Register */ 2201/* XM_HW_CFG 16 bit r/w Hardware Config Register */
@@ -2396,6 +2417,7 @@ struct skge_hw {
2396 u8 chip_rev; 2417 u8 chip_rev;
2397 u8 copper; 2418 u8 copper;
2398 u8 ports; 2419 u8 ports;
2420 u8 phy_type;
2399 2421
2400 u32 ram_size; 2422 u32 ram_size;
2401 u32 ram_offset; 2423 u32 ram_offset;
@@ -2422,6 +2444,7 @@ struct skge_port {
2422 2444
2423 struct net_device_stats net_stats; 2445 struct net_device_stats net_stats;
2424 2446
2447 struct work_struct link_thread;
2425 u8 rx_csum; 2448 u8 rx_csum;
2426 u8 blink_on; 2449 u8 blink_on;
2427 u8 flow_control; 2450 u8 flow_control;