aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/niu.c
diff options
context:
space:
mode:
authorMatheos Worku <Matheos.Worku@Sun.COM>2008-01-05 02:48:26 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-09 02:29:54 -0500
commit406f353c857e4b2dbddb7cd20c67941d829b8b15 (patch)
treef2d8ae4a0c41b48ad947dd59d32efca2fdf0d26a /drivers/net/niu.c
parentcdf71a10c7b6432d9b48e292cca2c62a0b9fa6cf (diff)
[NIU]: Fix slowpath interrupt handling.
niu_slowpath_interrupt() expects values to be setup in lp->{v0,v1,v2} but they aren't. That's only done by niu_schedule_napi() which is done later in the interrupt path. If niu_rx_error() returns zero, and v0 is clear, hit the RX_DMA_CTL_STATE register with a RX_DMA_CTL_STAT_MEX. Only emit verbose RX error logs if a fatal channel or port error is signalled. Other cases will be recorded into statistics by niu_log_rxchan_errors(). Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/niu.c')
-rw-r--r--drivers/net/niu.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index abfc61c3a38c..32ed87d54706 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -2508,15 +2508,19 @@ static int niu_rx_error(struct niu *np, struct rx_ring_info *rp)
2508 u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel)); 2508 u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel));
2509 int err = 0; 2509 int err = 0;
2510 2510
2511 dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
2512 np->dev->name, rp->rx_channel, (unsigned long long) stat);
2513
2514 niu_log_rxchan_errors(np, rp, stat);
2515 2511
2516 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL | 2512 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL |
2517 RX_DMA_CTL_STAT_PORT_FATAL)) 2513 RX_DMA_CTL_STAT_PORT_FATAL))
2518 err = -EINVAL; 2514 err = -EINVAL;
2519 2515
2516 if (err) {
2517 dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
2518 np->dev->name, rp->rx_channel,
2519 (unsigned long long) stat);
2520
2521 niu_log_rxchan_errors(np, rp, stat);
2522 }
2523
2520 nw64(RX_DMA_CTL_STAT(rp->rx_channel), 2524 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2521 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS); 2525 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS);
2522 2526
@@ -2749,13 +2753,16 @@ static int niu_device_error(struct niu *np)
2749 return -ENODEV; 2753 return -ENODEV;
2750} 2754}
2751 2755
2752static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) 2756static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp,
2757 u64 v0, u64 v1, u64 v2)
2753{ 2758{
2754 u64 v0 = lp->v0; 2759
2755 u64 v1 = lp->v1;
2756 u64 v2 = lp->v2;
2757 int i, err = 0; 2760 int i, err = 0;
2758 2761
2762 lp->v0 = v0;
2763 lp->v1 = v1;
2764 lp->v2 = v2;
2765
2759 if (v1 & 0x00000000ffffffffULL) { 2766 if (v1 & 0x00000000ffffffffULL) {
2760 u32 rx_vec = (v1 & 0xffffffff); 2767 u32 rx_vec = (v1 & 0xffffffff);
2761 2768
@@ -2764,8 +2771,13 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2764 2771
2765 if (rx_vec & (1 << rp->rx_channel)) { 2772 if (rx_vec & (1 << rp->rx_channel)) {
2766 int r = niu_rx_error(np, rp); 2773 int r = niu_rx_error(np, rp);
2767 if (r) 2774 if (r) {
2768 err = r; 2775 err = r;
2776 } else {
2777 if (!v0)
2778 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2779 RX_DMA_CTL_STAT_MEX);
2780 }
2769 } 2781 }
2770 } 2782 }
2771 } 2783 }
@@ -2803,7 +2815,7 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2803 if (err) 2815 if (err)
2804 niu_enable_interrupts(np, 0); 2816 niu_enable_interrupts(np, 0);
2805 2817
2806 return -EINVAL; 2818 return err;
2807} 2819}
2808 2820
2809static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, 2821static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp,
@@ -2905,7 +2917,7 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id)
2905 } 2917 }
2906 2918
2907 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) { 2919 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) {
2908 int err = niu_slowpath_interrupt(np, lp); 2920 int err = niu_slowpath_interrupt(np, lp, v0, v1, v2);
2909 if (err) 2921 if (err)
2910 goto out; 2922 goto out;
2911 } 2923 }