📄 usbklsiend.c
字号:
/* usbKlsiEnd.c - USB Ethernet driver for the KLSI USB-Ethernet adapter *//* Copyright 2000-2001 Wind river systems, Inc *//*Modification history--------------------01g,15oct01,wef fix SPR 70953 - fixes man page generation and 70716 - fixes coding convention and some warnings01f,08aug01,dat Removing warnings01e,01aug31,wef fixed man page generation comments01d,03may01,wef moved ATTACH_CALLBACK typedef to this file from .h 01c,30apr01,wef changed USB_DEV to USB_KLSI_DEV01b,11aug00,bri Dynamic memory allocation for input and output buffers and removal of wrappers for klsiEndStart and klsiEndStop.01a,03may00,bri Created*//*DESCRIPTION This module is the END (Enhanced Network Driver) driver for USB-ethernet adapters built around the Kawasaki-LSI KL5KUSB101 chip for the VxWorks operating system. This device falls under subclass Ethernet Networking Control Model (Clause 3.8.2) of USB Class Definition for Communication Devices (Ver1.1). This driver is designed to be moderately generic for all KLSI devices. To achieve this, the driver load routine requires an input string consisting of some target-specific values. These are described below.As this adapter deviates from the standard specification in some respects, it calls for addition of certain extensions which are required to fulfill the requirements of the hot-plugging USB environment. EXTERNAL INTERFACEThere are only two external interfaces usbKlsiEndInit() and klsiEndLoad() in this driver. usbKlsiEndInit() is called before the muxLoad() calls sysEndLoad(), to register with USBD. sysEndLoad() function calls klsiEndLoad(). klsiEndLoad() function expects a <initString> parameter as input which describes some target specific parameters. This parameter is passed in a colon-delimited string of the format:<initString>"unit : vendorId : productId : noOfInBfrs : noOfIrps"The klsiEndLoad() function uses strtok() to parse the string. TARGET-SPECIFIC PARAMETERS\is \i <unit>A convenient holdover from the former model. This parameter is used only in the string as name of the driver \i <vendorId>This is a vendorId for the target device supplied by the manufacturer. \i <productId>This is a productId for the target device supplied by the manufacturer. \i <noOfInBfrs>Tells the driver no of input buffers to be allocated for usage. \i <noOfIrps>Tells the driver no of output IRPs to be allocated for usage.\ie DEVICE FUNCTIONALITY The KLSI USB to ethernet adapter chip contains an USB serial interface,ethernet MAC and embedded microcontroller (called the QT Engine).The chip must have firmware loaded into it before it can operate.The KLSI Chip supports 4 End Points. The first is the default end point, which is of control type. The Second and the Third are BULK IN and BULK OUT end points respectively for transferring the data into the Host and from the Host. The Fourth End Point is an Interrupt end point that is currently not used.This device supports one configuration, which contains One Interface. This interface contains the 3 end points i.e. the Bulk IN/OUT and interruptend points. Issuing a SET_CONFIGURATION command will cause the MAC to be reset. Apart from the traditional commands, the device supports as many as 12 vendor specific commands. These commands are described in the device manual. This device even allows the user to change the contents of the EEPROM. Packets are passed between the chip and host via bulk transfers.There is an interrupt endpoint mentioned in the software spec, howeverit is currently unused. This device is 10Mbps half-duplex only, hencethere is no media selection logic. The MAC supports a 128 entry multicast filter, though the exact size of the filter can depend on the firmware. Curiously, while the software specification describes various ethernet statistics counters, this adapter and firmware combination claims not to support any statistics counters at all.The device supports the following (vendor specific )commands :\is \i USB_REQ_KLSI_ETHDESC_GET Retrieves the Ethernet functional descriptor from the device.\i USB_REQ_KLSI_SET_MCAST_FILTER Sets the ethernet device multicast filters as specified in the sequential list if 48 bit addresses ethernet multicastaddresses.\i USB_REQ_KLSI_SET_PACKET_FILTER This Sets the Ethernet packet filter settings.\i USB_REQ_KLSI_GET_STATS Retrieves the device statistics of the featurerequested.\i USB_REQ_KLSI_GET_AUX_INPUTS Reads four auxiliary input pins from the USB-Ethernet controller chip.\i USB_REQ_KLSI_SET_AUX_OUTPUTS Sets four auxiliary input pins from the USB-Ethernet controller chip.\i USB_REQ_KLSI_SET_TEMP_MAC Obtains the MAC address currently used by the ethernet adapter.\i USB_REQ_KLSI_GET_TEMP_MAC Sets the MAC address to be used by the ethernet adapter.\i USB_REQ_KLSI_SET_URB_SIZE Sets the USB Request Block size to be used by the ethernet adapter.\i USB_REQ_KLSI_SET_SOFS_TO_WAIT Sets the no. of Start of Frames to wait while filling a URB before sending a ZLP.\i USB_REQ_KLSI_SET_EVEN_PACKETS Specific to Win95. Not Applicable.\i USB_REQ_KLSI_SCAN Request to modify the I2C EEPROM on the device at a specified address.\ieDRIVER FUNCTIONALITY The function usbKlsiEndInit() is called at the time of usb system initialization. It registers as a client with the USBD. This function alsoregisters for the dynamic attachment and removal of the USB devices.Ideally the registering should be done for a specific Class ID and a SubclassID. Since the device doesn't support these parameters in the Device descriptor, ALL kinds of devices are registered for. A list of the ethernet devices on USB is maintained in a linked list "klsiDevList". This list is created and maintained using the linked list library provided as a part of the USBD. API calls are provided to find if the device exists in the list, by taking either the device "node ID" or the vendorID and productID as the parameters. klsiAttachCallback(), which is the Callback function registered for the dynamic attachment/removal, will be called if any device is found on the USB or removed from the USB. This function checks if this is duplicate information, by checking if this device already exists in the List. If not, the device descriptor is parsed to obtain the Vendor ID and Product ID. If theVendor ID and Product ID match with KLSI IDs, then the device is added to the list of ethernet devices found on the USB.klsiDevInit() does most of the device structure initialization. This routine checks if the device corresponding to the VendorID and ProductID match to any of the devices in the "List". If matched, a pointer structure on the list will be assigned to one of the device structure parameters. Next, InPut and OutPut end point details are found by parsing through the configuration descriptor and interface descriptor. Once these end point descriptors are found, respective input and output Pipes are created and assigned to the corresponding structure. At this moment device is triggered to reset.This driver is a Polled mode driver. It keeps listening on the input pipe by calling "klsiListenToInput" all the time, from the first time it is called by klsiEndStart(). Pre allocated buffer IRP is submitted. Unless the IRP is cancelled (by klsiEndStop()), it will be submitted again and again.If cancelled, it will again start listening only if klsiEndStart() is called.If there is data (IRP successful), then it will be passed on to upper layer bycalling klsiEndRecv().Rest of the functionality of the driver is straight forward and most ofthe places is achieved by sending a vendor specific command from the listdescribed above, to the device.INCLUDE FILES:end.h endLib.h lstLib.h etherMultiLib.h usbPlatform.h usb.h usbListLib.h usbdLib.h usbLib.h usbKlsiEnd.hSEE ALSO:muxLib, endLib, usbLib, usbdLib, ossLib .I "Writing and Enhanced Network Driver" and.I "USB Developer's Kit User's Guide"*//* includes */#include "vxWorks.h"#include "stdlib.h"#include "stdio.h"#include "string.h"#include "cacheLib.h"#include "intLib.h"#include "end.h" /* Common END structures. */#include "endLib.h"#include "lstLib.h" /* Needed to maintain protocol list */#include "wdLib.h"#include "iv.h"#include "semLib.h"#include "etherLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "sysLib.h"#include "errno.h"#include "errnoLib.h"#include "memLib.h"#include "iosLib.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h" /* multicast stuff. */#include "net/mbuf.h"#include "net/unixLib.h"#include "net/protosw.h"#include "net/systm.h"#include "net/if_subr.h"#include "net/route.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "sys/times.h"#include "usb/usbPlatform.h"#include "usb/ossLib.h" /* operations system services */#include "usb/usb.h" /* general USB definitions */#include "usb/usbListLib.h" /* linked list functions */#include "usb/usbdLib.h" /* USBD interface */#include "usb/usbLib.h" /* USB utility functions */#include "drv/usb/usbKlsiEnd.h"/* defines *//* for debugging */#define KLSI_DBG#ifdef KLSI_DBG#define KLSI_DBG_OFF 0x0000#define KLSI_DBG_RX 0x0001#define KLSI_DBG_TX 0x0002#define KLSI_DBG_MCAST 0x0004#define KLSI_DBG_ATTACH 0x0008#define KLSI_DBG_INIT 0x0010#define KLSI_DBG_START 0x0020#define KLSI_DBG_STOP 0x0040#define KLSI_DBG_RESET 0x0080#define KLSI_DBG_MAC 0x0100#define KLSI_DBG_POLL_RX 0x0200#define KLSI_DBG_POLL_TX 0x0400#define KLSI_DBG_LOAD 0x0800#define KLSI_DBG_IOCTL 0x1000#define KLSI_DBG_DNLD 0x2000int klsiDebug = (0x0000); #define KLSI_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (klsiDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#define KLSI_PRINT(FLG,X) \ if (klsiDebug & FLG) printf X;#else /*KLSI_DBG*/#define KLSI_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)#define KLSI_PRINT(DBG_SW,X)#endif /*KLSI_DBG*/#if (CPU == PPC604) #undef CACHE_PIPE_FLUSH() #define CACHE_PIPE_FLUSH() vxEieio()#endif#define KLSI_FIRMWARE_BUF 4096#define KLSI_CLIENT_NAME "usb"#define KLSI_BUFSIZ (ETHERMTU + ENET_HDR_REAL_SIZ + 6) #define EH_SIZE (14)#define END_SPEED_10M 10000000 /* 10Mbs */#define KLSI_SPEED END_SPEED_10M#define KLSI_NAME "usb"#define KLSI_NAME_LEN sizeof(KLSI_NAME)+1/* A shortcut for getting the hardware address from the MIB II stuff. */#define END_HADDR(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)#define KLSI_MIN_FBUF (1514) /* min first buffer size *//* typedefs *//* * This will only work if there is only a single unit, for multiple * unit device drivers these should be integrated into the KLSI_DEVICE * structure. */M_CL_CONFIG klsiMclBlkConfig = /* network mbuf configuration table */ { /* no. mBlks no. clBlks memArea memSize ----------- ---------- ------- ------- */ 0, 0, NULL, 0 };CL_DESC klsiClDescTbl [] = /* network cluster pool configuration table */ { /* clusterSize num memArea memSize ----------- ---- ------- ------- */ {ETHERMTU + EH_SIZE + 2, 0, NULL, 0} }; int klsiClDescTblNumEnt = (NELEMENTS(klsiClDescTbl));typedef struct attach_request { LINK reqLink; /* linked list of requests */ USB_KLSI_ATTACH_CALLBACK callback; /* client callback routine */ pVOID callbackArg; /* client callback argument*/ } ATTACH_REQUEST, *pATTACH_REQUEST;/* globals */USBD_CLIENT_HANDLE klsiHandle; /* our USBD client handle *//* Locals *//* Firmware Download details *//* * NOTE: B6/C3 is data header signature * 0xAA/0xBB is data length = total * bytes - 7, 0xCC is type, 0xDD is * interrupt to use. *//* * klsiNewCode */static UINT8 klsiNewCode[] = { 0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD, 0x9f, 0xcf, 0xbc, 0x08, 0xe7, 0x57, 0x00, 0x00, 0x9a, 0x08, 0x97, 0xc1, 0xe7, 0x67, 0xff, 0x1f,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -