aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/u_ether.c
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2009-08-14 11:04:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:35 -0400
commit9b39e9ddedeef48569f8aac60a7b4c1fbb127c7d (patch)
treed2cc583190e18fa03298e84093c3346e1646007c /drivers/usb/gadget/u_ether.c
parent877accca79b706afe5d78b9a92cf4f22919fb2b0 (diff)
USB: gadget: Add EEM gadget driver
This patch adds a CDC EEM ethernet gadget driver. CDC EEM is a newer USB ethernet specification that uses a simpler interface than the older CDC ECM. This makes CDC EEM usable by a wider set of USB hardware. By default the ethernet gadget will still use CDC ECM/Subset, but kernel configuration and/or a module parameter will allow alternative use of the CDC EEM protocol. Changes since last version: - Brought in missing RNDIS changes that caused compile error - Modified 'sentinel CRC' checking to match EEM host driver Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/u_ether.c')
-rw-r--r--drivers/usb/gadget/u_ether.c85
1 files changed, 57 insertions, 28 deletions
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index c66521953917..f8751ff863cd 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -37,8 +37,9 @@
37 * one (!) network link through the USB gadget stack, normally "usb0". 37 * one (!) network link through the USB gadget stack, normally "usb0".
38 * 38 *
39 * The control and data models are handled by the function driver which 39 * The control and data models are handled by the function driver which
40 * connects to this code; such as CDC Ethernet, "CDC Subset", or RNDIS. 40 * connects to this code; such as CDC Ethernet (ECM or EEM),
41 * That includes all descriptor and endpoint management. 41 * "CDC Subset", or RNDIS. That includes all descriptor and endpoint
42 * management.
42 * 43 *
43 * Link level addressing is handled by this component using module 44 * Link level addressing is handled by this component using module
44 * parameters; if no such parameters are provided, random link level 45 * parameters; if no such parameters are provided, random link level
@@ -68,9 +69,13 @@ struct eth_dev {
68 struct list_head tx_reqs, rx_reqs; 69 struct list_head tx_reqs, rx_reqs;
69 atomic_t tx_qlen; 70 atomic_t tx_qlen;
70 71
72 struct sk_buff_head rx_frames;
73
71 unsigned header_len; 74 unsigned header_len;
72 struct sk_buff *(*wrap)(struct sk_buff *skb); 75 struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb);
73 int (*unwrap)(struct sk_buff *skb); 76 int (*unwrap)(struct gether *,
77 struct sk_buff *skb,
78 struct sk_buff_head *list);
74 79
75 struct work_struct work; 80 struct work_struct work;
76 81
@@ -269,7 +274,7 @@ enomem:
269 274
270static void rx_complete(struct usb_ep *ep, struct usb_request *req) 275static void rx_complete(struct usb_ep *ep, struct usb_request *req)
271{ 276{
272 struct sk_buff *skb = req->context; 277 struct sk_buff *skb = req->context, *skb2;
273 struct eth_dev *dev = ep->driver_data; 278 struct eth_dev *dev = ep->driver_data;
274 int status = req->status; 279 int status = req->status;
275 280
@@ -278,26 +283,47 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
278 /* normal completion */ 283 /* normal completion */
279 case 0: 284 case 0:
280 skb_put(skb, req->actual); 285 skb_put(skb, req->actual);
281 if (dev->unwrap)
282 status = dev->unwrap(skb);
283 if (status < 0
284 || ETH_HLEN > skb->len
285 || skb->len > ETH_FRAME_LEN) {
286 dev->net->stats.rx_errors++;
287 dev->net->stats.rx_length_errors++;
288 DBG(dev, "rx length %d\n", skb->len);
289 break;
290 }
291 286
292 skb->protocol = eth_type_trans(skb, dev->net); 287 if (dev->unwrap) {
293 dev->net->stats.rx_packets++; 288 unsigned long flags;
294 dev->net->stats.rx_bytes += skb->len;
295 289
296 /* no buffer copies needed, unless hardware can't 290 spin_lock_irqsave(&dev->lock, flags);
297 * use skb buffers. 291 if (dev->port_usb) {
298 */ 292 status = dev->unwrap(dev->port_usb,
299 status = netif_rx(skb); 293 skb,
294 &dev->rx_frames);
295 } else {
296 dev_kfree_skb_any(skb);
297 status = -ENOTCONN;
298 }
299 spin_unlock_irqrestore(&dev->lock, flags);
300 } else {
301 skb_queue_tail(&dev->rx_frames, skb);
302 }
300 skb = NULL; 303 skb = NULL;
304
305 skb2 = skb_dequeue(&dev->rx_frames);
306 while (skb2) {
307 if (status < 0
308 || ETH_HLEN > skb2->len
309 || skb2->len > ETH_FRAME_LEN) {
310 dev->net->stats.rx_errors++;
311 dev->net->stats.rx_length_errors++;
312 DBG(dev, "rx length %d\n", skb2->len);
313 dev_kfree_skb_any(skb2);
314 goto next_frame;
315 }
316 skb2->protocol = eth_type_trans(skb2, dev->net);
317 dev->net->stats.rx_packets++;
318 dev->net->stats.rx_bytes += skb2->len;
319
320 /* no buffer copies needed, unless hardware can't
321 * use skb buffers.
322 */
323 status = netif_rx(skb2);
324next_frame:
325 skb2 = skb_dequeue(&dev->rx_frames);
326 }
301 break; 327 break;
302 328
303 /* software-driven interface shutdown */ 329 /* software-driven interface shutdown */
@@ -537,14 +563,15 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
537 * or there's not enough space for extra headers we need 563 * or there's not enough space for extra headers we need
538 */ 564 */
539 if (dev->wrap) { 565 if (dev->wrap) {
540 struct sk_buff *skb_new; 566 unsigned long flags;
541 567
542 skb_new = dev->wrap(skb); 568 spin_lock_irqsave(&dev->lock, flags);
543 if (!skb_new) 569 if (dev->port_usb)
570 skb = dev->wrap(dev->port_usb, skb);
571 spin_unlock_irqrestore(&dev->lock, flags);
572 if (!skb)
544 goto drop; 573 goto drop;
545 574
546 dev_kfree_skb_any(skb);
547 skb = skb_new;
548 length = skb->len; 575 length = skb->len;
549 } 576 }
550 req->buf = skb->data; 577 req->buf = skb->data;
@@ -578,9 +605,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
578 } 605 }
579 606
580 if (retval) { 607 if (retval) {
608 dev_kfree_skb_any(skb);
581drop: 609drop:
582 dev->net->stats.tx_dropped++; 610 dev->net->stats.tx_dropped++;
583 dev_kfree_skb_any(skb);
584 spin_lock_irqsave(&dev->req_lock, flags); 611 spin_lock_irqsave(&dev->req_lock, flags);
585 if (list_empty(&dev->tx_reqs)) 612 if (list_empty(&dev->tx_reqs))
586 netif_start_queue(net); 613 netif_start_queue(net);
@@ -753,6 +780,8 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
753 INIT_LIST_HEAD(&dev->tx_reqs); 780 INIT_LIST_HEAD(&dev->tx_reqs);
754 INIT_LIST_HEAD(&dev->rx_reqs); 781 INIT_LIST_HEAD(&dev->rx_reqs);
755 782
783 skb_queue_head_init(&dev->rx_frames);
784
756 /* network device setup */ 785 /* network device setup */
757 dev->net = net; 786 dev->net = net;
758 strcpy(net->name, "usb%d"); 787 strcpy(net->name, "usb%d");