aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2009-04-17 08:21:11 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-20 05:07:23 -0400
commit3851c66cf0d130ae49f99fe1dea42950d9835037 (patch)
treed1df90bef676f4db8da8e67d317261450c857ed4 /drivers/net/cxgb3
parent7816a0a862d851d0b05710e7d94bfe390f3180e2 (diff)
cxgb3: fix link fault handling
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>
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c22
-rw-r--r--drivers/net/cxgb3/t3_hw.c11
2 files changed, 3 insertions, 30 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index ab0e5febef83..9fdfe0bfaecb 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -2493,6 +2493,7 @@ static void check_link_status(struct adapter *adapter)
2493 2493
2494 spin_lock_irq(&adapter->work_lock); 2494 spin_lock_irq(&adapter->work_lock);
2495 if (p->link_fault) { 2495 if (p->link_fault) {
2496 t3_link_fault(adapter, i);
2496 spin_unlock_irq(&adapter->work_lock); 2497 spin_unlock_irq(&adapter->work_lock);
2497 continue; 2498 continue;
2498 } 2499 }
@@ -2554,9 +2555,7 @@ static void t3_adap_check_task(struct work_struct *work)
2554 2555
2555 adapter->check_task_cnt++; 2556 adapter->check_task_cnt++;
2556 2557
2557 /* Check link status for PHYs without interrupts */ 2558 check_link_status(adapter);
2558 if (p->linkpoll_period)
2559 check_link_status(adapter);
2560 2559
2561 /* Accumulate MAC stats if needed */ 2560 /* Accumulate MAC stats if needed */
2562 if (!p->linkpoll_period || 2561 if (!p->linkpoll_period ||
@@ -2680,21 +2679,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
2680 spin_unlock(&adapter->work_lock); 2679 spin_unlock(&adapter->work_lock);
2681} 2680}
2682 2681
2683static void link_fault_task(struct work_struct *work)
2684{
2685 struct adapter *adapter = container_of(work, struct adapter,
2686 link_fault_handler_task);
2687 int i;
2688
2689 for_each_port(adapter, i) {
2690 struct net_device *netdev = adapter->port[i];
2691 struct port_info *pi = netdev_priv(netdev);
2692
2693 if (pi->link_fault)
2694 t3_link_fault(adapter, i);
2695 }
2696}
2697
2698void t3_os_link_fault_handler(struct adapter *adapter, int port_id) 2682void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
2699{ 2683{
2700 struct net_device *netdev = adapter->port[port_id]; 2684 struct net_device *netdev = adapter->port[port_id];
@@ -2702,7 +2686,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
2702 2686
2703 spin_lock(&adapter->work_lock); 2687 spin_lock(&adapter->work_lock);
2704 pi->link_fault = 1; 2688 pi->link_fault = 1;
2705 queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
2706 spin_unlock(&adapter->work_lock); 2689 spin_unlock(&adapter->work_lock);
2707} 2690}
2708 2691
@@ -3082,7 +3065,6 @@ static int __devinit init_one(struct pci_dev *pdev,
3082 3065
3083 INIT_LIST_HEAD(&adapter->adapter_list); 3066 INIT_LIST_HEAD(&adapter->adapter_list);
3084 INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); 3067 INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
3085 INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
3086 INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); 3068 INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
3087 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); 3069 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
3088 3070
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 31ed31a3428b..e1bd690ff831 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1202,7 +1202,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
1202 struct cphy *phy = &pi->phy; 1202 struct cphy *phy = &pi->phy;
1203 struct cmac *mac = &pi->mac; 1203 struct cmac *mac = &pi->mac;
1204 struct link_config *lc = &pi->link_config; 1204 struct link_config *lc = &pi->link_config;
1205 int force_link_down = 0;
1206 1205
1207 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); 1206 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
1208 1207
@@ -1218,14 +1217,9 @@ void t3_link_changed(struct adapter *adapter, int port_id)
1218 status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); 1217 status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
1219 if (status & F_LINKFAULTCHANGE) { 1218 if (status & F_LINKFAULTCHANGE) {
1220 mac->stats.link_faults++; 1219 mac->stats.link_faults++;
1221 force_link_down = 1; 1220 pi->link_fault = 1;
1222 } 1221 }
1223 t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); 1222 t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
1224
1225 if (force_link_down) {
1226 t3_os_link_fault_handler(adapter, port_id);
1227 return;
1228 }
1229 } 1223 }
1230 1224
1231 if (lc->requested_fc & PAUSE_AUTONEG) 1225 if (lc->requested_fc & PAUSE_AUTONEG)
@@ -1292,9 +1286,6 @@ void t3_link_fault(struct adapter *adapter, int port_id)
1292 /* Account link faults only when the phy reports a link up */ 1286 /* Account link faults only when the phy reports a link up */
1293 if (link_ok) 1287 if (link_ok)
1294 mac->stats.link_faults++; 1288 mac->stats.link_faults++;
1295
1296 msleep(1000);
1297 t3_os_link_fault_handler(adapter, port_id);
1298 } else { 1289 } else {
1299 if (link_ok) 1290 if (link_ok)
1300 t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 1291 t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,