aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-08 16:15:38 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-08 16:47:38 -0500
commitfe6c791570efe717946ea7b7dd50aec96b70d551 (patch)
tree1becb5e8aea7a9c9a7d78f987bd73b0a5d8ee434 /drivers/net/sfc
parentf8bf5681cf15f77692c8ad8cb95d059ff7c622c9 (diff)
parentf19872575ff7819a3723154657a497d9bca66b33 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/ath/ath9k/ar9003_eeprom.c net/llc/af_llc.c
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c43
-rw-r--r--drivers/net/sfc/net_driver.h2
-rw-r--r--drivers/net/sfc/nic.c6
3 files changed, 37 insertions, 14 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index f3e4043d70e..2166c1d0a53 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -196,7 +196,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
196 196
197static void efx_remove_channels(struct efx_nic *efx); 197static void efx_remove_channels(struct efx_nic *efx);
198static void efx_remove_port(struct efx_nic *efx); 198static void efx_remove_port(struct efx_nic *efx);
199static void efx_init_napi(struct efx_nic *efx);
199static void efx_fini_napi(struct efx_nic *efx); 200static void efx_fini_napi(struct efx_nic *efx);
201static void efx_fini_napi_channel(struct efx_channel *channel);
200static void efx_fini_struct(struct efx_nic *efx); 202static void efx_fini_struct(struct efx_nic *efx);
201static void efx_start_all(struct efx_nic *efx); 203static void efx_start_all(struct efx_nic *efx);
202static void efx_stop_all(struct efx_nic *efx); 204static void efx_stop_all(struct efx_nic *efx);
@@ -334,8 +336,10 @@ void efx_process_channel_now(struct efx_channel *channel)
334 336
335 /* Disable interrupts and wait for ISRs to complete */ 337 /* Disable interrupts and wait for ISRs to complete */
336 efx_nic_disable_interrupts(efx); 338 efx_nic_disable_interrupts(efx);
337 if (efx->legacy_irq) 339 if (efx->legacy_irq) {
338 synchronize_irq(efx->legacy_irq); 340 synchronize_irq(efx->legacy_irq);
341 efx->legacy_irq_enabled = false;
342 }
339 if (channel->irq) 343 if (channel->irq)
340 synchronize_irq(channel->irq); 344 synchronize_irq(channel->irq);
341 345
@@ -350,6 +354,8 @@ void efx_process_channel_now(struct efx_channel *channel)
350 efx_channel_processed(channel); 354 efx_channel_processed(channel);
351 355
352 napi_enable(&channel->napi_str); 356 napi_enable(&channel->napi_str);
357 if (efx->legacy_irq)
358 efx->legacy_irq_enabled = true;
353 efx_nic_enable_interrupts(efx); 359 efx_nic_enable_interrupts(efx);
354} 360}
355 361
@@ -425,6 +431,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
425 431
426 *channel = *old_channel; 432 *channel = *old_channel;
427 433
434 channel->napi_dev = NULL;
428 memset(&channel->eventq, 0, sizeof(channel->eventq)); 435 memset(&channel->eventq, 0, sizeof(channel->eventq));
429 436
430 rx_queue = &channel->rx_queue; 437 rx_queue = &channel->rx_queue;
@@ -735,9 +742,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
735 if (rc) 742 if (rc)
736 goto rollback; 743 goto rollback;
737 744
745 efx_init_napi(efx);
746
738 /* Destroy old channels */ 747 /* Destroy old channels */
739 for (i = 0; i < efx->n_channels; i++) 748 for (i = 0; i < efx->n_channels; i++) {
749 efx_fini_napi_channel(other_channel[i]);
740 efx_remove_channel(other_channel[i]); 750 efx_remove_channel(other_channel[i]);
751 }
741out: 752out:
742 /* Free unused channel structures */ 753 /* Free unused channel structures */
743 for (i = 0; i < efx->n_channels; i++) 754 for (i = 0; i < efx->n_channels; i++)
@@ -1401,6 +1412,8 @@ static void efx_start_all(struct efx_nic *efx)
1401 efx_start_channel(channel); 1412 efx_start_channel(channel);
1402 } 1413 }
1403 1414
1415 if (efx->legacy_irq)
1416 efx->legacy_irq_enabled = true;
1404 efx_nic_enable_interrupts(efx); 1417 efx_nic_enable_interrupts(efx);
1405 1418
1406 /* Switch to event based MCDI completions after enabling interrupts. 1419 /* Switch to event based MCDI completions after enabling interrupts.
@@ -1461,8 +1474,10 @@ static void efx_stop_all(struct efx_nic *efx)
1461 1474
1462 /* Disable interrupts and wait for ISR to complete */ 1475 /* Disable interrupts and wait for ISR to complete */
1463 efx_nic_disable_interrupts(efx); 1476 efx_nic_disable_interrupts(efx);
1464 if (efx->legacy_irq) 1477 if (efx->legacy_irq) {
1465 synchronize_irq(efx->legacy_irq); 1478 synchronize_irq(efx->legacy_irq);
1479 efx->legacy_irq_enabled = false;
1480 }
1466 efx_for_each_channel(channel, efx) { 1481 efx_for_each_channel(channel, efx) {
1467 if (channel->irq) 1482 if (channel->irq)
1468 synchronize_irq(channel->irq); 1483 synchronize_irq(channel->irq);
@@ -1594,7 +1609,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1594 * 1609 *
1595 **************************************************************************/ 1610 **************************************************************************/
1596 1611
1597static int efx_init_napi(struct efx_nic *efx) 1612static void efx_init_napi(struct efx_nic *efx)
1598{ 1613{
1599 struct efx_channel *channel; 1614 struct efx_channel *channel;
1600 1615
@@ -1603,18 +1618,21 @@ static int efx_init_napi(struct efx_nic *efx)
1603 netif_napi_add(channel->napi_dev, &channel->napi_str, 1618 netif_napi_add(channel->napi_dev, &channel->napi_str,
1604 efx_poll, napi_weight); 1619 efx_poll, napi_weight);
1605 } 1620 }
1606 return 0; 1621}
1622
1623static void efx_fini_napi_channel(struct efx_channel *channel)
1624{
1625 if (channel->napi_dev)
1626 netif_napi_del(&channel->napi_str);
1627 channel->napi_dev = NULL;
1607} 1628}
1608 1629
1609static void efx_fini_napi(struct efx_nic *efx) 1630static void efx_fini_napi(struct efx_nic *efx)
1610{ 1631{
1611 struct efx_channel *channel; 1632 struct efx_channel *channel;
1612 1633
1613 efx_for_each_channel(channel, efx) { 1634 efx_for_each_channel(channel, efx)
1614 if (channel->napi_dev) 1635 efx_fini_napi_channel(channel);
1615 netif_napi_del(&channel->napi_str);
1616 channel->napi_dev = NULL;
1617 }
1618} 1636}
1619 1637
1620/************************************************************************** 1638/**************************************************************************
@@ -2331,9 +2349,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
2331 if (rc) 2349 if (rc)
2332 goto fail1; 2350 goto fail1;
2333 2351
2334 rc = efx_init_napi(efx); 2352 efx_init_napi(efx);
2335 if (rc)
2336 goto fail2;
2337 2353
2338 rc = efx->type->init(efx); 2354 rc = efx->type->init(efx);
2339 if (rc) { 2355 if (rc) {
@@ -2364,7 +2380,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
2364 efx->type->fini(efx); 2380 efx->type->fini(efx);
2365 fail3: 2381 fail3:
2366 efx_fini_napi(efx); 2382 efx_fini_napi(efx);
2367 fail2:
2368 efx_remove_all(efx); 2383 efx_remove_all(efx);
2369 fail1: 2384 fail1:
2370 return rc; 2385 return rc;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 0d19fbfc5c2..4c12332434b 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -621,6 +621,7 @@ struct efx_filter_state;
621 * @pci_dev: The PCI device 621 * @pci_dev: The PCI device
622 * @type: Controller type attributes 622 * @type: Controller type attributes
623 * @legacy_irq: IRQ number 623 * @legacy_irq: IRQ number
624 * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
624 * @workqueue: Workqueue for port reconfigures and the HW monitor. 625 * @workqueue: Workqueue for port reconfigures and the HW monitor.
625 * Work items do not hold and must not acquire RTNL. 626 * Work items do not hold and must not acquire RTNL.
626 * @workqueue_name: Name of workqueue 627 * @workqueue_name: Name of workqueue
@@ -702,6 +703,7 @@ struct efx_nic {
702 struct pci_dev *pci_dev; 703 struct pci_dev *pci_dev;
703 const struct efx_nic_type *type; 704 const struct efx_nic_type *type;
704 int legacy_irq; 705 int legacy_irq;
706 bool legacy_irq_enabled;
705 struct workqueue_struct *workqueue; 707 struct workqueue_struct *workqueue;
706 char workqueue_name[16]; 708 char workqueue_name[16];
707 struct work_struct reset_work; 709 struct work_struct reset_work;
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 9743cff1513..399b12abe2f 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1380,6 +1380,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
1380 u32 queues; 1380 u32 queues;
1381 int syserr; 1381 int syserr;
1382 1382
1383 /* Could this be ours? If interrupts are disabled then the
1384 * channel state may not be valid.
1385 */
1386 if (!efx->legacy_irq_enabled)
1387 return result;
1388
1383 /* Read the ISR which also ACKs the interrupts */ 1389 /* Read the ISR which also ACKs the interrupts */
1384 efx_readd(efx, &reg, FR_BZ_INT_ISR0); 1390 efx_readd(efx, &reg, FR_BZ_INT_ISR0);
1385 queues = EFX_EXTRACT_DWORD(reg, 0, 31); 1391 queues = EFX_EXTRACT_DWORD(reg, 0, 31);