RDMA/nes: Fix incorrect SFP+ link status detection on driver init

During iw_nes initialization the 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 the
iw_nes initialization procedure. Use link status recheck for
netdev_open to detect delayed state updates.

Signed-off-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Maciej Sosnowski and committed by Roland Dreier 843276ad 5f61b2c6

+39 -4
+39 -4
drivers/infiniband/hw/nes/nes_nic.c
··· 241 241 netif_carrier_on(netdev); 242 242 } 243 243 244 + spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); 245 + if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_SFP_D) { 246 + if (nesdev->link_recheck) 247 + cancel_delayed_work(&nesdev->work); 248 + nesdev->link_recheck = 1; 249 + schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY); 250 + } 251 + spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); 252 + 244 253 spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); 245 254 if (nesvnic->of_device_registered) { 246 255 nesdev->nesadapter->send_term_ok = 1; ··· 1791 1782 (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || 1792 1783 ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { 1793 1784 u32 u32temp; 1794 - u32 link_mask; 1795 - u32 link_val; 1785 + u32 link_mask = 0; 1786 + u32 link_val = 0; 1787 + u16 temp_phy_data; 1788 + u16 phy_data = 0; 1789 + unsigned long flags; 1796 1790 1797 1791 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1798 1792 (0x200 * (nesdev->mac_index & 1))); ··· 1817 1805 link_val = 0x02020000; 1818 1806 } 1819 1807 break; 1808 + case NES_PHY_TYPE_SFP_D: 1809 + spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); 1810 + nes_read_10G_phy_reg(nesdev, 1811 + nesdev->nesadapter->phy_index[nesdev->mac_index], 1812 + 1, 0x9003); 1813 + temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1814 + nes_read_10G_phy_reg(nesdev, 1815 + nesdev->nesadapter->phy_index[nesdev->mac_index], 1816 + 3, 0x0021); 1817 + nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1818 + nes_read_10G_phy_reg(nesdev, 1819 + nesdev->nesadapter->phy_index[nesdev->mac_index], 1820 + 3, 0x0021); 1821 + phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 1822 + spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); 1823 + phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; 1824 + break; 1820 1825 default: 1821 1826 link_mask = 0x0f1f0000; 1822 1827 link_val = 0x0f0f0000; ··· 1843 1814 u32temp = nes_read_indexed(nesdev, 1844 1815 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1845 1816 (0x200 * (nesdev->mac_index & 1))); 1846 - if ((u32temp & link_mask) == link_val) 1847 - nesvnic->linkup = 1; 1817 + 1818 + if (phy_type == NES_PHY_TYPE_SFP_D) { 1819 + if (phy_data & 0x0004) 1820 + nesvnic->linkup = 1; 1821 + } else { 1822 + if ((u32temp & link_mask) == link_val) 1823 + nesvnic->linkup = 1; 1824 + } 1848 1825 1849 1826 /* clear the MAC interrupt status, assumes direct logical to physical mapping */ 1850 1827 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));