aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/cdc_ncm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/cdc_ncm.c')
-rw-r--r--drivers/net/usb/cdc_ncm.c236
1 files changed, 115 insertions, 121 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 3a539a9cac54..7adc9f6b0ea1 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * cdc_ncm.c 2 * cdc_ncm.c
3 * 3 *
4 * Copyright (C) ST-Ericsson 2010-2011 4 * Copyright (C) ST-Ericsson 2010-2012
5 * Contact: Alexey Orishko <alexey.orishko@stericsson.com> 5 * Contact: Alexey Orishko <alexey.orishko@stericsson.com>
6 * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> 6 * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
7 * 7 *
@@ -47,20 +47,19 @@
47#include <linux/mii.h> 47#include <linux/mii.h>
48#include <linux/crc32.h> 48#include <linux/crc32.h>
49#include <linux/usb.h> 49#include <linux/usb.h>
50#include <linux/timer.h> 50#include <linux/hrtimer.h>
51#include <linux/spinlock.h>
52#include <linux/atomic.h> 51#include <linux/atomic.h>
53#include <linux/usb/usbnet.h> 52#include <linux/usb/usbnet.h>
54#include <linux/usb/cdc.h> 53#include <linux/usb/cdc.h>
55 54
56#define DRIVER_VERSION "04-Aug-2011" 55#define DRIVER_VERSION "14-Mar-2012"
57 56
58/* CDC NCM subclass 3.2.1 */ 57/* CDC NCM subclass 3.2.1 */
59#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 58#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
60 59
61/* Maximum NTB length */ 60/* Maximum NTB length */
62#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ 61#define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */
63#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ 62#define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */
64 63
65/* Minimum value for MaxDatagramSize, ch. 6.2.9 */ 64/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
66#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */ 65#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
@@ -68,19 +67,18 @@
68#define CDC_NCM_MIN_TX_PKT 512 /* bytes */ 67#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
69 68
70/* Default value for MaxDatagramSize */ 69/* Default value for MaxDatagramSize */
71#define CDC_NCM_MAX_DATAGRAM_SIZE 2048 /* bytes */ 70#define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */
72 71
73/* 72/*
74 * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting 73 * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting
75 * the last NULL entry. Any additional datagrams in NTB would be discarded. 74 * the last NULL entry.
76 */ 75 */
77#define CDC_NCM_DPT_DATAGRAMS_MAX 32 76#define CDC_NCM_DPT_DATAGRAMS_MAX 40
78
79/* Maximum amount of IN datagrams in NTB */
80#define CDC_NCM_DPT_DATAGRAMS_IN_MAX 0 /* unlimited */
81 77
82/* Restart the timer, if amount of datagrams is less than given value */ 78/* Restart the timer, if amount of datagrams is less than given value */
83#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 79#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3
80#define CDC_NCM_TIMER_PENDING_CNT 2
81#define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC)
84 82
85/* The following macro defines the minimum header space */ 83/* The following macro defines the minimum header space */
86#define CDC_NCM_MIN_HDR_SIZE \ 84#define CDC_NCM_MIN_HDR_SIZE \
@@ -94,10 +92,10 @@ struct cdc_ncm_data {
94}; 92};
95 93
96struct cdc_ncm_ctx { 94struct cdc_ncm_ctx {
97 struct cdc_ncm_data rx_ncm;
98 struct cdc_ncm_data tx_ncm; 95 struct cdc_ncm_data tx_ncm;
99 struct usb_cdc_ncm_ntb_parameters ncm_parm; 96 struct usb_cdc_ncm_ntb_parameters ncm_parm;
100 struct timer_list tx_timer; 97 struct hrtimer tx_timer;
98 struct tasklet_struct bh;
101 99
102 const struct usb_cdc_ncm_desc *func_desc; 100 const struct usb_cdc_ncm_desc *func_desc;
103 const struct usb_cdc_header_desc *header_desc; 101 const struct usb_cdc_header_desc *header_desc;
@@ -117,6 +115,7 @@ struct cdc_ncm_ctx {
117 struct sk_buff *tx_rem_skb; 115 struct sk_buff *tx_rem_skb;
118 116
119 spinlock_t mtx; 117 spinlock_t mtx;
118 atomic_t stop;
120 119
121 u32 tx_timer_pending; 120 u32 tx_timer_pending;
122 u32 tx_curr_offset; 121 u32 tx_curr_offset;
@@ -132,10 +131,13 @@ struct cdc_ncm_ctx {
132 u16 tx_modulus; 131 u16 tx_modulus;
133 u16 tx_ndp_modulus; 132 u16 tx_ndp_modulus;
134 u16 tx_seq; 133 u16 tx_seq;
134 u16 rx_seq;
135 u16 connected; 135 u16 connected;
136}; 136};
137 137
138static void cdc_ncm_tx_timeout(unsigned long arg); 138static void cdc_ncm_txpath_bh(unsigned long param);
139static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
140static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
139static const struct driver_info cdc_ncm_info; 141static const struct driver_info cdc_ncm_info;
140static struct usb_driver cdc_ncm_driver; 142static struct usb_driver cdc_ncm_driver;
141static const struct ethtool_ops cdc_ncm_ethtool_ops; 143static const struct ethtool_ops cdc_ncm_ethtool_ops;
@@ -361,27 +363,25 @@ size_err:
361 if (err < 0) { 363 if (err < 0) {
362 pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", 364 pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
363 CDC_NCM_MIN_DATAGRAM_SIZE); 365 CDC_NCM_MIN_DATAGRAM_SIZE);
364 kfree(max_datagram_size);
365 } else { 366 } else {
366 ctx->max_datagram_size = 367 ctx->max_datagram_size =
367 le16_to_cpu(*max_datagram_size); 368 le16_to_cpu(*max_datagram_size);
368 /* Check Eth descriptor value */ 369 /* Check Eth descriptor value */
369 if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) { 370 if (ctx->max_datagram_size > eth_max_sz)
370 if (ctx->max_datagram_size > eth_max_sz)
371 ctx->max_datagram_size = eth_max_sz; 371 ctx->max_datagram_size = eth_max_sz;
372 } else { 372
373 if (ctx->max_datagram_size > 373 if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
374 CDC_NCM_MAX_DATAGRAM_SIZE) 374 ctx->max_datagram_size =
375 ctx->max_datagram_size =
376 CDC_NCM_MAX_DATAGRAM_SIZE; 375 CDC_NCM_MAX_DATAGRAM_SIZE;
377 }
378 376
379 if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) 377 if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
380 ctx->max_datagram_size = 378 ctx->max_datagram_size =
381 CDC_NCM_MIN_DATAGRAM_SIZE; 379 CDC_NCM_MIN_DATAGRAM_SIZE;
382 380
383 /* if value changed, update device */ 381 /* if value changed, update device */
384 err = usb_control_msg(ctx->udev, 382 if (ctx->max_datagram_size !=
383 le16_to_cpu(*max_datagram_size)) {
384 err = usb_control_msg(ctx->udev,
385 usb_sndctrlpipe(ctx->udev, 0), 385 usb_sndctrlpipe(ctx->udev, 0),
386 USB_CDC_SET_MAX_DATAGRAM_SIZE, 386 USB_CDC_SET_MAX_DATAGRAM_SIZE,
387 USB_TYPE_CLASS | USB_DIR_OUT 387 USB_TYPE_CLASS | USB_DIR_OUT
@@ -389,14 +389,14 @@ size_err:
389 0, 389 0,
390 iface_no, max_datagram_size, 390 iface_no, max_datagram_size,
391 2, 1000); 391 2, 1000);
392 kfree(max_datagram_size); 392 if (err < 0)
393max_dgram_err: 393 pr_debug("SET_MAX_DGRAM_SIZE failed\n");
394 if (err < 0) 394 }
395 pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");
396 } 395 }
397 396 kfree(max_datagram_size);
398 } 397 }
399 398
399max_dgram_err:
400 if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) 400 if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
401 ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN; 401 ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
402 402
@@ -441,8 +441,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
441 if (ctx == NULL) 441 if (ctx == NULL)
442 return; 442 return;
443 443
444 del_timer_sync(&ctx->tx_timer);
445
446 if (ctx->tx_rem_skb != NULL) { 444 if (ctx->tx_rem_skb != NULL) {
447 dev_kfree_skb_any(ctx->tx_rem_skb); 445 dev_kfree_skb_any(ctx->tx_rem_skb);
448 ctx->tx_rem_skb = NULL; 446 ctx->tx_rem_skb = NULL;
@@ -469,7 +467,11 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
469 if (ctx == NULL) 467 if (ctx == NULL)
470 return -ENODEV; 468 return -ENODEV;
471 469
472 init_timer(&ctx->tx_timer); 470 hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
471 ctx->tx_timer.function = &cdc_ncm_tx_timer_cb;
472 ctx->bh.data = (unsigned long)ctx;
473 ctx->bh.func = cdc_ncm_txpath_bh;
474 atomic_set(&ctx->stop, 0);
473 spin_lock_init(&ctx->mtx); 475 spin_lock_init(&ctx->mtx);
474 ctx->netdev = dev->net; 476 ctx->netdev = dev->net;
475 477
@@ -579,11 +581,7 @@ advance:
579 if (temp) 581 if (temp)
580 goto error2; 582 goto error2;
581 583
582 dev_info(&dev->udev->dev, "MAC-Address: " 584 dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr);
583 "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
584 dev->net->dev_addr[0], dev->net->dev_addr[1],
585 dev->net->dev_addr[2], dev->net->dev_addr[3],
586 dev->net->dev_addr[4], dev->net->dev_addr[5]);
587 585
588 dev->in = usb_rcvbulkpipe(dev->udev, 586 dev->in = usb_rcvbulkpipe(dev->udev,
589 ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); 587 ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
@@ -621,6 +619,13 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
621 if (ctx == NULL) 619 if (ctx == NULL)
622 return; /* no setup */ 620 return; /* no setup */
623 621
622 atomic_set(&ctx->stop, 1);
623
624 if (hrtimer_active(&ctx->tx_timer))
625 hrtimer_cancel(&ctx->tx_timer);
626
627 tasklet_kill(&ctx->bh);
628
624 /* disconnect master --> disconnect slave */ 629 /* disconnect master --> disconnect slave */
625 if (intf == ctx->control && ctx->data) { 630 if (intf == ctx->control && ctx->data) {
626 usb_set_intfdata(ctx->data, NULL); 631 usb_set_intfdata(ctx->data, NULL);
@@ -791,7 +796,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
791 ctx->tx_curr_last_offset = last_offset; 796 ctx->tx_curr_last_offset = last_offset;
792 /* set the pending count */ 797 /* set the pending count */
793 if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT) 798 if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT)
794 ctx->tx_timer_pending = 2; 799 ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT;
795 goto exit_no_skb; 800 goto exit_no_skb;
796 801
797 } else { 802 } else {
@@ -871,44 +876,49 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
871 876
872 /* return skb */ 877 /* return skb */
873 ctx->tx_curr_skb = NULL; 878 ctx->tx_curr_skb = NULL;
879 ctx->netdev->stats.tx_packets += ctx->tx_curr_frame_num;
874 return skb_out; 880 return skb_out;
875 881
876exit_no_skb: 882exit_no_skb:
883 /* Start timer, if there is a remaining skb */
884 if (ctx->tx_curr_skb != NULL)
885 cdc_ncm_tx_timeout_start(ctx);
877 return NULL; 886 return NULL;
878} 887}
879 888
880static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) 889static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx)
881{ 890{
882 /* start timer, if not already started */ 891 /* start timer, if not already started */
883 if (timer_pending(&ctx->tx_timer) == 0) { 892 if (!(hrtimer_active(&ctx->tx_timer) || atomic_read(&ctx->stop)))
884 ctx->tx_timer.function = &cdc_ncm_tx_timeout; 893 hrtimer_start(&ctx->tx_timer,
885 ctx->tx_timer.data = (unsigned long)ctx; 894 ktime_set(0, CDC_NCM_TIMER_INTERVAL),
886 ctx->tx_timer.expires = jiffies + ((HZ + 999) / 1000); 895 HRTIMER_MODE_REL);
887 add_timer(&ctx->tx_timer);
888 }
889} 896}
890 897
891static void cdc_ncm_tx_timeout(unsigned long arg) 898static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer)
892{ 899{
893 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)arg; 900 struct cdc_ncm_ctx *ctx =
894 u8 restart; 901 container_of(timer, struct cdc_ncm_ctx, tx_timer);
895 902
896 spin_lock(&ctx->mtx); 903 if (!atomic_read(&ctx->stop))
897 if (ctx->tx_timer_pending != 0) { 904 tasklet_schedule(&ctx->bh);
898 ctx->tx_timer_pending--; 905 return HRTIMER_NORESTART;
899 restart = 1; 906}
900 } else {
901 restart = 0;
902 }
903 907
904 spin_unlock(&ctx->mtx); 908static void cdc_ncm_txpath_bh(unsigned long param)
909{
910 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)param;
905 911
906 if (restart) { 912 spin_lock_bh(&ctx->mtx);
907 spin_lock(&ctx->mtx); 913 if (ctx->tx_timer_pending != 0) {
914 ctx->tx_timer_pending--;
908 cdc_ncm_tx_timeout_start(ctx); 915 cdc_ncm_tx_timeout_start(ctx);
909 spin_unlock(&ctx->mtx); 916 spin_unlock_bh(&ctx->mtx);
910 } else if (ctx->netdev != NULL) { 917 } else if (ctx->netdev != NULL) {
918 spin_unlock_bh(&ctx->mtx);
919 netif_tx_lock_bh(ctx->netdev);
911 usbnet_start_xmit(NULL, ctx->netdev); 920 usbnet_start_xmit(NULL, ctx->netdev);
921 netif_tx_unlock_bh(ctx->netdev);
912 } 922 }
913} 923}
914 924
@@ -917,7 +927,6 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
917{ 927{
918 struct sk_buff *skb_out; 928 struct sk_buff *skb_out;
919 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; 929 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
920 u8 need_timer = 0;
921 930
922 /* 931 /*
923 * The Ethernet API we are using does not support transmitting 932 * The Ethernet API we are using does not support transmitting
@@ -929,19 +938,9 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
929 if (ctx == NULL) 938 if (ctx == NULL)
930 goto error; 939 goto error;
931 940
932 spin_lock(&ctx->mtx); 941 spin_lock_bh(&ctx->mtx);
933 skb_out = cdc_ncm_fill_tx_frame(ctx, skb); 942 skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
934 if (ctx->tx_curr_skb != NULL) 943 spin_unlock_bh(&ctx->mtx);
935 need_timer = 1;
936
937 /* Start timer, if there is a remaining skb */
938 if (need_timer)
939 cdc_ncm_tx_timeout_start(ctx);
940
941 if (skb_out)
942 dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
943
944 spin_unlock(&ctx->mtx);
945 return skb_out; 944 return skb_out;
946 945
947error: 946error:
@@ -954,108 +953,103 @@ error:
954static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) 953static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
955{ 954{
956 struct sk_buff *skb; 955 struct sk_buff *skb;
957 struct cdc_ncm_ctx *ctx; 956 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
958 int sumlen; 957 int len;
959 int actlen;
960 int temp;
961 int nframes; 958 int nframes;
962 int x; 959 int x;
963 int offset; 960 int offset;
961 struct usb_cdc_ncm_nth16 *nth16;
962 struct usb_cdc_ncm_ndp16 *ndp16;
963 struct usb_cdc_ncm_dpe16 *dpe16;
964 964
965 ctx = (struct cdc_ncm_ctx *)dev->data[0];
966 if (ctx == NULL) 965 if (ctx == NULL)
967 goto error; 966 goto error;
968 967
969 actlen = skb_in->len; 968 if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth16) +
970 sumlen = CDC_NCM_NTB_MAX_SIZE_RX; 969 sizeof(struct usb_cdc_ncm_ndp16))) {
971
972 if (actlen < (sizeof(ctx->rx_ncm.nth16) + sizeof(ctx->rx_ncm.ndp16))) {
973 pr_debug("frame too short\n"); 970 pr_debug("frame too short\n");
974 goto error; 971 goto error;
975 } 972 }
976 973
977 memcpy(&(ctx->rx_ncm.nth16), ((u8 *)skb_in->data), 974 nth16 = (struct usb_cdc_ncm_nth16 *)skb_in->data;
978 sizeof(ctx->rx_ncm.nth16));
979 975
980 if (le32_to_cpu(ctx->rx_ncm.nth16.dwSignature) != 976 if (le32_to_cpu(nth16->dwSignature) != USB_CDC_NCM_NTH16_SIGN) {
981 USB_CDC_NCM_NTH16_SIGN) {
982 pr_debug("invalid NTH16 signature <%u>\n", 977 pr_debug("invalid NTH16 signature <%u>\n",
983 le32_to_cpu(ctx->rx_ncm.nth16.dwSignature)); 978 le32_to_cpu(nth16->dwSignature));
984 goto error; 979 goto error;
985 } 980 }
986 981
987 temp = le16_to_cpu(ctx->rx_ncm.nth16.wBlockLength); 982 len = le16_to_cpu(nth16->wBlockLength);
988 if (temp > sumlen) { 983 if (len > ctx->rx_max) {
989 pr_debug("unsupported NTB block length %u/%u\n", temp, sumlen); 984 pr_debug("unsupported NTB block length %u/%u\n", len,
985 ctx->rx_max);
990 goto error; 986 goto error;
991 } 987 }
992 988
993 temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex); 989 if ((ctx->rx_seq + 1) != le16_to_cpu(nth16->wSequence) &&
994 if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { 990 (ctx->rx_seq || le16_to_cpu(nth16->wSequence)) &&
995 pr_debug("invalid DPT16 index\n"); 991 !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth16->wSequence))) {
992 pr_debug("sequence number glitch prev=%d curr=%d\n",
993 ctx->rx_seq, le16_to_cpu(nth16->wSequence));
994 }
995 ctx->rx_seq = le16_to_cpu(nth16->wSequence);
996
997 len = le16_to_cpu(nth16->wNdpIndex);
998 if ((len + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) {
999 pr_debug("invalid DPT16 index <%u>\n",
1000 le16_to_cpu(nth16->wNdpIndex));
996 goto error; 1001 goto error;
997 } 1002 }
998 1003
999 memcpy(&(ctx->rx_ncm.ndp16), ((u8 *)skb_in->data) + temp, 1004 ndp16 = (struct usb_cdc_ncm_ndp16 *)(((u8 *)skb_in->data) + len);
1000 sizeof(ctx->rx_ncm.ndp16));
1001 1005
1002 if (le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature) != 1006 if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) {
1003 USB_CDC_NCM_NDP16_NOCRC_SIGN) {
1004 pr_debug("invalid DPT16 signature <%u>\n", 1007 pr_debug("invalid DPT16 signature <%u>\n",
1005 le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); 1008 le32_to_cpu(ndp16->dwSignature));
1006 goto error; 1009 goto error;
1007 } 1010 }
1008 1011
1009 if (le16_to_cpu(ctx->rx_ncm.ndp16.wLength) < 1012 if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) {
1010 USB_CDC_NCM_NDP16_LENGTH_MIN) {
1011 pr_debug("invalid DPT16 length <%u>\n", 1013 pr_debug("invalid DPT16 length <%u>\n",
1012 le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); 1014 le32_to_cpu(ndp16->dwSignature));
1013 goto error; 1015 goto error;
1014 } 1016 }
1015 1017
1016 nframes = ((le16_to_cpu(ctx->rx_ncm.ndp16.wLength) - 1018 nframes = ((le16_to_cpu(ndp16->wLength) -
1017 sizeof(struct usb_cdc_ncm_ndp16)) / 1019 sizeof(struct usb_cdc_ncm_ndp16)) /
1018 sizeof(struct usb_cdc_ncm_dpe16)); 1020 sizeof(struct usb_cdc_ncm_dpe16));
1019 nframes--; /* we process NDP entries except for the last one */ 1021 nframes--; /* we process NDP entries except for the last one */
1020 1022
1021 pr_debug("nframes = %u\n", nframes); 1023 len += sizeof(struct usb_cdc_ncm_ndp16);
1022
1023 temp += sizeof(ctx->rx_ncm.ndp16);
1024 1024
1025 if ((temp + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > actlen) { 1025 if ((len + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) >
1026 skb_in->len) {
1026 pr_debug("Invalid nframes = %d\n", nframes); 1027 pr_debug("Invalid nframes = %d\n", nframes);
1027 goto error; 1028 goto error;
1028 } 1029 }
1029 1030
1030 if (nframes > CDC_NCM_DPT_DATAGRAMS_MAX) { 1031 dpe16 = (struct usb_cdc_ncm_dpe16 *)(((u8 *)skb_in->data) + len);
1031 pr_debug("Truncating number of frames from %u to %u\n",
1032 nframes, CDC_NCM_DPT_DATAGRAMS_MAX);
1033 nframes = CDC_NCM_DPT_DATAGRAMS_MAX;
1034 }
1035
1036 memcpy(&(ctx->rx_ncm.dpe16), ((u8 *)skb_in->data) + temp,
1037 nframes * (sizeof(struct usb_cdc_ncm_dpe16)));
1038 1032
1039 for (x = 0; x < nframes; x++) { 1033 for (x = 0; x < nframes; x++, dpe16++) {
1040 offset = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramIndex); 1034 offset = le16_to_cpu(dpe16->wDatagramIndex);
1041 temp = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramLength); 1035 len = le16_to_cpu(dpe16->wDatagramLength);
1042 1036
1043 /* 1037 /*
1044 * CDC NCM ch. 3.7 1038 * CDC NCM ch. 3.7
1045 * All entries after first NULL entry are to be ignored 1039 * All entries after first NULL entry are to be ignored
1046 */ 1040 */
1047 if ((offset == 0) || (temp == 0)) { 1041 if ((offset == 0) || (len == 0)) {
1048 if (!x) 1042 if (!x)
1049 goto error; /* empty NTB */ 1043 goto error; /* empty NTB */
1050 break; 1044 break;
1051 } 1045 }
1052 1046
1053 /* sanity checking */ 1047 /* sanity checking */
1054 if (((offset + temp) > actlen) || 1048 if (((offset + len) > skb_in->len) ||
1055 (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { 1049 (len > ctx->rx_max) || (len < ETH_HLEN)) {
1056 pr_debug("invalid frame detected (ignored)" 1050 pr_debug("invalid frame detected (ignored)"
1057 "offset[%u]=%u, length=%u, skb=%p\n", 1051 "offset[%u]=%u, length=%u, skb=%p\n",
1058 x, offset, temp, skb_in); 1052 x, offset, len, skb_in);
1059 if (!x) 1053 if (!x)
1060 goto error; 1054 goto error;
1061 break; 1055 break;
@@ -1064,9 +1058,9 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
1064 skb = skb_clone(skb_in, GFP_ATOMIC); 1058 skb = skb_clone(skb_in, GFP_ATOMIC);
1065 if (!skb) 1059 if (!skb)
1066 goto error; 1060 goto error;
1067 skb->len = temp; 1061 skb->len = len;
1068 skb->data = ((u8 *)skb_in->data) + offset; 1062 skb->data = ((u8 *)skb_in->data) + offset;
1069 skb_set_tail_pointer(skb, temp); 1063 skb_set_tail_pointer(skb, len);
1070 usbnet_skb_return(dev, skb); 1064 usbnet_skb_return(dev, skb);
1071 } 1065 }
1072 } 1066 }