diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_hw.c')
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 389 |
1 files changed, 194 insertions, 195 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 52e734042b8e..d6fc9ae44062 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; |
| @@ -546,8 +550,11 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
| 546 | msleep(1); | 550 | msleep(1); |
| 547 | } | 551 | } |
| 548 | if (int_cnt > 1) { | 552 | if (int_cnt > 1) { |
| 553 | u32 sds; | ||
| 549 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 554 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
| 550 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); | 555 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); |
| 556 | sds |= 0x00000040; | ||
| 557 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds); | ||
| 551 | mh_detected++; | 558 | mh_detected++; |
| 552 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); | 559 | reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); |
| 553 | reset_value |= 0x0000003d; | 560 | reset_value |= 0x0000003d; |
| @@ -736,39 +743,49 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
| 736 | { | 743 | { |
| 737 | int i; | 744 | int i; |
| 738 | u32 u32temp; | 745 | u32 u32temp; |
| 739 | u32 serdes_common_control; | 746 | u32 sds; |
| 740 | 747 | ||
| 741 | if (hw_rev != NE020_REV) { | 748 | if (hw_rev != NE020_REV) { |
| 742 | /* init serdes 0 */ | 749 | /* init serdes 0 */ |
| 750 | if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4)) | ||
| 751 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | ||
| 752 | else | ||
| 753 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
| 743 | 754 | ||
| 744 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
| 745 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | 755 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
| 746 | serdes_common_control = nes_read_indexed(nesdev, | 756 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); |
| 747 | NES_IDX_ETH_SERDES_COMMON_CONTROL0); | 757 | sds |= 0x00000100; |
| 748 | serdes_common_control |= 0x000000100; | 758 | 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 | } | 759 | } |
| 755 | if (((port_count > 1) && | 760 | if (!OneG_Mode) |
| 756 | (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) || | 761 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); |
| 757 | ((port_count > 2) && | 762 | |
| 758 | (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) { | 763 | if (port_count < 2) |
| 759 | /* init serdes 1 */ | 764 | return 0; |
| 760 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); | 765 | |
| 761 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | 766 | /* init serdes 1 */ |
| 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 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); |
| 770 | } | 775 | sds &= 0xFFFFFFBF; |
| 776 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds); | ||
| 777 | if (wide_ppm_offset) | ||
| 778 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA); | ||
| 779 | else | ||
| 780 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); | ||
| 781 | break; | ||
| 782 | case NES_PHY_TYPE_PUMA_1G: | ||
| 783 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); | ||
| 784 | sds |= 0x000000100; | ||
| 785 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds); | ||
| 771 | } | 786 | } |
| 787 | if (!OneG_Mode) | ||
| 788 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); | ||
| 772 | } else { | 789 | } else { |
| 773 | /* init serdes 0 */ | 790 | /* init serdes 0 */ |
| 774 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); | 791 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); |
| @@ -1259,203 +1276,162 @@ int nes_init_phy(struct nes_device *nesdev) | |||
| 1259 | { | 1276 | { |
| 1260 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1277 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 1261 | u32 counter = 0; | 1278 | u32 counter = 0; |
| 1262 | u32 sds_common_control0; | 1279 | u32 sds; |
| 1263 | u32 mac_index = nesdev->mac_index; | 1280 | u32 mac_index = nesdev->mac_index; |
| 1264 | u32 tx_config = 0; | 1281 | u32 tx_config = 0; |
| 1265 | u16 phy_data; | 1282 | u16 phy_data; |
| 1266 | u32 temp_phy_data = 0; | 1283 | u32 temp_phy_data = 0; |
| 1267 | u32 temp_phy_data2 = 0; | 1284 | u32 temp_phy_data2 = 0; |
| 1268 | u32 i = 0; | 1285 | u8 phy_type = nesadapter->phy_type[mac_index]; |
| 1286 | u8 phy_index = nesadapter->phy_index[mac_index]; | ||
| 1269 | 1287 | ||
| 1270 | if ((nesadapter->OneG_Mode) && | 1288 | if ((nesadapter->OneG_Mode) && |
| 1271 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | 1289 | (phy_type != NES_PHY_TYPE_PUMA_1G)) { |
| 1272 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | 1290 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); |
| 1273 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { | 1291 | 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); | 1292 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
| 1276 | tx_config &= 0xFFFFFFE3; | 1293 | tx_config &= 0xFFFFFFE3; |
| 1277 | tx_config |= 0x04; | 1294 | tx_config |= 0x04; |
| 1278 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | 1295 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
| 1279 | } | 1296 | } |
| 1280 | 1297 | ||
| 1281 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); | 1298 | 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", | 1299 | 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 | 1300 | ||
| 1286 | /* Reset the PHY */ | 1301 | /* Reset the PHY */ |
| 1287 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); | 1302 | nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); |
| 1288 | udelay(100); | 1303 | udelay(100); |
| 1289 | counter = 0; | 1304 | counter = 0; |
| 1290 | do { | 1305 | do { |
| 1291 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1306 | 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); | 1307 | if (counter++ > 100) |
| 1293 | if (counter++ > 100) break; | 1308 | break; |
| 1294 | } while (phy_data & 0x8000); | 1309 | } while (phy_data & 0x8000); |
| 1295 | 1310 | ||
| 1296 | /* Setting no phy loopback */ | 1311 | /* Setting no phy loopback */ |
| 1297 | phy_data &= 0xbfff; | 1312 | phy_data &= 0xbfff; |
| 1298 | phy_data |= 0x1140; | 1313 | phy_data |= 0x1140; |
| 1299 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data); | 1314 | 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); | 1315 | 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); | 1316 | nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); |
| 1302 | 1317 | 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 | 1318 | ||
| 1309 | /* Setting the interrupt mask */ | 1319 | /* Setting the interrupt mask */ |
| 1310 | nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data); | 1320 | 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); | 1321 | nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); |
| 1312 | nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee); | 1322 | 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 | 1323 | ||
| 1317 | /* turning on flow control */ | 1324 | /* turning on flow control */ |
| 1318 | nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data); | 1325 | 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); | 1326 | 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], | 1327 | 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 | |||
| 1335 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | ||
| 1336 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); | ||
| 1337 | } else { | ||
| 1338 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) || | ||
| 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 | 1328 | ||
| 1349 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1329 | /* Clear Half duplex */ |
| 1350 | mdelay(10); | 1330 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); |
| 1351 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | 1331 | nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); |
| 1352 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1332 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); |
| 1353 | 1333 | ||
| 1354 | /* | 1334 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); |
| 1355 | * if firmware is already running (like from a | 1335 | 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 | 1336 | ||
| 1370 | /* | 1337 | return 0; |
| 1371 | * remove micro from reset; chip boots from ROM, | 1338 | } |
| 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 | 1339 | ||
| 1376 | /* | 1340 | if ((phy_type == NES_PHY_TYPE_IRIS) || |
| 1377 | * wait for heart beat to start to | 1341 | (phy_type == NES_PHY_TYPE_ARGUS) || |
| 1378 | * know loading is done | 1342 | (phy_type == NES_PHY_TYPE_SFP_D)) { |
| 1379 | */ | 1343 | /* setup 10G MDIO operation */ |
| 1380 | counter = 0; | 1344 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
| 1381 | do { | 1345 | tx_config &= 0xFFFFFFE3; |
| 1382 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | 1346 | tx_config |= 0x15; |
| 1383 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1347 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
| 1384 | if (counter++ > 1000) { | 1348 | } |
| 1385 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n"); | 1349 | if ((phy_type == NES_PHY_TYPE_ARGUS) || |
| 1386 | break; | 1350 | (phy_type == NES_PHY_TYPE_SFP_D)) { |
| 1387 | } | 1351 | /* Check firmware heartbeat */ |
| 1388 | mdelay(100); | 1352 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
| 1389 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | 1353 | 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); | 1354 | udelay(1500); |
| 1391 | } while ((temp_phy_data2 == temp_phy_data)); | 1355 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
| 1356 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1357 | |||
| 1358 | if (temp_phy_data != temp_phy_data2) | ||
| 1359 | return 0; | ||
| 1392 | 1360 | ||
| 1393 | /* | 1361 | /* no heartbeat, configure the PHY */ |
| 1394 | * wait for tracking to start to know | 1362 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); |
| 1395 | * f/w is good to go | 1363 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); |
| 1396 | */ | 1364 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); |
| 1397 | counter = 0; | 1365 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); |
| 1398 | do { | 1366 | if (phy_type == NES_PHY_TYPE_ARGUS) { |
| 1399 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd); | 1367 | 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); | 1368 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); |
| 1401 | if (counter++ > 1000) { | 1369 | } else { |
| 1402 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n"); | 1370 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); |
| 1403 | break; | 1371 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); |
| 1404 | } | 1372 | } |
| 1405 | mdelay(1000); | 1373 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); |
| 1406 | /* | 1374 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); |
| 1407 | * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n", | 1375 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); |
| 1408 | * temp_phy_data); | ||
| 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 | 1376 | ||
| 1423 | /* | 1377 | /* setup LEDs */ |
| 1424 | * reset the res-calibration on t2 | 1378 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); |
| 1425 | * serdes; ensures it is stable after | 1379 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); |
| 1426 | * the amcc phy is stable | 1380 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); |
| 1427 | */ | ||
| 1428 | 1381 | ||
| 1429 | sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | 1382 | 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 | 1383 | ||
| 1433 | /* release the res-calibration reset */ | 1384 | /* Bring PHY out of reset */ |
| 1434 | sds_common_control0 &= 0xfffffffe; | 1385 | 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 | 1386 | ||
| 1437 | i = 0; | 1387 | /* Check for heartbeat */ |
| 1438 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | 1388 | counter = 0; |
| 1439 | && (i++ < 5000)) { | 1389 | mdelay(690); |
| 1440 | /* mdelay(1); */ | 1390 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
| 1441 | } | 1391 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
| 1392 | do { | ||
| 1393 | if (counter++ > 150) { | ||
| 1394 | nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); | ||
| 1395 | break; | ||
| 1396 | } | ||
| 1397 | mdelay(1); | ||
| 1398 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
| 1399 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1400 | } while ((temp_phy_data2 == temp_phy_data)); | ||
| 1442 | 1401 | ||
| 1443 | /* | 1402 | /* wait for tracking */ |
| 1444 | * wait for link train done before moving on, | 1403 | counter = 0; |
| 1445 | * or will get an interupt storm | 1404 | do { |
| 1446 | */ | 1405 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); |
| 1447 | counter = 0; | 1406 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
| 1448 | do { | 1407 | if (counter++ > 300) { |
| 1449 | temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1408 | nes_debug(NES_DBG_PHY, "PHY did not track\n"); |
| 1450 | (0x200 * (nesdev->mac_index & 1))); | 1409 | 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 | } | 1410 | } |
| 1458 | } | 1411 | mdelay(10); |
| 1412 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
| 1413 | |||
| 1414 | /* setup signal integrity */ | ||
| 1415 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); | ||
| 1416 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); | ||
| 1417 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | ||
| 1418 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002); | ||
| 1419 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063); | ||
| 1420 | |||
| 1421 | /* reset serdes */ | ||
| 1422 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
| 1423 | mac_index * 0x200); | ||
| 1424 | sds |= 0x1; | ||
| 1425 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
| 1426 | mac_index * 0x200, sds); | ||
| 1427 | sds &= 0xfffffffe; | ||
| 1428 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||
| 1429 | mac_index * 0x200, sds); | ||
| 1430 | |||
| 1431 | counter = 0; | ||
| 1432 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
| 1433 | && (counter++ < 5000)) | ||
| 1434 | ; | ||
| 1459 | } | 1435 | } |
| 1460 | return 0; | 1436 | return 0; |
| 1461 | } | 1437 | } |
| @@ -2359,6 +2335,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2359 | u16 temp_phy_data; | 2335 | u16 temp_phy_data; |
| 2360 | u32 pcs_val = 0x0f0f0000; | 2336 | u32 pcs_val = 0x0f0f0000; |
| 2361 | u32 pcs_mask = 0x0f1f0000; | 2337 | u32 pcs_mask = 0x0f1f0000; |
| 2338 | u32 cdr_ctrl; | ||
| 2362 | 2339 | ||
| 2363 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 2340 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
| 2364 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { | 2341 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { |
| @@ -2473,6 +2450,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2473 | break; | 2450 | break; |
| 2474 | 2451 | ||
| 2475 | case NES_PHY_TYPE_ARGUS: | 2452 | case NES_PHY_TYPE_ARGUS: |
| 2453 | case NES_PHY_TYPE_SFP_D: | ||
| 2476 | /* clear the alarms */ | 2454 | /* clear the alarms */ |
| 2477 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | 2455 | 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); | 2456 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); |
| @@ -2483,19 +2461,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); | 2461 | 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); | 2462 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); |
| 2485 | /* check link status */ | 2463 | /* check link status */ |
| 2486 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | 2464 | 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); | 2465 | 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 | 2466 | ||
| 2492 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 2467 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); |
| 2493 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | 2468 | nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
| 2494 | break; | 2469 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); |
| 2495 | temp_phy_data = phy_data; | 2470 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
| 2496 | } while (1); | 2471 | |
| 2472 | phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; | ||
| 2473 | |||
| 2497 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | 2474 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", |
| 2498 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | 2475 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); |
| 2499 | break; | 2476 | break; |
| 2500 | 2477 | ||
| 2501 | case NES_PHY_TYPE_PUMA_1G: | 2478 | case NES_PHY_TYPE_PUMA_1G: |
| @@ -2511,6 +2488,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2511 | } | 2488 | } |
| 2512 | 2489 | ||
| 2513 | if (phy_data & 0x0004) { | 2490 | if (phy_data & 0x0004) { |
| 2491 | if (wide_ppm_offset && | ||
| 2492 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) && | ||
| 2493 | (nesadapter->hw_rev != NE020_REV)) { | ||
| 2494 | cdr_ctrl = nes_read_indexed(nesdev, | ||
| 2495 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
| 2496 | mac_index * 0x200); | ||
| 2497 | nes_write_indexed(nesdev, | ||
| 2498 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
| 2499 | mac_index * 0x200, | ||
| 2500 | cdr_ctrl | 0x000F0000); | ||
| 2501 | } | ||
| 2514 | nesadapter->mac_link_down[mac_index] = 0; | 2502 | nesadapter->mac_link_down[mac_index] = 0; |
| 2515 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | 2503 | 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", | 2504 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", |
| @@ -2525,6 +2513,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2525 | } | 2513 | } |
| 2526 | } | 2514 | } |
| 2527 | } else { | 2515 | } else { |
| 2516 | if (wide_ppm_offset && | ||
| 2517 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) && | ||
| 2518 | (nesadapter->hw_rev != NE020_REV)) { | ||
| 2519 | cdr_ctrl = nes_read_indexed(nesdev, | ||
| 2520 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
| 2521 | mac_index * 0x200); | ||
| 2522 | nes_write_indexed(nesdev, | ||
| 2523 | NES_IDX_ETH_SERDES_CDR_CONTROL0 + | ||
| 2524 | mac_index * 0x200, | ||
| 2525 | cdr_ctrl & 0xFFF0FFFF); | ||
| 2526 | } | ||
| 2528 | nesadapter->mac_link_down[mac_index] = 1; | 2527 | nesadapter->mac_link_down[mac_index] = 1; |
| 2529 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | 2528 | 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", | 2529 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", |
