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

Commit 1b2bb76f authored by Ayaz Abdulla's avatar Ayaz Abdulla Committed by David S. Miller
Browse files

forcedeth: fix irq clearing and napi spin lock changes



This patch clears the irqstatus register with the exact same events it
has read from it. Since the read-write operation is not atomic, a new
irqstatus bit could have been set in between these operations and would
then be cleared accidentally.

Secondly, we now don't need any spin lock protection when
scheduling/completing napi poll as the isr will not execute anymore (as
we turn off all interrupts now).

Signed-off-by: default avatarAyaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6cef67a0
Loading
Loading
Loading
Loading
+4 −14
Original line number Original line Diff line number Diff line
@@ -3464,10 +3464,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data)


	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
		np->events = readl(base + NvRegIrqStatus);
		np->events = readl(base + NvRegIrqStatus);
		writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
		writel(np->events, base + NvRegIrqStatus);
	} else {
	} else {
		np->events = readl(base + NvRegMSIXIrqStatus);
		np->events = readl(base + NvRegMSIXIrqStatus);
		writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
		writel(np->events, base + NvRegMSIXIrqStatus);
	}
	}
	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
	if (!(np->events & np->irqmask))
	if (!(np->events & np->irqmask))
@@ -3476,15 +3476,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
	nv_msi_workaround(np);
	nv_msi_workaround(np);


#ifdef CONFIG_FORCEDETH_NAPI
#ifdef CONFIG_FORCEDETH_NAPI
	spin_lock(&np->lock);
	napi_schedule(&np->napi);
	napi_schedule(&np->napi);


	/* Disable furthur irq's
	/* Disable furthur irq's
	   (msix not enabled with napi) */
	   (msix not enabled with napi) */
	writel(0, base + NvRegIrqMask);
	writel(0, base + NvRegIrqMask);


	spin_unlock(&np->lock);

#else
#else
	do
	do
	{
	{
@@ -3568,10 +3565,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)


	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
		np->events = readl(base + NvRegIrqStatus);
		np->events = readl(base + NvRegIrqStatus);
		writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
		writel(np->events, base + NvRegIrqStatus);
	} else {
	} else {
		np->events = readl(base + NvRegMSIXIrqStatus);
		np->events = readl(base + NvRegMSIXIrqStatus);
		writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
		writel(np->events, base + NvRegMSIXIrqStatus);
	}
	}
	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
	if (!(np->events & np->irqmask))
	if (!(np->events & np->irqmask))
@@ -3580,15 +3577,12 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
	nv_msi_workaround(np);
	nv_msi_workaround(np);


#ifdef CONFIG_FORCEDETH_NAPI
#ifdef CONFIG_FORCEDETH_NAPI
	spin_lock(&np->lock);
	napi_schedule(&np->napi);
	napi_schedule(&np->napi);


	/* Disable furthur irq's
	/* Disable furthur irq's
	   (msix not enabled with napi) */
	   (msix not enabled with napi) */
	writel(0, base + NvRegIrqMask);
	writel(0, base + NvRegIrqMask);


	spin_unlock(&np->lock);

#else
#else
	do
	do
	{
	{
@@ -3758,13 +3752,9 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
	if (rx_work < budget) {
	if (rx_work < budget) {
		/* re-enable interrupts
		/* re-enable interrupts
		   (msix not enabled in napi) */
		   (msix not enabled in napi) */
		spin_lock_irqsave(&np->lock, flags);

		__napi_complete(napi);
		__napi_complete(napi);


		writel(np->irqmask, base + NvRegIrqMask);
		writel(np->irqmask, base + NvRegIrqMask);

		spin_unlock_irqrestore(&np->lock, flags);
	}
	}
	return rx_work;
	return rx_work;
}
}