aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorWoojung Huh <woojung.huh@microchip.com>2016-04-25 18:22:32 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-28 16:36:11 -0400
commit74d79a2e30c476ccc7d45ecf978f38d815287f81 (patch)
treec31c0e3a0a8bd7c25351654145168a762cfb146f /drivers/net/usb
parent1d9619d5337df6cf56eb66b6c8213d1317583513 (diff)
lan78xx: fix statistics counter error
Fix rx_bytes, tx_bytes and tx_frames error in netdev.stats. - rx_bytes counted bytes excluding size of struct ethhdr. - tx_packets didn't count multiple packets in a single urb - tx_bytes included 8 bytes of extra commands. Signed-off-by: Woojung Huh <woojung.huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/lan78xx.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index f20890ee03f3..0460b81a8784 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */
269 struct lan78xx_net *dev; 269 struct lan78xx_net *dev;
270 enum skb_state state; 270 enum skb_state state;
271 size_t length; 271 size_t length;
272 int num_of_packet;
272}; 273};
273 274
274struct usb_context { 275struct usb_context {
@@ -2464,7 +2465,7 @@ static void tx_complete(struct urb *urb)
2464 struct lan78xx_net *dev = entry->dev; 2465 struct lan78xx_net *dev = entry->dev;
2465 2466
2466 if (urb->status == 0) { 2467 if (urb->status == 0) {
2467 dev->net->stats.tx_packets++; 2468 dev->net->stats.tx_packets += entry->num_of_packet;
2468 dev->net->stats.tx_bytes += entry->length; 2469 dev->net->stats.tx_bytes += entry->length;
2469 } else { 2470 } else {
2470 dev->net->stats.tx_errors++; 2471 dev->net->stats.tx_errors++;
@@ -2681,10 +2682,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
2681 return; 2682 return;
2682 } 2683 }
2683 2684
2684 skb->protocol = eth_type_trans(skb, dev->net);
2685 dev->net->stats.rx_packets++; 2685 dev->net->stats.rx_packets++;
2686 dev->net->stats.rx_bytes += skb->len; 2686 dev->net->stats.rx_bytes += skb->len;
2687 2687
2688 skb->protocol = eth_type_trans(skb, dev->net);
2689
2688 netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", 2690 netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
2689 skb->len + sizeof(struct ethhdr), skb->protocol); 2691 skb->len + sizeof(struct ethhdr), skb->protocol);
2690 memset(skb->cb, 0, sizeof(struct skb_data)); 2692 memset(skb->cb, 0, sizeof(struct skb_data));
@@ -2934,13 +2936,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
2934 2936
2935 skb_totallen = 0; 2937 skb_totallen = 0;
2936 pkt_cnt = 0; 2938 pkt_cnt = 0;
2939 count = 0;
2940 length = 0;
2937 for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { 2941 for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) {
2938 if (skb_is_gso(skb)) { 2942 if (skb_is_gso(skb)) {
2939 if (pkt_cnt) { 2943 if (pkt_cnt) {
2940 /* handle previous packets first */ 2944 /* handle previous packets first */
2941 break; 2945 break;
2942 } 2946 }
2943 length = skb->len; 2947 count = 1;
2948 length = skb->len - TX_OVERHEAD;
2944 skb2 = skb_dequeue(tqp); 2949 skb2 = skb_dequeue(tqp);
2945 goto gso_skb; 2950 goto gso_skb;
2946 } 2951 }
@@ -2961,14 +2966,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
2961 for (count = pos = 0; count < pkt_cnt; count++) { 2966 for (count = pos = 0; count < pkt_cnt; count++) {
2962 skb2 = skb_dequeue(tqp); 2967 skb2 = skb_dequeue(tqp);
2963 if (skb2) { 2968 if (skb2) {
2969 length += (skb2->len - TX_OVERHEAD);
2964 memcpy(skb->data + pos, skb2->data, skb2->len); 2970 memcpy(skb->data + pos, skb2->data, skb2->len);
2965 pos += roundup(skb2->len, sizeof(u32)); 2971 pos += roundup(skb2->len, sizeof(u32));
2966 dev_kfree_skb(skb2); 2972 dev_kfree_skb(skb2);
2967 } 2973 }
2968 } 2974 }
2969 2975
2970 length = skb_totallen;
2971
2972gso_skb: 2976gso_skb:
2973 urb = usb_alloc_urb(0, GFP_ATOMIC); 2977 urb = usb_alloc_urb(0, GFP_ATOMIC);
2974 if (!urb) { 2978 if (!urb) {
@@ -2980,6 +2984,7 @@ gso_skb:
2980 entry->urb = urb; 2984 entry->urb = urb;
2981 entry->dev = dev; 2985 entry->dev = dev;
2982 entry->length = length; 2986 entry->length = length;
2987 entry->num_of_packet = count;
2983 2988
2984 spin_lock_irqsave(&dev->txq.lock, flags); 2989 spin_lock_irqsave(&dev->txq.lock, flags);
2985 ret = usb_autopm_get_interface_async(dev->intf); 2990 ret = usb_autopm_get_interface_async(dev->intf);