aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c44
-rw-r--r--drivers/net/cxgb3/t3_hw.c13
2 files changed, 22 insertions, 35 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index ab0e5febef83..7ea48414c6cb 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1117,8 +1117,8 @@ static void cxgb_down(struct adapter *adapter)
1117 spin_unlock_irq(&adapter->work_lock); 1117 spin_unlock_irq(&adapter->work_lock);
1118 1118
1119 free_irq_resources(adapter); 1119 free_irq_resources(adapter);
1120 flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
1121 quiesce_rx(adapter); 1120 quiesce_rx(adapter);
1121 flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
1122} 1122}
1123 1123
1124static void schedule_chk_task(struct adapter *adap) 1124static void schedule_chk_task(struct adapter *adap)
@@ -1187,6 +1187,9 @@ static int offload_close(struct t3cdev *tdev)
1187 1187
1188 sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); 1188 sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
1189 1189
1190 /* Flush work scheduled while releasing TIDs */
1191 flush_scheduled_work();
1192
1190 tdev->lldev = NULL; 1193 tdev->lldev = NULL;
1191 cxgb3_set_dummy_ops(tdev); 1194 cxgb3_set_dummy_ops(tdev);
1192 t3_tp_set_offload_mode(adapter, 0); 1195 t3_tp_set_offload_mode(adapter, 0);
@@ -1232,6 +1235,10 @@ static int cxgb_close(struct net_device *dev)
1232 struct port_info *pi = netdev_priv(dev); 1235 struct port_info *pi = netdev_priv(dev);
1233 struct adapter *adapter = pi->adapter; 1236 struct adapter *adapter = pi->adapter;
1234 1237
1238
1239 if (!adapter->open_device_map)
1240 return 0;
1241
1235 /* Stop link fault interrupts */ 1242 /* Stop link fault interrupts */
1236 t3_xgm_intr_disable(adapter, pi->port_id); 1243 t3_xgm_intr_disable(adapter, pi->port_id);
1237 t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); 1244 t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
@@ -1247,8 +1254,7 @@ static int cxgb_close(struct net_device *dev)
1247 spin_unlock_irq(&adapter->work_lock); 1254 spin_unlock_irq(&adapter->work_lock);
1248 1255
1249 if (!(adapter->open_device_map & PORT_MASK)) 1256 if (!(adapter->open_device_map & PORT_MASK))
1250 cancel_rearming_delayed_workqueue(cxgb3_wq, 1257 cancel_delayed_work_sync(&adapter->adap_check_task);
1251 &adapter->adap_check_task);
1252 1258
1253 if (!adapter->open_device_map) 1259 if (!adapter->open_device_map)
1254 cxgb_down(adapter); 1260 cxgb_down(adapter);
@@ -2493,6 +2499,7 @@ static void check_link_status(struct adapter *adapter)
2493 2499
2494 spin_lock_irq(&adapter->work_lock); 2500 spin_lock_irq(&adapter->work_lock);
2495 if (p->link_fault) { 2501 if (p->link_fault) {
2502 t3_link_fault(adapter, i);
2496 spin_unlock_irq(&adapter->work_lock); 2503 spin_unlock_irq(&adapter->work_lock);
2497 continue; 2504 continue;
2498 } 2505 }
@@ -2554,9 +2561,7 @@ static void t3_adap_check_task(struct work_struct *work)
2554 2561
2555 adapter->check_task_cnt++; 2562 adapter->check_task_cnt++;
2556 2563
2557 /* Check link status for PHYs without interrupts */ 2564 check_link_status(adapter);
2558 if (p->linkpoll_period)
2559 check_link_status(adapter);
2560 2565
2561 /* Accumulate MAC stats if needed */ 2566 /* Accumulate MAC stats if needed */
2562 if (!p->linkpoll_period || 2567 if (!p->linkpoll_period ||
@@ -2680,21 +2685,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
2680 spin_unlock(&adapter->work_lock); 2685 spin_unlock(&adapter->work_lock);
2681} 2686}
2682 2687
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) 2688void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
2699{ 2689{
2700 struct net_device *netdev = adapter->port[port_id]; 2690 struct net_device *netdev = adapter->port[port_id];
@@ -2702,7 +2692,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
2702 2692
2703 spin_lock(&adapter->work_lock); 2693 spin_lock(&adapter->work_lock);
2704 pi->link_fault = 1; 2694 pi->link_fault = 1;
2705 queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
2706 spin_unlock(&adapter->work_lock); 2695 spin_unlock(&adapter->work_lock);
2707} 2696}
2708 2697
@@ -2838,6 +2827,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
2838 struct adapter *adapter = pci_get_drvdata(pdev); 2827 struct adapter *adapter = pci_get_drvdata(pdev);
2839 int ret; 2828 int ret;
2840 2829
2830 if (state == pci_channel_io_perm_failure)
2831 return PCI_ERS_RESULT_DISCONNECT;
2832
2841 ret = t3_adapter_error(adapter, 0); 2833 ret = t3_adapter_error(adapter, 0);
2842 2834
2843 /* Request a slot reset. */ 2835 /* Request a slot reset. */
@@ -2932,8 +2924,13 @@ static int __devinit cxgb_enable_msix(struct adapter *adap)
2932 while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0) 2924 while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
2933 vectors = err; 2925 vectors = err;
2934 2926
2935 if (!err && vectors < (adap->params.nports + 1)) 2927 if (err < 0)
2928 pci_disable_msix(adap->pdev);
2929
2930 if (!err && vectors < (adap->params.nports + 1)) {
2931 pci_disable_msix(adap->pdev);
2936 err = -1; 2932 err = -1;
2933 }
2937 2934
2938 if (!err) { 2935 if (!err) {
2939 for (i = 0; i < vectors; ++i) 2936 for (i = 0; i < vectors; ++i)
@@ -3082,7 +3079,6 @@ static int __devinit init_one(struct pci_dev *pdev,
3082 3079
3083 INIT_LIST_HEAD(&adapter->adapter_list); 3080 INIT_LIST_HEAD(&adapter->adapter_list);
3084 INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); 3081 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); 3082 INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
3087 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); 3083 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
3088 3084
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 31ed31a3428b..4f68aeb2679a 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,
@@ -3788,7 +3779,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
3788 3779
3789 adapter->params.info = ai; 3780 adapter->params.info = ai;
3790 adapter->params.nports = ai->nports0 + ai->nports1; 3781 adapter->params.nports = ai->nports0 + ai->nports1;
3791 adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1); 3782 adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1);
3792 adapter->params.rev = t3_read_reg(adapter, A_PL_REV); 3783 adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
3793 /* 3784 /*
3794 * We used to only run the "adapter check task" once a second if 3785 * We used to only run the "adapter check task" once a second if