diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_hw.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 395 |
1 files changed, 200 insertions, 195 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 52e734042b8e..b832a7b814a2 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -46,6 +46,10 @@ static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR; | |||
46 | module_param(nes_lro_max_aggr, uint, 0444); | 46 | module_param(nes_lro_max_aggr, uint, 0444); |
47 | MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation"); | 47 | MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation"); |
48 | 48 | ||
49 | static int wide_ppm_offset; | ||
50 | module_param(wide_ppm_offset, int, 0644); | ||
51 | MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm"); | ||
52 | |||
49 | static u32 crit_err_count; | 53 | static u32 crit_err_count; |
50 | u32 int_mod_timer_init; | 54 | u32 int_mod_timer_init; |
51 | u32 int_mod_cq_depth_256; | 55 | u32 int_mod_cq_depth_256; |
@@ -547,7 +551,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
547 | } | 551 | } |
548 | if (int_cnt > 1) { | 552 | if (int_cnt > 1) { |
549 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 553 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
550 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); | 554 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8); |
551 | mh_detected++; | 555 | mh_detected++; |
552 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); | 556 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); |
553 | reset_value |= 0x0000003d; | 557 | reset_value |= 0x0000003d; |
@@ -572,7 +576,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
572 | if (++ext_cnt > int_cnt) { | 576 | if (++ext_cnt > int_cnt) { |
573 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 577 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
574 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, | 578 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, |
575 | 0x0000F0C8); | 579 | 0x0000F088); |
576 | mh_detected++; | 580 | mh_detected++; |
577 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); | 581 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); |
578 | reset_value |= 0x0000003d; | 582 | reset_value |= 0x0000003d; |
@@ -736,38 +740,50 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
736 | { | 740 | { |
737 | int i; | 741 | int i; |
738 | u32 u32temp; | 742 | u32 u32temp; |
739 | u32 serdes_common_control; | 743 | u32 sds; |
740 | 744 | ||
741 | if (hw_rev != NE020_REV) { | 745 | if (hw_rev != NE020_REV) { |
742 | /* init serdes 0 */ | 746 | /* init serdes 0 */ |
747 | if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4)) | ||
748 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | ||
749 | else | ||
750 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
743 | 751 | ||
744 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
745 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | 752 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
746 | serdes_common_control = nes_read_indexed(nesdev, | 753 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); |
747 | NES_IDX_ETH_SERDES_COMMON_CONTROL0); | 754 | sds |= 0x00000100; |
748 | serdes_common_control |= 0x000000100; | 755 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds); |
749 | nes_write_indexed(nesdev, | ||
750 | NES_IDX_ETH_SERDES_COMMON_CONTROL0, | ||
751 | serdes_common_control); | ||
752 | } else if (!OneG_Mode) { | ||
753 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); | ||
754 | } | 756 | } |
755 | if (((port_count > 1) && | 757 | if (!OneG_Mode) |
756 | (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) || | 758 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); |
757 | ((port_count > 2) && | 759 | |
758 | (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) { | 760 | if (port_count < 2) |
759 | /* init serdes 1 */ | 761 | return 0; |
762 | |||
763 | /* init serdes 1 */ | ||
764 | if (!(OneG_Mode && (nesadapter->phy_type[1] != NES_PHY_TYPE_PUMA_1G))) | ||
760 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); | 765 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); |
761 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | 766 | |
762 | serdes_common_control = nes_read_indexed(nesdev, | 767 | switch (nesadapter->phy_type[1]) { |
763 | NES_IDX_ETH_SERDES_COMMON_CONTROL1); | 768 | case NES_PHY_TYPE_ARGUS: |
764 | serdes_common_control |= 0x000000100; | 769 | case NES_PHY_TYPE_SFP_D: |
765 | nes_write_indexed(nesdev, | 770 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000); |
766 | NES_IDX_ETH_SERDES_COMMON_CONTROL1, | 771 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000); |
767 | serdes_common_control); | 772 | break; |
768 | } else if (!OneG_Mode) { | 773 | case NES_PHY_TYPE_CX4: |
769 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); | 774 | if (wide_ppm_offset) |
770 | } | 775 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA); |
776 | break; | ||
777 | case NES_PHY_TYPE_PUMA_1G: | ||
778 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); | ||
779 | sds |= 0x000000100; | ||
780 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds); | ||
781 | } | ||
782 | if (!OneG_Mode) { | ||
783 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); | ||
784 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); | ||
785 | sds &= 0xFFFFFFBF; | ||
786 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds); | ||
771 | } | 787 | } |
772 | } else { | 788 | } else { |
773 | /* init serdes 0 */ | 789 | /* init serdes 0 */ |
@@ -896,6 +912,12 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou | |||
896 | u32temp &= 0x7fffffff; | 912 | u32temp &= 0x7fffffff; |
897 | u32temp |= 0x7fff0010; | 913 | u32temp |= 0x7fff0010; |
898 | nes_write_indexed(nesdev, 0x000021f8, u32temp); | 914 | nes_write_indexed(nesdev, 0x000021f8, u32temp); |
915 | if (port_count > 1) { | ||
916 | u32temp = nes_read_indexed(nesdev, 0x000023f8); | ||
917 | u32temp &= 0x7fffffff; | ||
918 | u32temp |= 0x7fff0010; | ||
919 | nes_write_indexed(nesdev, 0x000023f8, u32temp); | ||
920 | } | ||
899 | } | 921 | } |
900 | } | 922 | } |
901 | 923 | ||
@@ -1259,203 +1281,163 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1259 | { | 1281 | { |
1260 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1282 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1261 | u32 counter = 0; | 1283 | u32 counter = 0; |
1262 | u32 sds_common_control0; | 1284 | u32 sds; |
1263 | u32 mac_index = nesdev->mac_index; | 1285 | u32 mac_index = nesdev->mac_index; |
1264 | u32 tx_config = 0; | 1286 | u32 tx_config = 0; |
1265 | u16 phy_data; | 1287 | u16 phy_data; |
1266 | u32 temp_phy_data = 0; | 1288 | u32 temp_phy_data = 0; |
1267 | u32 temp_phy_data2 = 0; | 1289 | u32 temp_phy_data2 = 0; |
1268 | u32 i = 0; | 1290 | u8 phy_type = nesadapter->phy_type[mac_index]; |
1291 | u8 phy_index = nesadapter->phy_index[mac_index]; | ||
1269 | 1292 | ||
1270 | if ((nesadapter->OneG_Mode) && | 1293 | if ((nesadapter->OneG_Mode) && |
1271 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | 1294 | (phy_type != NES_PHY_TYPE_PUMA_1G)) { |
1272 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | 1295 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); |
1273 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { | 1296 | if (phy_type == NES_PHY_TYPE_1G) { |
1274 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); | ||
1275 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | 1297 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
1276 | tx_config &= 0xFFFFFFE3; | 1298 | tx_config &= 0xFFFFFFE3; |
1277 | tx_config |= 0x04; | 1299 | tx_config |= 0x04; |
1278 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | 1300 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
1279 | } | 1301 | } |
1280 | 1302 | ||
1281 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); | 1303 | nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data); |
1282 | nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", | 1304 | nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000); |
1283 | nesadapter->phy_index[mac_index], phy_data); | ||
1284 | nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); | ||
1285 | 1305 | ||
1286 | /* Reset the PHY */ | 1306 | /* Reset the PHY */ |
1287 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); | 1307 | nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); |
1288 | udelay(100); | 1308 | udelay(100); |
1289 | counter = 0; | 1309 | counter = 0; |
1290 | do { | 1310 | do { |
1291 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1311 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); |
1292 | nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data); | 1312 | if (counter++ > 100) |
1293 | if (counter++ > 100) break; | 1313 | break; |
1294 | } while (phy_data & 0x8000); | 1314 | } while (phy_data & 0x8000); |
1295 | 1315 | ||
1296 | /* Setting no phy loopback */ | 1316 | /* Setting no phy loopback */ |
1297 | phy_data &= 0xbfff; | 1317 | phy_data &= 0xbfff; |
1298 | phy_data |= 0x1140; | 1318 | phy_data |= 0x1140; |
1299 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data); | 1319 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data); |
1300 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1320 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); |
1301 | nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data); | 1321 | nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); |
1302 | 1322 | nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data); | |
1303 | nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data); | ||
1304 | nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data); | ||
1305 | |||
1306 | nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data); | ||
1307 | nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data); | ||
1308 | 1323 | ||
1309 | /* Setting the interrupt mask */ | 1324 | /* Setting the interrupt mask */ |
1310 | nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data); | 1325 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); |
1311 | nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data); | 1326 | nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); |
1312 | nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee); | 1327 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); |
1313 | |||
1314 | nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data); | ||
1315 | nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data); | ||
1316 | 1328 | ||
1317 | /* turning on flow control */ | 1329 | /* turning on flow control */ |
1318 | nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data); | 1330 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); |
1319 | nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data); | 1331 | nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00); |
1320 | nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], | 1332 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); |
1321 | (phy_data & ~(0x03E0)) | 0xc00); | ||
1322 | /* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], | ||
1323 | phy_data | 0xc00); */ | ||
1324 | nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data); | ||
1325 | nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data); | ||
1326 | |||
1327 | nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data); | ||
1328 | nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data); | ||
1329 | /* Clear Half duplex */ | ||
1330 | nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], | ||
1331 | phy_data & ~(0x0100)); | ||
1332 | nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data); | ||
1333 | nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data); | ||
1334 | 1333 | ||
1335 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1334 | /* Clear Half duplex */ |
1336 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); | 1335 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); |
1337 | } else { | 1336 | nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); |
1338 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) || | 1337 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); |
1339 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1340 | /* setup 10G MDIO operation */ | ||
1341 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | ||
1342 | tx_config &= 0xFFFFFFE3; | ||
1343 | tx_config |= 0x15; | ||
1344 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||
1345 | } | ||
1346 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1347 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1348 | |||
1349 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1350 | mdelay(10); | ||
1351 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1352 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1353 | 1338 | ||
1354 | /* | 1339 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); |
1355 | * if firmware is already running (like from a | 1340 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300); |
1356 | * driver un-load/load, don't do anything. | ||
1357 | */ | ||
1358 | if (temp_phy_data == temp_phy_data2) { | ||
1359 | /* configure QT2505 AMCC PHY */ | ||
1360 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000); | ||
1361 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000); | ||
1362 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044); | ||
1363 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052); | ||
1364 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008); | ||
1365 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098); | ||
1366 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00); | ||
1367 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001); | ||
1368 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528); | ||
1369 | 1341 | ||
1370 | /* | 1342 | return 0; |
1371 | * remove micro from reset; chip boots from ROM, | 1343 | } |
1372 | * uploads EEPROM f/w image, uC executes f/w | ||
1373 | */ | ||
1374 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002); | ||
1375 | 1344 | ||
1376 | /* | 1345 | if ((phy_type == NES_PHY_TYPE_IRIS) || |
1377 | * wait for heart beat to start to | 1346 | (phy_type == NES_PHY_TYPE_ARGUS) || |
1378 | * know loading is done | 1347 | (phy_type == NES_PHY_TYPE_SFP_D)) { |
1379 | */ | 1348 | /* setup 10G MDIO operation */ |
1380 | counter = 0; | 1349 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
1381 | do { | 1350 | tx_config &= 0xFFFFFFE3; |
1382 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | 1351 | tx_config |= 0x15; |
1383 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1352 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
1384 | if (counter++ > 1000) { | 1353 | } |
1385 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n"); | 1354 | if ((phy_type == NES_PHY_TYPE_ARGUS) || |
1386 | break; | 1355 | (phy_type == NES_PHY_TYPE_SFP_D)) { |
1387 | } | 1356 | /* Check firmware heartbeat */ |
1388 | mdelay(100); | 1357 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
1389 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | 1358 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
1390 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1359 | udelay(1500); |
1391 | } while ((temp_phy_data2 == temp_phy_data)); | 1360 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
1361 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1362 | |||
1363 | if (temp_phy_data != temp_phy_data2) | ||
1364 | return 0; | ||
1392 | 1365 | ||
1393 | /* | 1366 | /* no heartbeat, configure the PHY */ |
1394 | * wait for tracking to start to know | 1367 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); |
1395 | * f/w is good to go | 1368 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); |
1396 | */ | 1369 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); |
1397 | counter = 0; | 1370 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); |
1398 | do { | 1371 | if (phy_type == NES_PHY_TYPE_ARGUS) { |
1399 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd); | 1372 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); |
1400 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1373 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); |
1401 | if (counter++ > 1000) { | 1374 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); |
1402 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n"); | 1375 | } else { |
1403 | break; | 1376 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); |
1404 | } | 1377 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); |
1405 | mdelay(1000); | 1378 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); |
1406 | /* | 1379 | } |
1407 | * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n", | 1380 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); |
1408 | * temp_phy_data); | 1381 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); |
1409 | */ | ||
1410 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
1411 | |||
1412 | /* set LOS Control invert RXLOSB_I_PADINV */ | ||
1413 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000); | ||
1414 | /* set LOS Control to mask of RXLOSB_I */ | ||
1415 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042); | ||
1416 | /* set LED1 to input mode (LED1 and LED2 share same LED) */ | ||
1417 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007); | ||
1418 | /* set LED2 to RX link_status and activity */ | ||
1419 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A); | ||
1420 | /* set LED3 to RX link_status */ | ||
1421 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009); | ||
1422 | 1382 | ||
1423 | /* | 1383 | /* setup LEDs */ |
1424 | * reset the res-calibration on t2 | 1384 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); |
1425 | * serdes; ensures it is stable after | 1385 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); |
1426 | * the amcc phy is stable | 1386 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); |
1427 | */ | ||
1428 | 1387 | ||
1429 | sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | 1388 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528); |
1430 | sds_common_control0 |= 0x1; | ||
1431 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1432 | 1389 | ||
1433 | /* release the res-calibration reset */ | 1390 | /* Bring PHY out of reset */ |
1434 | sds_common_control0 &= 0xfffffffe; | 1391 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002); |
1435 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1436 | 1392 | ||
1437 | i = 0; | 1393 | /* Check for heartbeat */ |
1438 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | 1394 | counter = 0; |
1439 | && (i++ < 5000)) { | 1395 | mdelay(690); |
1440 | /* mdelay(1); */ | 1396 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
1441 | } | 1397 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
1398 | do { | ||
1399 | if (counter++ > 150) { | ||
1400 | nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); | ||
1401 | break; | ||
1402 | } | ||
1403 | mdelay(1); | ||
1404 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
1405 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1406 | } while ((temp_phy_data2 == temp_phy_data)); | ||
1442 | 1407 | ||
1443 | /* | 1408 | /* wait for tracking */ |
1444 | * wait for link train done before moving on, | 1409 | counter = 0; |
1445 | * or will get an interupt storm | 1410 | do { |
1446 | */ | 1411 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); |
1447 | counter = 0; | 1412 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
1448 | do { | 1413 | if (counter++ > 300) { |
1449 | temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1414 | nes_debug(NES_DBG_PHY, "PHY did not track\n"); |
1450 | (0x200 * (nesdev->mac_index & 1))); | 1415 | break; |
1451 | if (counter++ > 1000) { | ||
1452 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n"); | ||
1453 | break; | ||
1454 | } | ||
1455 | mdelay(1); | ||
1456 | } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000)); | ||
1457 | } | 1416 | } |
1458 | } | 1417 | mdelay(10); |
1418 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
1419 | |||
1420 | /* setup signal integrity */ | ||
1421 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); | ||
1422 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); | ||
1423 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | ||
1424 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002); | ||
1425 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063); | ||
1426 | |||
1427 | /* reset serdes */ | ||
1428 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
1429 | mac_index * 0x200); | ||
1430 | sds |= 0x1; | ||
1431 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
1432 | mac_index * 0x200, sds); | ||
1433 | sds &= 0xfffffffe; | ||
1434 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
1435 | mac_index * 0x200, sds); | ||
1436 | |||
1437 | counter = 0; | ||
1438 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
1439 | && (counter++ < 5000)) | ||
1440 | ; | ||
1459 | } | 1441 | } |
1460 | return 0; | 1442 | return 0; |
1461 | } | 1443 | } |
@@ -2359,6 +2341,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2359 | u16 temp_phy_data; | 2341 | u16 temp_phy_data; |
2360 | u32 pcs_val = 0x0f0f0000; | 2342 | u32 pcs_val = 0x0f0f0000; |
2361 | u32 pcs_mask = 0x0f1f0000; | 2343 | u32 pcs_mask = 0x0f1f0000; |
2344 | u32 cdr_ctrl; | ||
2362 | 2345 | ||
2363 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 2346 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
2364 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { | 2347 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { |
@@ -2473,6 +2456,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2473 | break; | 2456 | break; |
2474 | 2457 | ||
2475 | case NES_PHY_TYPE_ARGUS: | 2458 | case NES_PHY_TYPE_ARGUS: |
2459 | case NES_PHY_TYPE_SFP_D: | ||
2476 | /* clear the alarms */ | 2460 | /* clear the alarms */ |
2477 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | 2461 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); |
2478 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | 2462 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); |
@@ -2483,19 +2467,18 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2483 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004); | 2467 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004); |
2484 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); | 2468 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); |
2485 | /* check link status */ | 2469 | /* check link status */ |
2486 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | 2470 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003); |
2487 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 2471 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
2488 | u32temp = 100; | ||
2489 | do { | ||
2490 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2491 | 2472 | ||
2492 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 2473 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); |
2493 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | 2474 | nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
2494 | break; | 2475 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); |
2495 | temp_phy_data = phy_data; | 2476 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
2496 | } while (1); | 2477 | |
2478 | phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; | ||
2479 | |||
2497 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | 2480 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", |
2498 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | 2481 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); |
2499 | break; | 2482 | break; |
2500 | 2483 | ||
2501 | case NES_PHY_TYPE_PUMA_1G: | 2484 | case NES_PHY_TYPE_PUMA_1G: |
@@ -2511,6 +2494,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2511 | } | 2494 | } |
2512 | 2495 | ||
2513 | if (phy_data & 0x0004) { | 2496 | if (phy_data & 0x0004) { |
2497 | if (wide_ppm_offset && | ||
2498 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) && | ||
2499 | (nesadapter->hw_rev != NE020_REV)) { | ||
2500 | cdr_ctrl = nes_read_indexed(nesdev, | ||
2501 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
2502 | mac_index * 0x200); | ||
2503 | nes_write_indexed(nesdev, | ||
2504 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
2505 | mac_index * 0x200, | ||
2506 | cdr_ctrl | 0x000F0000); | ||
2507 | } | ||
2514 | nesadapter->mac_link_down[mac_index] = 0; | 2508 | nesadapter->mac_link_down[mac_index] = 0; |
2515 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | 2509 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { |
2516 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", | 2510 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", |
@@ -2525,6 +2519,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2525 | } | 2519 | } |
2526 | } | 2520 | } |
2527 | } else { | 2521 | } else { |
2522 | if (wide_ppm_offset && | ||
2523 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) && | ||
2524 | (nesadapter->hw_rev != NE020_REV)) { | ||
2525 | cdr_ctrl = nes_read_indexed(nesdev, | ||
2526 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
2527 | mac_index * 0x200); | ||
2528 | nes_write_indexed(nesdev, | ||
2529 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
2530 | mac_index * 0x200, | ||
2531 | cdr_ctrl & 0xFFF0FFFF); | ||
2532 | } | ||
2528 | nesadapter->mac_link_down[mac_index] = 1; | 2533 | nesadapter->mac_link_down[mac_index] = 1; |
2529 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | 2534 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { |
2530 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", | 2535 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", |