📄 dm9kend.c
字号:
#include "vxWorks.h"#include "wdLib.h"#include "stdlib.h"#include "taskLib.h"#include "lstLib.h" /* Needed to maintain protocol list. */#include "logLib.h"#include "intLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "iv.h"#include "memLib.h"#include "semLib.h"#include "cacheLib.h"#include "sys/ioctl.h"//#include "at91rm9200.h"//#include "lib_AT91RM9200.h" /* added */#ifndef DOC /* don't include when building documentation */#include "net/mbuf.h"#endif /* DOC */#include "net/protosw.h"#include "sys/socket.h"#include "errno.h"#include "net/if.h"#include "net/route.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/if_ether.h"#include "net/if_subr.h"#include "m2Lib.h"#include "miiLib.h"#include "etherMultiLib.h" /* multicast stuff. */#include "end.h" /* Common END structures. */#include "netBufLib.h"#include "muxLib.h"#ifdef WR_IPV6#include "adv_net.h"#endif /*WR_IPV6*/#undef END_MACROS#include "endLib.h"#include "logLib.h"#include "drv/end/dm9kEnd.h"/* local defines */#define DRV_DEBUG /* temporary should be taken out */#undef DRV_DEBUG/* define the various levels of debugging if the DRV_DEBUG is defined */ #ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_INT 0x0004#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0008#define DRV_DEBUG_POLL_TX 0x0010#define DRV_DEBUG_LOAD 0x0020#define DRV_DEBUG_LOAD2 0x0040#define DRV_DEBUG_IOCTL 0x0080#define DRV_DEBUG_RESET 0x0100#define DRV_DEBUG_MCAST 0x0200#define DRV_DEBUG_CSR 0x0400#define DRV_DEBUG_RX_PKT 0x0800#define DRV_DEBUG_POLL_REDIR 0x10000#define DRV_DEBUG_LOG_NVRAM 0x20000#define DRV_DEBUG_MII 0x40000#define DRV_DEBUG_ALL 0xfffff#endif /* DRV_DEBUG */unsigned char dm9kEnetAddr [6] ={0x00, 0x01, 0x02, 0x03, 0x04, 0x05};/* * Default macro definitions for BSP interface. * These macros can be redefined in a wrapper file, to generate * a new module with an optimized interface. *//* Macro to connect interrupt handler to vector */#ifndef SYS_INT_CONNECT FUNCPTR dm9kIntConnectRtn = intConnect;#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ *pResult = (*dm9kIntConnectRtn) ((VOIDFUNCPTR *) \ INUM_TO_IVEC (pDrvCtrl->ivec), rtn, (int)arg); \ } while (0)#endif/* Macro to disconnect interrupt handler from vector */#ifndef SYS_INT_DISCONNECT STATUS (*dm9kIntDisconnectRtn) \ (int level, FUNCPTR rtn, int arg) = NULL;#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \ do { \ *pResult = OK; \ } while (0)#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDrvCtrl) \ { \ IMPORT STATUS intEnable(); \ intEnable (pDrvCtrl->ilevel); \ }#endif /* SYS_INT_ENABLE*//* Macro to disable the appropriate interrupt level */#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDrvCtrl) \ { \ IMPORT STATUS intDisable (); \ intDisable (pDrvCtrl->ilevel); \ }#endif /* SYS_INT_DISABLE */#ifndef SYS_WB_FLUSH#define SYS_WB_FLUSH() \ { \ IMPORT void sysWbFlush (void); \ sysWbFlush(); \ }#endif/* SYS_WB_FLUSH *//* 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 END_FLAGS_ISSET(pEnd, setBits) \ ((pEnd)->flags & (setBits))/* externs *//*IMPORT int endMultiLstCnt (END_OBJ *);*/#ifdef DRV_DEBUG /* if debugging driver */int dm9kDebug = DRV_DEBUG_ALL;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (dm9kDebug & FLG) \ logMsg((char *)X0, (int)X1, (int)X2, (int)X3, (int)X4, \ (int)X5, (int)X6);#define DRV_PRINT(FLG,X) \ if (dm9kDebug & FLG) printf X;#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_DEBUG*//*--------------------* PHY mode*/enum DM9KS_PHY_mode { DM9KS_10MHD = 0, DM9KS_100MHD = 1, DM9KS_10MFD = 4, DM9KS_100MFD = 5, DM9KS_AUTO = 8, };static int media_mode = DM9KS_100MFD;dm9kPS_TdDescriptor tableList;/* forward static functions *//* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS dm9kFuncTable = { (FUNCPTR) dm9kStart, /* Function to start the device. */ (FUNCPTR) dm9kStop, /* Function to stop the device. */ (FUNCPTR) dm9kUnload, /* Unloading function for the driver. */ (FUNCPTR) dm9kIoctl, /* Ioctl function for the driver. */ (FUNCPTR) dm9kSend, /* Send function for the driver. */ (FUNCPTR) dm9kMCastAddrAdd, /* Multicast address add */ (FUNCPTR) dm9kMCastAddrDel, /* Multicast address delete */ (FUNCPTR) dm9kMCastAddrGet, /* Multicast table retrieve */ (FUNCPTR) dm9kPollSend, /* Polling send function */ (FUNCPTR) dm9kPollReceive, /* Polling receive function */ endEtherAddressForm, /* Put address info into a packet. */ endEtherPacketDataGet, /* Get a pointer to packet data. */ endEtherPacketAddrGet /* Get packet addresses. */ };//DM9K_DRV_CTRL DrvCtrl;/******************************************************************************** dm9kEndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>, which* expects a string of the following format:** <unit>:<devMemAddr>:<devIoAddr>:<enableAddr>:<vecNum>:<intLvl>:<offset>* :<qtyCluster>:<flags>** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "dm9k") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ * dm9kEndLoad ( char * initString, /* string to be parse by the driver */ void * unused ) { DM9K_DRV_CTRL * pDrvCtrl; pDrvCtrl= (DM9K_DRV_CTRL *)calloc(sizeof(DM9K_DRV_CTRL),1); if (pDrvCtrl == NULL) { DRV_LOG(DRV_DEBUG_LOAD,"dm9kEndLoad Error: Failed to allocate DM9K_DRV_CTRL\n",1,2,3,4,5,6); return (NULL); } DRV_LOG (DRV_DEBUG_LOAD, "Loading dm9k...debug @ 0X%X\n", (int)&dm9kDebug, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString [0] == NULL) { bcopy ((char *)DM9K_DEV_NAME, initString, DM9K_DEV_NAME_LEN); DRV_LOG (DRV_DEBUG_LOAD, "Returning string...\n", 1, 2, 3, 4, 5, 6); return ((END_OBJ *)OK); } if (pDrvCtrl == NULL) goto errorExit; DRV_LOG (0, "DrvControl : 0x%X\n", (int)pDrvCtrl, 2, 3, 4, 5, 6); /* parse the init string, filling in the device structure */ if (dm9kInitParse (pDrvCtrl, initString) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Parse failed ...\n", 1, 2, 3, 4, 5, 6); goto errorExit; } DRV_LOG (DRV_DEBUG_LOAD, "pDrvCtrl->devAdrs is 0x%x ...\n", pDrvCtrl->devAdrs, 2, 3, 4, 5, 6); /* Have the BSP hand us our address. */ dm9kEnetAddrGet (pDrvCtrl, &(pDrvCtrl->enetAddr [0])); /* initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, DM9K_DEV_NAME, pDrvCtrl->unit, &dm9kFuncTable, "DM9000") == ERROR) goto errorExit; if ( END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, DM9K_SPEED) == ERROR) goto errorExit; DRV_LOG (DRV_DEBUG_LOAD, "END init done ...\n", 1, 2, 3, 4, 5, 6); /* Allocate PHY structure */ /* Perform memory allocation */ if (dm9kMemInit (pDrvCtrl) == ERROR) goto errorExit; DRV_LOG (DRV_DEBUG_LOAD, "Malloc done ...\n", 1, 2, 3, 4, 5, 6); END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_PROMISC); dm9kReset(pDrvCtrl); /* Perform memory distribution and reset and reconfigure the device */ dm9kConfig(pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "Restart setup done ...\n", 1, 2, 3, 4, 5, 6); /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_PROMISC); DRV_LOG (DRV_DEBUG_LOAD, "Done loading dm9k...\n", 1, 2, 3, 4, 5, 6); return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return ((END_OBJ *)NULL); }/******************************************************************************** dm9kEnetAddrGet - get enet address** NOMANUAL*/LOCAL void dm9kEnetAddrGet ( DM9K_DRV_CTRL* pDrvCtrl, UINT8 * pAddress ) { int i; /* get the enet addr from the BSP. */ for (i = 0; i < 6; i++) { pDrvCtrl->enetAddr[i] = dm9kEnetAddr[i]; } return;}/********************************************************************************* dm9kInitParse - parse the initialization string** Parse the input string. This routine is called from dm9kEndLoad() which* intializes some values in the driver control structure with the values* passed in the intialization string.** The initialization string format is:* <unit>:<devMemAddr>:<devIoAddr>:<vecNum>:<intLvl>:<offset>:<flags>** .IP <unit>* Device unit number, a small integer.* .IP <devMemAddr>* Device register base memory address* .IP <devIoAddr>* I/O register base memory address* .IP <enableAddr>* Address of MAC enable register* .IP <vecNum>* Interrupt vector number.* .IP <intLvl>* Interrupt level.* .IP <offset>* Offset of starting of data in the device buffers.* .IP <qtyCluster>* Number of clusters to allocate* .IP <flags>* Device specific flags, for future use.** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS dm9kInitParse ( DM9K_DRV_CTRL * pDrvCtrl, /* pointer to the control structure */ char * initString /* initialization string */ ) { char* tok; char* holder = NULL; DRV_LOG (DRV_DEBUG_LOAD, "Parse starting ...\n", 1, 2, 3, 4, 5, 6); /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); /* devAdrs address. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->devAdrs = (UINT32) strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "devAdrs : 0x%x ...\n", pDrvCtrl->devAdrs, 2, 3, 4, 5, 6); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%x ...\n", pDrvCtrl->ivec, 2, 3, 4, 5, 6); /* Interrupt level. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel, 2, 3, 4, 5, 6); /* Caller supplied alignment offset. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->offset = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "Offset : 0x%X ...\n", pDrvCtrl->offset, 2, 3, 4, 5, 6); /* caller supplied flags */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->flags |= strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags, 2, 3, 4, 5, 6); return (OK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -