aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Cooper <jcooper@solarflare.com>2013-04-15 13:51:54 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-08-29 13:12:08 -0400
commit261e4d96b45476fa7386130a309bc15af9eca2e0 (patch)
tree51f4a3d2a08085c5ea2ec2fc5c39c46bf4568cda
parentb883d0bd4ae91059242fd2f8c2a70f308ef63dc1 (diff)
sfc: Allow event queue initialisation to fail
On EF10, event queue initialisation requires an MCDI request which may return failure. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/efx.c111
-rw-r--r--drivers/net/ethernet/sfc/farch.c4
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
-rw-r--r--drivers/net/ethernet/sfc/nic.h6
4 files changed, 95 insertions, 28 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 69150fa1459b..84c47d3f2b53 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -189,7 +189,7 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
189 * 189 *
190 *************************************************************************/ 190 *************************************************************************/
191 191
192static void efx_soft_enable_interrupts(struct efx_nic *efx); 192static int efx_soft_enable_interrupts(struct efx_nic *efx);
193static void efx_soft_disable_interrupts(struct efx_nic *efx); 193static void efx_soft_disable_interrupts(struct efx_nic *efx);
194static void efx_remove_channel(struct efx_channel *channel); 194static void efx_remove_channel(struct efx_channel *channel);
195static void efx_remove_channels(struct efx_nic *efx); 195static void efx_remove_channels(struct efx_nic *efx);
@@ -329,15 +329,21 @@ static int efx_probe_eventq(struct efx_channel *channel)
329} 329}
330 330
331/* Prepare channel's event queue */ 331/* Prepare channel's event queue */
332static void efx_init_eventq(struct efx_channel *channel) 332static int efx_init_eventq(struct efx_channel *channel)
333{ 333{
334 int rc;
335
336 EFX_WARN_ON_PARANOID(channel->eventq_init);
337
334 netif_dbg(channel->efx, drv, channel->efx->net_dev, 338 netif_dbg(channel->efx, drv, channel->efx->net_dev,
335 "chan %d init event queue\n", channel->channel); 339 "chan %d init event queue\n", channel->channel);
336 340
337 channel->eventq_read_ptr = 0; 341 rc = efx_nic_init_eventq(channel);
338 342 if (rc == 0) {
339 efx_nic_init_eventq(channel); 343 channel->eventq_read_ptr = 0;
340 channel->eventq_init = true; 344 channel->eventq_init = true;
345 }
346 return rc;
341} 347}
342 348
343/* Enable event queue processing and NAPI */ 349/* Enable event queue processing and NAPI */
@@ -722,7 +728,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
722 struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel; 728 struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel;
723 u32 old_rxq_entries, old_txq_entries; 729 u32 old_rxq_entries, old_txq_entries;
724 unsigned i, next_buffer_table = 0; 730 unsigned i, next_buffer_table = 0;
725 int rc; 731 int rc, rc2;
726 732
727 rc = efx_check_disabled(efx); 733 rc = efx_check_disabled(efx);
728 if (rc) 734 if (rc)
@@ -802,9 +808,16 @@ out:
802 } 808 }
803 } 809 }
804 810
805 efx_soft_enable_interrupts(efx); 811 rc2 = efx_soft_enable_interrupts(efx);
806 efx_start_all(efx); 812 if (rc2) {
807 netif_device_attach(efx->net_dev); 813 rc = rc ? rc : rc2;
814 netif_err(efx, drv, efx->net_dev,
815 "unable to restart interrupts on channel reallocation\n");
816 efx_schedule_reset(efx, RESET_TYPE_DISABLE);
817 } else {
818 efx_start_all(efx);
819 netif_device_attach(efx->net_dev);
820 }
808 return rc; 821 return rc;
809 822
810rollback: 823rollback:
@@ -1327,9 +1340,10 @@ static int efx_probe_interrupts(struct efx_nic *efx)
1327 return 0; 1340 return 0;
1328} 1341}
1329 1342
1330static void efx_soft_enable_interrupts(struct efx_nic *efx) 1343static int efx_soft_enable_interrupts(struct efx_nic *efx)
1331{ 1344{
1332 struct efx_channel *channel; 1345 struct efx_channel *channel, *end_channel;
1346 int rc;
1333 1347
1334 BUG_ON(efx->state == STATE_DISABLED); 1348 BUG_ON(efx->state == STATE_DISABLED);
1335 1349
@@ -1337,12 +1351,28 @@ static void efx_soft_enable_interrupts(struct efx_nic *efx)
1337 smp_wmb(); 1351 smp_wmb();
1338 1352
1339 efx_for_each_channel(channel, efx) { 1353 efx_for_each_channel(channel, efx) {
1340 if (!channel->type->keep_eventq) 1354 if (!channel->type->keep_eventq) {
1341 efx_init_eventq(channel); 1355 rc = efx_init_eventq(channel);
1356 if (rc)
1357 goto fail;
1358 }
1342 efx_start_eventq(channel); 1359 efx_start_eventq(channel);
1343 } 1360 }
1344 1361
1345 efx_mcdi_mode_event(efx); 1362 efx_mcdi_mode_event(efx);
1363
1364 return 0;
1365fail:
1366 end_channel = channel;
1367 efx_for_each_channel(channel, efx) {
1368 if (channel == end_channel)
1369 break;
1370 efx_stop_eventq(channel);
1371 if (!channel->type->keep_eventq)
1372 efx_fini_eventq(channel);
1373 }
1374
1375 return rc;
1346} 1376}
1347 1377
1348static void efx_soft_disable_interrupts(struct efx_nic *efx) 1378static void efx_soft_disable_interrupts(struct efx_nic *efx)
@@ -1373,9 +1403,10 @@ static void efx_soft_disable_interrupts(struct efx_nic *efx)
1373 efx_mcdi_flush_async(efx); 1403 efx_mcdi_flush_async(efx);
1374} 1404}
1375 1405
1376static void efx_enable_interrupts(struct efx_nic *efx) 1406static int efx_enable_interrupts(struct efx_nic *efx)
1377{ 1407{
1378 struct efx_channel *channel; 1408 struct efx_channel *channel, *end_channel;
1409 int rc;
1379 1410
1380 BUG_ON(efx->state == STATE_DISABLED); 1411 BUG_ON(efx->state == STATE_DISABLED);
1381 1412
@@ -1387,11 +1418,31 @@ static void efx_enable_interrupts(struct efx_nic *efx)
1387 efx->type->irq_enable_master(efx); 1418 efx->type->irq_enable_master(efx);
1388 1419
1389 efx_for_each_channel(channel, efx) { 1420 efx_for_each_channel(channel, efx) {
1421 if (channel->type->keep_eventq) {
1422 rc = efx_init_eventq(channel);
1423 if (rc)
1424 goto fail;
1425 }
1426 }
1427
1428 rc = efx_soft_enable_interrupts(efx);
1429 if (rc)
1430 goto fail;
1431
1432 return 0;
1433
1434fail:
1435 end_channel = channel;
1436 efx_for_each_channel(channel, efx) {
1437 if (channel == end_channel)
1438 break;
1390 if (channel->type->keep_eventq) 1439 if (channel->type->keep_eventq)
1391 efx_init_eventq(channel); 1440 efx_fini_eventq(channel);
1392 } 1441 }
1393 1442
1394 efx_soft_enable_interrupts(efx); 1443 efx->type->irq_disable_non_ev(efx);
1444
1445 return rc;
1395} 1446}
1396 1447
1397static void efx_disable_interrupts(struct efx_nic *efx) 1448static void efx_disable_interrupts(struct efx_nic *efx)
@@ -2205,7 +2256,9 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
2205 "could not restore PHY settings\n"); 2256 "could not restore PHY settings\n");
2206 } 2257 }
2207 2258
2208 efx_enable_interrupts(efx); 2259 rc = efx_enable_interrupts(efx);
2260 if (rc)
2261 goto fail;
2209 efx_restore_filters(efx); 2262 efx_restore_filters(efx);
2210 efx_sriov_reset(efx); 2263 efx_sriov_reset(efx);
2211 2264
@@ -2649,10 +2702,14 @@ static int efx_pci_probe_main(struct efx_nic *efx)
2649 rc = efx_nic_init_interrupt(efx); 2702 rc = efx_nic_init_interrupt(efx);
2650 if (rc) 2703 if (rc)
2651 goto fail5; 2704 goto fail5;
2652 efx_enable_interrupts(efx); 2705 rc = efx_enable_interrupts(efx);
2706 if (rc)
2707 goto fail6;
2653 2708
2654 return 0; 2709 return 0;
2655 2710
2711 fail6:
2712 efx_nic_fini_interrupt(efx);
2656 fail5: 2713 fail5:
2657 efx_fini_port(efx); 2714 efx_fini_port(efx);
2658 fail4: 2715 fail4:
@@ -2780,12 +2837,15 @@ static int efx_pm_freeze(struct device *dev)
2780 2837
2781static int efx_pm_thaw(struct device *dev) 2838static int efx_pm_thaw(struct device *dev)
2782{ 2839{
2840 int rc;
2783 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 2841 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
2784 2842
2785 rtnl_lock(); 2843 rtnl_lock();
2786 2844
2787 if (efx->state != STATE_DISABLED) { 2845 if (efx->state != STATE_DISABLED) {
2788 efx_enable_interrupts(efx); 2846 rc = efx_enable_interrupts(efx);
2847 if (rc)
2848 goto fail;
2789 2849
2790 mutex_lock(&efx->mac_lock); 2850 mutex_lock(&efx->mac_lock);
2791 efx->phy_op->reconfigure(efx); 2851 efx->phy_op->reconfigure(efx);
@@ -2806,6 +2866,11 @@ static int efx_pm_thaw(struct device *dev)
2806 queue_work(reset_workqueue, &efx->reset_work); 2866 queue_work(reset_workqueue, &efx->reset_work);
2807 2867
2808 return 0; 2868 return 0;
2869
2870fail:
2871 rtnl_unlock();
2872
2873 return rc;
2809} 2874}
2810 2875
2811static int efx_pm_poweroff(struct device *dev) 2876static int efx_pm_poweroff(struct device *dev)
@@ -2842,8 +2907,8 @@ static int efx_pm_resume(struct device *dev)
2842 rc = efx->type->init(efx); 2907 rc = efx->type->init(efx);
2843 if (rc) 2908 if (rc)
2844 return rc; 2909 return rc;
2845 efx_pm_thaw(dev); 2910 rc = efx_pm_thaw(dev);
2846 return 0; 2911 return rc;
2847} 2912}
2848 2913
2849static int efx_pm_suspend(struct device *dev) 2914static int efx_pm_suspend(struct device *dev)
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index d21483dfea40..904af5c336b4 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -1325,7 +1325,7 @@ int efx_farch_ev_probe(struct efx_channel *channel)
1325 entries * sizeof(efx_qword_t)); 1325 entries * sizeof(efx_qword_t));
1326} 1326}
1327 1327
1328void efx_farch_ev_init(struct efx_channel *channel) 1328int efx_farch_ev_init(struct efx_channel *channel)
1329{ 1329{
1330 efx_oword_t reg; 1330 efx_oword_t reg;
1331 struct efx_nic *efx = channel->efx; 1331 struct efx_nic *efx = channel->efx;
@@ -1358,6 +1358,8 @@ void efx_farch_ev_init(struct efx_channel *channel)
1358 channel->channel); 1358 channel->channel);
1359 1359
1360 efx->type->push_irq_moderation(channel); 1360 efx->type->push_irq_moderation(channel);
1361
1362 return 0;
1361} 1363}
1362 1364
1363void efx_farch_ev_fini(struct efx_channel *channel) 1365void efx_farch_ev_fini(struct efx_channel *channel)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index e85bed09b5e9..54900f3c83b1 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1087,7 +1087,7 @@ struct efx_nic_type {
1087 void (*rx_write)(struct efx_rx_queue *rx_queue); 1087 void (*rx_write)(struct efx_rx_queue *rx_queue);
1088 void (*rx_defer_refill)(struct efx_rx_queue *rx_queue); 1088 void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
1089 int (*ev_probe)(struct efx_channel *channel); 1089 int (*ev_probe)(struct efx_channel *channel);
1090 void (*ev_init)(struct efx_channel *channel); 1090 int (*ev_init)(struct efx_channel *channel);
1091 void (*ev_fini)(struct efx_channel *channel); 1091 void (*ev_fini)(struct efx_channel *channel);
1092 void (*ev_remove)(struct efx_channel *channel); 1092 void (*ev_remove)(struct efx_channel *channel);
1093 int (*ev_process)(struct efx_channel *channel, int quota); 1093 int (*ev_process)(struct efx_channel *channel, int quota);
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 9afbf3616b4b..686ce7a677df 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -503,9 +503,9 @@ static inline int efx_nic_probe_eventq(struct efx_channel *channel)
503{ 503{
504 return channel->efx->type->ev_probe(channel); 504 return channel->efx->type->ev_probe(channel);
505} 505}
506static inline void efx_nic_init_eventq(struct efx_channel *channel) 506static inline int efx_nic_init_eventq(struct efx_channel *channel)
507{ 507{
508 channel->efx->type->ev_init(channel); 508 return channel->efx->type->ev_init(channel);
509} 509}
510static inline void efx_nic_fini_eventq(struct efx_channel *channel) 510static inline void efx_nic_fini_eventq(struct efx_channel *channel)
511{ 511{
@@ -539,7 +539,7 @@ extern void efx_farch_rx_remove(struct efx_rx_queue *rx_queue);
539extern void efx_farch_rx_write(struct efx_rx_queue *rx_queue); 539extern void efx_farch_rx_write(struct efx_rx_queue *rx_queue);
540extern void efx_farch_rx_defer_refill(struct efx_rx_queue *rx_queue); 540extern void efx_farch_rx_defer_refill(struct efx_rx_queue *rx_queue);
541extern int efx_farch_ev_probe(struct efx_channel *channel); 541extern int efx_farch_ev_probe(struct efx_channel *channel);
542extern void efx_farch_ev_init(struct efx_channel *channel); 542extern int efx_farch_ev_init(struct efx_channel *channel);
543extern void efx_farch_ev_fini(struct efx_channel *channel); 543extern void efx_farch_ev_fini(struct efx_channel *channel);
544extern void efx_farch_ev_remove(struct efx_channel *channel); 544extern void efx_farch_ev_remove(struct efx_channel *channel);
545extern int efx_farch_ev_process(struct efx_channel *channel, int quota); 545extern int efx_farch_ev_process(struct efx_channel *channel, int quota);