aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorChien Tung <chien.tin.tung@intel.com>2009-12-09 18:21:56 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 18:21:56 -0500
commita276510328d0721c252b37044c51e2fb4efe0364 (patch)
tree1a9d9632f919410cdbdada648ac1dc62ecca862c /drivers/infiniband/hw
parente293a26fe97c8598a96562c1c9376d9ae6cb96dd (diff)
RDMA/nes: Add additional SFP+ PHY uC status check and PHY reset
Add additional PHY uC status check in case PHY firmware is not running properly with heartbeat. Add a hard PHY reset if uC status is 0x0 after initial reset. Signed-off-by: Chien Tung <chien.tin.tung@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 3d9bbff4f7ac..b59ca5659423 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -1356,6 +1356,8 @@ int nes_init_phy(struct nes_device *nesdev)
1356 } 1356 }
1357 if ((phy_type == NES_PHY_TYPE_ARGUS) || 1357 if ((phy_type == NES_PHY_TYPE_ARGUS) ||
1358 (phy_type == NES_PHY_TYPE_SFP_D)) { 1358 (phy_type == NES_PHY_TYPE_SFP_D)) {
1359 u32 first_time = 1;
1360
1359 /* Check firmware heartbeat */ 1361 /* Check firmware heartbeat */
1360 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); 1362 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
1361 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1363 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
@@ -1363,8 +1365,13 @@ int nes_init_phy(struct nes_device *nesdev)
1363 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); 1365 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
1364 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1366 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1365 1367
1366 if (temp_phy_data != temp_phy_data2) 1368 if (temp_phy_data != temp_phy_data2) {
1367 return 0; 1369 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
1370 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1371 if ((temp_phy_data & 0xff) > 0x20)
1372 return 0;
1373 printk(PFX "Reinitializing PHY\n");
1374 }
1368 1375
1369 /* no heartbeat, configure the PHY */ 1376 /* no heartbeat, configure the PHY */
1370 nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); 1377 nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
@@ -1400,7 +1407,7 @@ int nes_init_phy(struct nes_device *nesdev)
1400 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1407 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1401 do { 1408 do {
1402 if (counter++ > 150) { 1409 if (counter++ > 150) {
1403 nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); 1410 printk(PFX "No PHY heartbeat\n");
1404 break; 1411 break;
1405 } 1412 }
1406 mdelay(1); 1413 mdelay(1);
@@ -1414,11 +1421,20 @@ int nes_init_phy(struct nes_device *nesdev)
1414 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); 1421 nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
1415 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1422 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1416 if (counter++ > 300) { 1423 if (counter++ > 300) {
1417 nes_debug(NES_DBG_PHY, "PHY did not track\n"); 1424 if (((temp_phy_data & 0xff) == 0x0) && first_time) {
1418 break; 1425 first_time = 0;
1426 counter = 0;
1427 /* reset AMCC PHY and try again */
1428 nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0);
1429 nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040);
1430 continue;
1431 } else {
1432 printk(PFX "PHY did not track\n");
1433 break;
1434 }
1419 } 1435 }
1420 mdelay(10); 1436 mdelay(10);
1421 } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); 1437 } while ((temp_phy_data & 0xff) < 0x30);
1422 1438
1423 /* setup signal integrity */ 1439 /* setup signal integrity */
1424 nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); 1440 nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);