Merge branch 'sfc-2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-2.6
This commit is contained in:
commit
0833847552
3 changed files with 37 additions and 14 deletions
|
@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
|
||||||
|
|
||||||
static void efx_remove_channels(struct efx_nic *efx);
|
static void efx_remove_channels(struct efx_nic *efx);
|
||||||
static void efx_remove_port(struct efx_nic *efx);
|
static void efx_remove_port(struct efx_nic *efx);
|
||||||
|
static void efx_init_napi(struct efx_nic *efx);
|
||||||
static void efx_fini_napi(struct efx_nic *efx);
|
static void efx_fini_napi(struct efx_nic *efx);
|
||||||
|
static void efx_fini_napi_channel(struct efx_channel *channel);
|
||||||
static void efx_fini_struct(struct efx_nic *efx);
|
static void efx_fini_struct(struct efx_nic *efx);
|
||||||
static void efx_start_all(struct efx_nic *efx);
|
static void efx_start_all(struct efx_nic *efx);
|
||||||
static void efx_stop_all(struct efx_nic *efx);
|
static void efx_stop_all(struct efx_nic *efx);
|
||||||
|
@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel)
|
||||||
|
|
||||||
/* Disable interrupts and wait for ISRs to complete */
|
/* Disable interrupts and wait for ISRs to complete */
|
||||||
efx_nic_disable_interrupts(efx);
|
efx_nic_disable_interrupts(efx);
|
||||||
if (efx->legacy_irq)
|
if (efx->legacy_irq) {
|
||||||
synchronize_irq(efx->legacy_irq);
|
synchronize_irq(efx->legacy_irq);
|
||||||
|
efx->legacy_irq_enabled = false;
|
||||||
|
}
|
||||||
if (channel->irq)
|
if (channel->irq)
|
||||||
synchronize_irq(channel->irq);
|
synchronize_irq(channel->irq);
|
||||||
|
|
||||||
|
@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel)
|
||||||
efx_channel_processed(channel);
|
efx_channel_processed(channel);
|
||||||
|
|
||||||
napi_enable(&channel->napi_str);
|
napi_enable(&channel->napi_str);
|
||||||
|
if (efx->legacy_irq)
|
||||||
|
efx->legacy_irq_enabled = true;
|
||||||
efx_nic_enable_interrupts(efx);
|
efx_nic_enable_interrupts(efx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
|
||||||
|
|
||||||
*channel = *old_channel;
|
*channel = *old_channel;
|
||||||
|
|
||||||
|
channel->napi_dev = NULL;
|
||||||
memset(&channel->eventq, 0, sizeof(channel->eventq));
|
memset(&channel->eventq, 0, sizeof(channel->eventq));
|
||||||
|
|
||||||
rx_queue = &channel->rx_queue;
|
rx_queue = &channel->rx_queue;
|
||||||
|
@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto rollback;
|
goto rollback;
|
||||||
|
|
||||||
|
efx_init_napi(efx);
|
||||||
|
|
||||||
/* Destroy old channels */
|
/* Destroy old channels */
|
||||||
for (i = 0; i < efx->n_channels; i++)
|
for (i = 0; i < efx->n_channels; i++) {
|
||||||
|
efx_fini_napi_channel(other_channel[i]);
|
||||||
efx_remove_channel(other_channel[i]);
|
efx_remove_channel(other_channel[i]);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
/* Free unused channel structures */
|
/* Free unused channel structures */
|
||||||
for (i = 0; i < efx->n_channels; i++)
|
for (i = 0; i < efx->n_channels; i++)
|
||||||
|
@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx)
|
||||||
efx_start_channel(channel);
|
efx_start_channel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (efx->legacy_irq)
|
||||||
|
efx->legacy_irq_enabled = true;
|
||||||
efx_nic_enable_interrupts(efx);
|
efx_nic_enable_interrupts(efx);
|
||||||
|
|
||||||
/* Switch to event based MCDI completions after enabling interrupts.
|
/* Switch to event based MCDI completions after enabling interrupts.
|
||||||
|
@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx)
|
||||||
|
|
||||||
/* Disable interrupts and wait for ISR to complete */
|
/* Disable interrupts and wait for ISR to complete */
|
||||||
efx_nic_disable_interrupts(efx);
|
efx_nic_disable_interrupts(efx);
|
||||||
if (efx->legacy_irq)
|
if (efx->legacy_irq) {
|
||||||
synchronize_irq(efx->legacy_irq);
|
synchronize_irq(efx->legacy_irq);
|
||||||
|
efx->legacy_irq_enabled = false;
|
||||||
|
}
|
||||||
efx_for_each_channel(channel, efx) {
|
efx_for_each_channel(channel, efx) {
|
||||||
if (channel->irq)
|
if (channel->irq)
|
||||||
synchronize_irq(channel->irq);
|
synchronize_irq(channel->irq);
|
||||||
|
@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
|
||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int efx_init_napi(struct efx_nic *efx)
|
static void efx_init_napi(struct efx_nic *efx)
|
||||||
{
|
{
|
||||||
struct efx_channel *channel;
|
struct efx_channel *channel;
|
||||||
|
|
||||||
|
@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)
|
||||||
netif_napi_add(channel->napi_dev, &channel->napi_str,
|
netif_napi_add(channel->napi_dev, &channel->napi_str,
|
||||||
efx_poll, napi_weight);
|
efx_poll, napi_weight);
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
static void efx_fini_napi_channel(struct efx_channel *channel)
|
||||||
|
{
|
||||||
|
if (channel->napi_dev)
|
||||||
|
netif_napi_del(&channel->napi_str);
|
||||||
|
channel->napi_dev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void efx_fini_napi(struct efx_nic *efx)
|
static void efx_fini_napi(struct efx_nic *efx)
|
||||||
{
|
{
|
||||||
struct efx_channel *channel;
|
struct efx_channel *channel;
|
||||||
|
|
||||||
efx_for_each_channel(channel, efx) {
|
efx_for_each_channel(channel, efx)
|
||||||
if (channel->napi_dev)
|
efx_fini_napi_channel(channel);
|
||||||
netif_napi_del(&channel->napi_str);
|
|
||||||
channel->napi_dev = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
|
||||||
rc = efx_init_napi(efx);
|
efx_init_napi(efx);
|
||||||
if (rc)
|
|
||||||
goto fail2;
|
|
||||||
|
|
||||||
rc = efx->type->init(efx);
|
rc = efx->type->init(efx);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
|
||||||
efx->type->fini(efx);
|
efx->type->fini(efx);
|
||||||
fail3:
|
fail3:
|
||||||
efx_fini_napi(efx);
|
efx_fini_napi(efx);
|
||||||
fail2:
|
|
||||||
efx_remove_all(efx);
|
efx_remove_all(efx);
|
||||||
fail1:
|
fail1:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -621,6 +621,7 @@ struct efx_filter_state;
|
||||||
* @pci_dev: The PCI device
|
* @pci_dev: The PCI device
|
||||||
* @type: Controller type attributes
|
* @type: Controller type attributes
|
||||||
* @legacy_irq: IRQ number
|
* @legacy_irq: IRQ number
|
||||||
|
* @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
|
||||||
* @workqueue: Workqueue for port reconfigures and the HW monitor.
|
* @workqueue: Workqueue for port reconfigures and the HW monitor.
|
||||||
* Work items do not hold and must not acquire RTNL.
|
* Work items do not hold and must not acquire RTNL.
|
||||||
* @workqueue_name: Name of workqueue
|
* @workqueue_name: Name of workqueue
|
||||||
|
@ -709,6 +710,7 @@ struct efx_nic {
|
||||||
struct pci_dev *pci_dev;
|
struct pci_dev *pci_dev;
|
||||||
const struct efx_nic_type *type;
|
const struct efx_nic_type *type;
|
||||||
int legacy_irq;
|
int legacy_irq;
|
||||||
|
bool legacy_irq_enabled;
|
||||||
struct workqueue_struct *workqueue;
|
struct workqueue_struct *workqueue;
|
||||||
char workqueue_name[16];
|
char workqueue_name[16];
|
||||||
struct work_struct reset_work;
|
struct work_struct reset_work;
|
||||||
|
|
|
@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
|
||||||
u32 queues;
|
u32 queues;
|
||||||
int syserr;
|
int syserr;
|
||||||
|
|
||||||
|
/* Could this be ours? If interrupts are disabled then the
|
||||||
|
* channel state may not be valid.
|
||||||
|
*/
|
||||||
|
if (!efx->legacy_irq_enabled)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* Read the ISR which also ACKs the interrupts */
|
/* Read the ISR which also ACKs the interrupts */
|
||||||
efx_readd(efx, ®, FR_BZ_INT_ISR0);
|
efx_readd(efx, ®, FR_BZ_INT_ISR0);
|
||||||
queues = EFX_EXTRACT_DWORD(reg, 0, 31);
|
queues = EFX_EXTRACT_DWORD(reg, 0, 31);
|
||||||
|
|
Loading…
Reference in a new issue