|
@@ -144,6 +144,7 @@ static int nes_netdev_open(struct net_device *netdev)
|
|
|
u32 nic_active_bit;
|
|
|
u32 nic_active;
|
|
|
struct list_head *list_pos, *list_temp;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
assert(nesdev != NULL);
|
|
|
|
|
@@ -233,18 +234,36 @@ static int nes_netdev_open(struct net_device *netdev)
|
|
|
first_nesvnic = nesvnic;
|
|
|
}
|
|
|
|
|
|
- if (nesvnic->of_device_registered) {
|
|
|
- nesdev->iw_status = 1;
|
|
|
- nesdev->nesadapter->send_term_ok = 1;
|
|
|
- nes_port_ibevent(nesvnic);
|
|
|
- }
|
|
|
-
|
|
|
if (first_nesvnic->linkup) {
|
|
|
/* Enable network packets */
|
|
|
nesvnic->linkup = 1;
|
|
|
netif_start_queue(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;
|
|
|
+ if (nesvnic->linkup == 1) {
|
|
|
+ if (nesdev->iw_status == 0) {
|
|
|
+ nesdev->iw_status = 1;
|
|
|
+ nes_port_ibevent(nesvnic);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ nesdev->iw_status = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags);
|
|
|
+
|
|
|
napi_enable(&nesvnic->napi);
|
|
|
nesvnic->netdev_open = 1;
|
|
|
|
|
@@ -263,6 +282,7 @@ static int nes_netdev_stop(struct net_device *netdev)
|
|
|
u32 nic_active;
|
|
|
struct nes_vnic *first_nesvnic = NULL;
|
|
|
struct list_head *list_pos, *list_temp;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
|
|
|
nesvnic, nesdev, netdev, netdev->name);
|
|
@@ -315,12 +335,17 @@ static int nes_netdev_stop(struct net_device *netdev)
|
|
|
nic_active &= nic_active_mask;
|
|
|
nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
|
|
|
|
|
|
-
|
|
|
+ spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags);
|
|
|
if (nesvnic->of_device_registered) {
|
|
|
nesdev->nesadapter->send_term_ok = 0;
|
|
|
nesdev->iw_status = 0;
|
|
|
- nes_port_ibevent(nesvnic);
|
|
|
+ if (nesvnic->linkup == 1)
|
|
|
+ nes_port_ibevent(nesvnic);
|
|
|
}
|
|
|
+ del_timer_sync(&nesvnic->event_timer);
|
|
|
+ nesvnic->event_timer.function = NULL;
|
|
|
+ spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags);
|
|
|
+
|
|
|
nes_destroy_nic_qp(nesvnic);
|
|
|
|
|
|
nesvnic->netdev_open = 0;
|
|
@@ -1750,7 +1775,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
|
|
nesvnic->rdma_enabled = 0;
|
|
|
}
|
|
|
nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id;
|
|
|
+ init_timer(&nesvnic->event_timer);
|
|
|
+ nesvnic->event_timer.function = NULL;
|
|
|
spin_lock_init(&nesvnic->tx_lock);
|
|
|
+ spin_lock_init(&nesvnic->port_ibevent_lock);
|
|
|
nesdev->netdev[nesdev->netdev_count] = netdev;
|
|
|
|
|
|
nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n",
|
|
@@ -1763,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)));
|
|
@@ -1786,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;
|
|
@@ -1795,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));
|