Commit a2765103 authored by Chien Tung's avatar Chien Tung Committed by Roland Dreier

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: default avatarChien Tung <chien.tin.tung@intel.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent e293a26f
...@@ -1356,6 +1356,8 @@ int nes_init_phy(struct nes_device *nesdev) ...@@ -1356,6 +1356,8 @@ int nes_init_phy(struct nes_device *nesdev)
} }
if ((phy_type == NES_PHY_TYPE_ARGUS) || if ((phy_type == NES_PHY_TYPE_ARGUS) ||
(phy_type == NES_PHY_TYPE_SFP_D)) { (phy_type == NES_PHY_TYPE_SFP_D)) {
u32 first_time = 1;
/* Check firmware heartbeat */ /* Check firmware heartbeat */
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 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,8 +1365,13 @@ int nes_init_phy(struct nes_device *nesdev)
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
if (temp_phy_data != temp_phy_data2) if (temp_phy_data != temp_phy_data2) {
return 0; nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
if ((temp_phy_data & 0xff) > 0x20)
return 0;
printk(PFX "Reinitializing PHY\n");
}
/* no heartbeat, configure the PHY */ /* no heartbeat, configure the PHY */
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
...@@ -1400,7 +1407,7 @@ int nes_init_phy(struct nes_device *nesdev) ...@@ -1400,7 +1407,7 @@ int nes_init_phy(struct nes_device *nesdev)
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
do { do {
if (counter++ > 150) { if (counter++ > 150) {
nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); printk(PFX "No PHY heartbeat\n");
break; break;
} }
mdelay(1); mdelay(1);
...@@ -1414,11 +1421,20 @@ int nes_init_phy(struct nes_device *nesdev) ...@@ -1414,11 +1421,20 @@ int nes_init_phy(struct nes_device *nesdev)
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
if (counter++ > 300) { if (counter++ > 300) {
nes_debug(NES_DBG_PHY, "PHY did not track\n"); if (((temp_phy_data & 0xff) == 0x0) && first_time) {
break; first_time = 0;
counter = 0;
/* reset AMCC PHY and try again */
nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0);
nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040);
continue;
} else {
printk(PFX "PHY did not track\n");
break;
}
} }
mdelay(10); mdelay(10);
} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); } while ((temp_phy_data & 0xff) < 0x30);
/* setup signal integrity */ /* setup signal integrity */
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment