diff options
author | Alexey Orishko <alexey.orishko@gmail.com> | 2010-11-29 18:23:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-06 15:59:02 -0500 |
commit | 073285fd392f6dc901da7c698d46e1e2a7e26436 (patch) | |
tree | 5207bc21a56d42eb9f86811068a8c55772b451f0 /drivers/net/usb/usbnet.c | |
parent | 5ee493767352314893520ac40aec5bb07d0147e0 (diff) |
usbnet: changes for upcoming cdc_ncm driver
Changes:
include/linux/usb/usbnet.h:
- a new flag to indicate driver's capability to accumulate IP packets in Tx
direction and extract several packets from single skb in Rx direction.
drivers/net/usb/usbnet.c:
- the procedure of counting packets in usbnet was updated due to the
accumulating of IP packets in the driver
- no short packets are sent if indicated by the flag in driver_info
structure
Signed-off-by: Alexey Orishko <alexey.orishko@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index c04d49e31f81..cff74b81a7d2 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -391,14 +391,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
391 | goto error; | 391 | goto error; |
392 | // else network stack removes extra byte if we forced a short packet | 392 | // else network stack removes extra byte if we forced a short packet |
393 | 393 | ||
394 | if (skb->len) | 394 | if (skb->len) { |
395 | usbnet_skb_return (dev, skb); | 395 | /* all data was already cloned from skb inside the driver */ |
396 | else { | 396 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) |
397 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | 397 | dev_kfree_skb_any(skb); |
398 | error: | 398 | else |
399 | dev->net->stats.rx_errors++; | 399 | usbnet_skb_return(dev, skb); |
400 | skb_queue_tail (&dev->done, skb); | 400 | return; |
401 | } | 401 | } |
402 | |||
403 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | ||
404 | error: | ||
405 | dev->net->stats.rx_errors++; | ||
406 | skb_queue_tail(&dev->done, skb); | ||
402 | } | 407 | } |
403 | 408 | ||
404 | /*-------------------------------------------------------------------------*/ | 409 | /*-------------------------------------------------------------------------*/ |
@@ -971,7 +976,8 @@ static void tx_complete (struct urb *urb) | |||
971 | struct usbnet *dev = entry->dev; | 976 | struct usbnet *dev = entry->dev; |
972 | 977 | ||
973 | if (urb->status == 0) { | 978 | if (urb->status == 0) { |
974 | dev->net->stats.tx_packets++; | 979 | if (!(dev->driver_info->flags & FLAG_MULTI_PACKET)) |
980 | dev->net->stats.tx_packets++; | ||
975 | dev->net->stats.tx_bytes += entry->length; | 981 | dev->net->stats.tx_bytes += entry->length; |
976 | } else { | 982 | } else { |
977 | dev->net->stats.tx_errors++; | 983 | dev->net->stats.tx_errors++; |
@@ -1044,8 +1050,13 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1044 | if (info->tx_fixup) { | 1050 | if (info->tx_fixup) { |
1045 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); | 1051 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); |
1046 | if (!skb) { | 1052 | if (!skb) { |
1047 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); | 1053 | if (netif_msg_tx_err(dev)) { |
1048 | goto drop; | 1054 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); |
1055 | goto drop; | ||
1056 | } else { | ||
1057 | /* cdc_ncm collected packet; waits for more */ | ||
1058 | goto not_drop; | ||
1059 | } | ||
1049 | } | 1060 | } |
1050 | } | 1061 | } |
1051 | length = skb->len; | 1062 | length = skb->len; |
@@ -1067,13 +1078,18 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1067 | /* don't assume the hardware handles USB_ZERO_PACKET | 1078 | /* don't assume the hardware handles USB_ZERO_PACKET |
1068 | * NOTE: strictly conforming cdc-ether devices should expect | 1079 | * NOTE: strictly conforming cdc-ether devices should expect |
1069 | * the ZLP here, but ignore the one-byte packet. | 1080 | * the ZLP here, but ignore the one-byte packet. |
1081 | * NOTE2: CDC NCM specification is different from CDC ECM when | ||
1082 | * handling ZLP/short packets, so cdc_ncm driver will make short | ||
1083 | * packet itself if needed. | ||
1070 | */ | 1084 | */ |
1071 | if (length % dev->maxpacket == 0) { | 1085 | if (length % dev->maxpacket == 0) { |
1072 | if (!(info->flags & FLAG_SEND_ZLP)) { | 1086 | if (!(info->flags & FLAG_SEND_ZLP)) { |
1073 | urb->transfer_buffer_length++; | 1087 | if (!(info->flags & FLAG_MULTI_PACKET)) { |
1074 | if (skb_tailroom(skb)) { | 1088 | urb->transfer_buffer_length++; |
1075 | skb->data[skb->len] = 0; | 1089 | if (skb_tailroom(skb)) { |
1076 | __skb_put(skb, 1); | 1090 | skb->data[skb->len] = 0; |
1091 | __skb_put(skb, 1); | ||
1092 | } | ||
1077 | } | 1093 | } |
1078 | } else | 1094 | } else |
1079 | urb->transfer_flags |= URB_ZERO_PACKET; | 1095 | urb->transfer_flags |= URB_ZERO_PACKET; |
@@ -1122,6 +1138,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1122 | netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval); | 1138 | netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval); |
1123 | drop: | 1139 | drop: |
1124 | dev->net->stats.tx_dropped++; | 1140 | dev->net->stats.tx_dropped++; |
1141 | not_drop: | ||
1125 | if (skb) | 1142 | if (skb) |
1126 | dev_kfree_skb_any (skb); | 1143 | dev_kfree_skb_any (skb); |
1127 | usb_free_urb (urb); | 1144 | usb_free_urb (urb); |