cxgb3: fix link fault handling
authorDivy Le Ray <divy@chelsio.com>
Fri, 17 Apr 2009 12:21:11 +0000 (12:21 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Apr 2009 09:07:23 +0000 (02:07 -0700)
Use the existing periodic task to handle link faults.
The link fault interrupt handler is also called in work queue context,
which is wrong and might cause potential deadlocks.

Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/t3_hw.c

index ab0e5fe..9fdfe0b 100644 (file)
@@ -2493,6 +2493,7 @@ static void check_link_status(struct adapter *adapter)
 
                spin_lock_irq(&adapter->work_lock);
                if (p->link_fault) {
+                       t3_link_fault(adapter, i);
                        spin_unlock_irq(&adapter->work_lock);
                        continue;
                }
@@ -2554,9 +2555,7 @@ static void t3_adap_check_task(struct work_struct *work)
 
        adapter->check_task_cnt++;
 
-       /* Check link status for PHYs without interrupts */
-       if (p->linkpoll_period)
-               check_link_status(adapter);
+       check_link_status(adapter);
 
        /* Accumulate MAC stats if needed */
        if (!p->linkpoll_period ||
@@ -2680,21 +2679,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
        spin_unlock(&adapter->work_lock);
 }
 
-static void link_fault_task(struct work_struct *work)
-{
-       struct adapter *adapter = container_of(work, struct adapter,
-                                              link_fault_handler_task);
-       int i;
-
-       for_each_port(adapter, i) {
-               struct net_device *netdev = adapter->port[i];
-               struct port_info *pi = netdev_priv(netdev);
-
-               if (pi->link_fault)
-                       t3_link_fault(adapter, i);
-       }
-}
-
 void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
 {
        struct net_device *netdev = adapter->port[port_id];
@@ -2702,7 +2686,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
 
        spin_lock(&adapter->work_lock);
        pi->link_fault = 1;
-       queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
        spin_unlock(&adapter->work_lock);
 }
 
@@ -3082,7 +3065,6 @@ static int __devinit init_one(struct pci_dev *pdev,
 
        INIT_LIST_HEAD(&adapter->adapter_list);
        INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
-       INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
        INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
        INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
 
index 31ed31a..e1bd690 100644 (file)
@@ -1202,7 +1202,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
        struct cphy *phy = &pi->phy;
        struct cmac *mac = &pi->mac;
        struct link_config *lc = &pi->link_config;
-       int force_link_down = 0;
 
        phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
@@ -1218,14 +1217,9 @@ void t3_link_changed(struct adapter *adapter, int port_id)
                status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
                if (status & F_LINKFAULTCHANGE) {
                        mac->stats.link_faults++;
-                       force_link_down = 1;
+                       pi->link_fault = 1;
                }
                t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
-
-               if (force_link_down) {
-                       t3_os_link_fault_handler(adapter, port_id);
-                       return;
-               }
        }
 
        if (lc->requested_fc & PAUSE_AUTONEG)
@@ -1292,9 +1286,6 @@ void t3_link_fault(struct adapter *adapter, int port_id)
                /* Account link faults only when the phy reports a link up */
                if (link_ok)
                        mac->stats.link_faults++;
-
-               msleep(1000);
-               t3_os_link_fault_handler(adapter, port_id);
        } else {
                if (link_ok)
                        t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,