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

Reply via email to