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>
This commit is contained in:
committed by
Roland Dreier
parent
e293a26fe9
commit
a276510328
@@ -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)
|
|||||||
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) {
|
||||||
|
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;
|
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)
|
|||||||
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)
|
|||||||
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) {
|
||||||
|
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;
|
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);
|
||||||
|
Reference in New Issue
Block a user