diff options
Diffstat (limited to 'drivers/net/niu.c')
| -rw-r--r-- | drivers/net/niu.c | 43 |
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 | ||
| 39 | static char version[] __devinitdata = | 39 | static 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 | ||
| 2752 | static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) | 2758 | static 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 | ||
| 2809 | static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, | 2823 | static 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); |
