aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
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
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')
-rw-r--r--drivers/net/sfc/efx.c218
-rw-r--r--drivers/net/sfc/efx.h7
-rw-r--r--drivers/net/sfc/ethtool.c38
-rw-r--r--drivers/net/sfc/net_driver.h4
-rw-r--r--drivers/net/sfc/nic.c9
5 files changed, 224 insertions, 52 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 6166e2207160..f702f1fb63b6 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)
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index c15a2d3c2c23..e783c0fedfd8 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -59,8 +59,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
59#define EFX_MAX_EVQ_SIZE 16384UL 59#define EFX_MAX_EVQ_SIZE 16384UL
60#define EFX_MIN_EVQ_SIZE 512UL 60#define EFX_MIN_EVQ_SIZE 512UL
61 61
62/* The smallest [rt]xq_entries that the driver supports. Callers of
63 * efx_wake_queue() assume that they can subsequently send at least one
64 * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
65#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
66
62/* Channels */ 67/* Channels */
63extern void efx_process_channel_now(struct efx_channel *channel); 68extern void efx_process_channel_now(struct efx_channel *channel);
69extern int
70efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
64 71
65/* Ports */ 72/* Ports */
66extern int efx_reconfigure_port(struct efx_nic *efx); 73extern int efx_reconfigure_port(struct efx_nic *efx);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index b9291db023bb..7f735d804801 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -742,6 +742,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
742 return 0; 742 return 0;
743} 743}
744 744
745static void efx_ethtool_get_ringparam(struct net_device *net_dev,
746 struct ethtool_ringparam *ring)
747{
748 struct efx_nic *efx = netdev_priv(net_dev);
749
750 ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
751 ring->tx_max_pending = EFX_MAX_DMAQ_SIZE;
752 ring->rx_mini_max_pending = 0;
753 ring->rx_jumbo_max_pending = 0;
754 ring->rx_pending = efx->rxq_entries;
755 ring->tx_pending = efx->txq_entries;
756 ring->rx_mini_pending = 0;
757 ring->rx_jumbo_pending = 0;
758}
759
760static int efx_ethtool_set_ringparam(struct net_device *net_dev,
761 struct ethtool_ringparam *ring)
762{
763 struct efx_nic *efx = netdev_priv(net_dev);
764
765 if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
766 ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
767 ring->tx_pending > EFX_MAX_DMAQ_SIZE)
768 return -EINVAL;
769
770 if (ring->rx_pending < EFX_MIN_RING_SIZE ||
771 ring->tx_pending < EFX_MIN_RING_SIZE) {
772 netif_err(efx, drv, efx->net_dev,
773 "TX and RX queues cannot be smaller than %ld\n",
774 EFX_MIN_RING_SIZE);
775 return -EINVAL;
776 }
777
778 return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
779}
780
745static int efx_ethtool_set_pauseparam(struct net_device *net_dev, 781static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
746 struct ethtool_pauseparam *pause) 782 struct ethtool_pauseparam *pause)
747{ 783{
@@ -972,6 +1008,8 @@ const struct ethtool_ops efx_ethtool_ops = {
972 .set_eeprom = efx_ethtool_set_eeprom, 1008 .set_eeprom = efx_ethtool_set_eeprom,
973 .get_coalesce = efx_ethtool_get_coalesce, 1009 .get_coalesce = efx_ethtool_get_coalesce,
974 .set_coalesce = efx_ethtool_set_coalesce, 1010 .set_coalesce = efx_ethtool_set_coalesce,
1011 .get_ringparam = efx_ethtool_get_ringparam,
1012 .set_ringparam = efx_ethtool_set_ringparam,
975 .get_pauseparam = efx_ethtool_get_pauseparam, 1013 .get_pauseparam = efx_ethtool_get_pauseparam,
976 .set_pauseparam = efx_ethtool_set_pauseparam, 1014 .set_pauseparam = efx_ethtool_set_pauseparam,
977 .get_rx_csum = efx_ethtool_get_rx_csum, 1015 .get_rx_csum = efx_ethtool_get_rx_csum,
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index ac622ab72e11..4b3f680ba69e 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -299,7 +299,6 @@ enum efx_rx_alloc_method {
299 * 299 *
300 * @efx: Associated Efx NIC 300 * @efx: Associated Efx NIC
301 * @channel: Channel instance number 301 * @channel: Channel instance number
302 * @name: Name for channel and IRQ
303 * @enabled: Channel enabled indicator 302 * @enabled: Channel enabled indicator
304 * @irq: IRQ number (MSI and MSI-X only) 303 * @irq: IRQ number (MSI and MSI-X only)
305 * @irq_moderation: IRQ moderation value (in hardware ticks) 304 * @irq_moderation: IRQ moderation value (in hardware ticks)
@@ -333,7 +332,6 @@ enum efx_rx_alloc_method {
333struct efx_channel { 332struct efx_channel {
334 struct efx_nic *efx; 333 struct efx_nic *efx;
335 int channel; 334 int channel;
336 char name[IFNAMSIZ + 6];
337 bool enabled; 335 bool enabled;
338 int irq; 336 int irq;
339 unsigned int irq_moderation; 337 unsigned int irq_moderation;
@@ -644,6 +642,7 @@ union efx_multicast_hash {
644 * @tx_queue: TX DMA queues 642 * @tx_queue: TX DMA queues
645 * @rx_queue: RX DMA queues 643 * @rx_queue: RX DMA queues
646 * @channel: Channels 644 * @channel: Channels
645 * @channel_name: Names for channels and their IRQs
647 * @rxq_entries: Size of receive queues requested by user. 646 * @rxq_entries: Size of receive queues requested by user.
648 * @txq_entries: Size of transmit queues requested by user. 647 * @txq_entries: Size of transmit queues requested by user.
649 * @next_buffer_table: First available buffer table id 648 * @next_buffer_table: First available buffer table id
@@ -730,6 +729,7 @@ struct efx_nic {
730 enum reset_type reset_pending; 729 enum reset_type reset_pending;
731 730
732 struct efx_channel *channel[EFX_MAX_CHANNELS]; 731 struct efx_channel *channel[EFX_MAX_CHANNELS];
732 char channel_name[IFNAMSIZ + 6][EFX_MAX_CHANNELS];
733 733
734 unsigned rxq_entries; 734 unsigned rxq_entries;
735 unsigned txq_entries; 735 unsigned txq_entries;
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 0deb5c38efff..6c5c0cefa9d8 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1478,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
1478 */ 1478 */
1479static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) 1479static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
1480{ 1480{
1481 struct efx_channel *channel = dev_id; 1481 struct efx_channel *channel = *(struct efx_channel **)dev_id;
1482 struct efx_nic *efx = channel->efx; 1482 struct efx_nic *efx = channel->efx;
1483 efx_oword_t *int_ker = efx->irq_status.addr; 1483 efx_oword_t *int_ker = efx->irq_status.addr;
1484 int syserr; 1484 int syserr;
@@ -1553,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
1553 efx_for_each_channel(channel, efx) { 1553 efx_for_each_channel(channel, efx) {
1554 rc = request_irq(channel->irq, efx_msi_interrupt, 1554 rc = request_irq(channel->irq, efx_msi_interrupt,
1555 IRQF_PROBE_SHARED, /* Not shared */ 1555 IRQF_PROBE_SHARED, /* Not shared */
1556 channel->name, channel); 1556 efx->channel_name[channel->channel],
1557 &efx->channel[channel->channel]);
1557 if (rc) { 1558 if (rc) {
1558 netif_err(efx, drv, efx->net_dev, 1559 netif_err(efx, drv, efx->net_dev,
1559 "failed to hook IRQ %d\n", channel->irq); 1560 "failed to hook IRQ %d\n", channel->irq);
@@ -1565,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
1565 1566
1566 fail2: 1567 fail2:
1567 efx_for_each_channel(channel, efx) 1568 efx_for_each_channel(channel, efx)
1568 free_irq(channel->irq, channel); 1569 free_irq(channel->irq, &efx->channel[channel->channel]);
1569 fail1: 1570 fail1:
1570 return rc; 1571 return rc;
1571} 1572}
@@ -1578,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
1578 /* Disable MSI/MSI-X interrupts */ 1579 /* Disable MSI/MSI-X interrupts */
1579 efx_for_each_channel(channel, efx) { 1580 efx_for_each_channel(channel, efx) {
1580 if (channel->irq) 1581 if (channel->irq)
1581 free_irq(channel->irq, channel); 1582 free_irq(channel->irq, &efx->channel[channel->channel]);
1582 } 1583 }
1583 1584
1584 /* ACK legacy interrupt */ 1585 /* ACK legacy interrupt */