|
@@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */
|
|
struct lan78xx_net *dev;
|
|
struct lan78xx_net *dev;
|
|
enum skb_state state;
|
|
enum skb_state state;
|
|
size_t length;
|
|
size_t length;
|
|
|
|
+ int num_of_packet;
|
|
};
|
|
};
|
|
|
|
|
|
struct usb_context {
|
|
struct usb_context {
|
|
@@ -2464,7 +2465,7 @@ static void tx_complete(struct urb *urb)
|
|
struct lan78xx_net *dev = entry->dev;
|
|
struct lan78xx_net *dev = entry->dev;
|
|
|
|
|
|
if (urb->status == 0) {
|
|
if (urb->status == 0) {
|
|
- dev->net->stats.tx_packets++;
|
|
|
|
|
|
+ dev->net->stats.tx_packets += entry->num_of_packet;
|
|
dev->net->stats.tx_bytes += entry->length;
|
|
dev->net->stats.tx_bytes += entry->length;
|
|
} else {
|
|
} else {
|
|
dev->net->stats.tx_errors++;
|
|
dev->net->stats.tx_errors++;
|
|
@@ -2681,10 +2682,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- skb->protocol = eth_type_trans(skb, dev->net);
|
|
|
|
dev->net->stats.rx_packets++;
|
|
dev->net->stats.rx_packets++;
|
|
dev->net->stats.rx_bytes += skb->len;
|
|
dev->net->stats.rx_bytes += skb->len;
|
|
|
|
|
|
|
|
+ skb->protocol = eth_type_trans(skb, dev->net);
|
|
|
|
+
|
|
netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
|
|
netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
|
|
skb->len + sizeof(struct ethhdr), skb->protocol);
|
|
skb->len + sizeof(struct ethhdr), skb->protocol);
|
|
memset(skb->cb, 0, sizeof(struct skb_data));
|
|
memset(skb->cb, 0, sizeof(struct skb_data));
|
|
@@ -2934,13 +2936,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
|
|
|
|
|
|
skb_totallen = 0;
|
|
skb_totallen = 0;
|
|
pkt_cnt = 0;
|
|
pkt_cnt = 0;
|
|
|
|
+ count = 0;
|
|
|
|
+ length = 0;
|
|
for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) {
|
|
for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) {
|
|
if (skb_is_gso(skb)) {
|
|
if (skb_is_gso(skb)) {
|
|
if (pkt_cnt) {
|
|
if (pkt_cnt) {
|
|
/* handle previous packets first */
|
|
/* handle previous packets first */
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- length = skb->len;
|
|
|
|
|
|
+ count = 1;
|
|
|
|
+ length = skb->len - TX_OVERHEAD;
|
|
skb2 = skb_dequeue(tqp);
|
|
skb2 = skb_dequeue(tqp);
|
|
goto gso_skb;
|
|
goto gso_skb;
|
|
}
|
|
}
|
|
@@ -2961,14 +2966,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev)
|
|
for (count = pos = 0; count < pkt_cnt; count++) {
|
|
for (count = pos = 0; count < pkt_cnt; count++) {
|
|
skb2 = skb_dequeue(tqp);
|
|
skb2 = skb_dequeue(tqp);
|
|
if (skb2) {
|
|
if (skb2) {
|
|
|
|
+ length += (skb2->len - TX_OVERHEAD);
|
|
memcpy(skb->data + pos, skb2->data, skb2->len);
|
|
memcpy(skb->data + pos, skb2->data, skb2->len);
|
|
pos += roundup(skb2->len, sizeof(u32));
|
|
pos += roundup(skb2->len, sizeof(u32));
|
|
dev_kfree_skb(skb2);
|
|
dev_kfree_skb(skb2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- length = skb_totallen;
|
|
|
|
-
|
|
|
|
gso_skb:
|
|
gso_skb:
|
|
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
|
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
|
if (!urb) {
|
|
if (!urb) {
|
|
@@ -2980,6 +2984,7 @@ gso_skb:
|
|
entry->urb = urb;
|
|
entry->urb = urb;
|
|
entry->dev = dev;
|
|
entry->dev = dev;
|
|
entry->length = length;
|
|
entry->length = length;
|
|
|
|
+ entry->num_of_packet = count;
|
|
|
|
|
|
spin_lock_irqsave(&dev->txq.lock, flags);
|
|
spin_lock_irqsave(&dev->txq.lock, flags);
|
|
ret = usb_autopm_get_interface_async(dev->intf);
|
|
ret = usb_autopm_get_interface_async(dev->intf);
|