cs8900aEnd.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:53k
源码类别:

VxWorks

开发平台:

Objective-C

  1. /* cs8900aEnd.c - cs8900a Enhanced Network Driver (END) */
  2. /*
  3. DESCRIPTION
  4. TODO - Describe the chip being used completely, even if it provides more
  5. features than ethernet.
  6. TODO - Describe the device's full ethernet capabilities, even if this driver
  7. doesn't or can't utilize all of them.  Describe the features that the driver
  8. does implement and any restrictions on their use.
  9. TODO - Describe all macros that can be used to customize this driver.  All
  10. accesses to chip registers should be done through redefineable macros.
  11. In this example driver the macros cs8900a_OUT_SHORT and cs8900a_IN_SHORT
  12. are sample macros to read/write data to a mock device.  If a device
  13. communicates through formatted control blocks in shared memory, the
  14. accesses to those control blocks should also be through redefinable
  15. macros.
  16. TODO - The following information describes the procedure an end user would
  17. follow to integrate this new END device into a new BSP.  The procedure 
  18. needs to be well documented.
  19. This driver is easily customized for a BSP by modifying global pointers
  20. to routines.  The routine pointers are declared below.  The code below
  21. indicates the default values for each routine as well.  By modifying
  22. these global pointer values, the BSP can change the behaviour of the driver.
  23. .CS
  24.     IMPORT STATUS (*cs8900aIntConnectRtn)(int level, FUNCTPR pFunc, int arg);
  25.     IMPORT STATUS (*cs8900aIntDisconnectRtn)(int level, FUNCTPR pFunc, int arg);
  26.     IMPORT STATUS (*cs8900aIntEnableRtn) (int level);
  27.     IMPORT STATUS (*cs8900aEnetAddrGetRtn)(int unit, char *pResult);
  28.     IMPORT STATUS (*cs8900aOutShortRtn)(UINT addr, UINT value);
  29.     IMPORT STATUS (*cs8900aInShortRtn)(UINT addr, USHORT *pData);
  30.     
  31.     cs8900aIntConnectRtn = intConnect; /@ must not be NULL @/
  32.     cs8900aIntDisconnectRtn = NULL;
  33.     cs8900aIntEnableRtn = NULL;
  34.     cs8900aEndAddrGetRtn = NULL;
  35.     cs8900aOutShortRtn = NULL;
  36.     cs8900aInShortRtn = NULL;
  37. .CE
  38. Excecpt for cs8900aIntConnectRtn and cs8900aIntEnableRtn, a NULL value
  39. will result in the driver taking a default action.  For the int disconnect
  40. function the default action is to do nothing at all.  For the short in and out
  41. routines, the default is to assume memory mapped device registers and to
  42. access them directly.  The default ethernet address get routine
  43. provides an invalid ethernet address of all zeros (0:0:0:0:0:0).
  44. If the BSP is willing to accept these default values no action at all
  45. is needed.  To change the default value, the BSP should create an appropriate
  46. routine and set the address into the global value before first use.  This
  47. would normally be done at function sysHwInit2() time.
  48. For Tornado 3.0 you need to pay attention to virtual physical address
  49. translations which are important.  Use the cache lib macros to to
  50. proper VIRT_TO_PHYS translation as part of generating the physical DMA
  51. address for the device.  Avoid the use of PHYS_TO_VIRT translation as
  52. it can be very time consuming.  If at all possible, the driver should
  53. cache the virtual address of each data buffer used for DMA.
  54. Prior to VxWorks AE 1.1, the muxLib function muxDevUnload() did a free
  55. of the actual END_OBJ structure that was malloc'd during the driver
  56. load routine.  Starting with VxWorks AE 1.1, this behaviour can be
  57. changed.  If the second argument to END_OBJ_INIT points to the END_OBJ
  58. then muxLib will free it during muxDevUnload.  If not, then muxDevUnload
  59. will not free the allocated space.  Under this situation, it is assumed
  60. that the driver unload routine has free'd the space itself.  This preserves
  61. backward compatibility with older drivers that always specified the second
  62. argument to END_OBJ_INIT() as a pointer to the END_OBJ structure.  This
  63. cs8900a has been changed to use the new behaviour instead.
  64. INCLUDES:
  65. end.h endLib.h etherMultiLib.h
  66. SEE ALSO: muxLib, endLib
  67. .I "Writing and Enhanced Network Driver"
  68. */
  69. /* includes */
  70. #include "vxWorks.h"
  71. #include "stdlib.h"
  72. #include "cacheLib.h"
  73. #include "intLib.h"
  74. #include "end.h" /* Common END structures. */
  75. #include "endLib.h"
  76. #include "lstLib.h" /* Needed to maintain protocol list. */
  77. #include "iv.h"
  78. #include "semLib.h"
  79. #include "logLib.h"
  80. #include "netLib.h"
  81. #include "stdio.h"
  82. #include "sysLib.h"
  83. #include "errno.h"
  84. #include "errnoLib.h"
  85. #include "memLib.h"
  86. #include "iosLib.h"
  87. #undef ETHER_MAP_IP_MULTICAST
  88. #include "etherMultiLib.h" /* multicast stuff. */
  89. #include "net/mbuf.h"
  90. #include "net/unixLib.h"
  91. #include "net/protosw.h"
  92. #include "net/systm.h"
  93. #include "net/if_subr.h"
  94. #include "net/route.h"
  95. #include "netinet/if_ether.h"
  96. #include "sys/socket.h"
  97. #include "sys/ioctl.h"
  98. #include "sys/times.h"
  99. #include "string.h"
  100. /* addition. */
  101. #include "cs8900a.h"
  102. #include "s3c2410x.h"
  103. /* Maximum number of CS8900 chips */
  104. #define MAXUNITS    1
  105. /* read one byte from I/O space */
  106. #ifndef CS_IN_BYTE
  107. #define CS_IN_BYTE(reg,pAddr) (*(pAddr) = *((volatile UCHAR*)(reg)))
  108. #endif /*CS_IN_BYTE*/
  109. /* read a short (16bits) from I/O */
  110. #ifndef CS_IN_WORD
  111. #define CS_IN_WORD(reg,pAddr) (*((volatile USHORT*)(pAddr))) = *((volatile USHORT*)(reg)))
  112. #endif /*CS_IN_WORD*/
  113. /* write a short to I/O space */
  114. #ifndef CS_OUT_WORD
  115. #define CS_OUT_WORD(reg,data) (*((volatile USHORT*)(reg)) = data)
  116. #endif /*CS_OUT_WORD*/
  117. /* enable interrupt level */
  118. #ifndef CS_INT_ENABLE
  119. #define CS_INT_ENABLE(level,pResult) (*pResult = intEnable(level))
  120. #endif /*CS_INT_ENABLE*/
  121. /* connect routine to intr. vector */
  122. #ifndef CS_INT_CONNECT
  123. #define CS_INT_CONNECT(ivec,rtn,arg,pResult) (*pResult = intConnect(ivec,rtn,arg))
  124. #endif /*CS_INT_CONNECT*/
  125. IMPORT int endMultiLstCnt (END_OBJ* pEnd);
  126. /* defines */
  127. #define DRV_NAME "cs"
  128. #define DRV_NAME_LEN (sizeof(DRV_NAME) + 1)
  129. #define DRV_DESC "Cirrus Logic CS8900A END driver"
  130. #define DRV_DESC_LEN (sizeof(DRV_DESC) + 1)
  131. #define TASK_CS_INT_PRI (54)
  132. /* Configuration items */
  133. #ifndef ETHERMTU
  134. #define ETHERMTU (1500)
  135. #endif
  136. #define END_BUFSIZ (ETHERMTU + SIZEOF_ETHERHEADER + 6)
  137. #define EH_SIZE (14)
  138. #define END_SPEED_10M 10000000 /* 10Mbs */
  139. #define END_SPEED_100M 100000000 /* 100Mbs */
  140. #define END_SPEED END_SPEED_10M
  141. /*
  142.  * Default macro definitions for BSP interface.
  143.  * These macros can be redefined in a wrapper file, to generate
  144.  * a new module with an optimized interface.
  145.  */
  146. /* A shortcut for getting the hardware address from the MIB II stuff. */
  147. #define END_HADDR(pEnd) ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
  148. #define END_HADDR_LEN(pEnd) ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
  149. /* typedefs */
  150. /* mac address mask */
  151. typedef struct struct_mac_address
  152. {
  153. USHORT i_g : 1;
  154. USHORT u_l : 1;
  155. USHORT val15_2 : 14;
  156. UINT val47_16;
  157. }STRUCT_MAC_ADDRESS;
  158. /* The definition of the driver control structure */
  159. typedef struct end_device{
  160. END_OBJ end; /* The class we inherit from. */
  161. int unit; /* unit number */
  162. int ivec; /* interrupt vector */
  163. int ilevel; /* interrupt level */
  164. char* pShMem; /* real ptr to shared memory */
  165. long flags; /* Our local flags. */
  166. USHORT enetAddr[3]; /* ethernet address */
  167. CACHE_FUNCS* pCacheFuncs; /* cache function pointers */
  168. FUNCPTR freeRtn[128]; /* Array of free routines. */
  169. /* struct free_args freeData[128];  Array of free arguments */
  170. /* the free routines. */
  171. CL_POOL_ID pClPoolId; /* cluster pool */
  172. BOOL rxHandling; /* rcv task is scheduled */
  173. /* chip */
  174. USHORT io_addr; /* The io base of the cs8900a. */
  175. UINT mem_addr; /* The mem base of the cs8900a. */
  176. USHORT chip_int_num; /* The cs8900a intrX(0..3) */
  177. USHORT chip_dma_num; /* The cs8900a dmaX(0..2) */
  178. UINT media_type; /* The media type in software. */
  179. BOOL in_memory_mode; /* The flag of mode.(io(false) or memory(true)) */
  180. BOOL resetting;
  181. UINT rx_depth;
  182. UINT max_rx_depth;
  183. UINT max_tx_depth;
  184. UINT loan_count;
  185. STRUCT_MAC_ADDRESS * p_mac_adr;
  186. }END_DEVICE;
  187. typedef struct self_pkg_buf
  188. {
  189. char * p_char;
  190. int len;
  191. }self_pkg_buf, * p_self_pkg_buf;
  192. /*
  193.  * This will only work if there is only a single unit, for multiple
  194.  * unit device drivers these should be integrated into the END_DEVICE
  195.  * structure.
  196.  */
  197. /* -------------------------------- no. mBlks no. clBlks memArea memSize */
  198. /* network mbuf configuration table --------- ---------- ------- ------- */
  199. M_CL_CONFIG cs8900aMclBlkConfig = { 0, 0, NULL, 0};
  200. /* ---------------------------------------- clusterSize num memArea memSize   */
  201. /* network cluster pool configuration table  ----------- --- ------- --------- */
  202. CL_DESC cs8900aClDescTbl [] =  {{ 0, 0, NULL, 0 }};
  203. int cs8900aClDescTblNumEnt = (NELEMENTS(cs8900aClDescTbl));
  204. /* Definitions for the flags field */
  205. #define cs8900a_PROMISCUOUS 0x1
  206. #define cs8900a_POLLING 0x2
  207. #define cs8900a_MIN_FBUF (1536) /* min first buffer size */
  208. /* DEBUG MACROS */
  209. #ifdef DEBUG
  210. #define LOGMSG(x,a,b,c,d,e,f) if(endDebug){logMsg(x,a,b,c,d,e,f);}
  211. #else
  212. #define LOGMSG(x,a,b,c,d,e,f)
  213. #endif /* ENDDEBUG */
  214. #undef DRV_DEBUG
  215. #ifdef DRV_DEBUG
  216. #define DRV_DEBUG_OFF 0x0000
  217. #define DRV_DEBUG_RX 0x0001
  218. #define DRV_DEBUG_TX 0x0002
  219. #define DRV_DEBUG_INT 0x0004
  220. #define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)
  221. #define DRV_DEBUG_POLL_RX 0x0008
  222. #define DRV_DEBUG_POLL_TX 0x0010
  223. #define DRV_DEBUG_LOAD 0x0020
  224. #define DRV_DEBUG_IOCTL 0x0040
  225. #define DRV_DEBUG_POLL_REDIR 0x10000
  226. #define DRV_DEBUG_LOG_NVRAM 0x20000
  227. int cs8900aDebug = 0x00;
  228. int     cs8900aTxInts = 0;
  229. #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) if(cs8900aDebug & FLG)logMsg(X0, X1, X2, X3, X4, X5, X6);
  230. #define DRV_PRINT(FLG,X) if(cs8900aDebug & FLG)printf X;
  231. #else /*DRV_DEBUG*/
  232. #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
  233. #define DRV_PRINT(DBG_SW,X)
  234. #endif /*DRV_DEBUG*/
  235. /* LOCALS */
  236. /* forward static functions */
  237. LOCAL void cs8900aReset(END_DEVICE *pDrvCtrl);
  238. LOCAL void cs8900aRecv(END_DEVICE * pDrvCtrl, char * pNewCluster, int len);
  239. LOCAL void cs8900aConfig(END_DEVICE *pDrvCtrl);
  240. /* END Specific interfaces. */
  241. /* This is the only externally visible interface. */
  242. END_OBJ*  cs8900aLoad(char* initString, void* p_v);
  243. LOCAL STATUS cs8900aStart(END_DEVICE* pDrvCtrl);
  244. LOCAL STATUS cs8900aStop(END_DEVICE* pDrvCtrl);
  245. LOCAL int cs8900aIoctl(END_DEVICE* pDrvCtrl, int cmd, caddr_t data);
  246. LOCAL STATUS cs8900aUnload(END_DEVICE* pDrvCtrl);
  247. LOCAL STATUS cs8900aSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
  248. LOCAL void cs8900aInt(END_DEVICE* pDrvCtrl);
  249. LOCAL STATUS cs8900aMCastAdd(END_DEVICE* pDrvCtrl, char* pAddress);
  250. LOCAL STATUS cs8900aMCastDel(END_DEVICE* pDrvCtrl, char* pAddress);
  251. LOCAL STATUS cs8900aMCastGet(END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);
  252. LOCAL STATUS cs8900aPollStart(END_DEVICE* pDrvCtrl);
  253. LOCAL STATUS cs8900aPollStop(END_DEVICE* pDrvCtrl);
  254. LOCAL STATUS cs8900aPollSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
  255. LOCAL STATUS cs8900aPollRcv(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
  256. LOCAL void cs8900aAddrFilterSet(END_DEVICE *pDrvCtrl);
  257. LOCAL STATUS cs8900aMemInit();
  258. void cs_pp_w(END_DEVICE* pDrvCtrl, USHORT offset, USHORT value);
  259. USHORT cs_pp_r(END_DEVICE* pDrvCtrl, USHORT offset);
  260. void cs_chip_generate_interrupt(END_DEVICE * pDrvCtrl);
  261. int cs_chip_get_rx_miss_num(END_DEVICE * pDrvCtrl);
  262. int cs_chip_get_tx_col_num(END_DEVICE * pDrvCtrl);
  263. STATUS cs_chip_int_disable(END_DEVICE * pDrvCtrl);
  264. STATUS cs_chip_int_enable(END_DEVICE * pDrvCtrl);
  265. STATUS cs_chip_loop_set(END_DEVICE * pDrvCtrl, int val);
  266. void cs_chip_rx_frame_drop(END_DEVICE * pDrvCtrl, int num);
  267. STATUS cs_chip_select_rx_frame_type(END_DEVICE * pDrvCtrl, USHORT type_mask, int val);
  268. STATUS cs_chip_self_reset(END_DEVICE * pDrvCtrl);
  269. STATUS cs_chip_set_full_duplex(END_DEVICE * pDrvCtrl, int val);
  270. STATUS cs_chip_set_link_dep(END_DEVICE * pDrvCtrl, int val);
  271. STATUS cs_chip_set_tx_crc(END_DEVICE * pDrvCtrl, int val);
  272. STATUS cs_chip_to_mem_mode(END_DEVICE * pDrvCtrl, int flag);
  273. STATUS cs_chip_tx_force_terminate(END_DEVICE * pDrvCtrl, int val);
  274. STATUS cs_chip_send_frame(END_DEVICE * pDrvCtrl, USHORT * p_src_buf, int length);
  275. STATUS cs_soft_end_init(END_DEVICE * pDrvCtrl);
  276. int cs8900a_pin_enable(void);
  277. int cs8900a_pin_disable(void);
  278. STATUS cs_chip_event_enable(END_DEVICE * pDrvCtrl);
  279. STATUS mask32_change_bsp(int* dist32, int num, int len, int src);
  280. /*
  281.  * Declare our function table.  This is static across all device
  282.  * instances.
  283.  */
  284. STATUS endEtherPacketDataGet1(void *g,void *h)
  285. {
  286. printf("wowowowon");
  287. }
  288. LOCAL NET_FUNCS cs8900aFuncTable =
  289. {        
  290. (FUNCPTR) cs8900aStart, /* Function to start the device. */
  291. (FUNCPTR) cs8900aStop, /* Function to stop the device. */
  292. (FUNCPTR) cs8900aUnload, /* Unloading function for the driver. */
  293. (FUNCPTR) cs8900aIoctl, /* Ioctl function for the driver. */
  294. (FUNCPTR) cs8900aSend, /* Send function for the driver. */
  295. (FUNCPTR) cs8900aMCastAdd, /* Multicast add function for the driver. */
  296. (FUNCPTR) cs8900aMCastDel, /* Multicast delete function for the driver. */
  297. (FUNCPTR) cs8900aMCastGet, /* Multicast retrieve function for the driver. */
  298. (FUNCPTR) cs8900aPollSend, /* Polling send function */
  299. (FUNCPTR) cs8900aPollRcv, /* Polling receive function */
  300. endEtherAddressForm, /* put address info into a NET_BUFFER */
  301. endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
  302. endEtherPacketAddrGet    /* Get packet addresses. */
  303. };
  304. END_DEVICE * p_end_device;
  305. int display_net_event = 0;
  306. /*
  307.  * cs8900aLoad - initialize the driver and device
  308.  *
  309.  * This routine initializes the driver and the device to the operational state.
  310.  * All of the device specific parameters are passed in the initString.
  311.  *
  312.  * The string contains the target specific parameters like this:
  313.  *
  314.  * "register addr:int vector:int level:shmem addr:shmem size:shmem width"
  315.  *
  316.  * This routine can be called in two modes.  If it is called with an empty but
  317.  * allocated string, it places the name of this device into the <initString>
  318.  * and returns 0.
  319.  *
  320.  * If the string is allocated and not empty, the routine attempts to load
  321.  * the driver using the values specified in the string.
  322.  *
  323.  * RETURNS: An END object pointer, or NULL on error, or 0 and the name of the
  324.  * device if the <initString> was empty.
  325.  */
  326.  
  327.  /*typedef struct    BOOT_PARAMS */
  328.  
  329.  /*{*/
  330.  
  331.  /*char bootDev [BOOT_DEV_LEN];   boot device code */
  332.  
  333.  /*char hostName [BOOT_HOST_LEN];    name of host */
  334.  
  335.  /*char targetName [BOOT_HOST_LEN];   name of target */
  336.  
  337.  /*char ead [BOOT_ADDR_LEN];    ethernet internet addr */
  338.  
  339.  /*char bad [BOOT_ADDR_LEN];    backplane internet addr */
  340.  
  341.  /*char had [BOOT_ADDR_LEN];    host internet addr */
  342.  
  343.  /*char gad [BOOT_ADDR_LEN];    gateway internet addr */
  344.  
  345.  /*char bootFile [BOOT_FILE_LEN];     name of boot file */
  346.  
  347.  /*char startupScript [BOOT_FILE_LEN];   name of startup script file */
  348.  
  349.  /*char usr [BOOT_USR_LEN];    user name */
  350.  
  351.  /*char passwd [BOOT_PASSWORD_LEN]; password */
  352.  
  353.  /*char other [BOOT_OTHER_LEN];  available for applications */
  354.  
  355.  /*int procNum;   processor number */
  356.  
  357.  /*int unitNum;   network device unit number */
  358.  
  359.  /*int flags;     configuration flags */
  360.  
  361.  /*} BOOT_PARAMS;*/
  362.  
  363. END_OBJ* cs8900aLoad
  364. (
  365. char* initString, /* String to be parsed by the driver. */
  366. void* p_v
  367. )
  368. {
  369. END_DEVICE *pDrvCtrl;  
  370. DRV_LOG(DRV_DEBUG_LOAD, "Loading cs8900a...n", 1, 2, 3, 4, 5, 6);
  371. if(initString == NULL)
  372.         {
  373. DRV_LOG(DRV_DEBUG_LOAD, "cs8900aLoad: NULL initStrrn",0,0,0,0,0,0);
  374. return NULL;
  375. }
  376.     
  377. if(initString[0] == EOS)
  378. {
  379. bcopy((char *)DRV_NAME, initString, DRV_NAME_LEN);
  380. return NULL;
  381. }
  382. /* else initString is not blank, pass two ... */
  383. /* allocate the device structure */
  384. pDrvCtrl = (END_DEVICE*)calloc(1,sizeof(END_DEVICE));
  385. if(pDrvCtrl == NULL) goto errorExit;
  386. cs_soft_end_init(pDrvCtrl);
  387. /*
  388.  * initialize the END and MIB2 parts of the structure
  389.  * The M2 element must come from m2Lib.h
  390.  * This cs8900a is set up for a DIX type ethernet device.
  391.  */
  392. if( (END_OBJ_INIT(&pDrvCtrl->end, (DEV_OBJ*)pDrvCtrl, DRV_NAME, pDrvCtrl->unit,
  393. &cs8900aFuncTable,DRV_DESC) == ERROR)
  394. ||
  395. (END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
  396. (UCHAR*)&(pDrvCtrl->enetAddr[0]), 6, ETHERMTU,END_SPEED) == ERROR))
  397. {
  398. goto errorExit;
  399. }
  400. /* Perform memory allocation/distribution */
  401. if(cs8900aMemInit(pDrvCtrl) == ERROR) goto errorExit;
  402. /* reset and reconfigure the device */
  403. cs8900aReset(pDrvCtrl);
  404. cs8900aConfig(pDrvCtrl);
  405. /* set the flags to indicate readiness */
  406. END_OBJ_READY(&pDrvCtrl->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);
  407. DRV_LOG(DRV_DEBUG_LOAD, "Done loading cs8900a...", 1, 2, 3, 4, 5, 6);
  408. p_end_device = pDrvCtrl;
  409. pDrvCtrl->p_mac_adr = (void *)(pDrvCtrl->enetAddr);
  410. return (&(pDrvCtrl->end));
  411. errorExit:
  412. if(pDrvCtrl != NULL) free((char *)pDrvCtrl);
  413. p_end_device = NULL;
  414. return NULL;
  415. }
  416. /*
  417.  * cs8900aMemInit - initialize memory for the chip
  418.  *
  419.  * This routine is highly specific to the device.
  420.  *
  421.  * Design choices available:
  422.  *
  423.  * Use default system buffers, or create device specific buffer pools.
  424.  *
  425.  * Use contiguous buffers for device frame descriptors and the data, or
  426.  * use descriptor buffers separate from the data buffers.
  427.  *
  428.  * Use the same buffering scheme for Rx and Tx, or each side uses it's
  429.  * own buffering scheme.
  430.  *
  431.  * RETURNS: OK or ERROR.
  432.  */
  433. LOCAL STATUS cs8900aMemInit
  434. (
  435. END_DEVICE * pDrvCtrl /* device to be initialized */
  436. )
  437. {
  438. /* Set up an END netPool using netBufLib(1). */
  439. cs8900aMclBlkConfig.mBlkNum  = 128;
  440. cs8900aClDescTbl[0].clNum    = 128;
  441. cs8900aClDescTbl[0].clSize   = 2048;
  442. cs8900aMclBlkConfig.clBlkNum = cs8900aClDescTbl[0].clNum;
  443. /* Calculate the total memory for all the M-Blks and CL-Blks. */
  444. cs8900aMclBlkConfig.memSize = ((cs8900aMclBlkConfig.mBlkNum * (MSIZE + sizeof (long)))
  445.     +  (cs8900aMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))));
  446. /* allocate mbuf/Cluster blocks from normal memory */
  447. cs8900aMclBlkConfig.memArea = (char *)memalign(sizeof(long),cs8900aMclBlkConfig.memSize);
  448. if(cs8900aMclBlkConfig.memArea == NULL)return ERROR;
  449. /* Calculate the memory size of all the clusters. */
  450. cs8900aClDescTbl[0].memSize = (cs8900aClDescTbl[0].clNum * (cs8900aClDescTbl[0].clSize + 8));
  451. /* Allocate the memory for the clusters from cache safe memory. */
  452. cs8900aClDescTbl[0].memArea = (char*)cacheDmaMalloc(cs8900aClDescTbl[0].memSize);
  453. if(cs8900aClDescTbl[0].memArea == NULL)
  454. {
  455. DRV_LOG(DRV_DEBUG_LOAD, "system memory unavailablen", 1, 2, 3, 4, 5, 6);
  456. return ERROR;
  457. }
  458. /* TODO - allocate and initialize any shared memory areas */
  459. if((pDrvCtrl->end.pNetPool = malloc(sizeof(NET_POOL))) == NULL) return ERROR;
  460. /* Initialize the memory pool. */
  461. if(netPoolInit(
  462. pDrvCtrl->end.pNetPool,
  463. &cs8900aMclBlkConfig,
  464. &cs8900aClDescTbl[0],
  465. cs8900aClDescTblNumEnt,
  466. NULL) == ERROR)
  467.         {
  468. DRV_LOG(DRV_DEBUG_LOAD, "Could not init bufferingn", 1, 2, 3, 4, 5, 6);
  469. return ERROR;
  470. }
  471. DRV_LOG(DRV_DEBUG_LOAD, "Memory setup completen", 1, 2, 3, 4, 5, 6);
  472. return OK;
  473. }
  474. /*
  475.  * cs8900aStart - start the device
  476.  *
  477.  * This function calls BSP functions to connect interrupts and start the
  478.  * device running in interrupt mode.
  479.  *
  480.  * RETURNS: OK or ERROR
  481.  *
  482.  */
  483. LOCAL STATUS cs8900aStart
  484. (
  485. END_DEVICE* pDrvCtrl /* device ID */
  486. )
  487. {
  488. /* TODO  - start the device, enabling interrupts */
  489. /* enable pins for net interrupt. */
  490. cs8900a_pin_enable();
  491. /* clear any interrupt. */
  492. while(cs_pp_r(pDrvCtrl, CS_PKTPG_ISQ) != 0);
  493. cs_chip_int_enable(pDrvCtrl);
  494. /* install isr. */
  495. if(intConnect(INUM_TO_IVEC(pDrvCtrl->ivec), cs8900aInt, (int)pDrvCtrl) == ERROR)
  496. {
  497. return ERROR;
  498. }
  499. DRV_LOG(DRV_DEBUG_LOAD, "Interrupt connected.n", 1, 2, 3, 4, 5, 6);
  500. /* enable interrupt. */
  501. intEnable(pDrvCtrl->ilevel);
  502. DRV_LOG(DRV_DEBUG_LOAD, "interrupt enabled.n", 1, 2, 3, 4, 5, 6);
  503. END_FLAGS_SET(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
  504. return OK;
  505. }
  506. /*
  507.  * cs8900aInt - handle controller interrupt
  508.  *
  509.  * This routine is called at interrupt level in response to an interrupt from
  510.  * the controller.
  511.  *
  512.  * RETURNS: N/A.
  513.  */
  514. void cs8900aInt(END_DEVICE * pDrvCtrl)
  515. {
  516. USHORT stat = 0;
  517. int recv_len = 0;
  518. volatile char * p_char = NULL;
  519. /*volatile unsigned int * p_src = (volatile unsigned int *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_FRAME);*/
  520. volatile char * p_src = (char *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_FRAME);
  521. volatile char temp_char1, temp_char2;
  522. int i;
  523. DRV_LOG(DRV_DEBUG_INT, "Got an interrupt!n", 1, 2, 3, 4, 5, 6);
  524.     /*logMsg("cs8900aInt come here!!!n",0,0,0,0,0,0);*/
  525. while(1)
  526. {
  527. /* Read the device status register */
  528. stat = *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_ISQ));
  529. if(stat == 0)
  530. {
  531. break;
  532. }
  533. else
  534. {
  535.     ;
  536. }
  537. switch(stat & CS_REG_NUM_MASK)
  538. {
  539. case CS_REG_NUM_RX_EVENT:
  540. if(CS_RX_EVENT_CRC_ERR & stat)
  541. {
  542. if(display_net_event) printf("recv-data CRC error!n");
  543. cs_chip_rx_frame_drop(pDrvCtrl, 1);
  544. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  545. break;
  546. }
  547. if(CS_RX_EVENT_RUNT & stat)
  548. {
  549. if(display_net_event) printf("error, recv-data too short!n");
  550. cs_chip_rx_frame_drop(pDrvCtrl, 1);
  551. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  552. break;
  553. }
  554. if(CS_RX_EVENT_X_DATA & stat)
  555. {
  556. if(display_net_event) printf("error, recv-data too long!n");
  557. cs_chip_rx_frame_drop(pDrvCtrl, 1);
  558. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  559. break;
  560. }
  561. if(CS_RX_EVENT_RX_OK & stat)
  562. {
  563. pDrvCtrl->rxHandling = TRUE;
  564. p_char = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->end.pNetPool->clTbl[0]);
  565. if(p_char != NULL)
  566. {   
  567.     /*recv_len = *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_LENGTH));*/ 
  568. recv_len = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_LENGTH);
  569. logMsg("recv_len =  %d n",recv_len,0,0,0,0,0);
  570. #if 0
  571.                     for(i = recv_len-2; i < recv_len;i+=2)
  572.                     {
  573.                         logMsg(" 0x%x n",*((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_FRAME + i)),0,0,0,0,0);
  574.                     }
  575.                     logMsg("receive endn",0,0,0,0,0,0);
  576. bcopyBytes((char *)p_src, (char *)(p_char), recv_len);
  577. #endif
  578. /* The chip is ready for transmission now */
  579. /* Copy the frame to the chip to start transmission */
  580. #if 1
  581. for(i = 0; i < recv_len; i+=2)
  582. {
  583.     *((USHORT *)p_char+(i+2)/2) = *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_FRAME + i));
  584. /*printf(" : 0x%x",p_src_buf[count/2]);*/
  585. }
  586.  
  587. #endif
  588. //recv_len += 2;
  589. }
  590.  /*netJobAdd ((FUNCPTR)cs8900aRecv, (int)pDrvCtrl, (int)p_char,recv_len,0,0);*/ 
  591. netJobAdd ((FUNCPTR)cs8900aRecv, (END_DEVICE *)pDrvCtrl, (char*)p_char,recv_len,0,0);
  592. }
  593. break;
  594. case CS_REG_NUM_TX_EVENT:
  595. if(CS_TX_EVENT_JABBER & stat);
  596. if(CS_TX_EVENT_LOSS_CRS & stat);
  597. if(CS_TX_EVENT_OUT_WIN & stat);
  598. if(CS_TX_EVENT_SQE_ERR & stat);
  599. if(CS_TX_EVENT_TX_OK & stat)
  600. {logMsg("TX_OK!!!n",0,0,0,0,0,0);
  601.              *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  602. if(display_net_event) printf("tx_okn");
  603. }
  604. break;
  605. case CS_REG_NUM_BUF_EVENT:
  606. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  607. break;
  608. case CS_REG_NUM_RX_MISS:
  609. if(display_net_event) printf("Warning, net-rx miss!n");
  610. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  611. break;
  612. case CS_REG_NUM_TX_COL:
  613. if(display_net_event) printf("Warning, net-tx collision!n");
  614. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  615. break;
  616. default:;
  617.     *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  618. }
  619. }
  620. return ;
  621. }
  622. /*
  623.  * cs8900aRecv - process the next incoming packet
  624.  *
  625.  * Handle one incoming packet.  The packet is checked for errors.
  626.  *
  627.  * RETURNS: N/A.
  628.  */
  629. LOCAL void cs8900aRecv
  630. (
  631. END_DEVICE * pDrvCtrl, /* device structure */
  632. char* pNewCluster,
  633. int len
  634. )
  635. {
  636. char * temp_buf = NULL;
  637. int temp_count = 0;
  638. M_BLK_ID pMblk;
  639. CL_BLK_ID pClBlk;
  640. int i = 0;
  641. pDrvCtrl->rxHandling = TRUE;
  642. /* TODO - Packet must be checked for errors. */
  643. END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_UCAST, +1);
  644. /*
  645.  * We implicitly are loaning here, if copying is necessary this
  646.  * step may be skipped, but the data must be copied before being
  647.  * passed up to the protocols.
  648.  */
  649. /* pDrvCtrl->pClPoolId); */
  650. /*logMsg("cs8900aRecv come here!!!n",0,0,0,0,0,0);*/
  651. if(pNewCluster == NULL)
  652.         {
  653. DRV_LOG(DRV_DEBUG_RX, "Cannot loan!n", 1, 2, 3, 4, 5, 6);
  654. END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);
  655. goto cleanRXD;
  656.         }
  657. /* Grab a cluster block to marry to the cluster we received. */
  658. if(((pClBlk = netClBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
  659. ||(len <= 0))
  660. {
  661. netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);
  662. DRV_LOG(DRV_DEBUG_RX, "Out of Cluster Blocks!n", 1, 2, 3, 4, 5, 6);
  663. END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);
  664. goto cleanRXD;
  665. }
  666. if((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
  667. {
  668. netClBlkFree(pDrvCtrl->end.pNetPool, pClBlk);
  669. netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);
  670. DRV_LOG(DRV_DEBUG_RX, "Out of M Blocks!n", 1, 2, 3, 4, 5, 6);
  671. END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);
  672. goto cleanRXD;
  673. }
  674. /* Join the cluster to the MBlock */
  675. netClBlkJoin(pClBlk, pNewCluster, len, NULL, 0, 0, 0);
  676. netMblkClJoin(pMblk, pClBlk);
  677. /* TODO - Invalidate any RFD dma buffers */
  678. pMblk->mBlkHdr.mLen = len;
  679. pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  680. pMblk->mBlkPktHdr.len = len;
  681. pMblk->mBlkHdr.mData += 2; //在截取出IP层数据后必须保证mData是字对齐,因为在IP层数据
  682.                            //截取后要进行数据类型的转换,而在这之前可以不要求mData
  683.                            //是字对齐,因为在MAC层数据中,不会进行数据结构类型的转换
  684. #if 0
  685.     printf("begin n");
  686. printf("len = %d n",len);
  687. for(i=0 ; i<len ;i++)
  688. {  
  689.     printf("  0x%x ",*((unsigned char*)pMblk->mBlkHdr.mData+i));
  690. /*printf("  0x%x ",*(pNewCluster+i));*/
  691. }
  692.     printf("n end n");
  693. #endif
  694. DRV_LOG(DRV_DEBUG_RX, "Calling upper layer!n", 1, 2, 3, 4, 5, 6);
  695. /* TODO - Done with processing, clean up and pass it up. */
  696. /* Call the upper layer's receive routine. */
  697. END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
  698. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  699. cleanRXD:
  700. pDrvCtrl->rxHandling = FALSE;
  701. *((volatile unsigned int *)(0x560000A4))=(*((volatile unsigned int *)(0x560000A4)))&(~(1<<9));
  702. return;
  703. }
  704. /*
  705.  * cs8900aSend - the driver send routine
  706.  *
  707.  * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
  708.  * The buffer must already have the addressing information properly installed
  709.  * in it.  This is done by a higher layer.  The last arguments are a free
  710.  * routine to be called when the device is done with the buffer and a pointer
  711.  * to the argument to pass to the free routine.
  712.  *
  713.  * RETURNS: OK, ERROR, or END_ERR_BLOCK.
  714.  */
  715. LOCAL STATUS cs8900aSend
  716. (
  717. END_DEVICE* pDrvCtrl, /* device ptr */
  718. M_BLK_ID pMblk /* data to send */
  719. )
  720. {
  721. static UCHAR p_src_buf[CS_CHIP_FRAME_BUF_SIZE];
  722. int old_level = 0;
  723. int length = 0;
  724. STATUS tx_status = ERROR;
  725.   if(pDrvCtrl->resetting) return END_ERR_BLOCK;
  726. if(!(pDrvCtrl->flags & cs8900a_POLLING))
  727. {
  728. END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER);
  729. }
  730. /* Get data from Mblk to tx buffer. */
  731. length = netMblkToBufCopy(pMblk, (char*)p_src_buf, NULL);
  732. /* lock interrupt. */
  733. if(!(pDrvCtrl->flags & cs8900a_POLLING))
  734. {
  735. old_level = intLock();
  736. }
  737.   /* transmit it. */
  738. tx_status = cs_chip_send_frame(pDrvCtrl, (USHORT *)p_src_buf, length);
  739. /* unlock interrupt. */
  740. if(!(pDrvCtrl->flags & cs8900a_POLLING))
  741. {
  742. intUnlock (old_level);
  743. }
  744. if(!(pDrvCtrl->flags & cs8900a_POLLING))
  745. {
  746. END_TX_SEM_GIVE(&pDrvCtrl->end);
  747. }
  748. /* Bump the statistics counters. */
  749. END_ERR_ADD(&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
  750. if(tx_status == ERROR)
  751. {
  752. /* transmit failed. */
  753. return END_ERR_BLOCK;
  754. }
  755. /*
  756.  * Cleanup.  If the driver copied the data from the mblks to a different
  757.  * buffer, then free the mblks now.  Otherwise, free the mblk chain
  758.  * after the device is finished with the TFD.
  759.  */
  760. netMblkClChainFree(pMblk);
  761. return OK;
  762. }
  763. /*
  764.  * cs8900aIoctl - the driver I/O control routine
  765.  *
  766.  * Process an ioctl request.
  767.  *
  768.  * RETURNS: A command specific response, usually OK or ERROR.
  769.  */
  770. LOCAL int cs8900aIoctl
  771. (
  772. END_DEVICE* pDrvCtrl, /* device receiving command */
  773. int cmd, /* ioctl command code */
  774. caddr_t data /* command argument */
  775. )
  776. {
  777. int error = 0;
  778. long value;
  779. switch((unsigned)cmd)
  780. {
  781. case EIOCSADDR: /* set MAC address */
  782. if (data == NULL) return EINVAL;
  783. bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end));
  784. break;
  785. case EIOCGADDR: /* get MAC address */
  786. if(data == NULL) return EINVAL;
  787. bcopy((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end));
  788. break;
  789. case EIOCSFLAGS: /* set (or clear) flags */
  790. value = (long)data;
  791. if(value < 0)
  792. {
  793. value = -value;
  794. value--;
  795. END_FLAGS_CLR(&pDrvCtrl->end, value);
  796. }
  797. else
  798. {
  799. END_FLAGS_SET(&pDrvCtrl->end, value);
  800. }
  801. cs8900aConfig (pDrvCtrl);
  802. break;
  803. case EIOCGFLAGS: /* get flags */
  804. *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
  805. break;
  806. case EIOCPOLLSTART: /* Begin polled operation */
  807. cs8900aPollStart(pDrvCtrl);
  808. break;
  809. case EIOCPOLLSTOP: /* End polled operation */
  810. cs8900aPollStop(pDrvCtrl);
  811. break;
  812. case EIOCGMIB2233:
  813. case EIOCGMIB2: /* return MIB information */
  814. if(data == NULL) return EINVAL;
  815. bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl));
  816. break;
  817. case EIOCGFBUF: /* return minimum First Buffer for chaining */
  818. if(data == NULL) return EINVAL;
  819. *(int *)data = cs8900a_MIN_FBUF;
  820. break;
  821.         case EIOCGHDRLEN:
  822. if(data == NULL) return EINVAL;
  823. *(int *)data = EH_SIZE;
  824. break;
  825. default: /* unknown request */
  826. error = EINVAL;
  827. }
  828. return error;
  829. }
  830. /*
  831.  * cs8900aConfig - reconfigure the interface under us.
  832.  *
  833.  * Reconfigure the interface setting promiscuous mode, and changing the
  834.  * multicast interface list.
  835.  *
  836.  * RETURNS: N/A.
  837.  */
  838. LOCAL void cs8900aConfig
  839. (
  840. END_DEVICE* pDrvCtrl /* device to be re-configured */
  841. )
  842. {
  843. /* Set promiscuous mode if it's asked for. */
  844. if(END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)
  845. {
  846. DRV_LOG(DRV_DEBUG_IOCTL, "Setting promiscuous mode on!n", 1, 2, 3, 4, 5, 6);
  847. }
  848. else
  849. {
  850. DRV_LOG(DRV_DEBUG_IOCTL, "Setting promiscuous mode off!n", 1, 2, 3, 4, 5, 6);
  851. }
  852. /* Set up address filter for multicasting. */
  853. if(END_MULTI_LST_CNT(&pDrvCtrl->end) > 0)
  854. {
  855. cs8900aAddrFilterSet(pDrvCtrl);
  856. }
  857. /* TODO - initialise the hardware according to flags */
  858. cs_pp_w(pDrvCtrl, CS_PKTPG_IO_BASE, pDrvCtrl->io_addr); /* io base. */
  859. cs_pp_w(pDrvCtrl, CS_PKTPG_MEM_BASE, (USHORT)((pDrvCtrl->mem_addr)&0xFFFF)); /* memory base.*/ 
  860. cs_pp_w(pDrvCtrl, CS_PKTPG_MEM_BASE+2, (USHORT)((pDrvCtrl->mem_addr)>>16));
  861. cs_pp_w(pDrvCtrl, CS_PKTPG_INT_NUM, pDrvCtrl->chip_int_num); /* interrupt pin. */
  862. cs_pp_w(pDrvCtrl, CS_PKTPG_DMA_NUM, pDrvCtrl->chip_dma_num); /* Turn off the dma. */
  863. cs_chip_to_mem_mode(pDrvCtrl, 1);
  864. cs_chip_event_enable(pDrvCtrl);
  865. /* receive style. */
  866. cs_pp_w(pDrvCtrl,
  867. CS_PKTPG_RX_CTL,
  868. CS_RX_CTL_RX_OK_A | CS_RX_CTL_ALL_FRAME_A | CS_RX_CTL_BCAST_A | CS_RX_CTL_IND_A);
  869. /* select 10baseT, and turn on rx/tx. */
  870. cs_pp_w(pDrvCtrl,
  871. CS_PKTPG_LINE_CTL,
  872. CS_LINE_CTL_10BASET | CS_LINE_CTL_TX_ON | CS_LINE_CTL_RX_ON);
  873. /* full duplex mode. */
  874. cs_pp_w(pDrvCtrl,
  875. CS_PKTPG_TEST_CTL,
  876. CS_TEST_CTL_FDX | CS_TEST_CTL_DIS_LT);
  877. /* led. */
  878. cs_pp_w(pDrvCtrl, CS_PKTPG_SELF_CTL, 0);
  879. return;
  880. }
  881. /*
  882.  * cs8900aAddrFilterSet - set the address filter for multicast addresses
  883.  *
  884.  * This routine goes through all of the multicast addresses on the list
  885.  * of addresses (added with the endAddrAdd() routine) and sets the
  886.  * device's filter correctly.
  887.  *
  888.  * RETURNS: N/A.
  889.  */
  890. LOCAL void cs8900aAddrFilterSet
  891. (
  892. END_DEVICE* pDrvCtrl /* device to be updated */
  893. )
  894. {
  895. ETHER_MULTI* pCurr;
  896. pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);
  897. while(pCurr != NULL)
  898. {
  899. /* TODO - set up the multicast list */
  900. pCurr = END_MULTI_LST_NEXT(pCurr);
  901. }
  902. /* TODO - update the device filter list */
  903. /* Address Filter Register. */
  904. cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR, pDrvCtrl->enetAddr[0]);
  905. cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR+2, pDrvCtrl->enetAddr[1]);
  906. cs_pp_w(pDrvCtrl, CS_PKTPG_IND_ADDR+4, pDrvCtrl->enetAddr[2]);
  907. }
  908. /*
  909.  * cs8900aPollRcv - routine to receive a packet in polled mode.
  910.  *
  911.  * Polled mode operation takes place without any kernel or other OS
  912.  * services available.  Use extreme care to insure that this code does not
  913.  * call any kernel services.  Polled mode is only for WDB system mode use.
  914.  * Kernel services, semaphores, tasks, etc, are not available during WDB
  915.  * system mode.
  916.  *
  917.  * The WDB agent polls the device constantly looking for new data.  Typically
  918.  * the device has a ring of RFDs to receive incoming packets.  This routine
  919.  * examines the ring for any new data and copies it to the provided mblk.
  920.  * The concern here is to keep the device supplied with empty buffers at all
  921.  * time.
  922.  *
  923.  * RETURNS: OK upon success.  EAGAIN is returned when no packet is available.
  924.  * A return of ERROR indicates a hardware fault or no support for polled mode
  925.  * at all.
  926.  */
  927. LOCAL STATUS cs8900aPollRcv
  928. (
  929. END_DEVICE* pDrvCtrl, /* device to be polled */
  930. M_BLK_ID pMblk /* ptr to buffer */
  931. )
  932. {
  933. USHORT stat = 0;
  934. int len = 0;
  935. int i = 0;
  936. /* Upper layer must provide a valid buffer. */
  937. if((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))
  938. {
  939. return EAGAIN;
  940. }
  941. /* TODO - Invalidate any inbound RFD DMA buffers */
  942. /* TODO - clear any status bits that may be set. */
  943. stat = cs_pp_r(pDrvCtrl, CS_PKTPG_ISQ);
  944. if(!(stat & CS_RX_EVENT_RX_OK)) return EAGAIN;
  945. /* TODO - Check packet and device for errors */
  946. /* Get packet and  length from device buffer/descriptor */
  947. stat = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_STATUS);
  948. if(stat & CS_RX_EVENT_RX_OK)
  949. {
  950. len = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_LENGTH);
  951. /* TODO - Process device packet into net buffer */
  952. /* bcopy(pPacket, pMblk->m_data, len); */
  953. for(i = 0; i < (len / 2); i++)
  954. {
  955. ((USHORT *)(pMblk->m_data+2))[i] = 
  956. cs_pp_r(pDrvCtrl, CS_PKTPG_RX_FRAME + (i * 2));
  957. }
  958.    
  959. pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
  960. pMblk->mBlkHdr.mLen = len+2; /* set the data len */
  961. pMblk->mBlkPktHdr.len = len+2; /* set the total len */
  962. }
  963. /*
  964.  * TODO - Done with this packet, clean up device. If needed
  965.  * setup a new RFD/buffer for incoming packets
  966.  */
  967. return OK;
  968. }
  969. /*
  970.  * cs8900aPollSend - routine to send a packet in polled mode.
  971.  *
  972.  * Polled mode operation takes place without any kernel or other OS
  973.  * services available.  Use extreme care to insure that this code does not
  974.  * call any kernel services.  Polled mode is only for WDB system mode use.
  975.  * Kernel services, semaphores, tasks, etc, are not available during WDB
  976.  * system mode.
  977.  *
  978.  * A typical implementation is to set aside a fixed buffer for polled send
  979.  * operation.  Copy the mblk data to the buffer and pass the fixed buffer
  980.  * to the device.  Performance is not a consideration for polled operations.
  981.  *
  982.  * An alternate implementation is a synchronous one.  The routine accepts
  983.  * user data but does not return until the data has actually been sent.  If an
  984.  * error occurs, the routine returns EAGAIN and the user will retry the request.
  985.  *
  986.  * If the device returns OK, then the data has been sent and the user may free
  987.  * the associated mblk.  The driver never frees the mblk in polled mode.
  988.  * The calling routine will free the mblk upon success.
  989.  *
  990.  * RETURNS: OK upon success.  EAGAIN if device is busy or no resources.
  991.  * A return of ERROR indicates a hardware fault or no support for polled mode
  992.  * at all.
  993.  */
  994. LOCAL STATUS cs8900aPollSend
  995. (
  996. END_DEVICE* pDrvCtrl, /* device to be polled */
  997. M_BLK_ID pMblk /* packet to send */
  998. )
  999. {
  1000. static UCHAR p_src_buf[CS_CHIP_FRAME_BUF_SIZE];
  1001. int length = 0;
  1002. STATUS tx_status = ERROR;
  1003. /* reset? */
  1004.   if(pDrvCtrl->resetting)
  1005. {
  1006. return EAGAIN;
  1007. }
  1008. /* Get data from Mblk to tx buffer. */
  1009. length = netMblkToBufCopy(pMblk, p_src_buf, NULL);
  1010. /* transmit it. */
  1011. tx_status = cs_chip_send_frame(pDrvCtrl, (USHORT *)p_src_buf, length);
  1012. END_ERR_ADD(&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
  1013. if(tx_status == ERROR)
  1014. {
  1015. return EAGAIN;
  1016. }
  1017. netMblkClChainFree(pMblk);
  1018. return OK;
  1019. }
  1020. /*
  1021.  * cs8900aMCastAdd - add a multicast address for the device
  1022.  *
  1023.  * This routine adds a multicast address to whatever the driver
  1024.  * is already listening for.  It then resets the address filter.
  1025.  *
  1026.  * RETURNS: OK or ERROR.
  1027.  */
  1028. LOCAL STATUS cs8900aMCastAdd
  1029. (
  1030. END_DEVICE* pDrvCtrl, /* device pointer */
  1031. char* pAddress /* new address to add */
  1032. )
  1033. {
  1034. int error;
  1035. if((error = etherMultiAdd(&pDrvCtrl->end.multiList, pAddress)) == ENETRESET)
  1036. {
  1037. cs8900aConfig(pDrvCtrl);
  1038. }
  1039. return OK;
  1040. }
  1041. /*
  1042.  * cs8900aMCastDel - delete a multicast address for the device
  1043.  *
  1044.  * This routine removes a multicast address from whatever the driver
  1045.  * is listening for.  It then resets the address filter.
  1046.  *
  1047.  * RETURNS: OK or ERROR.
  1048.  */
  1049. LOCAL STATUS cs8900aMCastDel
  1050. (
  1051. END_DEVICE* pDrvCtrl, /* device pointer */
  1052. char* pAddress /* address to be deleted */
  1053. )
  1054. {
  1055. int error;
  1056. if((error = etherMultiDel(&pDrvCtrl->end.multiList, (char*)pAddress)) == ENETRESET)
  1057. {
  1058. cs8900aConfig(pDrvCtrl);
  1059. }
  1060. return OK;
  1061. }
  1062. /*
  1063.  * cs8900aMCastGet - get the multicast address list for the device
  1064.  *
  1065.  * This routine gets the multicast list of whatever the driver
  1066.  * is already listening for.
  1067.  *
  1068.  * RETURNS: OK or ERROR.
  1069.  */
  1070. LOCAL STATUS cs8900aMCastGet
  1071. (
  1072. END_DEVICE* pDrvCtrl, /* device pointer */
  1073. MULTI_TABLE* pTable /* address table to be filled in */
  1074. )
  1075. {
  1076. return(etherMultiGet(&pDrvCtrl->end.multiList, pTable));
  1077. }
  1078. /*
  1079.  * cs8900aStop - stop the device
  1080.  *
  1081.  * This function calls BSP functions to disconnect interrupts and stop
  1082.  * the device from operating in interrupt mode.
  1083.  *
  1084.  * RETURNS: OK or ERROR.
  1085.  */
  1086. LOCAL STATUS cs8900aStop
  1087. (
  1088. END_DEVICE* pDrvCtrl /* device to be stopped */
  1089. )
  1090. {
  1091. END_FLAGS_CLR(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
  1092. /* TODO - stop/disable the device. */
  1093. if(intDisable(pDrvCtrl->ilevel) == ERROR)
  1094. {
  1095. DRV_LOG(DRV_DEBUG_LOAD, "Could not disconnect interrupt!n", 1, 2, 3, 4, 5, 6);
  1096. return ERROR;
  1097. }
  1098. /* disable the interrupt input pin of cs. */
  1099. cs8900a_pin_disable();
  1100. cs_chip_int_disable(pDrvCtrl);
  1101. return OK;
  1102. }
  1103. /*
  1104.  * cs8900aUnload - unload a driver from the system
  1105.  *
  1106.  * This function first brings down the device, and then frees any
  1107.  * stuff that was allocated by the driver in the load function.
  1108.  *
  1109.  * RETURNS: OK or ERROR.
  1110.  */
  1111. LOCAL STATUS cs8900aUnload
  1112. (
  1113. END_DEVICE* pDrvCtrl /* device to be unloaded */
  1114. )
  1115. {
  1116. if(pDrvCtrl == NULL) return ERROR;
  1117. END_OBJECT_UNLOAD(&pDrvCtrl->end);
  1118. /* stop it. */
  1119. cs8900aStop(pDrvCtrl);
  1120. /* reset it. */
  1121. cs8900aReset(pDrvCtrl);
  1122. /* TODO - Free any special allocated memory */
  1123. if(pDrvCtrl->end.pNetPool)
  1124. {
  1125. netPoolDelete(pDrvCtrl->end.pNetPool);
  1126. free(pDrvCtrl->end.pNetPool);
  1127. pDrvCtrl->end.pNetPool = (NET_POOL_ID)0;
  1128. }
  1129. if(cs8900aClDescTbl[0].memArea)
  1130. {
  1131. free(cs8900aClDescTbl[0].memArea);
  1132. cs8900aClDescTbl[0].memArea = (char *)0;
  1133. }
  1134. if(cs8900aMclBlkConfig.memArea)
  1135. {
  1136. free(cs8900aMclBlkConfig.memArea);
  1137. cs8900aMclBlkConfig.memArea = (char *)0;
  1138. }
  1139. /* New: free the END_OBJ structure allocated during cs8900aLoad() */
  1140. cfree((char *)pDrvCtrl);
  1141. pDrvCtrl = NULL;
  1142. return OK;
  1143. }
  1144. /*
  1145.  * cs8900aPollStart - start polled mode operations
  1146.  *
  1147.  * RETURNS: OK or ERROR.
  1148.  */
  1149. LOCAL STATUS cs8900aPollStart
  1150. (
  1151. END_DEVICE* pDrvCtrl /* device to be polled */
  1152. )
  1153. {
  1154. int oldLevel;
  1155. oldLevel = intLock();          /* disable ints during update */
  1156. /* TODO - turn off interrupts */
  1157. pDrvCtrl->flags |= cs8900a_POLLING;
  1158. intUnlock(oldLevel);   /* now cs8900aInt won't get confused */
  1159. DRV_LOG(DRV_DEBUG_POLL, "STARTEDn", 1, 2, 3, 4, 5, 6);
  1160. cs8900aConfig(pDrvCtrl); /* reconfigure device */
  1161. cs_chip_int_disable(pDrvCtrl);
  1162. return OK;
  1163. }
  1164. /*
  1165.  * cs8900aPollStop - stop polled mode operations
  1166.  *
  1167.  * This function terminates polled mode operation.  The device returns to
  1168.  * interrupt mode.
  1169.  *
  1170.  * The device interrupts are enabled, the current mode flag is switched
  1171.  * to indicate interrupt mode and the device is then reconfigured for
  1172.  * interrupt operation.
  1173.  *
  1174.  * RETURNS: OK or ERROR.
  1175.  */
  1176. LOCAL STATUS cs8900aPollStop
  1177. (
  1178. END_DEVICE* pDrvCtrl /* device to be polled */
  1179. )
  1180. {
  1181. int oldLevel;
  1182. oldLevel = intLock(); /* disable ints during register updates */
  1183. /* TODO - re-enable interrupts */
  1184. pDrvCtrl->flags &= ~cs8900a_POLLING;
  1185. intUnlock(oldLevel);
  1186. cs8900aConfig(pDrvCtrl);
  1187. DRV_LOG(DRV_DEBUG_POLL, "STOPPEDn", 1, 2, 3, 4, 5, 6);
  1188. return OK;
  1189. }
  1190. /*
  1191.  * cs8900aReset - reset device
  1192.  *
  1193.  * RETURNS: N/A.
  1194.  */
  1195. LOCAL void cs8900aReset
  1196. (
  1197. END_DEVICE* pDrvCtrl
  1198. )
  1199. {
  1200. int intState;
  1201. if(pDrvCtrl->unit != 0) return;
  1202. pDrvCtrl->resetting = TRUE;
  1203. /* chip reset. */
  1204. intState = intLock();
  1205. cs_chip_self_reset(pDrvCtrl);
  1206. intUnlock(intState);
  1207. /* TODO - reset all device counters/pointers, etc. */
  1208. cs_soft_end_init(pDrvCtrl);
  1209. pDrvCtrl->resetting = FALSE;
  1210. return;
  1211. }
  1212. /* Addition. */
  1213. /*
  1214.  * cs8900a_pin_enable - Enable the pin for the interrupt of cs8900a.
  1215.  * 
  1216.  * RETURNS: status(int).
  1217.  */
  1218. int cs8900a_pin_enable(void)/*GPGCON EINT9*/
  1219. {
  1220. mask32_change_bsp(
  1221. (int*)0x56000060, /* GPGCON of s3c2410x */
  1222. (int)2, /* start bit0 */
  1223. (int)2, /* change length 2, bit0..1 */
  1224. (int)2 /* Value is 2 for EINT0. */
  1225. );
  1226. mask32_change_bsp(
  1227. (int*)0x5600008C, /* EXTINT0 of s3c2410x */
  1228. (int)4, /* start bit0 */
  1229. (int)3, /* change length 3, bit0..2 */
  1230. (int)4 /* Value is 4, that rise edge triggered for EINT0. */
  1231. /* (int)1  Value is 1, that high level triggered for EINT0. */
  1232. );
  1233. mask32_change_bsp(
  1234. (int*)0x56000068, /* GPFUP of s3c2410x */
  1235. (int)1, /* start bit0 */
  1236. (int)1, /* change length 1, bit0 */
  1237. (int)1 /* Value is 1 for disable EINT0's pull-up. */
  1238. );
  1239. mask32_change_bsp(
  1240. (int*)0x560000A4, /* GPFUP of s3c2410x */
  1241. (int)9, /* start bit0 */
  1242. (int)1, /* change length 1, bit0 */
  1243. (int)0 /* Value is 1 for disable EINT0's pull-up. */
  1244. );
  1245. mask32_change_bsp(
  1246. (int*)0x560000A8, /* GPFUP of s3c2410x */
  1247. (int)9, /* start bit0 */
  1248. (int)1, /* change length 1, bit0 */
  1249. (int)1 /* Value is 1 for disable EINT0's pull-up. */
  1250. );
  1251. #if 0
  1252. mask32_change_bsp(
  1253. (int*)0x4A000008, /* GPFUP of s3c2410x */
  1254. (int)5, /* start bit0 */
  1255. (int)1, /* change length 1, bit0 */
  1256. (int)0 /* Value is 1 for disable EINT0's pull-up. */
  1257. );
  1258. mask32_change_bsp(
  1259. (int*)0x4A000000, /* GPFUP of s3c2410x */
  1260. (int)5, /* start bit0 */
  1261. (int)1, /* change length 1, bit0 */
  1262. (int)1 /* Value is 1 for disable EINT0's pull-up. */
  1263. );
  1264. mask32_change_bsp(
  1265. (int*)0x4A000010, /* GPFUP of s3c2410x */
  1266. (int)5, /* start bit0 */
  1267. (int)1, /* change length 1, bit0 */
  1268. (int)1 /* Value is 1 for disable EINT0's pull-up. */
  1269. );
  1270. #endif
  1271. return 0;
  1272. }
  1273. /*
  1274.  * cs8900a_pin_disable - Disable the pin for the interrupt of cs8900a.
  1275.  * 
  1276.  * RETURNS: status(int).
  1277.  */
  1278. int cs8900a_pin_disable(void)
  1279. {
  1280.     mask32_change_bsp(  
  1281.             (int*)0x56000060,   /* GPFCON of s3c2410x */  
  1282.             (int)2,         /* start bit0 */  
  1283.             (int)2,         /* change length 2, bit0..1 */  
  1284.             (int)0          /* Value is 0 for input. */  
  1285.             );  
  1286.     mask32_change_bsp(  
  1287.             (int*)0x5600008c,   /* EXTINT0 of s3c2410x */  
  1288.             (int)4,         /* start bit0 */  
  1289.             (int)3,         /* change length 3, bit0..2 */  
  1290.             (int)0          /* Value is 4, that low level triggered for EINT0. */  
  1291.             );  
  1292.     return 0;  
  1293. }
  1294. /*
  1295.  * cs_pp_r - reads a word from the PacketPage
  1296.  *
  1297.  * This routine reads a word from the PacketPage at the specified offset.
  1298.  *
  1299.  * RETURNS: a word in the offset
  1300.  */
  1301. USHORT cs_pp_r(END_DEVICE * pDrvCtrl, USHORT offset)
  1302. {
  1303. volatile USHORT temp_ushort = 0;
  1304. if(pDrvCtrl->in_memory_mode == TRUE)
  1305. {
  1306. /* in memory mode */
  1307. temp_ushort = *((volatile USHORT *)((pDrvCtrl->mem_addr) + CS_CHIP_MEM_BASE + offset));
  1308. return temp_ushort;
  1309. }
  1310. else
  1311. {
  1312. /* in io mode */
  1313. *((volatile USHORT *)((pDrvCtrl->io_addr) + CS_CHIP_IO_BASE + CS_PORT_PKTPG_PTR)) = offset;
  1314. temp_ushort = *((volatile USHORT *)((pDrvCtrl->io_addr) + CS_CHIP_IO_BASE + CS_PORT_PKTPG_DATA));
  1315. return temp_ushort;
  1316. }
  1317. }
  1318. /*
  1319.  * cs_pp_w - writes a value to the PacketPage
  1320.  *
  1321.  * This routine writes a value to the PacketPage at the specified offset.
  1322.  *
  1323.  * RETURNS: N/A
  1324.  */
  1325. void cs_pp_w(END_DEVICE * pDrvCtrl, USHORT offset, USHORT value)
  1326. {
  1327. if(pDrvCtrl->in_memory_mode == TRUE)
  1328. {
  1329. /* in memory mode */
  1330. *((volatile USHORT *)((pDrvCtrl->mem_addr) + CS_CHIP_MEM_BASE + offset)) = value;
  1331. }
  1332. else
  1333. {
  1334. /* in io mode */
  1335. *((volatile USHORT *)((pDrvCtrl->io_addr) + CS_CHIP_IO_BASE + CS_PORT_PKTPG_PTR)) = offset;
  1336. *((volatile USHORT *)((pDrvCtrl->io_addr) + CS_CHIP_IO_BASE + CS_PORT_PKTPG_DATA)) = value;
  1337. }
  1338. return;
  1339. }
  1340. /* add by phoenix                         左移位   修改位长 值  */
  1341. STATUS mask32_change_bsp(int* dist32, int num, int len, int src)
  1342. {
  1343. UINT32 tempUINT32;
  1344. tempUINT32 = *dist32;
  1345. if(len <= 0) return ERROR;
  1346. if((num+len) > 32) return ERROR;
  1347. tempUINT32 = ((tempUINT32&(~(((1<<len)-1)<<num)))|((src&((1<<len)-1))<<num));
  1348. *dist32 = tempUINT32;
  1349. return OK;
  1350. }
  1351. /* cs_chip_rx_frame_drop - delete some receive frame. */
  1352. void cs_chip_rx_frame_drop(END_DEVICE * pDrvCtrl, int num)
  1353. {
  1354. while(num--)
  1355. {
  1356. cs_pp_w(pDrvCtrl,CS_PKTPG_RX_CFG,
  1357. ((cs_pp_r(pDrvCtrl,CS_PKTPG_RX_CFG)) | CS_RX_CFG_SKIP));
  1358. }
  1359. return;
  1360. }
  1361. /* cs_generate_interrupt - generate a software interrupt for test. */
  1362. void cs_chip_generate_interrupt(END_DEVICE* pDrvCtrl)
  1363. {
  1364. cs_pp_w(pDrvCtrl,CS_PKTPG_BUF_CFG,
  1365. ((cs_pp_r(pDrvCtrl,CS_PKTPG_BUF_CFG)) | CS_BUF_CFG_SW_INT));
  1366. return;
  1367. }
  1368. /* cs_get_rx_miss_num - get the miss number of receive frames. */
  1369. int cs_chip_get_rx_miss_num(END_DEVICE* pDrvCtrl)
  1370. {
  1371. int temp_int;
  1372. temp_int = cs_pp_r(pDrvCtrl,CS_PKTPG_RX_MISS);
  1373. temp_int = (temp_int >> 6) & 0x03ff;
  1374. return temp_int;
  1375. }
  1376. /* cs_get_tx_col_num - get the collision number of transmit frames. */
  1377. int cs_chip_get_tx_col_num(END_DEVICE* pDrvCtrl)
  1378. {
  1379. int temp_int;
  1380. temp_int = cs_pp_r(pDrvCtrl,CS_PKTPG_TX_COL);
  1381. temp_int = (temp_int >> 6) & 0x03ff;
  1382. return temp_int;
  1383. }
  1384. /* cs_chip_to_mem_mode - set the cs to memory mode. */
  1385. STATUS cs_chip_to_mem_mode(END_DEVICE* pDrvCtrl, int flag)
  1386. {
  1387. pDrvCtrl->in_memory_mode = FALSE;
  1388. if(flag)
  1389. {
  1390. cs_pp_w(pDrvCtrl, CS_PKTPG_BUS_CTL,
  1391. cs_pp_r(pDrvCtrl, CS_PKTPG_BUS_CTL) | CS_BUS_CTL_MEM_MODE);
  1392. pDrvCtrl->in_memory_mode = TRUE;
  1393. }
  1394. else
  1395. {
  1396. cs_pp_w(pDrvCtrl, CS_PKTPG_BUS_CTL,
  1397. cs_pp_r(pDrvCtrl, CS_PKTPG_BUS_CTL) & (~CS_BUS_CTL_MEM_MODE));
  1398. pDrvCtrl->in_memory_mode = FALSE;
  1399. }
  1400. return OK;
  1401. }
  1402. /* cs_chip_self_reset - cs chip reset by software command. */
  1403. STATUS cs_chip_self_reset(END_DEVICE* pDrvCtrl)
  1404. {
  1405. const int reset_time = 5;
  1406. int wait_count = 0; 
  1407. if (cs_pp_r(pDrvCtrl,CS_PKTPG_EISA_NUM) != CS_EISA_NUM_CRYSTAL)
  1408. {
  1409. printf("CS_PKTPG_EISA_NUM Errorn");
  1410. }
  1411. if ((cs_pp_r(pDrvCtrl,CS_PKTPG_PRODUCT_ID) & 0xe0ff)!= 0x0000)
  1412. {
  1413. printf("Product ID Errorn");
  1414. }
  1415. /* do reset. */
  1416. cs_pp_w(pDrvCtrl, CS_PKTPG_SELF_CTL,
  1417. cs_pp_r(pDrvCtrl, CS_PKTPG_SELF_CTL) | CS_SELF_CTL_RESET);
  1418. /* wait for reset finish. */
  1419. while(!(cs_pp_r(pDrvCtrl, CS_PKTPG_SELF_ST) & CS_SELF_ST_INIT_DONE))
  1420. {
  1421. taskDelay(reset_time);
  1422. if((wait_count++) >= CS_MAXLOOP) return ERROR;
  1423. }
  1424. return OK;
  1425. }
  1426. /* cs_chip_int_enable - interrupt enable for cs chip. */
  1427. STATUS cs_chip_int_enable(END_DEVICE * pDrvCtrl)
  1428. {
  1429. /* set the master interrupt enable bit in cs chip. 0x0116 = 0x8017*/
  1430. cs_pp_w(pDrvCtrl,
  1431. CS_PKTPG_BUS_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_BUS_CTL)) | CS_BUS_CTL_INT_ENBL);
  1432. return OK;
  1433. }
  1434. /* cs_chip_event_enable - interrupt enable for cs chip. */
  1435. STATUS cs_chip_event_enable(END_DEVICE * pDrvCtrl)
  1436. {
  1437. /* enable > data, < data, CRC_err, and Rx_OK interrupt. 0x0102 = 0x7103*/
  1438. cs_pp_w(pDrvCtrl,
  1439. CS_PKTPG_RX_CFG, (cs_pp_r(pDrvCtrl, CS_PKTPG_RX_CFG)) | CS_RX_CFG_ALL_IE);
  1440. /* enable all of the tx interrupt. 0x0106 = 0x8fc7*/
  1441. cs_pp_w(pDrvCtrl, CS_PKTPG_TX_CFG, CS_TX_CFG_ALL_IE);
  1442. /* enable Rx miss and Tx underrun interrupt. 0x010a = 0x070b*/
  1443. cs_pp_w(pDrvCtrl, CS_PKTPG_BUF_CFG,
  1444. CS_BUF_CFG_RX_MISS_IE | CS_BUF_CFG_TX_UNDR_IE | CS_BUF_CFG_RDY4TX_IE);
  1445. return OK;
  1446. }
  1447. /* cs_chip_int_disable - interrupt disable for cs chip. */
  1448. STATUS cs_chip_int_disable(END_DEVICE * pDrvCtrl)
  1449. {
  1450. /* clear the master interrupt enable bit in cs chip. */
  1451. cs_pp_w(pDrvCtrl,
  1452. CS_PKTPG_BUS_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_BUS_CTL)) & (~CS_BUS_CTL_INT_ENBL));
  1453. return OK;
  1454. }
  1455. /* cs_chip_event_disable - interrupt disable for cs chip. */
  1456. STATUS cs_chip_event_disable(END_DEVICE * pDrvCtrl)
  1457. {
  1458. /* disable all of Rx interrupt. 0x0102 = ~0x7103*/
  1459. cs_pp_w(pDrvCtrl,
  1460. CS_PKTPG_RX_CFG, (cs_pp_r(pDrvCtrl, CS_PKTPG_RX_CFG)) & (~CS_RX_CFG_ALL_IE));
  1461. /* disable all of Tx interrupt. 0x0106 = 0x0007*/
  1462. cs_pp_w(pDrvCtrl, CS_PKTPG_TX_CFG, 0);
  1463. /* disable buffer interrupt. 0x010a = 0x0013*/
  1464. cs_pp_w(pDrvCtrl, CS_PKTPG_BUF_CFG, 0);
  1465. return OK;
  1466. }
  1467. /* cs_chip_select_rx_frame_type - select the receiver frame type. */
  1468. STATUS cs_chip_select_rx_frame_type(END_DEVICE * pDrvCtrl,USHORT type_mask,int val)
  1469. {
  1470. /* clear this bit. */
  1471. if(val == 0)
  1472. {
  1473. cs_pp_w(pDrvCtrl,
  1474. CS_PKTPG_RX_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_RX_CTL)) & (~type_mask));
  1475. return OK;
  1476. }
  1477. /* set this bit. */
  1478. if(val == 1)
  1479. {
  1480. cs_pp_w(pDrvCtrl,
  1481. CS_PKTPG_RX_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_RX_CTL)) | type_mask);
  1482. return OK;
  1483. }
  1484. return ERROR;
  1485. }
  1486. /* cs_chip_loop_set - on or off cs chip loop. */
  1487. STATUS cs_chip_loop_set(END_DEVICE * pDrvCtrl, int val)
  1488. {
  1489. if(val == 1)
  1490. {
  1491. cs_chip_set_full_duplex(pDrvCtrl, 1);
  1492. cs_pp_w(pDrvCtrl,
  1493. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL))
  1494. | CS_TEST_CTL_ENDEC_LP | CS_TEST_CTL_FDX);
  1495. return OK;
  1496. }
  1497. if(val == 0)
  1498. {
  1499. cs_pp_w(pDrvCtrl,
  1500. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL)) & (~CS_TEST_CTL_ENDEC_LP));
  1501. return OK;
  1502. }
  1503. return ERROR;
  1504. }
  1505. /* cs_chip_set_full_duplex - set cs rx/tx mode to full duplex or half duplex. */
  1506. STATUS cs_chip_set_full_duplex(END_DEVICE * pDrvCtrl, int val)
  1507. {
  1508. if(val == 1)
  1509. {
  1510. cs_pp_w(pDrvCtrl,
  1511. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL)) | CS_TEST_CTL_FDX);
  1512. return OK;
  1513. }
  1514. if(val == 0)
  1515. {
  1516. cs_pp_w(pDrvCtrl,
  1517. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL)) & (~CS_TEST_CTL_FDX));
  1518. return OK;
  1519. }
  1520. return ERROR;
  1521. }
  1522. /* cs_chip_set_link_dep - set cs run depend on link or independ. */
  1523. STATUS cs_chip_set_link_dep(END_DEVICE * pDrvCtrl, int val)
  1524. {
  1525. if(val == 1)
  1526. {
  1527. cs_pp_w(pDrvCtrl,
  1528. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL)) | CS_TEST_CTL_DIS_LT);
  1529. return OK;
  1530. }
  1531. if(val == 0)
  1532. {
  1533. cs_pp_w(pDrvCtrl,
  1534. CS_PKTPG_TEST_CTL, (cs_pp_r(pDrvCtrl, CS_PKTPG_TEST_CTL)) & (~CS_TEST_CTL_DIS_LT));
  1535. return OK;
  1536. }
  1537. return ERROR;
  1538. }
  1539. /* cs_chip_tx_force_terminate - force terminate tx frame for cs chip. */
  1540. STATUS cs_chip_tx_force_terminate(END_DEVICE * pDrvCtrl,int val)
  1541. {
  1542. if(val == 1)
  1543. {
  1544. cs_pp_w(pDrvCtrl,
  1545. CS_PKTPG_TX_CMD, (cs_pp_r(pDrvCtrl, CS_PKTPG_TX_CMD)) | CS_TX_CMD_FORCE);
  1546. return OK;
  1547. }
  1548. if(val == 0)
  1549. {
  1550. cs_pp_w(pDrvCtrl,
  1551. CS_PKTPG_TX_CMD, (cs_pp_r(pDrvCtrl, CS_PKTPG_TX_CMD)) & (~CS_TX_CMD_FORCE));
  1552. return OK;
  1553. }
  1554. return ERROR;
  1555. }
  1556. /* cs_chip_set_tx_crc - on or off tx CRC. */
  1557. STATUS cs_chip_set_tx_crc(END_DEVICE * pDrvCtrl, int val)
  1558. {
  1559. if(val == 0)
  1560. {
  1561. cs_pp_w(pDrvCtrl,
  1562. CS_PKTPG_TX_CMD, (cs_pp_r(pDrvCtrl, CS_PKTPG_TX_CMD)) | CS_TX_CMD_NO_CRC);
  1563. return OK;
  1564. }
  1565. if(val == 1)
  1566. {
  1567. cs_pp_w(pDrvCtrl,
  1568. CS_PKTPG_TX_CMD, (cs_pp_r(pDrvCtrl, CS_PKTPG_TX_CMD)) & (~CS_TX_CMD_NO_CRC));
  1569. return OK;
  1570. }
  1571. return ERROR;
  1572. }
  1573. /* cs_chip_send_frame - send one frame to cs chip. */
  1574. STATUS cs_chip_send_frame(END_DEVICE * pDrvCtrl, USHORT * p_src_buf, int length)
  1575. {
  1576. USHORT bus_status = 0;
  1577. int count = 0;
  1578. int i;
  1579. unsigned char * p_src_buffer = (unsigned char *)p_src_buf;
  1580. if(length > 0)
  1581. {
  1582. /* Request that the transmit be started after all data has been copied */
  1583. *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_TX_CMD)) = CS_TX_CMD_START_ALL+0x9;
  1584. /* TODO - initiate device transmit. */
  1585. *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_TX_LENGTH)) = length;
  1586. /* Read the busStatus register which indicates success of the request */
  1587. bus_status = *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_BUS_ST));
  1588. if((!(bus_status & CS_BUS_ST_TX_BID_ERR)) && (bus_status & CS_BUS_ST_RDY4TXNOW))
  1589. {
  1590.   
  1591.             /* The chip is ready for transmission now */
  1592. /* Copy the frame to the chip to start transmission */
  1593. for(count = 0; count < length; count+=2)
  1594. {
  1595. *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_TX_FRAME + count)) = p_src_buf[count/2];
  1596. }
  1597. /*logMsg("transimite finish!!n",0,0,0,0,0,0);*/
  1598. return OK;
  1599. }
  1600. else
  1601. {
  1602.             logMsg("the chip tx buffer unuse!!n",0,0,0,0,0,0);
  1603. /* the chip tx buffer unuse. */
  1604. if(display_net_event)printf("Error, the tx buffer is invalid!!!n");
  1605. return ERROR;
  1606. }
  1607. }
  1608. else
  1609. {
  1610. /* null frame. */
  1611. if(display_net_event)printf("Error, the length of tx frame less 0!!!n");
  1612. return ERROR;
  1613. }
  1614. }
  1615. /* cs_soft_end_init - initialize the END_DEVICE. */
  1616. STATUS cs_soft_end_init(END_DEVICE * pDrvCtrl)
  1617. {
  1618. pDrvCtrl->chip_dma_num = CS_INIT_DMA_NUM;
  1619. pDrvCtrl->chip_int_num = CS_INIT_INT_NUM;
  1620. pDrvCtrl->ilevel = CS_INIT_VECT;
  1621. pDrvCtrl->ivec = CS_INIT_VECT;
  1622. pDrvCtrl->io_addr = CS_CHIP_IO_OFFSET;
  1623. pDrvCtrl->mem_addr = CS_CHIP_MEM_OFFSET;
  1624.     pDrvCtrl->enetAddr[2] = (USHORT)0x0F66;  
  1625.     pDrvCtrl->enetAddr[1] = (USHORT)0x5544;  
  1626.     pDrvCtrl->enetAddr[0] = (USHORT)0x3322;  
  1627. pDrvCtrl->media_type = CS_MEDIA_10BASET;
  1628. pDrvCtrl->in_memory_mode = FALSE;
  1629. pDrvCtrl->resetting = FALSE;
  1630. return OK;
  1631. }