diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-08 16:15:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-08 16:47:38 -0500 |
commit | fe6c791570efe717946ea7b7dd50aec96b70d551 (patch) | |
tree | 1becb5e8aea7a9c9a7d78f987bd73b0a5d8ee434 /drivers/net/sfc/efx.c | |
parent | f8bf5681cf15f77692c8ad8cb95d059ff7c622c9 (diff) | |
parent | f19872575ff7819a3723154657a497d9bca66b33 (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/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f3e4043d70ee..2166c1d0a533 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 | ||
197 | static void efx_remove_channels(struct efx_nic *efx); | 197 | static void efx_remove_channels(struct efx_nic *efx); |
198 | static void efx_remove_port(struct efx_nic *efx); | 198 | static void efx_remove_port(struct efx_nic *efx); |
199 | static void efx_init_napi(struct efx_nic *efx); | ||
199 | static void efx_fini_napi(struct efx_nic *efx); | 200 | static void efx_fini_napi(struct efx_nic *efx); |
201 | static void efx_fini_napi_channel(struct efx_channel *channel); | ||
200 | static void efx_fini_struct(struct efx_nic *efx); | 202 | static void efx_fini_struct(struct efx_nic *efx); |
201 | static void efx_start_all(struct efx_nic *efx); | 203 | static void efx_start_all(struct efx_nic *efx); |
202 | static void efx_stop_all(struct efx_nic *efx); | 204 | static 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 | } | ||
741 | out: | 752 | out: |
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 | ||
1597 | static int efx_init_napi(struct efx_nic *efx) | 1612 | static 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 | |||
1623 | static 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 | ||
1609 | static void efx_fini_napi(struct efx_nic *efx) | 1630 | static 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; |