📄 usbnet.c
字号:
/* * USB Networking Links * Copyright (C) 2000-2003 by David Brownell <dbrownell@users.sourceforge.net> * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz> * Copyright (C) 2003 David Hollis <dhollis@davehollis.com> * Copyright (c) 2002-2003 TiVo Inc. * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * This is a generic "USB networking" framework that works with several * kinds of full and high speed networking devices: * * + USB host-to-host "network cables", used for IP-over-USB links. * These are often used for Laplink style connectivity products. * - AnchorChip 2720 * - Belkin, eTEK (interops with Win32 drivers) * - GeneSys GL620USB-A * - NetChip 1080 (interoperates with NetChip Win32 drivers) * - Prolific PL-2301/2302 (replaces "plusb" driver) * - KC Technology KC2190 * * + Smart USB devices can support such links directly, using Internet * standard protocols instead of proprietary host-to-device links. * - Linux PDAs like iPaq, Yopy, and Zaurus * - The BLOB boot loader (for diskless booting) * - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers * - Devices using EPSON's sample USB firmware * - CDC-Ethernet class devices, such as many cable modems * * + Adapters to networks such as Ethernet. * - AX8817X based USB 2.0 products * * Links to these devices can be bridged using Linux Ethernet bridging. * With minor exceptions, these all use similar USB framing for network * traffic, but need different protocols for control traffic. * * USB devices can implement their side of this protocol at the cost * of two bulk endpoints; it's not restricted to "cable" applications. * See the SA1110, Zaurus, or EPSON device/client support in this driver; * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or * "g_ether" (in the Linux "gadget" framework) implement that behavior * within devices. * * * CHANGELOG: * * 13-sep-2000 experimental, new * 10-oct-2000 usb_device_id table created. * 28-oct-2000 misc fixes; mostly, discard more TTL-mangled rx packets. * 01-nov-2000 usb_device_id table and probing api update by * Adam J. Richter <adam@yggdrasil.com>. * 18-dec-2000 (db) tx watchdog, "net1080" renaming to "usbnet", device_info * and prolific support, isolate net1080-specific bits, cleanup. * fix unlink_urbs oops in D3 PM resume code path. * * 02-feb-2001 (db) fix tx skb sharing, packet length, match_flags, ... * 08-feb-2001 stubbed in "linuxdev", maybe the SA-1100 folk can use it; * AnchorChips 2720 support (from spec) for testing; * fix bit-ordering problem with ethernet multicast addr * 19-feb-2001 Support for clearing halt conditions. SA1100 UDC support * updates. Oleg Drokin (green@iXcelerator.com) * 25-mar-2001 More SA-1100 updates, including workaround for ip problem * expecting cleared skb->cb and framing change to match latest * handhelds.org version (Oleg). Enable device IDs from the * Win32 Belkin driver; other cleanups (db). * 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various * cleanups for problems not yet seen in the field. (db) * 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices, * from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>; * rx unlinks somehow weren't async; minor cleanup. * 03-nov-2001 Merged GeneSys driver; original code from Jiun-Jie Huang * <huangjj@genesyslogic.com.tw>, updated by Stanislav Brabec * <utx@penguin.cz>. Made framing options (NetChip/GeneSys) * tie mostly to (sub)driver info. Workaround some PL-2302 * chips that seem to reject SET_INTERFACE requests. * * 06-apr-2002 Added ethtool support, based on a patch from Brad Hards. * Level of diagnostics is more configurable; they use device * location (usb_device->devpath) instead of address (2.5). * For tx_fixup, memflags can't be NOIO. * 07-may-2002 Generalize/cleanup keventd support, handling rx stalls (mostly * for USB 2.0 TTs) and memory shortages (potential) too. (db) * Use "locally assigned" IEEE802 address space. (Brad Hards) * 18-oct-2002 Support for Zaurus (Pavel Machek), related cleanup (db). * 14-dec-2002 Remove Zaurus-private crc32 code (Pavel); 2.5 oops fix, * cleanups and stubbed PXA-250 support (db), fix for framing * issues on Z, net1080, and gl620a (Toby Milne) * * 31-mar-2003 Use endpoint descriptors: high speed support, simpler sa1100 * vs pxa25x, and CDC Ethernet. Throttle down log floods on * disconnect; other cleanups. (db) Flush net1080 fifos * after several sequential framing errors. (Johannes Erdfelt) * 22-aug-2003 AX8817X support (Dave Hollis). * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan * (Neil Bortnak) * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell) * *-------------------------------------------------------------------------*/// #define DEBUG // error path messages, extra info// #define VERBOSE // more; success messages#include <linux/config.h>#ifdef CONFIG_USB_DEBUG# define DEBUG#endif#include <linux/module.h>#include <linux/kmod.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/random.h>#include <linux/ethtool.h>#include <linux/workqueue.h>#include <linux/mii.h>#include <asm/uaccess.h>#include <asm/unaligned.h>#include <linux/usb.h>#include <asm/io.h>#include <asm/scatterlist.h>#include <linux/mm.h>#include <linux/dma-mapping.h>#define DRIVER_VERSION "03-Nov-2004"/*-------------------------------------------------------------------------*//* * Nineteen USB 1.1 max size bulk transactions per frame (ms), max. * Several dozen bytes of IPv4 data can fit in two such transactions. * One maximum size Ethernet packet takes twenty four of them. * For high speed, each frame comfortably fits almost 36 max size * Ethernet packets (so queues should be bigger). */#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)// packets are always ethernet inside// ... except they can be bigger (limit of 64K with NetChip framing)#define MIN_PACKET sizeof(struct ethhdr)#define MAX_PACKET 32768// reawaken network queue this soon after stopping; else watchdog barks#define TX_TIMEOUT_JIFFIES (5*HZ)// throttle rx/tx briefly after some faults, so khubd might disconnect()// us (it polls at HZ/4 usually) before we report too many false errors.#define THROTTLE_JIFFIES (HZ/8)// for vendor-specific control operations#define CONTROL_TIMEOUT_MS (500) /* msec */#define CONTROL_TIMEOUT_JIFFIES ((CONTROL_TIMEOUT_MS * HZ)/1000)// between wakeups#define UNLINK_TIMEOUT_MS 3/*-------------------------------------------------------------------------*/// randomly generated ethernet addressstatic u8 node_id [ETH_ALEN];// state we keep for each device we handlestruct usbnet { // housekeeping struct usb_device *udev; struct driver_info *driver_info; wait_queue_head_t *wait; // i/o info: pipes etc unsigned in, out; unsigned maxpacket; struct timer_list delay; // protocol/interface state struct net_device *net; struct net_device_stats stats; int msg_level; unsigned long data [5]; struct mii_if_info mii; // various kinds of pending driver work struct sk_buff_head rxq; struct sk_buff_head txq; struct sk_buff_head done; struct tasklet_struct bh; struct work_struct kevent; unsigned long flags;# define EVENT_TX_HALT 0# define EVENT_RX_HALT 1# define EVENT_RX_MEMORY 2};// device-specific info used by the driverstruct driver_info { char *description; int flags;/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */ #define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); /* cleanup device ... can sleep, but can't fail */ void (*unbind)(struct usbnet *, struct usb_interface *); /* reset device ... can sleep */ int (*reset)(struct usbnet *); /* see if peer is connected ... can sleep */ int (*check_connect)(struct usbnet *); /* fixup rx packet (strip framing) */ int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb); /* fixup tx packet (add framing) */ struct sk_buff *(*tx_fixup)(struct usbnet *dev, struct sk_buff *skb, int flags); // FIXME -- also an interrupt mechanism // useful for at least PL2301/2302 and GL620USB-A // and CDC use them to report 'is it connected' changes /* for new devices, use the descriptor-reading code instead */ int in; /* rx endpoint */ int out; /* tx endpoint */ unsigned long data; /* Misc driver specific data */};// we record the state for each of our queued skbsenum skb_state { illegal = 0, tx_start, tx_done, rx_start, rx_done, rx_cleanup};struct skb_data { // skb->cb is one of these struct urb *urb; struct usbnet *dev; enum skb_state state; size_t length;};static const char driver_name [] = "usbnet";/* use ethtool to change the level for any given device */static int msg_level = 1;module_param (msg_level, int, 0);MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)");#define RUN_CONTEXT (in_irq () ? "in_irq" \ : (in_interrupt () ? "in_interrupt" : "can sleep"))#ifdef DEBUG#define devdbg(usbnet, fmt, arg...) \ printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)#else#define devdbg(usbnet, fmt, arg...) do {} while(0)#endif#define deverr(usbnet, fmt, arg...) \ printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)#define devwarn(usbnet, fmt, arg...) \ printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)#define devinfo(usbnet, fmt, arg...) \ do { if ((usbnet)->msg_level >= 1) \ printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \ } while (0)/*-------------------------------------------------------------------------*/static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);static u32 usbnet_get_link (struct net_device *);static u32 usbnet_get_msglevel (struct net_device *);static void usbnet_set_msglevel (struct net_device *, u32);/* mostly for PDA style devices, which are always connected if present */static int always_connected (struct usbnet *dev){ return 0;}/* handles CDC Ethernet and many other network "bulk data" interfaces */static intget_endpoints (struct usbnet *dev, struct usb_interface *intf){ int tmp; struct usb_host_interface *alt; struct usb_host_endpoint *in, *out; for (tmp = 0; tmp < intf->num_altsetting; tmp++) { unsigned ep; in = out = NULL; alt = intf->altsetting + tmp; /* take the first altsetting with in-bulk + out-bulk; * ignore other endpoints and altsetttings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; e = alt->endpoint + ep; if (e->desc.bmAttributes != USB_ENDPOINT_XFER_BULK) continue; if (e->desc.bEndpointAddress & USB_DIR_IN) { if (!in) in = e; } else { if (!out) out = e; } if (in && out) goto found; } } return -EINVAL;found: if (alt->desc.bAlternateSetting != 0 || !(dev->driver_info->flags & FLAG_NO_SETINT)) { tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); if (tmp < 0) return tmp; } dev->in = usb_rcvbulkpipe (dev->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe (dev->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); return 0;}static void skb_return (struct usbnet *dev, struct sk_buff *skb){ int status; skb->dev = dev->net; skb->protocol = eth_type_trans (skb, dev->net); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len;#ifdef VERBOSE devdbg (dev, "< rx, len %d, type 0x%x", skb->len + sizeof (struct ethhdr), skb->protocol);#endif memset (skb->cb, 0, sizeof (struct skb_data)); status = netif_rx (skb); if (status != NET_RX_SUCCESS) devdbg (dev, "netif_rx status %d", status);}#ifdef CONFIG_USB_ALI_M5632#define HAVE_HARDWARE/*------------------------------------------------------------------------- * * ALi M5632 driver ... does high speed * *-------------------------------------------------------------------------*/static const struct driver_info ali_m5632_info = { .description = "ALi M5632",};#endif#ifdef CONFIG_USB_AN2720#define HAVE_HARDWARE/*------------------------------------------------------------------------- * * AnchorChips 2720 driver ... http://www.cypress.com * * This doesn't seem to have a way to detect whether the peer is * connected, or need any reset handshaking. It's got pretty big * internal buffers (handles most of a frame's worth of data). * Chip data sheets don't describe any vendor control messages. * *-------------------------------------------------------------------------*/static const struct driver_info an2720_info = { .description = "AnchorChips/Cypress 2720", // no reset available! // no check_connect available! .in = 2, .out = 2, // direction distinguishes these};#endif /* CONFIG_USB_AN2720 */#ifdef CONFIG_USB_AX8817X/* ASIX AX8817X based USB 2.0 Ethernet Devices */#define HAVE_HARDWARE#define NEED_MII#include <linux/crc32.h>#define AX_CMD_SET_SW_MII 0x06#define AX_CMD_READ_MII_REG 0x07#define AX_CMD_WRITE_MII_REG 0x08#define AX_CMD_SET_HW_MII 0x0a#define AX_CMD_READ_EEPROM 0x0b#define AX_CMD_WRITE_EEPROM 0x0c#define AX_CMD_WRITE_RX_CTL 0x10#define AX_CMD_READ_IPG012 0x11#define AX_CMD_WRITE_IPG0 0x12#define AX_CMD_WRITE_IPG1 0x13#define AX_CMD_WRITE_IPG2 0x14#define AX_CMD_WRITE_MULTI_FILTER 0x16#define AX_CMD_READ_NODE_ID 0x17#define AX_CMD_READ_PHY_ID 0x19#define AX_CMD_WRITE_MEDIUM_MODE 0x1b#define AX_CMD_READ_MONITOR_MODE 0x1c#define AX_CMD_WRITE_MONITOR_MODE 0x1d#define AX_CMD_WRITE_GPIOS 0x1f#define AX_MONITOR_MODE 0x01#define AX_MONITOR_LINK 0x02#define AX_MONITOR_MAGIC 0x04#define AX_MONITOR_HSFS 0x10#define AX_MCAST_FILTER_SIZE 8#define AX_MAX_MCAST 64#define AX_INTERRUPT_BUFSIZE 8/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */struct ax8817x_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; struct urb *int_urb; u8 *int_buf;};static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data){ return usb_control_msg( dev->udev, usb_rcvctrlpipe(dev->udev, 0), cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -