aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/niu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/niu.c')
-rw-r--r--drivers/net/niu.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index abfc61c3a38c..9a0c6d3adfe9 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -33,8 +33,8 @@
33 33
34#define DRV_MODULE_NAME "niu" 34#define DRV_MODULE_NAME "niu"
35#define PFX DRV_MODULE_NAME ": " 35#define PFX DRV_MODULE_NAME ": "
36#define DRV_MODULE_VERSION "0.5" 36#define DRV_MODULE_VERSION "0.6"
37#define DRV_MODULE_RELDATE "October 5, 2007" 37#define DRV_MODULE_RELDATE "January 5, 2008"
38 38
39static char version[] __devinitdata = 39static char version[] __devinitdata =
40 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 40 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -2241,6 +2241,8 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
2241 skb->protocol = eth_type_trans(skb, np->dev); 2241 skb->protocol = eth_type_trans(skb, np->dev);
2242 netif_receive_skb(skb); 2242 netif_receive_skb(skb);
2243 2243
2244 np->dev->last_rx = jiffies;
2245
2244 return num_rcr; 2246 return num_rcr;
2245} 2247}
2246 2248
@@ -2508,15 +2510,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)); 2510 u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel));
2509 int err = 0; 2511 int err = 0;
2510 2512
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 2513
2516 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL | 2514 if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL |
2517 RX_DMA_CTL_STAT_PORT_FATAL)) 2515 RX_DMA_CTL_STAT_PORT_FATAL))
2518 err = -EINVAL; 2516 err = -EINVAL;
2519 2517
2518 if (err) {
2519 dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
2520 np->dev->name, rp->rx_channel,
2521 (unsigned long long) stat);
2522
2523 niu_log_rxchan_errors(np, rp, stat);
2524 }
2525
2520 nw64(RX_DMA_CTL_STAT(rp->rx_channel), 2526 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2521 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS); 2527 stat & RX_DMA_CTL_WRITE_CLEAR_ERRS);
2522 2528
@@ -2749,13 +2755,16 @@ static int niu_device_error(struct niu *np)
2749 return -ENODEV; 2755 return -ENODEV;
2750} 2756}
2751 2757
2752static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) 2758static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp,
2759 u64 v0, u64 v1, u64 v2)
2753{ 2760{
2754 u64 v0 = lp->v0; 2761
2755 u64 v1 = lp->v1;
2756 u64 v2 = lp->v2;
2757 int i, err = 0; 2762 int i, err = 0;
2758 2763
2764 lp->v0 = v0;
2765 lp->v1 = v1;
2766 lp->v2 = v2;
2767
2759 if (v1 & 0x00000000ffffffffULL) { 2768 if (v1 & 0x00000000ffffffffULL) {
2760 u32 rx_vec = (v1 & 0xffffffff); 2769 u32 rx_vec = (v1 & 0xffffffff);
2761 2770
@@ -2764,8 +2773,13 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2764 2773
2765 if (rx_vec & (1 << rp->rx_channel)) { 2774 if (rx_vec & (1 << rp->rx_channel)) {
2766 int r = niu_rx_error(np, rp); 2775 int r = niu_rx_error(np, rp);
2767 if (r) 2776 if (r) {
2768 err = r; 2777 err = r;
2778 } else {
2779 if (!v0)
2780 nw64(RX_DMA_CTL_STAT(rp->rx_channel),
2781 RX_DMA_CTL_STAT_MEX);
2782 }
2769 } 2783 }
2770 } 2784 }
2771 } 2785 }
@@ -2803,7 +2817,7 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp)
2803 if (err) 2817 if (err)
2804 niu_enable_interrupts(np, 0); 2818 niu_enable_interrupts(np, 0);
2805 2819
2806 return -EINVAL; 2820 return err;
2807} 2821}
2808 2822
2809static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, 2823static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp,
@@ -2905,7 +2919,7 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id)
2905 } 2919 }
2906 2920
2907 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) { 2921 if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) {
2908 int err = niu_slowpath_interrupt(np, lp); 2922 int err = niu_slowpath_interrupt(np, lp, v0, v1, v2);
2909 if (err) 2923 if (err)
2910 goto out; 2924 goto out;
2911 } 2925 }
@@ -5194,7 +5208,8 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
5194 } 5208 }
5195 kfree_skb(skb); 5209 kfree_skb(skb);
5196 skb = skb_new; 5210 skb = skb_new;
5197 } 5211 } else
5212 skb_orphan(skb);
5198 5213
5199 align = ((unsigned long) skb->data & (16 - 1)); 5214 align = ((unsigned long) skb->data & (16 - 1));
5200 headroom = align + sizeof(struct tx_pkt_hdr); 5215 headroom = align + sizeof(struct tx_pkt_hdr);