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>
This commit is contained in:
Родитель
5f61b2c693
Коммит
843276ad98
|
@ -241,6 +241,15 @@ static int nes_netdev_open(struct net_device *netdev)
|
|||
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;
|
||||
|
@ -1782,8 +1791,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
|||
(((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)));
|
||||
|
@ -1805,6 +1817,23 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
|||
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;
|
||||
|
@ -1814,8 +1843,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
|||
u32temp = nes_read_indexed(nesdev,
|
||||
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));
|
||||
|
|
Загрузка…
Ссылка в новой задаче