aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-09-10 02:42:33 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-10 15:27:34 -0400
commit4642610c77b345130d6b5a08c75d23ad98601fd5 (patch)
treebf6345d84e6dbd3a3d44ff4e050dc862f01a01fc /drivers/net/sfc/efx.c
parentecc910f520ba8f22848982ee816ad75c449b805d (diff)
sfc: Allow changing the DMA ring sizes dynamically via ethtool
This requires some reorganisation of channel setup and teardown to ensure that we can always roll-back a failed change. Based on work by Steve Hodgson <shodgson@solarflare.com> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c218
1 files changed, 172 insertions, 46 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 6166e220716..f702f1fb63b 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -201,10 +201,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
201 * Utility functions and prototypes 201 * Utility functions and prototypes
202 * 202 *
203 *************************************************************************/ 203 *************************************************************************/
204static void efx_remove_channel(struct efx_channel *channel); 204
205static void efx_remove_channels(struct efx_nic *efx);
205static void efx_remove_port(struct efx_nic *efx); 206static void efx_remove_port(struct efx_nic *efx);
206static void efx_fini_napi(struct efx_nic *efx); 207static void efx_fini_napi(struct efx_nic *efx);
207static void efx_fini_channels(struct efx_nic *efx); 208static void efx_fini_struct(struct efx_nic *efx);
209static void efx_start_all(struct efx_nic *efx);
210static void efx_stop_all(struct efx_nic *efx);
208 211
209#define EFX_ASSERT_RESET_SERIALISED(efx) \ 212#define EFX_ASSERT_RESET_SERIALISED(efx) \
210 do { \ 213 do { \
@@ -413,6 +416,63 @@ static void efx_remove_eventq(struct efx_channel *channel)
413 * 416 *
414 *************************************************************************/ 417 *************************************************************************/
415 418
419/* Allocate and initialise a channel structure, optionally copying
420 * parameters (but not resources) from an old channel structure. */
421static struct efx_channel *
422efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
423{
424 struct efx_channel *channel;
425 struct efx_rx_queue *rx_queue;
426 struct efx_tx_queue *tx_queue;
427 int j;
428
429 if (old_channel) {
430 channel = kmalloc(sizeof(*channel), GFP_KERNEL);
431 if (!channel)
432 return NULL;
433
434 *channel = *old_channel;
435
436 memset(&channel->eventq, 0, sizeof(channel->eventq));
437
438 rx_queue = &channel->rx_queue;
439 rx_queue->buffer = NULL;
440 memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd));
441
442 for (j = 0; j < EFX_TXQ_TYPES; j++) {
443 tx_queue = &channel->tx_queue[j];
444 if (tx_queue->channel)
445 tx_queue->channel = channel;
446 tx_queue->buffer = NULL;
447 memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
448 }
449 } else {
450 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
451 if (!channel)
452 return NULL;
453
454 channel->efx = efx;
455 channel->channel = i;
456
457 for (j = 0; j < EFX_TXQ_TYPES; j++) {
458 tx_queue = &channel->tx_queue[j];
459 tx_queue->efx = efx;
460 tx_queue->queue = i * EFX_TXQ_TYPES + j;
461 tx_queue->channel = channel;
462 }
463 }
464
465 spin_lock_init(&channel->tx_stop_lock);
466 atomic_set(&channel->tx_stop_count, 1);
467
468 rx_queue = &channel->rx_queue;
469 rx_queue->efx = efx;
470 setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
471 (unsigned long)rx_queue);
472
473 return channel;
474}
475
416static int efx_probe_channel(struct efx_channel *channel) 476static int efx_probe_channel(struct efx_channel *channel)
417{ 477{
418 struct efx_tx_queue *tx_queue; 478 struct efx_tx_queue *tx_queue;
@@ -469,11 +529,38 @@ static void efx_set_channel_names(struct efx_nic *efx)
469 number -= efx->n_rx_channels; 529 number -= efx->n_rx_channels;
470 } 530 }
471 } 531 }
472 snprintf(channel->name, sizeof(channel->name), 532 snprintf(efx->channel_name[channel->channel],
533 sizeof(efx->channel_name[0]),
473 "%s%s-%d", efx->name, type, number); 534 "%s%s-%d", efx->name, type, number);
474 } 535 }
475} 536}
476 537
538static int efx_probe_channels(struct efx_nic *efx)
539{
540 struct efx_channel *channel;
541 int rc;
542
543 /* Restart special buffer allocation */
544 efx->next_buffer_table = 0;
545
546 efx_for_each_channel(channel, efx) {
547 rc = efx_probe_channel(channel);
548 if (rc) {
549 netif_err(efx, probe, efx->net_dev,
550 "failed to create channel %d\n",
551 channel->channel);
552 goto fail;
553 }
554 }
555 efx_set_channel_names(efx);
556
557 return 0;
558
559fail:
560 efx_remove_channels(efx);
561 return rc;
562}
563
477/* Channels are shutdown and reinitialised whilst the NIC is running 564/* Channels are shutdown and reinitialised whilst the NIC is running
478 * to propagate configuration changes (mtu, checksum offload), or 565 * to propagate configuration changes (mtu, checksum offload), or
479 * to clear hardware error conditions 566 * to clear hardware error conditions
@@ -611,6 +698,75 @@ static void efx_remove_channel(struct efx_channel *channel)
611 efx_remove_eventq(channel); 698 efx_remove_eventq(channel);
612} 699}
613 700
701static void efx_remove_channels(struct efx_nic *efx)
702{
703 struct efx_channel *channel;
704
705 efx_for_each_channel(channel, efx)
706 efx_remove_channel(channel);
707}
708
709int
710efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
711{
712 struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel;
713 u32 old_rxq_entries, old_txq_entries;
714 unsigned i;
715 int rc;
716
717 efx_stop_all(efx);
718 efx_fini_channels(efx);
719
720 /* Clone channels */
721 memset(other_channel, 0, sizeof(other_channel));
722 for (i = 0; i < efx->n_channels; i++) {
723 channel = efx_alloc_channel(efx, i, efx->channel[i]);
724 if (!channel) {
725 rc = -ENOMEM;
726 goto out;
727 }
728 other_channel[i] = channel;
729 }
730
731 /* Swap entry counts and channel pointers */
732 old_rxq_entries = efx->rxq_entries;
733 old_txq_entries = efx->txq_entries;
734 efx->rxq_entries = rxq_entries;
735 efx->txq_entries = txq_entries;
736 for (i = 0; i < efx->n_channels; i++) {
737 channel = efx->channel[i];
738 efx->channel[i] = other_channel[i];
739 other_channel[i] = channel;
740 }
741
742 rc = efx_probe_channels(efx);
743 if (rc)
744 goto rollback;
745
746 /* Destroy old channels */
747 for (i = 0; i < efx->n_channels; i++)
748 efx_remove_channel(other_channel[i]);
749out:
750 /* Free unused channel structures */
751 for (i = 0; i < efx->n_channels; i++)
752 kfree(other_channel[i]);
753
754 efx_init_channels(efx);
755 efx_start_all(efx);
756 return rc;
757
758rollback:
759 /* Swap back */
760 efx->rxq_entries = old_rxq_entries;
761 efx->txq_entries = old_txq_entries;
762 for (i = 0; i < efx->n_channels; i++) {
763 channel = efx->channel[i];
764 efx->channel[i] = other_channel[i];
765 other_channel[i] = channel;
766 }
767 goto out;
768}
769
614void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue) 770void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
615{ 771{
616 mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100)); 772 mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100));
@@ -1182,41 +1338,28 @@ static void efx_remove_nic(struct efx_nic *efx)
1182 1338
1183static int efx_probe_all(struct efx_nic *efx) 1339static int efx_probe_all(struct efx_nic *efx)
1184{ 1340{
1185 struct efx_channel *channel;
1186 int rc; 1341 int rc;
1187 1342
1188 /* Create NIC */
1189 rc = efx_probe_nic(efx); 1343 rc = efx_probe_nic(efx);
1190 if (rc) { 1344 if (rc) {
1191 netif_err(efx, probe, efx->net_dev, "failed to create NIC\n"); 1345 netif_err(efx, probe, efx->net_dev, "failed to create NIC\n");
1192 goto fail1; 1346 goto fail1;
1193 } 1347 }
1194 1348
1195 /* Create port */
1196 rc = efx_probe_port(efx); 1349 rc = efx_probe_port(efx);
1197 if (rc) { 1350 if (rc) {
1198 netif_err(efx, probe, efx->net_dev, "failed to create port\n"); 1351 netif_err(efx, probe, efx->net_dev, "failed to create port\n");
1199 goto fail2; 1352 goto fail2;
1200 } 1353 }
1201 1354
1202 /* Create channels */
1203 efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; 1355 efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
1204 efx_for_each_channel(channel, efx) { 1356 rc = efx_probe_channels(efx);
1205 rc = efx_probe_channel(channel); 1357 if (rc)
1206 if (rc) { 1358 goto fail3;
1207 netif_err(efx, probe, efx->net_dev,
1208 "failed to create channel %d\n",
1209 channel->channel);
1210 goto fail3;
1211 }
1212 }
1213 efx_set_channel_names(efx);
1214 1359
1215 return 0; 1360 return 0;
1216 1361
1217 fail3: 1362 fail3:
1218 efx_for_each_channel(channel, efx)
1219 efx_remove_channel(channel);
1220 efx_remove_port(efx); 1363 efx_remove_port(efx);
1221 fail2: 1364 fail2:
1222 efx_remove_nic(efx); 1365 efx_remove_nic(efx);
@@ -1346,10 +1489,7 @@ static void efx_stop_all(struct efx_nic *efx)
1346 1489
1347static void efx_remove_all(struct efx_nic *efx) 1490static void efx_remove_all(struct efx_nic *efx)
1348{ 1491{
1349 struct efx_channel *channel; 1492 efx_remove_channels(efx);
1350
1351 efx_for_each_channel(channel, efx)
1352 efx_remove_channel(channel);
1353 efx_remove_port(efx); 1493 efx_remove_port(efx);
1354 efx_remove_nic(efx); 1494 efx_remove_nic(efx);
1355} 1495}
@@ -2058,10 +2198,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
2058static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, 2198static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
2059 struct pci_dev *pci_dev, struct net_device *net_dev) 2199 struct pci_dev *pci_dev, struct net_device *net_dev)
2060{ 2200{
2061 struct efx_channel *channel; 2201 int i;
2062 struct efx_tx_queue *tx_queue;
2063 struct efx_rx_queue *rx_queue;
2064 int i, j;
2065 2202
2066 /* Initialise common structures */ 2203 /* Initialise common structures */
2067 memset(efx, 0, sizeof(*efx)); 2204 memset(efx, 0, sizeof(*efx));
@@ -2089,24 +2226,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
2089 INIT_WORK(&efx->mac_work, efx_mac_work); 2226 INIT_WORK(&efx->mac_work, efx_mac_work);
2090 2227
2091 for (i = 0; i < EFX_MAX_CHANNELS; i++) { 2228 for (i = 0; i < EFX_MAX_CHANNELS; i++) {
2092 efx->channel[i] = kzalloc(sizeof(*channel), GFP_KERNEL); 2229 efx->channel[i] = efx_alloc_channel(efx, i, NULL);
2093 channel = efx->channel[i]; 2230 if (!efx->channel[i])
2094 channel->efx = efx; 2231 goto fail;
2095 channel->channel = i;
2096 spin_lock_init(&channel->tx_stop_lock);
2097 atomic_set(&channel->tx_stop_count, 1);
2098
2099 for (j = 0; j < EFX_TXQ_TYPES; j++) {
2100 tx_queue = &channel->tx_queue[j];
2101 tx_queue->efx = efx;
2102 tx_queue->queue = i * EFX_TXQ_TYPES + j;
2103 tx_queue->channel = channel;
2104 }
2105
2106 rx_queue = &channel->rx_queue;
2107 rx_queue->efx = efx;
2108 setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
2109 (unsigned long)rx_queue);
2110 } 2232 }
2111 2233
2112 efx->type = type; 2234 efx->type = type;
@@ -2122,9 +2244,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
2122 pci_name(pci_dev)); 2244 pci_name(pci_dev));
2123 efx->workqueue = create_singlethread_workqueue(efx->workqueue_name); 2245 efx->workqueue = create_singlethread_workqueue(efx->workqueue_name);
2124 if (!efx->workqueue) 2246 if (!efx->workqueue)
2125 return -ENOMEM; 2247 goto fail;
2126 2248
2127 return 0; 2249 return 0;
2250
2251fail:
2252 efx_fini_struct(efx);
2253 return -ENOMEM;
2128} 2254}
2129 2255
2130static void efx_fini_struct(struct efx_nic *efx) 2256static void efx_fini_struct(struct efx_nic *efx)