summaryrefslogtreecommitdiff
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 21:04:47 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 21:04:47 -0700
commit3b59bf081622b6446db77ad06c93fe23677bc533 (patch)
tree3f4bb5a27c90cc86994a1f6d3c53fbf9208003cb /drivers/net/usb
parente45836fafe157df137a837093037f741ad8f4c90 (diff)
parentbbdb32cb5b73597386913d052165423b9d736145 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking merge from David Miller: "1) Move ixgbe driver over to purely page based buffering on receive. From Alexander Duyck. 2) Add receive packet steering support to e1000e, from Bruce Allan. 3) Convert TCP MD5 support over to RCU, from Eric Dumazet. 4) Reduce cpu usage in handling out-of-order TCP packets on modern systems, also from Eric Dumazet. 5) Support the IP{,V6}_UNICAST_IF socket options, making the wine folks happy, from Erich Hoover. 6) Support VLAN trunking from guests in hyperv driver, from Haiyang Zhang. 7) Support byte-queue-limtis in r8169, from Igor Maravic. 8) Outline code intended for IP_RECVTOS in IP_PKTOPTIONS existed but was never properly implemented, Jiri Benc fixed that. 9) 64-bit statistics support in r8169 and 8139too, from Junchang Wang. 10) Support kernel side dump filtering by ctmark in netfilter ctnetlink, from Pablo Neira Ayuso. 11) Support byte-queue-limits in gianfar driver, from Paul Gortmaker. 12) Add new peek socket options to assist with socket migration, from Pavel Emelyanov. 13) Add sch_plug packet scheduler whose queue is controlled by userland daemons using explicit freeze and release commands. From Shriram Rajagopalan. 14) Fix FCOE checksum offload handling on transmit, from Yi Zou." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1846 commits) Fix pppol2tp getsockname() Remove printk from rds_sendmsg ipv6: fix incorrent ipv6 ipsec packet fragment cpsw: Hook up default ndo_change_mtu. net: qmi_wwan: fix build error due to cdc-wdm dependecy netdev: driver: ethernet: Add TI CPSW driver netdev: driver: ethernet: add cpsw address lookup engine support phy: add am79c874 PHY support mlx4_core: fix race on comm channel bonding: send igmp report for its master fs_enet: Add MPC5125 FEC support and PHY interface selection net: bpf_jit: fix BPF_S_LDX_B_MSH compilation net: update the usage of CHECKSUM_UNNECESSARY fcoe: use CHECKSUM_UNNECESSARY instead of CHECKSUM_PARTIAL on tx net: do not do gso for CHECKSUM_UNNECESSARY in netif_needs_gso ixgbe: Fix issues with SR-IOV loopback when flow control is disabled net/hyperv: Fix the code handling tx busy ixgbe: fix namespace issues when FCoE/DCB is not enabled rtlwifi: Remove unused ETH_ADDR_LEN defines igbvf: Use ETH_ALEN ... Fix up fairly trivial conflicts in drivers/isdn/gigaset/interface.c and drivers/net/usb/{Kconfig,qmi_wwan.c} as per David.
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/Kconfig1
-rw-r--r--drivers/net/usb/asix.c88
-rw-r--r--drivers/net/usb/cdc_ncm.c236
-rw-r--r--drivers/net/usb/kaweth.c8
-rw-r--r--drivers/net/usb/mcs7830.c2
-rw-r--r--drivers/net/usb/pegasus.c4
-rw-r--r--drivers/net/usb/rtl8150.c4
-rw-r--r--drivers/net/usb/smsc75xx.c2
-rw-r--r--drivers/net/usb/smsc95xx.c2
-rw-r--r--drivers/net/usb/usbnet.c6
10 files changed, 144 insertions, 209 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 4bad899fb38..833e32f8d63 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -401,6 +401,7 @@ config USB_NET_KALMIA
config USB_NET_QMI_WWAN
tristate "QMI WWAN driver for Qualcomm MSM based 3G and LTE modems"
depends on USB_USBNET
+ select USB_WDM
help
Support WWAN LTE/3G devices based on Qualcomm Mobile Data Modem
(MDM) chipsets. Examples of such devices are
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index d6da5eed545..5ee032cafad 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -305,88 +305,40 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- u8 *head;
- u32 header;
- char *packet;
- struct sk_buff *ax_skb;
- u16 size;
+ int offset = 0;
- head = (u8 *) skb->data;
- memcpy(&header, head, sizeof(header));
- le32_to_cpus(&header);
- packet = head + sizeof(header);
+ while (offset + sizeof(u32) < skb->len) {
+ struct sk_buff *ax_skb;
+ u16 size;
+ u32 header = get_unaligned_le32(skb->data + offset);
- skb_pull(skb, 4);
-
- while (skb->len > 0) {
- if ((header & 0x07ff) != ((~header >> 16) & 0x07ff))
- netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
+ offset += sizeof(u32);
/* get the packet length */
- size = (u16) (header & 0x000007ff);
-
- if ((skb->len) - ((size + 1) & 0xfffe) == 0) {
- u8 alignment = (unsigned long)skb->data & 0x3;
- if (alignment != 0x2) {
- /*
- * not 16bit aligned so use the room provided by
- * the 32 bit header to align the data
- *
- * note we want 16bit alignment as MAC header is
- * 14bytes thus ip header will be aligned on
- * 32bit boundary so accessing ipheader elements
- * using a cast to struct ip header wont cause
- * an unaligned accesses.
- */
- u8 realignment = (alignment + 2) & 0x3;
- memmove(skb->data - realignment,
- skb->data,
- size);
- skb->data -= realignment;
- skb_set_tail_pointer(skb, size);
- }
- return 2;
+ size = (u16) (header & 0x7ff);
+ if (size != ((~header >> 16) & 0x07ff)) {
+ netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
+ return 0;
}
- if (size > dev->net->mtu + ETH_HLEN) {
+ if ((size > dev->net->mtu + ETH_HLEN) ||
+ (size + offset > skb->len)) {
netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
size);
return 0;
}
- ax_skb = skb_clone(skb, GFP_ATOMIC);
- if (ax_skb) {
- u8 alignment = (unsigned long)packet & 0x3;
- ax_skb->len = size;
-
- if (alignment != 0x2) {
- /*
- * not 16bit aligned use the room provided by
- * the 32 bit header to align the data
- */
- u8 realignment = (alignment + 2) & 0x3;
- memmove(packet - realignment, packet, size);
- packet -= realignment;
- }
- ax_skb->data = packet;
- skb_set_tail_pointer(ax_skb, size);
- usbnet_skb_return(dev, ax_skb);
- } else {
+ ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
+ if (!ax_skb)
return 0;
- }
-
- skb_pull(skb, (size + 1) & 0xfffe);
- if (skb->len < sizeof(header))
- break;
+ skb_put(ax_skb, size);
+ memcpy(ax_skb->data, skb->data + offset, size);
+ usbnet_skb_return(dev, ax_skb);
- head = (u8 *) skb->data;
- memcpy(&header, head, sizeof(header));
- le32_to_cpus(&header);
- packet = head + sizeof(header);
- skb_pull(skb, 4);
+ offset += (size + 1) & 0xfffe;
}
- if (skb->len < 0) {
+ if (skb->len != offset) {
netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n",
skb->len);
return 0;
@@ -1541,7 +1493,7 @@ static const struct driver_info ax88772_info = {
.status = asix_status,
.link_reset = ax88772_link_reset,
.reset = ax88772_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET,
.rx_fixup = asix_rx_fixup,
.tx_fixup = asix_tx_fixup,
};
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 3a539a9cac5..7adc9f6b0ea 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1,7 +1,7 @@
/*
* cdc_ncm.c
*
- * Copyright (C) ST-Ericsson 2010-2011
+ * Copyright (C) ST-Ericsson 2010-2012
* Contact: Alexey Orishko <alexey.orishko@stericsson.com>
* Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
*
@@ -47,20 +47,19 @@
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/usb.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
#include <linux/atomic.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/cdc.h>
-#define DRIVER_VERSION "04-Aug-2011"
+#define DRIVER_VERSION "14-Mar-2012"
/* CDC NCM subclass 3.2.1 */
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
/* Maximum NTB length */
-#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */
-#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */
+#define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */
+#define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
@@ -68,19 +67,18 @@
#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
/* Default value for MaxDatagramSize */
-#define CDC_NCM_MAX_DATAGRAM_SIZE 2048 /* bytes */
+#define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */
/*
* Maximum amount of datagrams in NCM Datagram Pointer Table, not counting
- * the last NULL entry. Any additional datagrams in NTB would be discarded.
+ * the last NULL entry.
*/
-#define CDC_NCM_DPT_DATAGRAMS_MAX 32
-
-/* Maximum amount of IN datagrams in NTB */
-#define CDC_NCM_DPT_DATAGRAMS_IN_MAX 0 /* unlimited */
+#define CDC_NCM_DPT_DATAGRAMS_MAX 40
/* Restart the timer, if amount of datagrams is less than given value */
#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3
+#define CDC_NCM_TIMER_PENDING_CNT 2
+#define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC)
/* The following macro defines the minimum header space */
#define CDC_NCM_MIN_HDR_SIZE \
@@ -94,10 +92,10 @@ struct cdc_ncm_data {
};
struct cdc_ncm_ctx {
- struct cdc_ncm_data rx_ncm;
struct cdc_ncm_data tx_ncm;
struct usb_cdc_ncm_ntb_parameters ncm_parm;
- struct timer_list tx_timer;
+ struct hrtimer tx_timer;
+ struct tasklet_struct bh;
const struct usb_cdc_ncm_desc *func_desc;
const struct usb_cdc_header_desc *header_desc;
@@ -117,6 +115,7 @@ struct cdc_ncm_ctx {
struct sk_buff *tx_rem_skb;
spinlock_t mtx;
+ atomic_t stop;
u32 tx_timer_pending;
u32 tx_curr_offset;
@@ -132,10 +131,13 @@ struct cdc_ncm_ctx {
u16 tx_modulus;
u16 tx_ndp_modulus;
u16 tx_seq;
+ u16 rx_seq;
u16 connected;
};
-static void cdc_ncm_tx_timeout(unsigned long arg);
+static void cdc_ncm_txpath_bh(unsigned long param);
+static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
+static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
static const struct driver_info cdc_ncm_info;
static struct usb_driver cdc_ncm_driver;
static const struct ethtool_ops cdc_ncm_ethtool_ops;
@@ -361,27 +363,25 @@ size_err:
if (err < 0) {
pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
CDC_NCM_MIN_DATAGRAM_SIZE);
- kfree(max_datagram_size);
} else {
ctx->max_datagram_size =
le16_to_cpu(*max_datagram_size);
/* Check Eth descriptor value */
- if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) {
- if (ctx->max_datagram_size > eth_max_sz)
+ if (ctx->max_datagram_size > eth_max_sz)
ctx->max_datagram_size = eth_max_sz;
- } else {
- if (ctx->max_datagram_size >
- CDC_NCM_MAX_DATAGRAM_SIZE)
- ctx->max_datagram_size =
+
+ if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
+ ctx->max_datagram_size =
CDC_NCM_MAX_DATAGRAM_SIZE;
- }
if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
ctx->max_datagram_size =
CDC_NCM_MIN_DATAGRAM_SIZE;
/* if value changed, update device */
- err = usb_control_msg(ctx->udev,
+ if (ctx->max_datagram_size !=
+ le16_to_cpu(*max_datagram_size)) {
+ err = usb_control_msg(ctx->udev,
usb_sndctrlpipe(ctx->udev, 0),
USB_CDC_SET_MAX_DATAGRAM_SIZE,
USB_TYPE_CLASS | USB_DIR_OUT
@@ -389,14 +389,14 @@ size_err:
0,
iface_no, max_datagram_size,
2, 1000);
- kfree(max_datagram_size);
-max_dgram_err:
- if (err < 0)
- pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");
+ if (err < 0)
+ pr_debug("SET_MAX_DGRAM_SIZE failed\n");
+ }
}
-
+ kfree(max_datagram_size);
}
+max_dgram_err:
if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
@@ -441,8 +441,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
if (ctx == NULL)
return;
- del_timer_sync(&ctx->tx_timer);
-
if (ctx->tx_rem_skb != NULL) {
dev_kfree_skb_any(ctx->tx_rem_skb);
ctx->tx_rem_skb = NULL;
@@ -469,7 +467,11 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
if (ctx == NULL)
return -ENODEV;
- init_timer(&ctx->tx_timer);
+ hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ctx->tx_timer.function = &cdc_ncm_tx_timer_cb;
+ ctx->bh.data = (unsigned long)ctx;
+ ctx->bh.func = cdc_ncm_txpath_bh;
+ atomic_set(&ctx->stop, 0);
spin_lock_init(&ctx->mtx);
ctx->netdev = dev->net;
@@ -579,11 +581,7 @@ advance:
if (temp)
goto error2;
- dev_info(&dev->udev->dev, "MAC-Address: "
- "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
- dev->net->dev_addr[0], dev->net->dev_addr[1],
- dev->net->dev_addr[2], dev->net->dev_addr[3],
- dev->net->dev_addr[4], dev->net->dev_addr[5]);
+ dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr);
dev->in = usb_rcvbulkpipe(dev->udev,
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)
if (ctx == NULL)
return; /* no setup */
+ atomic_set(&ctx->stop, 1);
+
+ if (hrtimer_active(&ctx->tx_timer))
+ hrtimer_cancel(&ctx->tx_timer);
+
+ tasklet_kill(&ctx->bh);
+
/* disconnect master --> disconnect slave */
if (intf == ctx->control && ctx->data) {
usb_set_intfdata(ctx->data, NULL);
@@ -791,7 +796,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
ctx->tx_curr_last_offset = last_offset;
/* set the pending count */
if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT)
- ctx->tx_timer_pending = 2;
+ ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT;
goto exit_no_skb;
} else {
@@ -871,44 +876,49 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
/* return skb */
ctx->tx_curr_skb = NULL;
+ ctx->netdev->stats.tx_packets += ctx->tx_curr_frame_num;
return skb_out;
exit_no_skb:
+ /* Start timer, if there is a remaining skb */
+ if (ctx->tx_curr_skb != NULL)
+ cdc_ncm_tx_timeout_start(ctx);
return NULL;
}
static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx)
{
/* start timer, if not already started */
- if (timer_pending(&ctx->tx_timer) == 0) {
- ctx->tx_timer.function = &cdc_ncm_tx_timeout;
- ctx->tx_timer.data = (unsigned long)ctx;
- ctx->tx_timer.expires = jiffies + ((HZ + 999) / 1000);
- add_timer(&ctx->tx_timer);
- }
+ if (!(hrtimer_active(&ctx->tx_timer) || atomic_read(&ctx->stop)))
+ hrtimer_start(&ctx->tx_timer,
+ ktime_set(0, CDC_NCM_TIMER_INTERVAL),
+ HRTIMER_MODE_REL);
}
-static void cdc_ncm_tx_timeout(unsigned long arg)
+static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)arg;
- u8 restart;
+ struct cdc_ncm_ctx *ctx =
+ container_of(timer, struct cdc_ncm_ctx, tx_timer);
- spin_lock(&ctx->mtx);
- if (ctx->tx_timer_pending != 0) {
- ctx->tx_timer_pending--;
- restart = 1;
- } else {
- restart = 0;
- }
+ if (!atomic_read(&ctx->stop))
+ tasklet_schedule(&ctx->bh);
+ return HRTIMER_NORESTART;
+}
- spin_unlock(&ctx->mtx);
+static void cdc_ncm_txpath_bh(unsigned long param)
+{
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)param;
- if (restart) {
- spin_lock(&ctx->mtx);
+ spin_lock_bh(&ctx->mtx);
+ if (ctx->tx_timer_pending != 0) {
+ ctx->tx_timer_pending--;
cdc_ncm_tx_timeout_start(ctx);
- spin_unlock(&ctx->mtx);
+ spin_unlock_bh(&ctx->mtx);
} else if (ctx->netdev != NULL) {
+ spin_unlock_bh(&ctx->mtx);
+ netif_tx_lock_bh(ctx->netdev);
usbnet_start_xmit(NULL, ctx->netdev);
+ netif_tx_unlock_bh(ctx->netdev);
}
}
@@ -917,7 +927,6 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb_out;
struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
- u8 need_timer = 0;
/*
* 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)
if (ctx == NULL)
goto error;
- spin_lock(&ctx->mtx);
+ spin_lock_bh(&ctx->mtx);
skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
- if (ctx->tx_curr_skb != NULL)
- need_timer = 1;
-
- /* Start timer, if there is a remaining skb */
- if (need_timer)
- cdc_ncm_tx_timeout_start(ctx);
-
- if (skb_out)
- dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
-
- spin_unlock(&ctx->mtx);
+ spin_unlock_bh(&ctx->mtx);
return skb_out;
error:
@@ -954,108 +953,103 @@ error:
static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
struct sk_buff *skb;
- struct cdc_ncm_ctx *ctx;
- int sumlen;
- int actlen;
- int temp;
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ int len;
int nframes;
int x;
int offset;
+ struct usb_cdc_ncm_nth16 *nth16;
+ struct usb_cdc_ncm_ndp16 *ndp16;
+ struct usb_cdc_ncm_dpe16 *dpe16;
- ctx = (struct cdc_ncm_ctx *)dev->data[0];
if (ctx == NULL)
goto error;
- actlen = skb_in->len;
- sumlen = CDC_NCM_NTB_MAX_SIZE_RX;
-
- if (actlen < (sizeof(ctx->rx_ncm.nth16) + sizeof(ctx->rx_ncm.ndp16))) {
+ if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth16) +
+ sizeof(struct usb_cdc_ncm_ndp16))) {
pr_debug("frame too short\n");
goto error;
}
- memcpy(&(ctx->rx_ncm.nth16), ((u8 *)skb_in->data),
- sizeof(ctx->rx_ncm.nth16));
+ nth16 = (struct usb_cdc_ncm_nth16 *)skb_in->data;
- if (le32_to_cpu(ctx->rx_ncm.nth16.dwSignature) !=
- USB_CDC_NCM_NTH16_SIGN) {
+ if (le32_to_cpu(nth16->dwSignature) != USB_CDC_NCM_NTH16_SIGN) {
pr_debug("invalid NTH16 signature <%u>\n",
- le32_to_cpu(ctx->rx_ncm.nth16.dwSignature));
+ le32_to_cpu(nth16->dwSignature));
goto error;
}
- temp = le16_to_cpu(ctx->rx_ncm.nth16.wBlockLength);
- if (temp > sumlen) {
- pr_debug("unsupported NTB block length %u/%u\n", temp, sumlen);
+ len = le16_to_cpu(nth16->wBlockLength);
+ if (len > ctx->rx_max) {
+ pr_debug("unsupported NTB block length %u/%u\n", len,
+ ctx->rx_max);
goto error;
}
- temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex);
- if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) {
- pr_debug("invalid DPT16 index\n");
+ if ((ctx->rx_seq + 1) != le16_to_cpu(nth16->wSequence) &&
+ (ctx->rx_seq || le16_to_cpu(nth16->wSequence)) &&
+ !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth16->wSequence))) {
+ pr_debug("sequence number glitch prev=%d curr=%d\n",
+ ctx->rx_seq, le16_to_cpu(nth16->wSequence));
+ }
+ ctx->rx_seq = le16_to_cpu(nth16->wSequence);
+
+ len = le16_to_cpu(nth16->wNdpIndex);
+ if ((len + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) {
+ pr_debug("invalid DPT16 index <%u>\n",
+ le16_to_cpu(nth16->wNdpIndex));
goto error;
}
- memcpy(&(ctx->rx_ncm.ndp16), ((u8 *)skb_in->data) + temp,
- sizeof(ctx->rx_ncm.ndp16));
+ ndp16 = (struct usb_cdc_ncm_ndp16 *)(((u8 *)skb_in->data) + len);
- if (le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature) !=
- USB_CDC_NCM_NDP16_NOCRC_SIGN) {
+ if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) {
pr_debug("invalid DPT16 signature <%u>\n",
- le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature));
+ le32_to_cpu(ndp16->dwSignature));
goto error;
}
- if (le16_to_cpu(ctx->rx_ncm.ndp16.wLength) <
- USB_CDC_NCM_NDP16_LENGTH_MIN) {
+ if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) {
pr_debug("invalid DPT16 length <%u>\n",
- le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature));
+ le32_to_cpu(ndp16->dwSignature));
goto error;
}
- nframes = ((le16_to_cpu(ctx->rx_ncm.ndp16.wLength) -
+ nframes = ((le16_to_cpu(ndp16->wLength) -
sizeof(struct usb_cdc_ncm_ndp16)) /
sizeof(struct usb_cdc_ncm_dpe16));
nframes--; /* we process NDP entries except for the last one */
- pr_debug("nframes = %u\n", nframes);
-
- temp += sizeof(ctx->rx_ncm.ndp16);
+ len += sizeof(struct usb_cdc_ncm_ndp16);
- if ((temp + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > actlen) {
+ if ((len + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) >
+ skb_in->len) {
pr_debug("Invalid nframes = %d\n", nframes);
goto error;
}
- if (nframes > CDC_NCM_DPT_DATAGRAMS_MAX) {
- pr_debug("Truncating number of frames from %u to %u\n",
- nframes, CDC_NCM_DPT_DATAGRAMS_MAX);
- nframes = CDC_NCM_DPT_DATAGRAMS_MAX;
- }
-
- memcpy(&(ctx->rx_ncm.dpe16), ((u8 *)skb_in->data) + temp,
- nframes * (sizeof(struct usb_cdc_ncm_dpe16)));
+ dpe16 = (struct usb_cdc_ncm_dpe16 *)(((u8 *)skb_in->data) + len);
- for (x = 0; x < nframes; x++) {
- offset = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramIndex);
- temp = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramLength);
+ for (x = 0; x < nframes; x++, dpe16++) {
+ offset = le16_to_cpu(dpe16->wDatagramIndex);
+ len = le16_to_cpu(dpe16->wDatagramLength);
/*
* CDC NCM ch. 3.7
* All entries after first NULL entry are to be ignored
*/
- if ((offset == 0) || (temp == 0)) {
+ if ((offset == 0) || (len == 0)) {
if (!x)
goto error; /* empty NTB */
break;
}
/* sanity checking */
- if (((offset + temp) > actlen) ||
- (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) {
+ if (((offset + len) > skb_in->len) ||
+ (len > ctx->rx_max) || (len < ETH_HLEN)) {
pr_debug("invalid frame detected (ignored)"
"offset[%u]=%u, length=%u, skb=%p\n",
- x, offset, temp, skb_in);
+ x, offset, len, skb_in);
if (!x)
goto error;
break;
@@ -1064,9 +1058,9 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
skb = skb_clone(skb_in, GFP_ATOMIC);
if (!skb)
goto error;
- skb->len = temp;
+ skb->len = len;
skb->data = ((u8 *)skb_in->data) + offset;
- skb_set_tail_pointer(skb, temp);
+ skb_set_tail_pointer(skb, len);
usbnet_skb_return(dev, skb);
}
}
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index d034d9c4254..df2a2cf35a9 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -1098,13 +1098,7 @@ err_fw:
dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
- dev_info(&intf->dev, "Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- (int)kaweth->configuration.hw_addr[0],
- (int)kaweth->configuration.hw_addr[1],
- (int)kaweth->configuration.hw_addr[2],
- (int)kaweth->configuration.hw_addr[3],
- (int)kaweth->configuration.hw_addr[4],
- (int)kaweth->configuration.hw_addr[5]);
+ dev_info(&intf->dev, "Read MAC address %pM\n", kaweth->configuration.hw_addr);
if(!memcmp(&kaweth->configuration.hw_addr,
&bcast_addr,
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index a29aa9cf9f6..c434b6ba033 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -239,7 +239,7 @@ static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
return -EBUSY;
if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
+ return -EADDRNOTAVAIL;
ret = mcs7830_hif_set_mac_address(dev, addr->sa_data);
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 5d99b8cacd7..75239309232 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -1332,10 +1332,8 @@ static int pegasus_probe(struct usb_interface *intf,
usb_get_dev(dev);
net = alloc_etherdev(sizeof(struct pegasus));
- if (!net) {
- dev_err(&intf->dev, "can't allocate %s\n", "device");
+ if (!net)
goto out;
- }
pegasus = netdev_priv(net);
pegasus->dev_index = dev_index;
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index 0710b4ca925..6dda2fe5b15 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -894,10 +894,8 @@ static int rtl8150_probe(struct usb_interface *intf,
struct net_device *netdev;
netdev = alloc_etherdev(sizeof(rtl8150_t));
- if (!netdev) {
- err("Out of memory");
+ if (!netdev)
return -ENOMEM;
- }
dev = netdev_priv(netdev);
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 3b017bbd2a2..187d01ccb97 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -615,7 +615,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev)
}
/* no eeprom, or eeprom values are invalid. generate random MAC */
- random_ether_addr(dev->net->dev_addr);
+ eth_hw_addr_random(dev->net);
netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
}
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index d45520e6dd4..5f19f84d349 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -614,7 +614,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev)
}
/* no eeprom, or eeprom values are invalid. generate random MAC */
- random_ether_addr(dev->net->dev_addr);
+ eth_hw_addr_random(dev->net);
netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n");
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 59681f01a54..4b8b52ca09d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1336,10 +1336,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
// set up our own records
net = alloc_etherdev(sizeof(*dev));
- if (!net) {
- dbg ("can't kmalloc dev");
+ if (!net)
goto out;
- }
/* netdev_printk() needs this so do it as early as possible */
SET_NETDEV_DEV(net, &udev->dev);
@@ -1537,7 +1535,7 @@ int usbnet_resume (struct usb_interface *intf)
if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
if (!(dev->txq.qlen >= TX_QLEN(dev)))
- netif_start_queue(dev->net);
+ netif_tx_wake_all_queues(dev->net);
tasklet_schedule (&dev->bh);
}
}