1179 lines · 28.7 KB · C
RawDownload
/* * u_ether.c -- Ethernet-over-USB link layer utilities for Gadget stack * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 Nokia Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ /* #define VERBOSE_DEBUG */ #include <linux/kernel.h>#include <linux/module.h>#include <linux/gfp.h>#include <linux/device.h>#include <linux/ctype.h>#include <linux/etherdevice.h>#include <linux/ethtool.h>#include <linux/if_vlan.h> #include "u_ether.h"  /* * This component encapsulates the Ethernet link glue needed to provide * one (!) network link through the USB gadget stack, normally "usb0". * * The control and data models are handled by the function driver which * connects to this code; such as CDC Ethernet (ECM or EEM), * "CDC Subset", or RNDIS.  That includes all descriptor and endpoint * management. * * Link level addressing is handled by this component using module * parameters; if no such parameters are provided, random link level * addresses are used.  Each end of the link uses one address.  The * host end address is exported in various ways, and is often recorded * in configuration databases. * * The driver which assembles each configuration using such a link is * responsible for ensuring that each configuration includes at most one * instance of is network link.  (The network layer provides ways for * this single "physical" link to be used by multiple virtual links.) */ #define UETH__VERSION	"29-May-2008" /* Experiments show that both Linux and Windows hosts allow up to 16k * frame sizes. Set the max size to 15k+52 to prevent allocating 32k * blocks and still have efficient handling. */#define GETHER_MAX_ETH_FRAME_LEN 15412 struct eth_dev {	/* lock is held while accessing port_usb	 */	spinlock_t		lock;	struct gether		*port_usb; 	struct net_device	*net;	struct usb_gadget	*gadget; 	spinlock_t		req_lock;	/* guard {rx,tx}_reqs */	struct list_head	tx_reqs, rx_reqs;	atomic_t		tx_qlen; 	struct sk_buff_head	rx_frames; 	unsigned		qmult; 	unsigned		header_len;	struct sk_buff		*(*wrap)(struct gether *, struct sk_buff *skb);	int			(*unwrap)(struct gether *,						struct sk_buff *skb,						struct sk_buff_head *list); 	struct work_struct	work; 	unsigned long		todo;#define	WORK_RX_MEMORY		0 	bool			zlp;	bool			no_skb_reserve;	u8			host_mac[ETH_ALEN];	u8			dev_mac[ETH_ALEN];}; /*-------------------------------------------------------------------------*/ #define RX_EXTRA	20	/* bytes guarding against rx overflows */ #define DEFAULT_QLEN	2	/* double buffering by default */ /* for dual-speed hardware, use deeper queues at high/super speed */static inline int qlen(struct usb_gadget *gadget, unsigned qmult){	if (gadget_is_dualspeed(gadget) && (gadget->speed == USB_SPEED_HIGH ||					    gadget->speed == USB_SPEED_SUPER))		return qmult * DEFAULT_QLEN;	else		return DEFAULT_QLEN;} /*-------------------------------------------------------------------------*/ /* REVISIT there must be a better way than having two sets * of debug calls ... */ #undef DBG#undef VDBG#undef ERROR#undef INFO #define xprintk(d, level, fmt, args...) \	printk(level "%s: " fmt , (d)->net->name , ## args) #ifdef DEBUG#undef DEBUG#define DBG(dev, fmt, args...) \	xprintk(dev , KERN_DEBUG , fmt , ## args)#else#define DBG(dev, fmt, args...) \	do { } while (0)#endif /* DEBUG */ #ifdef VERBOSE_DEBUG#define VDBG	DBG#else#define VDBG(dev, fmt, args...) \	do { } while (0)#endif /* DEBUG */ #define ERROR(dev, fmt, args...) \	xprintk(dev , KERN_ERR , fmt , ## args)#define INFO(dev, fmt, args...) \	xprintk(dev , KERN_INFO , fmt , ## args) /*-------------------------------------------------------------------------*/ /* NETWORK DRIVER HOOKUP (to the layer above this driver) */ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p){	struct eth_dev *dev = netdev_priv(net); 	strlcpy(p->driver, "g_ether", sizeof(p->driver));	strlcpy(p->version, UETH__VERSION, sizeof(p->version));	strlcpy(p->fw_version, dev->gadget->name, sizeof(p->fw_version));	strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof(p->bus_info));} /* REVISIT can also support: *   - WOL (by tracking suspends and issuing remote wakeup) *   - msglevel (implies updated messaging) *   - ... probably more ethtool ops */ static const struct ethtool_ops ops = {	.get_drvinfo = eth_get_drvinfo,	.get_link = ethtool_op_get_link,}; static void defer_kevent(struct eth_dev *dev, int flag){	if (test_and_set_bit(flag, &dev->todo))		return;	if (!schedule_work(&dev->work))		ERROR(dev, "kevent %d may have been dropped\n", flag);	else		DBG(dev, "kevent %d scheduled\n", flag);} static void rx_complete(struct usb_ep *ep, struct usb_request *req); static intrx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags){	struct usb_gadget *g = dev->gadget;	struct sk_buff	*skb;	int		retval = -ENOMEM;	size_t		size = 0;	struct usb_ep	*out;	unsigned long	flags; 	spin_lock_irqsave(&dev->lock, flags);	if (dev->port_usb)		out = dev->port_usb->out_ep;	else		out = NULL;	spin_unlock_irqrestore(&dev->lock, flags); 	if (!out)		return -ENOTCONN;  	/* Padding up to RX_EXTRA handles minor disagreements with host.	 * Normally we use the USB "terminate on short read" convention;	 * so allow up to (N*maxpacket), since that memory is normally	 * already allocated.  Some hardware doesn't deal well with short	 * reads (e.g. DMA must be N*maxpacket), so for now don't trim a	 * byte off the end (to force hardware errors on overflow).	 *	 * RNDIS uses internal framing, and explicitly allows senders to	 * pad to end-of-packet.  That's potentially nice for speed, but	 * means receivers can't recover lost synch on their own (because	 * new packets don't only start after a short RX).	 */	size += sizeof(struct ethhdr) + dev->net->mtu + RX_EXTRA;	size += dev->port_usb->header_len; 	if (g->quirk_ep_out_aligned_size) {		size += out->maxpacket - 1;		size -= size % out->maxpacket;	} 	if (dev->port_usb->is_fixed)		size = max_t(size_t, size, dev->port_usb->fixed_out_len); 	skb = __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags);	if (skb == NULL) {		DBG(dev, "no rx skb\n");		goto enomem;	} 	/* Some platforms perform better when IP packets are aligned,	 * but on at least one, checksumming fails otherwise.  Note:	 * RNDIS headers involve variable numbers of LE32 values.	 */	if (likely(!dev->no_skb_reserve))		skb_reserve(skb, NET_IP_ALIGN); 	req->buf = skb->data;	req->length = size;	req->complete = rx_complete;	req->context = skb; 	retval = usb_ep_queue(out, req, gfp_flags);	if (retval == -ENOMEM)enomem:		defer_kevent(dev, WORK_RX_MEMORY);	if (retval) {		DBG(dev, "rx submit --> %d\n", retval);		if (skb)			dev_kfree_skb_any(skb);		spin_lock_irqsave(&dev->req_lock, flags);		list_add(&req->list, &dev->rx_reqs);		spin_unlock_irqrestore(&dev->req_lock, flags);	}	return retval;} static void rx_complete(struct usb_ep *ep, struct usb_request *req){	struct sk_buff	*skb = req->context, *skb2;	struct eth_dev	*dev = ep->driver_data;	int		status = req->status; 	switch (status) { 	/* normal completion */	case 0:		skb_put(skb, req->actual); 		if (dev->unwrap) {			unsigned long	flags; 			spin_lock_irqsave(&dev->lock, flags);			if (dev->port_usb) {				status = dev->unwrap(dev->port_usb,							skb,							&dev->rx_frames);			} else {				dev_kfree_skb_any(skb);				status = -ENOTCONN;			}			spin_unlock_irqrestore(&dev->lock, flags);		} else {			skb_queue_tail(&dev->rx_frames, skb);		}		skb = NULL; 		skb2 = skb_dequeue(&dev->rx_frames);		while (skb2) {			if (status < 0					|| ETH_HLEN > skb2->len					|| skb2->len > GETHER_MAX_ETH_FRAME_LEN) {				dev->net->stats.rx_errors++;				dev->net->stats.rx_length_errors++;				DBG(dev, "rx length %d\n", skb2->len);				dev_kfree_skb_any(skb2);				goto next_frame;			}			skb2->protocol = eth_type_trans(skb2, dev->net);			dev->net->stats.rx_packets++;			dev->net->stats.rx_bytes += skb2->len; 			/* no buffer copies needed, unless hardware can't			 * use skb buffers.			 */			status = netif_rx(skb2);next_frame:			skb2 = skb_dequeue(&dev->rx_frames);		}		break; 	/* software-driven interface shutdown */	case -ECONNRESET:		/* unlink */	case -ESHUTDOWN:		/* disconnect etc */		VDBG(dev, "rx shutdown, code %d\n", status);		goto quiesce; 	/* for hardware automagic (such as pxa) */	case -ECONNABORTED:		/* endpoint reset */		DBG(dev, "rx %s reset\n", ep->name);		defer_kevent(dev, WORK_RX_MEMORY);quiesce:		dev_kfree_skb_any(skb);		goto clean; 	/* data overrun */	case -EOVERFLOW:		dev->net->stats.rx_over_errors++;		/* FALLTHROUGH */ 	default:		dev->net->stats.rx_errors++;		DBG(dev, "rx status %d\n", status);		break;	} 	if (skb)		dev_kfree_skb_any(skb);	if (!netif_running(dev->net)) {clean:		spin_lock(&dev->req_lock);		list_add(&req->list, &dev->rx_reqs);		spin_unlock(&dev->req_lock);		req = NULL;	}	if (req)		rx_submit(dev, req, GFP_ATOMIC);} static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n){	unsigned		i;	struct usb_request	*req; 	if (!n)		return -ENOMEM; 	/* queue/recycle up to N requests */	i = n;	list_for_each_entry(req, list, list) {		if (i-- == 0)			goto extra;	}	while (i--) {		req = usb_ep_alloc_request(ep, GFP_ATOMIC);		if (!req)			return list_empty(list) ? -ENOMEM : 0;		list_add(&req->list, list);	}	return 0; extra:	/* free extras */	for (;;) {		struct list_head	*next; 		next = req->list.next;		list_del(&req->list);		usb_ep_free_request(ep, req); 		if (next == list)			break; 		req = container_of(next, struct usb_request, list);	}	return 0;} static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n){	int	status; 	spin_lock(&dev->req_lock);	status = prealloc(&dev->tx_reqs, link->in_ep, n);	if (status < 0)		goto fail;	status = prealloc(&dev->rx_reqs, link->out_ep, n);	if (status < 0)		goto fail;	goto done;fail:	DBG(dev, "can't alloc requests\n");done:	spin_unlock(&dev->req_lock);	return status;} static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags){	struct usb_request	*req;	struct usb_request	*tmp;	unsigned long		flags; 	/* fill unused rxq slots with some skb */	spin_lock_irqsave(&dev->req_lock, flags);	list_for_each_entry_safe(req, tmp, &dev->rx_reqs, list) {		list_del_init(&req->list);		spin_unlock_irqrestore(&dev->req_lock, flags); 		if (rx_submit(dev, req, gfp_flags) < 0) {			defer_kevent(dev, WORK_RX_MEMORY);			return;		} 		spin_lock_irqsave(&dev->req_lock, flags);	}	spin_unlock_irqrestore(&dev->req_lock, flags);} static void eth_work(struct work_struct *work){	struct eth_dev	*dev = container_of(work, struct eth_dev, work); 	if (test_and_clear_bit(WORK_RX_MEMORY, &dev->todo)) {		if (netif_running(dev->net))			rx_fill(dev, GFP_KERNEL);	} 	if (dev->todo)		DBG(dev, "work done, flags = 0x%lx\n", dev->todo);} static void tx_complete(struct usb_ep *ep, struct usb_request *req){	struct sk_buff	*skb = req->context;	struct eth_dev	*dev = ep->driver_data; 	switch (req->status) {	default:		dev->net->stats.tx_errors++;		VDBG(dev, "tx err %d\n", req->status);		/* FALLTHROUGH */	case -ECONNRESET:		/* unlink */	case -ESHUTDOWN:		/* disconnect etc */		dev_kfree_skb_any(skb);		break;	case 0:		dev->net->stats.tx_bytes += skb->len;		dev_consume_skb_any(skb);	}	dev->net->stats.tx_packets++; 	spin_lock(&dev->req_lock);	list_add(&req->list, &dev->tx_reqs);	spin_unlock(&dev->req_lock); 	atomic_dec(&dev->tx_qlen);	if (netif_carrier_ok(dev->net))		netif_wake_queue(dev->net);} static inline int is_promisc(u16 cdc_filter){	return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;} static netdev_tx_t eth_start_xmit(struct sk_buff *skb,					struct net_device *net){	struct eth_dev		*dev = netdev_priv(net);	int			length = 0;	int			retval;	struct usb_request	*req = NULL;	unsigned long		flags;	struct usb_ep		*in;	u16			cdc_filter; 	spin_lock_irqsave(&dev->lock, flags);	if (dev->port_usb) {		in = dev->port_usb->in_ep;		cdc_filter = dev->port_usb->cdc_filter;	} else {		in = NULL;		cdc_filter = 0;	}	spin_unlock_irqrestore(&dev->lock, flags); 	if (skb && !in) {		dev_kfree_skb_any(skb);		return NETDEV_TX_OK;	} 	/* apply outgoing CDC or RNDIS filters */

Lines 1–500 of 1179.