diff options
author | Divy Le Ray <divy@chelsio.com> | 2009-04-17 08:21:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-20 05:07:23 -0400 |
commit | 3851c66cf0d130ae49f99fe1dea42950d9835037 (patch) | |
tree | d1df90bef676f4db8da8e67d317261450c857ed4 /drivers/net/cxgb3 | |
parent | 7816a0a862d851d0b05710e7d94bfe390f3180e2 (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.c | 22 | ||||
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 11 |
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 | ||
2683 | static 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 | |||
2698 | void t3_os_link_fault_handler(struct adapter *adapter, int port_id) | 2682 | void 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, |