diff options
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 05df20e4797..fb83cdd9464 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -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_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_channel(struct efx_channel *channel);  static void efx_fini_struct(struct efx_nic *efx);  static void efx_start_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 */  	efx_nic_disable_interrupts(efx); -	if (efx->legacy_irq) +	if (efx->legacy_irq) {  		synchronize_irq(efx->legacy_irq); +		efx->legacy_irq_enabled = false; +	}  	if (channel->irq)  		synchronize_irq(channel->irq); @@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel)  	efx_channel_processed(channel);  	napi_enable(&channel->napi_str); +	if (efx->legacy_irq) +		efx->legacy_irq_enabled = true;  	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->napi_dev = NULL;  		memset(&channel->eventq, 0, sizeof(channel->eventq));  		rx_queue = &channel->rx_queue; @@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)  	if (rc)  		goto rollback; +	efx_init_napi(efx); +  	/* 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]); +	}  out:  	/* Free unused channel structures */  	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);  	} +	if (efx->legacy_irq) +		efx->legacy_irq_enabled = true;  	efx_nic_enable_interrupts(efx);  	/* 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 */  	efx_nic_disable_interrupts(efx); -	if (efx->legacy_irq) +	if (efx->legacy_irq) {  		synchronize_irq(efx->legacy_irq); +		efx->legacy_irq_enabled = false; +	}  	efx_for_each_channel(channel, efx) {  		if (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; @@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)  		netif_napi_add(channel->napi_dev, &channel->napi_str,  			       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)  {  	struct efx_channel *channel; -	efx_for_each_channel(channel, efx) { -		if (channel->napi_dev) -			netif_napi_del(&channel->napi_str); -		channel->napi_dev = NULL; -	} +	efx_for_each_channel(channel, efx) +		efx_fini_napi_channel(channel);  }  /************************************************************************** @@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)  	if (rc)  		goto fail1; -	rc = efx_init_napi(efx); -	if (rc) -		goto fail2; +	efx_init_napi(efx);  	rc = efx->type->init(efx);  	if (rc) { @@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)  	efx->type->fini(efx);   fail3:  	efx_fini_napi(efx); - fail2:  	efx_remove_all(efx);   fail1:  	return rc;  |