@@ -3724,6 +3724,10 @@ static int niu_rx_work(struct napi_struct *napi, struct niu *np,
mbox->rx_dma_ctl_stat = 0;
mbox->rcrstat_a = 0;
+ if (!qlen)
+ printk(KERN_DEBUG PFX "%s() CPU=%i rx_channel=%i qlen is zero!\n",
+ __FUNCTION__, raw_smp_processor_id(), rp->rx_channel);
+
niudbg(RX_STATUS, "%s: niu_rx_work(chan[%d]), stat[%llx] qlen=%d\n",
np->dev->name, rp->rx_channel, (unsigned long long) stat, qlen);
@@ -4193,10 +4197,17 @@ static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
for (i = 0; i < np->num_rx_rings; i++) {
struct rx_ring_info *rp = &np->rx_rings[i];
int ldn = LDN_RXDMA(rp->rx_channel);
+ u64 qlen;
if (parent->ldg_map[ldn] != ldg)
continue;
+ qlen = nr64(RCRSTAT_A(rp->rx_channel)) & RCRSTAT_A_QLEN;
+ if (!qlen) {
+ printk(KERN_DEBUG PFX "%s() CPU=%i rx_channel=%i qlen is 0!\n",
+ __FUNCTION__, smp_processor_id(), rp->rx_channel);
+ }
+
nw64(LD_IM0(ldn), LD_IM0_MASK);
if (rx_vec & (1 << rp->rx_channel))
niu_rxchan_intr(np, rp, ldn);
@@ -4215,6 +4226,22 @@ static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
}
}
+static void niu_dump_ldg_irq(struct niu *np, int ldg, u64 v0)
+{
+ static DEFINE_PER_CPU(unsigned long, spurious_count) = { 4 };
+
+ struct niu_parent *parent = np->parent;
+ int qlen, ldn, i;
+
+ if (!__get_cpu_var(spurious_count))
+ return;
+
+ __get_cpu_var(spurious_count)--;
+
+ printk(KERN_DEBUG PFX "%s CPU=%i LDG=%i v0=%p: spurious interrupt\n",
+ np->dev->name, smp_processor_id(), ldg, (void *)v0);
+}
+
static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
u64 v0, u64 v1, u64 v2)
{
@@ -4224,7 +4251,8 @@ static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
lp->v2 = v2;
__niu_fastpath_interrupt(np, lp->ldg_num, v0);
__napi_schedule(&lp->napi);
- }
+ } else
+ niu_dump_ldg_irq(np, lp->ldg_num, v0);
}
static irqreturn_t niu_interrupt(int irq, void *dev_id)
@@ -4251,6 +4279,10 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id)
(unsigned long long) v1,
(unsigned long long) v2);
+ if (!v0)
+ printk(KERN_DEBUG PFX "%s() CPU=%i LDG=%i v0 is zero!\n",
+ __FUNCTION__, smp_processor_id(), ldg);
+
if (unlikely(!v0 && !v1 && !v2)) {
spin_unlock_irqrestore(&np->lock, flags);
return IRQ_NONE;
@@ -4263,8 +4295,11 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id)
}
if (likely(v0 & ~((u64)1 << LDN_MIF)))
niu_schedule_napi(np, lp, v0, v1, v2);
- else
+ else {
+ printk(KERN_DEBUG PFX "%s() CPU=%i no DMA work, rearming LDG\n",
+ __FUNCTION__, smp_processor_id());
niu_ldg_rearm(np, lp, 1);
+ }
out:
spin_unlock_irqrestore(&np->lock, flags);