Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08338475 authored by David S. Miller's avatar David S. Miller
Browse files
parents 35d9b0c9 e8f14992
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -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(struct efx_nic *efx)
static void efx_fini_napi_channel(struct efx_channel *channel)
{
	struct efx_channel *channel;

	efx_for_each_channel(channel, efx) {
	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)
		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;
+2 −0
Original line number Diff line number Diff line
@@ -621,6 +621,7 @@ struct efx_filter_state;
 * @pci_dev: The PCI device
 * @type: Controller type attributes
 * @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.
 *	Work items do not hold and must not acquire RTNL.
 * @workqueue_name: Name of workqueue
@@ -709,6 +710,7 @@ struct efx_nic {
	struct pci_dev *pci_dev;
	const struct efx_nic_type *type;
	int legacy_irq;
	bool legacy_irq_enabled;
	struct workqueue_struct *workqueue;
	char workqueue_name[16];
	struct work_struct reset_work;
+6 −0
Original line number Diff line number Diff line
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
	u32 queues;
	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 */
	efx_readd(efx, &reg, FR_BZ_INT_ISR0);
	queues = EFX_EXTRACT_DWORD(reg, 0, 31);