Skip to content

Commit 74d79a2

Browse files
WoojungHuhdavem330
authored andcommitted
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>
1 parent 1d9619d commit 74d79a2

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

drivers/net/usb/lan78xx.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */
269269
struct lan78xx_net *dev;
270270
enum skb_state state;
271271
size_t length;
272+
int num_of_packet;
272273
};
273274

274275
struct usb_context {
@@ -2464,7 +2465,7 @@ static void tx_complete(struct urb *urb)
24642465
struct lan78xx_net *dev = entry->dev;
24652466

24662467
if (urb->status == 0) {
2467-
dev->net->stats.tx_packets++;
2468+
dev->net->stats.tx_packets += entry->num_of_packet;
24682469
dev->net->stats.tx_bytes += entry->length;
24692470
} else {
24702471
dev->net->stats.tx_errors++;
@@ -2681,10 +2682,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
26812682
return;
26822683
}
26832684

2684-
skb->protocol = eth_type_trans(skb, dev->net);
26852685
dev->net->stats.rx_packets++;
26862686
dev->net->stats.rx_bytes += skb->len;
26872687

2688+
skb->protocol = eth_type_trans(skb, dev->net);
2689+
26882690
netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
26892691
skb->len + sizeof(struct ethhdr), skb->protocol);
26902692
memset(skb->cb, 0, sizeof(struct skb_data));
@@ -2934,13 +2936,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
29342936

29352937
skb_totallen = 0;
29362938
pkt_cnt = 0;
2939+
count = 0;
2940+
length = 0;
29372941
for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) {
29382942
if (skb_is_gso(skb)) {
29392943
if (pkt_cnt) {
29402944
/* handle previous packets first */
29412945
break;
29422946
}
2943-
length = skb->len;
2947+
count = 1;
2948+
length = skb->len - TX_OVERHEAD;
29442949
skb2 = skb_dequeue(tqp);
29452950
goto gso_skb;
29462951
}
@@ -2961,14 +2966,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
29612966
for (count = pos = 0; count < pkt_cnt; count++) {
29622967
skb2 = skb_dequeue(tqp);
29632968
if (skb2) {
2969+
length += (skb2->len - TX_OVERHEAD);
29642970
memcpy(skb->data + pos, skb2->data, skb2->len);
29652971
pos += roundup(skb2->len, sizeof(u32));
29662972
dev_kfree_skb(skb2);
29672973
}
29682974
}
29692975

2970-
length = skb_totallen;
2971-
29722976
gso_skb:
29732977
urb = usb_alloc_urb(0, GFP_ATOMIC);
29742978
if (!urb) {
@@ -2980,6 +2984,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
29802984
entry->urb = urb;
29812985
entry->dev = dev;
29822986
entry->length = length;
2987+
entry->num_of_packet = count;
29832988

29842989
spin_lock_irqsave(&dev->txq.lock, flags);
29852990
ret = usb_autopm_get_interface_async(dev->intf);

0 commit comments

Comments
 (0)