During iw_nes initialization link status for SFP phy is always detected as "up" regardless of real state (cable either connected or disconnected). Add SFP phy specific link status detection to iw_nes initialization procedure. Use link status recheck for netdev_open to detect delayed state updates.
Signed-off-by: Maciej Sosnowski <[email protected]> --- .../fixes/nes_0050_init_sfp_port_state.patch | 74 +++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-) diff --git a/kernel_patches/fixes/nes_0050_init_sfp_port_state.patch b/kernel_patches/fixes/nes_0050_init_sfp_port_state.patch new file mode 100644 index 0000000..91e7d86 --- /dev/null +++ b/kernel_patches/fixes/nes_0050_init_sfp_port_state.patch @@ -0,0 +1,74 @@ +diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c +index 9500cb0..0aaa1db 100644 +--- a/drivers/infiniband/hw/nes/nes_nic.c ++++ b/drivers/infiniband/hw/nes/nes_nic.c +@@ -240,6 +240,15 @@ static int nes_netdev_open(struct net_de + netif_carrier_on(netdev); + } + ++ spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); ++ if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_SFP_D) { ++ if (nesdev->link_recheck) ++ cancel_delayed_work(&nesdev->work); ++ nesdev->link_recheck = 1; ++ schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY); ++ } ++ spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); ++ + spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); + if (nesvnic->of_device_registered) { + nesdev->nesadapter->send_term_ok = 1; +@@ -1760,8 +1769,11 @@ struct net_device *nes_netdev_init(struc + (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || + ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { + u32 u32temp; +- u32 link_mask; +- u32 link_val; ++ u32 link_mask = 0; ++ u32 link_val = 0; ++ u16 temp_phy_data; ++ u16 phy_data = 0; ++ unsigned long flags; + + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + + (0x200 * (nesdev->mac_index & 1))); +@@ -1783,6 +1795,23 @@ struct net_device *nes_netdev_init(struc + link_val = 0x02020000; + } + break; ++ case NES_PHY_TYPE_SFP_D: ++ spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); ++ nes_read_10G_phy_reg(nesdev, ++ nesdev->nesadapter->phy_index[nesdev->mac_index], ++ 1, 0x9003); ++ temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); ++ nes_read_10G_phy_reg(nesdev, ++ nesdev->nesadapter->phy_index[nesdev->mac_index], ++ 3, 0x0021); ++ nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); ++ nes_read_10G_phy_reg(nesdev, ++ nesdev->nesadapter->phy_index[nesdev->mac_index], ++ 3, 0x0021); ++ phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); ++ spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); ++ phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; ++ break; + default: + link_mask = 0x0f1f0000; + link_val = 0x0f0f0000; +@@ -1793,8 +1822,13 @@ struct net_device *nes_netdev_init(struc + NES_IDX_PHY_PCS_CONTROL_STATUS0 + + (0x200 * (nesdev->mac_index & 1))); + +- if ((u32temp & link_mask) == link_val) +- nesvnic->linkup = 1; ++ if (phy_type == NES_PHY_TYPE_SFP_D) { ++ if (phy_data & 0x0004) ++ nesvnic->linkup = 1; ++ } else { ++ if ((u32temp & link_mask) == link_val) ++ nesvnic->linkup = 1; ++ } + + /* clear the MAC interrupt status, assumes direct logical to physical mapping */ + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); _______________________________________________ ewg mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg
