📄 net-fd.c
字号:
/* * linux/drivers/usbd/net_fd/net-fd.c - network function driver * * Copyright (c) 2000, 2001, 2002 Lineo * Copyright (c) 2001 Hewlett Packard * * By: * Stuart Lynne <sl@lineo.com>, * Tom Rushworth <tbr@lineo.com>, * Bruce Balden <balden@lineo.com> * * Changes copyright (c) 2003 MontaVista Software, 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <linux/config.h>#include <linux/module.h>#include "../usbd-export.h"#include "../usbd-build.h"#include "../usbd-module.h"MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("USB Device Network Function");USBD_MODULE_INFO ("net_fd 0.1");#include <linux/init.h>#include <linux/kernel.h>#include <linux/list.h>#include <asm/uaccess.h>#include <linux/netdevice.h>#include <linux/skbuff.h>#include <linux/etherdevice.h>#include <net/arp.h>#include <linux/rtnetlink.h>#include <linux/smp_lock.h>#include <linux/ctype.h>#include <linux/timer.h>#include <linux/string.h>#include <linux/atmdev.h>#include <linux/pkt_sched.h>#include <asm/system.h>#include "../usbd.h"#include "../usbd-func.h"#include "../usbd-bus.h"#include "../usbd-inline.h"#include "../usbd-arch.h"#include "crc32.h"#include "../hotplug.h"#include "netproto.h"#define MCCI_ENABLE_CRC 0x03#if !defined (CONFIG_USBD_VENDORID) && !defined(CONFIG_USBD_NET_VENDORID)#error No Vendor ID#endif#if !defined (CONFIG_USBD_PRODUCTID) && !defined(CONFIG_USBD_NET_PRODUCTID)#error No Product ID#endif#if !defined(CONFIG_USBD_NET_ALWAYSUP)#define CONFIG_USBD_NET_ALWAYSUP 0;#endif#if defined(CONFIG_USBD_NET_VENDORID) && (CONFIG_USBD_NET_VENDORID > 0)#undef CONFIG_USBD_VENDORID#define CONFIG_USBD_VENDORID CONFIG_USBD_NET_VENDORID#endif#if defined(CONFIG_USBD_NET_PRODUCTID) && (CONFIG_USBD_NET_PRODUCTID > 0)#undef CONFIG_USBD_PRODUCTID#define CONFIG_USBD_PRODUCTID CONFIG_USBD_NET_PRODUCTID#endif#ifndef CONFIG_USBD_NET_LOCAL_OUI#define CONFIG_USBD_NET_LOCAL_OUI 0x400001 //#warning Setting default MAC LOCAL_OUI#endif#ifndef CONFIG_USBD_NET_REMOTE_OUI#define CONFIG_USBD_NET_REMOTE_OUI 0x400002 //#warning Setting default MAC REMOTE_OUI#endif#ifndef CONFIG_USBD_NET_LOCAL_MACADDR#define CONFIG_USBD_NET_LOCAL_MACADDR "400001000001" //#warning Setting default Local MAC Address#endif#ifndef CONFIG_USBD_NET_REMOTE_MACADDR#define CONFIG_USBD_NET_REMOTE_MACADDR "400002000001" //#warning Setting default Remote MAC Address#endif#ifndef CONFIG_USBD_MAXPOWER#define CONFIG_USBD_MAXPOWER 0#endif#ifndef CONFIG_USBD_MANUFACTURER#define CONFIG_USBD_MANUFACTURER "Lineo"#endif#define MAXTRANSFER 1514#ifndef CONFIG_USBD_VENDORID#error "CONFIG_USBD_VENDORID not defined"#endif#ifndef CONFIG_USBD_PRODUCTID#error "CONFIG_USBD_PRODUCTID not defined"#endif#ifndef CONFIG_USBD_NET_IFNAME#define CONFIG_USBD_NET_IFNAME "usbd"#endif#ifndef CONFIG_USBD_PRODUCT_NAME#ifndef CONFIG_USBD_NET_CDC#define CONFIG_USBD_PRODUCT_NAME "CDC Network Driver"#else#define CONFIG_USBD_PRODUCT_NAME "Linux Network Driver"#endif#endif#ifndef CONFIG_USBD_SERIAL_NUMBER_STR#define CONFIG_USBD_SERIAL_NUMBER_STR ""#endif/* * USB 2.0 spec does not mention it, but MaxPower is expected to be at least one * and is tested for in USB configuration tests. */#ifdef CONFIG_USBD_SELFPOWERED#define BMATTRIBUTE BMATTRIBUTE_RESERVED | BMATTRIBUTE_SELF_POWERED#define BMAXPOWER 1#else#define BMATTRIBUTE BMATTRIBUTE_RESERVED#define BMAXPOWER CONFIG_USBD_MAXPOWER#endif/* * setup some default values for pktsizes and endpoint addresses. */#ifndef CONFIG_USBD_NET_OUT_PKTSIZE#define CONFIG_USBD_NET_OUT_PKTSIZE 64#endif#ifndef CONFIG_USBD_NET_IN_PKTSIZE#define CONFIG_USBD_NET_IN_PKTSIZE 64#endif#ifndef CONFIG_USBD_NET_INT_PKTSIZE#define CONFIG_USBD_NET_INT_PKTSIZE 16#endif#ifndef CONFIG_USBD_NET_OUT_ENDPOINT#define CONFIG_USBD_NET_OUT_ENDPOINT 1#endif#ifndef CONFIG_USBD_NET_IN_ENDPOINT#define CONFIG_USBD_NET_IN_ENDPOINT 2#endif#ifndef CONFIG_USBD_NET_INT_ENDPOINT#define CONFIG_USBD_NET_INT_ENDPOINT 3#endif/* * check for architecture specific endpoint configurations */#if defined(ABS_OUT_ADDR) //#warning //#warning USING ABS ENDPOINT OUT ADDRESS #undef CONFIG_USBD_NET_OUT_ENDPOINT #if ABS_OUT_ADDR > 0 #define CONFIG_USBD_NET_OUT_ENDPOINT ABS_OUT_ADDR #endif#elif defined(MAX_OUT_ADDR) && defined(CONFIG_USBD_NET_OUT_ENDPOINT) && (CONFIG_USBD_NET_OUT_ENDPOINT > MAX_OUT_ADDR) //#warning //#warning USING DEFAULT ENDPOINT OUT ADDRESS #undef CONFIG_USBD_NET_OUT_ENDPOINT #define CONFIG_USBD_NET_OUT_ENDPOINT DFL_OUT_ADDR#endif /* elif */#if defined(ABS_IN_ADDR) //#warning //#warning USING ABS ENDPOINT IN ADDRESS #undef CONFIG_USBD_NET_IN_ENDPOINT #if ABS_IN_ADDR > 0 #define CONFIG_USBD_NET_IN_ENDPOINT ABS_IN_ADDR #endif#elif defined(MAX_IN_ADDR) && defined(CONFIG_USBD_NET_IN_ENDPOINT) && (CONFIG_USBD_NET_IN_ENDPOINT > MAX_IN_ADDR) //#warning //#warning USING DEFAULT ENDPOINT IN ADDRESS #undef CONFIG_USBD_NET_IN_ENDPOINT #define CONFIG_USBD_NET_IN_ENDPOINT DFL_IN_ADDR#endif /* elif */#if defined(ABS_INT_ADDR) //#warning //#warning USING ABS ENDPOINT INT ADDRESS #undef CONFIG_USBD_NET_INT_ENDPOINT #if ABS_INT_ADDR #define CONFIG_USBD_NET_INT_ENDPOINT ABS_INT_ADDR #endif#elif defined(MAX_INT_ADDR) && defined(CONFIG_USBD_NET_INT_ENDPOINT) && (CONFIG_USBD_NET_INT_ENDPOINT > MAX_INT_ADDR) //#warning //#warning USING DEFAULT ENDPOINT INT ADDRESS #undef CONFIG_USBD_NET_INT_ENDPOINT #define CONFIG_USBD_NET_INT_ENDPOINT DFL_INT_ADDR#endif /* elif */#if defined(MAX_OUT_PKTSIZE) && defined(CONFIG_USBD_NET_OUT_PKTSIZE) && CONFIG_USBD_NET_OUT_PKTSIZE > MAX_OUT_PKTSIZE //#warning //#warning OVERIDING ENDPOINT OUT PKTSIZE #undef CONFIG_USBD_NET_OUT_PKTSIZE #define CONFIG_USBD_NET_OUT_PKTSIZE MAX_OUT_PKTSIZE#endif#if defined(MAX_IN_PKTSIZE) && defined(CONFIG_USBD_NET_IN_PKTSIZE) && CONFIG_USBD_NET_IN_PKTSIZE > MAX_IN_PKTSIZE //#warning //#warning OVERIDING ENDPOINT IN PKTSIZE #undef CONFIG_USBD_NET_IN_PKTSIZE #define CONFIG_USBD_NET_IN_PKTSIZE MAX_IN_PKTSIZE#endif#if defined(MAX_INT_PKTSIZE) && defined(CONFIG_USBD_NET_INT_PKTSIZE) && CONFIG_USBD_NET_INT_PKTSIZE > MAX_INT_PKTSIZE //#warning //#warning OVERIDING ENDPOINT INT PKTSIZE #undef CONFIG_USBD_NET_INT_PKTSIZE #define CONFIG_USBD_NET_INT_PKTSIZE MAX_INT_PKTSIZE#endif/* Module Parameters ************************************************************************* */#define MAX_INTERFACES 1static char *if_name = CONFIG_USBD_NET_IFNAME;#if defined(CONFIG_USBD_NET_CDC) || defined(CONFIG_USBD_NET_MDLM)static char *remote_mac_address;#endifstatic char *local_mac_address;static char *dbg = NULL;#if defined(CONFIG_USBD_NET_CDC) || defined(CONFIG_USBD_NET_MDLM)static char remote_mac_address_buffer[14];#endifstatic u32 vendor_id;static u32 product_id;static int alwaysup = CONFIG_USBD_NET_ALWAYSUP;static int out_pkt_sz = CONFIG_USBD_NET_OUT_PKTSIZE;static int in_pkt_sz = CONFIG_USBD_NET_IN_PKTSIZE;MODULE_PARM (if_name, "s");#if defined(CONFIG_USBD_NET_CDC) || defined(CONFIG_USBD_NET_MDLM)MODULE_PARM (remote_mac_address, "s");#endifMODULE_PARM (local_mac_address, "s");MODULE_PARM (vendor_id, "i");MODULE_PARM (product_id, "i");MODULE_PARM (alwaysup, "i");MODULE_PARM (out_pkt_sz, "i");MODULE_PARM (in_pkt_sz, "i");MODULE_PARM (dbg, "s");MODULE_PARM_DESC (if_name, "Network Interface name prefix");#if defined(CONFIG_USBD_NET_CDC) || defined(CONFIG_USBD_NET_MDLM)MODULE_PARM_DESC (remote_mac_address, "Remote MAC");#endifMODULE_PARM_DESC (local_mac_address, "Local MAC");MODULE_PARM_DESC (vendor_id, "vendor id");MODULE_PARM_DESC (product_id, "product id");MODULE_PARM_DESC (alwaysup, "always up");MODULE_PARM_DESC (dbg, "dbg string");/* Debug switches (module parameter "dbg=...") *********************************************** */extern int dbgflg_usbdfd_init;int dbgflg_usbdfd_usbe;int dbgflg_usbdfd_rx;int dbgflg_usbdfd_tx;int dbgflg_usbdfd_ep0;static debug_option dbg_table[] = { {&dbgflg_usbdfd_init, NULL, "init", "initialization and termination"}, {&dbgflg_usbdfd_ep0, NULL, "ep0", "End Point 0 (setup) packet handling"}, {&dbgflg_usbdfd_rx, NULL, "rx", "USB RX (host->device) handling"}, {&dbgflg_usbdfd_tx, NULL, "tx", "USB TX (device->host) handling"}, {&dbgflg_usbdfd_usbe, NULL, "usbe", "USB events"}, {NULL, NULL, "net", "network device handling"}, {NULL, NULL, NULL, NULL},};#define dbg_init(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_init,lvl,fmt,##args)#define dbg_ep0(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_ep0,lvl,fmt,##args)#define dbg_rx(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_rx,lvl,fmt,##args)#define dbg_tx(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_tx,lvl,fmt,##args)#define dbg_usbe(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_usbe,lvl,fmt,##args)#define NET_INUSE 0x01#define NET_ATTACHED 0x02struct usb_net_private { int flags; int interface; struct usb_device_instance *device; int crc; unsigned int maxtransfer; char name[IFNAMSIZ]; int index;#ifdef CONFIG_ARCH_SA1100 int first;#endif};static struct usb_net_private net_private_array[MAX_INTERFACES];static rwlock_t net_rwlock = RW_LOCK_UNLOCKED; // lock for netproto device array access#define RXECHO#define TXECHOtypedef enum net_device_event { NET_UNKOWN, // net - unknown NET_SET_CRC, // net - vendor command} net_device_event_t;static __devinitdata unsigned char default_dev_addr[ETH_ALEN] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x01};/* proc file system ********************************************************************** */static void net_device_check_condition(usb_device_event_t event);/* USB Configuration Description ************************************************************* */#if !defined(CONFIG_USBD_NET_SAFE) && !defined(CONFIG_USBD_NET_CDC) && !defined(CONFIG_USBD_NET_MDLM) #error One of CONFIG_USBD_NET_{SAFE,CDC,MDLM} must be set#endif#if defined(CONFIG_USBD_NET_MDLM) && defined(CONFIG_USBD_NET_SAFE) #error Only one of CONFIG_USBD_NET_SAFE or CONFIG_USBD_NET_MDLM can be set#endif#if defined(CONFIG_USBD_NET_MDLM) && defined(CONFIG_USBD_NET_CDC) #error One of CONFIG_USBD_NET_CDC or CONFIG_USBD_NET_MDLM can be set#endif/* USB Safe Configuration ******************************************************************** */#ifdef CONFIG_USBD_NET_SAFE/* * Simple Ethernet Configuration *//* Communication Interface Class descriptions */static __devinitdata struct usb_endpoint_description net_default[] = { {bEndpointAddress:CONFIG_USBD_NET_OUT_ENDPOINT, bmAttributes:BULK, wMaxPacketSize:CONFIG_USBD_NET_OUT_PKTSIZE, bInterval:0, direction:OUT, transferSize:MAXTRANSFER + 4,}, {bEndpointAddress:CONFIG_USBD_NET_IN_ENDPOINT, bmAttributes:BULK, wMaxPacketSize:CONFIG_USBD_NET_IN_PKTSIZE, bInterval:0, direction:IN, transferSize:MAXTRANSFER + 4,},#if defined(CONFIG_USBD_NET_INT_ENDPOINT) && (CONFIG_USBD_NET_INT_ENDPOINT > 0) {bEndpointAddress:CONFIG_USBD_NET_INT_ENDPOINT, bmAttributes:INTERRUPT, wMaxPacketSize:CONFIG_USBD_NET_INT_PKTSIZE, bInterval:10, direction:IN, transferSize:CONFIG_USBD_NET_INT_PKTSIZE,},#endif};/* Data Interface Alternate description(s) */static __devinitdata struct usb_alternate_description net_data_alternate_descriptions[] = { { #if defined(CONFIG_USBD_NET_NO_STRINGS) iInterface:"", #else iInterface:"Simple Network Data Interface - Bulk mode", #endif bAlternateSetting:0, endpoints:sizeof (net_default) / sizeof (struct usb_endpoint_description), endpoint_list:net_default,},};/* Interface description(s) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -