dec21x4xEnd.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:107k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* dec21x4xEnd.c - END style DEC 21x4x PCI Ethernet network interface driver */
  2. /* Copyright 1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02d,29mar99,dat  SPR 26040, changed BIG_ENDIAN issue
  8. 02c,29mar99,dat  SPR 26119, fixed .bS/.bE calls
  9. 02b,14sep98,kla  modified pci calls for new library. (SPR 24794)
  10. 02a,11sep98,kla  modified from ebsa285 BSP, for pc486 target (SPR 24794)
  11. 01z,13oct98,cn   removed setting CSR6_FD in xxxMediaSelect [SPR# 21683]
  12.  and updated documentation about user flags.
  13. 01y,30sep98,dbt  Adding missing code in poll receive routine.
  14. 01x,22sep98,dat  SPR 22325, system mode transition.
  15. 01w,21apr98,jpd  added call to dec21x4xChipReset in dec21x4xStop().
  16. 01v,17mar98,jgn  fixed problems with this driver on CMA22x cards (SPR #20166)
  17.  (includes start up fix for 21x40 devices on all platforms)
  18. 01u,29jan98,rlp  check interrupt status before acknowledgement (SPR# 9995).
  19.  renamed macro names containing lower case characters.
  20. 01t,08dec97,tam  added _func_dec2114xIntAck.
  21. 01s,30oct97,rlp  added support for dec21143.
  22.                  renamed _func_dec21x40MediaSelect to _func_dec2114xMediaSelect.
  23. 01r,19oct97,vin  moved swapping of loaned buffer before END_RCV_RTN_CALL
  24. 01q,17oct97,vin  removed extra free.
  25. 01p,09oct97,vin  delete unwanted frees in PollSend routine
  26. 01o,07oct97,vin  fixed multicasting, MIB MTU size to ETHER_MTU
  27. 01n,25sep97,gnn  SENS beta feedback fixes
  28. 01m,24sep97,vin  added clBlk related calls
  29. 01l,02sep97,gnn  fixed a race condition in the txRestart handling.
  30. 01k,25aug97,vin  adjusted cluster mem size.
  31. 01j,22aug97,vin  fixed initialization of cluster mem area.
  32. 01i,22aug97,gnn  fixed a bug in polled mode.
  33. 01h,21aug97,vin  added changes for newBuffering API
  34. 01g,12aug97,gnn  changes necessitated by MUX/END update.
  35. 01f,08aug97,map  fixed muxBufInit for user-specified bufpool.
  36.                  added ilevel arg to sysLanIntDisable().
  37.                  update collision statistics.
  38.                  added more flags to userFlags.
  39. 01e,10jun97,map  renamed funcDec21x40MediaSelect to _func_dec21x40MediaSelect.
  40. 01d,28may97,kbw  general text edit
  41.             map  added DEC SROM support for media configuration.
  42. 01c,23apr97,map  cleaned up; replaced SWAP_SHORT with PCISWAP_SHORT.
  43. 01b,16apr97,map  added support for dec21140.
  44. 01a,07apr97,map  modified if_dc.c to END style.
  45. */
  46. /*
  47.   
  48. This module implements a DEC 21x4x PCI Ethernet network interface driver and
  49. supports 21040, 21140 and 21143 versions of the chip.
  50. The DEC 21x4x PCI Ethernet controller is little endian because it interfaces
  51. with a little endian PCI bus.  Although PCI configuration for a device is
  52. handled in the BSP, all other device programming and initialization are handled
  53. in this module.
  54. This driver is designed to be moderately generic. Without modification, it can
  55. operate across the range of architectures and targets supported by VxWorks.
  56. To achieve this, the driver requires a few external support routines as well
  57. as several target-specific parameters.  These parameters, and the mechanisms
  58. used to communicate them to the driver, are detailed below.  If any of the
  59. assumptions stated below are not true for your particular hardware, you need to
  60. modify the driver before it can operate correctly on your hardware.
  61. On 21040, the driver configures the 10BASE-T interface by default, waits for
  62. two seconds, and checks the status of the link. If the link status indicates
  63. failure, AUI interface is configured.
  64. On other versions of the 2114x family, the driver reads media information from
  65. a DEC serial ROM and configures the media. On targets that do not support a
  66. DEC format serial ROM, the driver calls a target-specfic media select routine
  67. using the hook, _func_dec2114xMediaSelect, to configure the media.
  68. The driver supports big-endian or little-endian architectures (as a 
  69. configurable option).  The driver also and contains error recovery code 
  70. that handles known device errata related to DMA activity.
  71. Big endian processors can be connected to the PCI bus through some controllers
  72. which take care of hardware byte swapping. In such cases all the registers
  73. which the chip DMAs to have to be swapped and written to, so that when the
  74. hardware swaps the accesses, the chip would see them correctly. The chip still
  75. has to be programmed to operate in little endian mode as it is on the PCI
  76. bus.  If the cpu board hardware automatically swaps all the accesses to and
  77. from the PCI bus, then input and output byte stream need not be swapped.
  78. BOARD LAYOUT
  79. This device is on-board.  No jumpering diagram is necessary.
  80. EXTERNAL INTERFACE
  81. The driver provides one standard external interface, dec21x4xEndLoad(), which
  82. a takes a string of colon separated parameters. The parameters should be
  83. specified as hexadecimal strings, optionally preceded by "0x" or a minus sign
  84. "-".
  85. Although the parameter string is parsed using strtok_r(), each parameter is
  86. converted from string to binary by a call to strtoul(parameter, NULL, 16).
  87. The format of the parameter string is:
  88.  "<unit number>:<device addr>:<PCI addr>:<ivec>:<ilevel>:<mem base>:
  89. <mem size>:<user flags>:<offset>"
  90. TARGET-SPECIFIC PARAMETERS
  91. .iP "unit number"
  92. This represents the device instance number relative to this driver. 
  93. I.e. a value of zero represents the first dec21x4x device, a value of 1
  94. represents the second dec21x4x device.
  95. .iP "device addr"
  96. This is the base address at which the hardware device registers are located.
  97. .iP "PCI addr"
  98. This parameter defines the main memory address over the PCI bus. It is used to
  99. translate physical memory address into PCI accessible address.
  100. .iP "ivec"
  101. This is the interrupt vector number of the hardware interrupt generated by
  102. this Ethernet device.  The driver uses intConnect, or pciIntConnect (x86 arch),
  103. to attach an interrupt handler for this interrupt.
  104. .iP "ilevel"
  105. This parameter defines the level of the hardware interrupt.
  106. .iP "mem base"
  107. This parameter specifies the base address of a DMA-able, cache free,
  108. pre-allocated memory region for use as a memory pool for transmit/receive
  109. descriptors and buffers.
  110. If there is no pre-allocated memory available for the driver, this parameter
  111. should be -1 (NONE). In which case, the driver allocates cache safe memory
  112. for its use using cacheDmaAlloc().
  113. .iP "mem size"
  114. The memory size parameter specifies the size of the pre-allocated memory
  115. region. If memory base is specified as NONE (-1), the driver ignores this
  116. parameter.
  117. .iP "user flags"
  118. User flags control the run-time characteristics of the Ethernet
  119. chip. Most flags specify non default CSR0 bit values. Refer to
  120. dec21x4xEnd.h for the bit values of the flags, and to the device hardware
  121. reference manual for details about device capabilities, and CSR 0.
  122. Some of them are worth mentioning:
  123. Full Duplex Mode: When set, the DEC_USR_FD flag allows the device to
  124. work in full duplex mode, as long as the PHY used has this
  125. capability. It is worth noting here that in this operation mode,
  126. the dec21x40 chip ignores the Collision and the Carrier Sense signals.
  127.  
  128. Transmit treshold value: The DEC_USR_THR_XXX flags enable the user to
  129. choose among different threshold values for the transmit FIFO.
  130. Transmission starts when the frame size within the transmit FIFO is
  131. larger than the treshold value. This should be selected taking into
  132. account the actual operating speed of the PHY.  Again, see the device
  133. hardware reference manual for details.
  134.  
  135. .iP "offset"
  136. This parameter defines the offset which is used to solve alignment problem.
  137. .iP "Device Type"
  138. Although the default device type is DEC 21040, specifying the DEC_USR_21140
  139. or DEC_USR_21143 flag bit turns on DEC 21140 or DEC_USR_21143 functionality.
  140. .iP "Ethernet Address"
  141. The Ethernet address is retrieved from standard serial ROM on DEC 21040, DEC
  142. 21140 and DEC 21143 devices. If retrieve from ROM fails, the driver calls the
  143. BSP routine, sysDec21x4xEnetAddrGet(). Specifying DEC_USR_XEA flag bit tells
  144. the driver should, by default, retrieve the Ethernet address using
  145. the BSP routine, sysDec21x4xEnetAddrGet().
  146. .iP "Priority RX processing"
  147. The driver programs the chip to process the transmit and receive queues at the
  148. same priority. By specifying DEC_USR_BAR_RX, the device is programmed
  149. to process receives at a higher priority.
  150. .iP "TX poll rate"
  151. By default, the driver sets the Ethernet chip into a non-polling mode. 
  152. In this mode, if the transmit engine is idle, it is kick-started every 
  153. time a packet needs to be transmitted.  Alternately, the chip can be 
  154. programmed to poll for the next available transmit descriptor if 
  155. the transmit engine is in idle state. The poll rate is specified by one 
  156. of DEC_USR_TAP_xxx.
  157. .iP "Cache Alignment"
  158. The DEC_USR_CAL_xxx flags specify the address boundaries for
  159. data burst transfers.
  160. .iP "DMA burst length"    
  161. The DEC_USR_PBL_xxx flags specify the maximum number of long
  162. words in a DMA burst.
  163. .iP "PCI multiple read"
  164. The DEC_USR_RML flag specifies that a device supports PCI
  165. memory-read-multiple.
  166. EXTERNAL SUPPORT REQUIREMENTS
  167. This driver requires four external support functions, and provides a hook
  168. function:
  169. .iP "void sysLanIntEnable (int level)" "" 9 -1
  170. This routine provides a target-specific interface for enabling Ethernet device
  171. interrupts at a specified interrupt level.
  172. .iP "void sysLanIntDisable (void)" "" 9 -1
  173. This routine provides a target-specific interface for disabling Ethernet device
  174. interrupts.
  175. .iP "STATUS sysDec21x4xEnetAddrGet (int unit, char *enetAdrs)" "" 9 -1
  176. This routine provides a target-specific interface for accessing a device
  177. Ethernet address.
  178. .iP "STATUS sysDec21143Init (DRV_CTRL * pDrvCtrl)" "" 9 -1
  179. This routine performs any target-specific initialization
  180. required before the dec21143 device is initialized by the driver.
  181. The driver calls this routine every time it wants to load
  182. the device.  This routine returns OK, or ERROR if it fails.
  183. .iP "FUNCPTR _func_dec2114xMediaSelect" "" 9 -1
  184. This driver provides a default media select routine, when
  185. <_func_dec2114xMediaSelect> is NULL, to read and setup physical media with
  186. configuration information from a Version 3 DEC Serial ROM. Any other media
  187. configuration can be supported by initializing <_func_dec2114xMediaSelect>,
  188. typically in sysHwInit(), to a target-specific media select routine.
  189. A media select routine is typically defined as:
  190. .ne 7
  191. .CS
  192.    STATUS decMediaSelect
  193.        (
  194.        DEC21X4X_DRV_CTRL * pDrvCtrl,   /@ Driver control @/
  195.        UINT * pCsr6Val    /@ CSR6 return value @/
  196.        )
  197.        {
  198.            ...
  199.        }
  200. .CE
  201. Parameter <pDrvCtrl> is a pointer to the driver control structure which this
  202. routine may use to access the Ethenet device. The driver control structure
  203. field mediaCount, is initialized to 0xff at startup, while the other media
  204. control fields (mediaDefault, mediaCurrent, and gprModeVal) are initialized to
  205. zero. This routine may use these fields in any manner, however all other
  206. driver control fields should be considered read-only and should not be
  207. modified.
  208. This routine should reset, initialize and select an appropriate media, and
  209. write necessary the CSR6 bits (port select, PCS, SCR, and full duplex) to
  210. memory location pointed to by <pCsr6Val>. The driver will use this value to
  211. program register CSR6. This routine should return OK, and ERROR on failure.
  212. .iP "FUNCPTR _func_dec2114xIntAck" "" 9 -1
  213. This driver does acknowledge the LAN interrupts. However if the board hardware
  214. requires specific interrupt acknowledgement, not provided by this driver,
  215. the BSP should define such a routine and attach it to the driver via
  216. _func_dec2114xIntAck. 
  217. SEE ALSO: ifLib, 
  218. .I "DECchip 21040 Ethernet LAN Controller for PCI."
  219. .I "Digital Semiconductor 21140A PCI Fast Ethernet LAN Controller."
  220. .I "Digital Semiconductor 21143 PCI/CardBus Fast Ethernet LAN Controller."
  221. .I "Using the Digital Semiconductor 21140A with Boot ROM, Serial ROM, 
  222.     and External Register: An Application Note"
  223. .I "Using the Digital Semiconductor 21143 with Boot ROM, Serial ROM, 
  224.     and External Register: An Application Note"
  225. */
  226. /* includes */
  227. #include "vxWorks.h"
  228. #include "wdLib.h"
  229. #include "iv.h"
  230. #include "vme.h"
  231. #include "errno.h"
  232. #include "memLib.h"
  233. #include "intLib.h"
  234. #include "vxLib.h"
  235. #include "net/mbuf.h"
  236. #include "net/unixLib.h"
  237. #include "net/protosw.h"
  238. #include "sys/socket.h"
  239. #include "sys/ioctl.h"
  240. #include "net/route.h"
  241. #include "iosLib.h"
  242. #include "errnoLib.h"
  243. #include "cacheLib.h"
  244. #include "logLib.h"
  245. #include "netLib.h"
  246. #include "stdio.h"
  247. #include "stdlib.h"
  248. #include "sysLib.h"
  249. #include "etherLib.h"
  250. #include "net/systm.h"
  251. #include "sys/times.h"
  252. #include "net/if_subr.h"
  253. #include "drv/end/dec21x4xEnd.h"
  254. #undef ETHER_MAP_IP_MULTICAST
  255. #include "etherMultiLib.h"
  256. #include "end.h"
  257. #include "endLib.h"
  258. #include "lstLib.h"
  259. #include "semLib.h"
  260. #undef DRV_DEBUG
  261. #undef DRV_DEBUG_LOG
  262. /* defines */
  263. #define LOG_MSG(X0, X1, X2, X3, X4, X5, X6)
  264. if (_func_logMsg != NULL)
  265.     _func_logMsg(X0, X1, X2, X3, X4, X5, X6);
  266. #ifdef DRV_DEBUG_LOG
  267. #define DRV_DEBUG_OFF 0x0000
  268. #define DRV_DEBUG_RX 0x0001
  269. #define DRV_DEBUG_TX 0x0002
  270. #define DRV_DEBUG_INT 0x0004
  271. #define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)
  272. #define DRV_DEBUG_POLL_RX 0x0008
  273. #define DRV_DEBUG_POLL_TX 0x0010
  274. #define DRV_DEBUG_LOAD 0x0020
  275. #define DRV_DEBUG_IOCTL 0x0040
  276. #define DRV_DEBUG_POLL_REDIR 0x10000
  277. #define DRV_DEBUG_LOG_NVRAM 0x20000
  278. int decDebug = 0x60;
  279. #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)                        
  280. if (decDebug & FLG)                                             
  281.             LOG_MSG(X0, X1, X2, X3, X4, X5, X6);
  282. #else /* DRV_DEBUG_LOG */
  283. #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
  284. #endif /* DRV_DEBUG_LOG */
  285. #ifdef  DRV_DEBUG
  286. int     decTxInts=0;
  287.  
  288. IMPORT void decCsrShow (void);
  289. IMPORT void decTxDShow(int numTxD); 
  290. IMPORT void decRxDShow(int numRxD);
  291. IMPORT void decShow(void); 
  292. IMPORT  void eAdrsDisplay(UINT8 * pAddr);
  293. IMPORT void mcAdd (char *eAddr);
  294. IMPORT void mcDel (char *eAddr);
  295. IMPORT void decSerialRomUpload(void);
  296. IMPORT int decReset(void);
  297. #endif /* DRV_DEBUG */
  298. #define END_FLAGS_ISSET(pEnd, setBits)                                  
  299.             ((pEnd)->flags & (setBits))
  300. #define END_HADDR(pEnd)                                                 
  301. ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
  302. #define END_HADDR_LEN(pEnd)                                             
  303. ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
  304. #define DEC_SPEED_10 10000000             /* 10 Mbps */
  305. #define DEC_SPEED_100 100000000            /* 100 Mbps */
  306. #define DEC_SPEED_DEF DEC_SPEED_10
  307. #define EADDR_LEN 6                    /* ethernet address length */
  308. #define DEC_PKT_SIZE (ETHERMTU + ENET_HDR_REAL_SIZ + 6)
  309. #define DELAY(count) {                                               
  310. volatile int cx = 0;                            
  311. for (cx = 0; cx < (count); cx++);               
  312. }
  313. #define LOOPS_PER_NS 4
  314. #define NSDELAY(nsec) {                                               
  315. volatile int nx = 0;                            
  316. volatile int loop = (int)((nsec)*LOOPS_PER_NS); 
  317. for (nx = 0; nx < loop; nx++);                  
  318. }
  319. #define DEC_BUF_ALLOC_ROUTINE                                           
  320. (FUNCPTR) (DRV_FLAGS_ISSET(DEC_MEMOWN) ?                        
  321.                    cacheDmaMalloc : NULL)
  322. #define DEC_BUF_POOL_ADRS                                               
  323. (char *)(DRV_FLAGS_ISSET(DEC_MEMOWN) ?                          
  324.                   NULL:(pDrvCtrl->txRing + pDrvCtrl->numTds))
  325. /* DRV_CTRL flags access macros */
  326. #define DRV_FLAGS_SET(setBits)                                          
  327. (pDrvCtrl->flags |= (setBits))
  328. #define DRV_FLAGS_ISSET(setBits)                                        
  329. (pDrvCtrl->flags & (setBits))
  330. #define DRV_FLAGS_CLR(clrBits)                                          
  331. (pDrvCtrl->flags &= ~(clrBits))
  332. #define DRV_FLAGS_GET()                                                 
  333.         (pDrvCtrl->flags)
  334. /* Cache macros */
  335. #define DEC_CACHE_INVALIDATE(address, len)                              
  336.         CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))
  337. #define DEC_CACHE_VIRT_TO_PHYS(address)                                 
  338.         CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))
  339. #define DEC_CACHE_PHYS_TO_VIRT(address)                                 
  340.         CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))
  341. /* memory to PCI address translation macros */
  342. #define PCI_TO_MEM_PHYS(pciAdrs)                                        
  343. (((ULONG)(pciAdrs)) - (pDrvCtrl->pciMemBase))
  344. #define MEM_TO_PCI_PHYS(memAdrs)                                        
  345. (((ULONG)(memAdrs)) + (pDrvCtrl->pciMemBase))
  346. #define DEC_VIRT_TO_PCI(vAdrs)                                          
  347. MEM_TO_PCI_PHYS (DEC_CACHE_VIRT_TO_PHYS (vAdrs))
  348. #define DEC_PCI_TO_VIRT(pciAdrs)                                        
  349. DEC_CACHE_PHYS_TO_VIRT (PCI_TO_MEM_PHYS (pciAdrs))
  350. /*
  351.  * CSR access macros
  352.  *
  353.  * To optimize CSR accesses, redefine DEC_CSR_READ and
  354.  * DEC_CSR_WRITE macros in a wrapper file.
  355.  */
  356. #ifndef DEC_CSR_READ
  357. #define DEC_CSR_READ(csr)                                               
  358. dec21x4xCsrRead(pDrvCtrl->devAdrs, (csr))
  359. #endif /* DEC_CSR_READ */
  360. #ifndef DEC_CSR_WRITE
  361. #define DEC_CSR_WRITE(csr,val)                                          
  362. dec21x4xCsrWrite(pDrvCtrl->devAdrs, (csr), (val))
  363. #endif /* DEC_CSR_WRITE */
  364. #define DEC_CSR_UPDATE(csr,val)                                         
  365. DEC_CSR_WRITE((csr), DEC_CSR_READ(csr) | (val))
  366.     
  367. #define DEC_CSR_RESET(csr,val)                                          
  368. DEC_CSR_WRITE((csr), DEC_CSR_READ(csr) & ~(val))
  369.     
  370. #define DEC_SROM_CMD_WRITE(adrs,delay)                                  
  371. {                                                               
  372.         DEC_CSR_WRITE(CSR9, CSR9_2114X_SR | CSR9_2114X_WR | (adrs));    
  373.         NSDELAY (delay);                                                
  374.         }
  375. #define DEC_SROM_CMD_READ()                                             
  376. ((DEC_CSR_READ(CSR9) & 0x8) >> 3)
  377. /*
  378.  * Special purpose macros
  379.  * These macros can be redefined in a wrapper file if desired
  380.  */
  381. #ifndef INITIAL_RESET
  382. #define DUMMY_BUFFER_SIZE  60
  383. #define INITIAL_RESET(pDrvCtrl) 
  384.         dec21x4xInitialReset(pDrvCtrl)
  385. #endif
  386. /*
  387.  * Default macro definitions for BSP interface.
  388.  * These macros can be redefined in a wrapper file, to generate
  389.  * a new module with an optimized interface.
  390.  */
  391. /*
  392.  * For X86 arch, the intConnect/Disconnect defaults are pciIntConnect and
  393.  * pciIntDisconnect.  For all others it is just intConnect and a dummy
  394.  * disconnect function.
  395.  * HELP: This needs to be fixed by porting pciIntLib to all architectures.
  396.  */
  397. #if CPU_FAMILY == I80X86
  398. #ifndef SYS_INT_CONNECT
  399. #define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)                       
  400.     {                                                                   
  401.     IMPORT STATUS pciIntConnect();                                      
  402.     *pResult = pciIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),
  403.      (rtn), (int)(arg));                        
  404.     }
  405. #endif /*SYS_INT_CONNECT*/
  406. #ifndef SYS_INT_DISCONNECT
  407. #define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)                    
  408.     {                                                                   
  409.     IMPORT STATUS pciIntDisconnect();                                      
  410.     *pResult = pciIntDisconnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),
  411.      (rtn));                         
  412.     }
  413. #endif /*SYS_INT_DISCONNECT*/
  414. #else /* CPU_FAMILY == I80X86 */
  415. #ifndef SYS_INT_CONNECT
  416. #define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)                       
  417.     {                                                                   
  418.     IMPORT STATUS intConnect();                                      
  419.     *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),
  420.      (rtn), (int)(arg));                        
  421.     }
  422. #endif /*SYS_INT_CONNECT*/
  423. #ifndef SYS_INT_DISCONNECT
  424. #define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)                    
  425.     {                                                                   
  426.     *pResult = OK;
  427.     }
  428. #endif /*SYS_INT_DISCONNECT*/
  429. #endif /* CPU_FAMILY == I80X86 */
  430. #ifndef SYS_INT_ENABLE
  431. #define SYS_INT_ENABLE(pDrvCtrl)                                        
  432.     {                                                                   
  433.     IMPORT STATUS sysLanIntEnable();
  434.     sysLanIntEnable(pDrvCtrl->ilevel);
  435.     }
  436. #endif /*SYS_INT_ENABLE*/
  437. #ifndef SYS_INT_DISABLE
  438. #define SYS_INT_DISABLE(pDrvCtrl)                                       
  439.     {                                                                   
  440.     IMPORT STATUS sysLanIntDisable();
  441.     sysLanIntDisable(pDrvCtrl->ilevel);
  442.     }
  443. #endif /*SYS_INT_DISABLE*/
  444. #ifndef SYS_DEC21X4X_INIT
  445. #define SYS_DEC21X4X_INIT(pDrvCtrl,pResult)                             
  446.     {                                                                   
  447.     IMPORT STATUS sysDec21x4xInit();                                    
  448.     *pResult = sysDec21x4xInit (pDrvCtrl);                         
  449.     }
  450. #endif /* SYS_DEC21X4X_INIT */
  451. #define END_MIB_SPEED_SET(pEndObj, speed)                               
  452. ((pEndObj)->mib2Tbl.ifSpeed=speed)
  453. #define NET_BUF_ALLOC()                                                 
  454.     netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->clPoolId)
  455. #define NET_BUF_FREE(pBuf)                                              
  456.     netClFree (pDrvCtrl->endObj.pNetPool, pBuf)
  457. #define NET_MBLK_ALLOC()                                                
  458.     mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)
  459. #define NET_MBLK_FREE(pMblk)                                            
  460.     netMblkFree (pDrvCtrl->endObj.pNetPool, (M_BLK_ID)pMblk)
  461. #define NET_CL_BLK_ALLOC()                                              
  462.     clBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)
  463. #define NET_CL_BLK_FREE(pClblk)                                         
  464.     clBlkFree (pDrvCtrl->endObj.pNetPool, (CL_BLK_ID)pClBlk)
  465.             
  466. #define NET_MBLK_BUF_FREE(pMblk)                                        
  467.     netMblkClFree ((M_BLK_ID)pMblk)
  468. #define NET_MBLK_CHAIN_FREE(pMblk)                                      
  469.     {                                                                   
  470.     M_BLK *pNext;                                                       
  471.                                                                         
  472.     pNext=pMblk;                                                        
  473.     while (pNext)                                                       
  474.         pNext=NET_MBLK_BUF_FREE (pNext);                                
  475.     }
  476.     
  477. #define NET_MBLK_CL_JOIN(pMblk, pClBlk)                              
  478.     netMblkClJoin ((pMblk), (pClBlk))
  479. #define NET_CL_BLK_JOIN(pClBlk, pBuf, len)                             
  480.     netClBlkJoin ((pClBlk), (pBuf), (len), NULL, 0, 0, 0)
  481.         
  482. #define DRV_CTRL DEC21X4X_DRV_CTRL
  483. #ifdef DRV_DEBUG
  484. DRV_CTRL *pDrvCtrlDbg;
  485. #endif
  486. /* structure sizes */
  487. #define DRV_CTRL_SIZ sizeof(DRV_CTRL)
  488. #define RD_SIZ sizeof(DEC_RD)
  489. #define TD_SIZ sizeof(DEC_TD)
  490. /* locals */
  491. /* Default network buffer configuration */
  492. NET_POOL dec21x4xNetPool; 
  493. /* forward declarations */
  494. LOCAL STATUS dec21x4xInitParse (DRV_CTRL *pDrvCtrl, char *InitString);
  495. LOCAL STATUS dec21x4xInitMem (DRV_CTRL *pDrvCtrl);
  496. LOCAL STATUS dec21x4xIASetup (DRV_CTRL *pDrvCtrl);
  497. LOCAL void  dec21x4xModeSet (DRV_CTRL *pDrvCtrl);
  498. LOCAL int dec21x4xHashIndex (char *eAddr);
  499. LOCAL void  dec21x4xInt (DRV_CTRL *pDrvCtrl);
  500. LOCAL STATUS  dec21x4xRecv (DRV_CTRL *pDrvCtrl, DEC_RD *rmd);
  501. LOCAL STATUS  dec21x4xChipReset (DRV_CTRL *pDrvCtrl);
  502. LOCAL void dec21040AuiTpInit (DRV_CTRL *pDrvCtrl);
  503. LOCAL STATUS  dec21x4xEnetAddrGet (DRV_CTRL *pDrvCtrl, char *enetAdrs);
  504. LOCAL STATUS  dec21040EnetAddrGet (DRV_CTRL *pDrvCtrl, char *enetAdrs);
  505. LOCAL STATUS  dec2114xEnetAddrGet (DRV_CTRL *pDrvCtrl, char *enetAdrs);
  506. LOCAL void dec21x4xRestart (DRV_CTRL *pDrvCtrl);
  507. LOCAL DEC_TD * dec21x4xTxDGet (DRV_CTRL *pDrvCtrl);
  508. LOCAL DEC_RD * dec21x4xRxDGet (DRV_CTRL *pDrvCtrl);
  509. LOCAL void  dec21x4xTxRingClean (DRV_CTRL *pDrvCtrl);
  510. LOCAL void  dec21x4xRxIntHandle (DRV_CTRL *pDrvCtrl);
  511. LOCAL USHORT dec2114xSromWordRead (DRV_CTRL *pDrvCtrl, UCHAR lineCnt);
  512. LOCAL STATUS  dec21140MediaSelect (DRV_CTRL *pDrvCtrl, UINT *pCsr6Val);
  513. LOCAL STATUS  dec21143MediaSelect (DRV_CTRL *pDrvCtrl, UINT *pCsr6Val);
  514. LOCAL void      dec21x4xInitialReset (DRV_CTRL *pDrvCtrl);
  515. LOCAL void dec21x4xCsrWrite (ULONG devAdrs, int reg, ULONG value);
  516. LOCAL ULONG dec21x4xCsrRead (ULONG devAdrs, int reg);
  517. /* externals */
  518. IMPORT STATUS sysDec21x4xEnetAddrGet (int unit, char *enetAdrs);
  519. /* globals */
  520. FUNCPTR _func_dec2114xMediaSelect;
  521. VOIDFUNCPTR  _func_dec2114xIntAck;
  522. /* END Specific interfaces. */
  523. END_OBJ * dec21x4xEndLoad (char *initString);
  524. LOCAL STATUS dec21x4xUnload (DRV_CTRL *pDrvCtrl);
  525. LOCAL STATUS dec21x4xStart (DRV_CTRL *pDrvCtrl);
  526. LOCAL STATUS dec21x4xStop (DRV_CTRL *pDrvCtrl);
  527. LOCAL int dec21x4xIoctl (DRV_CTRL *pDrvCtrl, int cmd, caddr_t data);
  528. LOCAL STATUS dec21x4xSend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
  529. LOCAL STATUS dec21x4xMCastAddrAdd (DRV_CTRL *pDrvCtrl, char* pAddress);
  530. LOCAL STATUS dec21x4xMCastAddrDel (DRV_CTRL *pDrvCtrl, char* pAddress);
  531. LOCAL STATUS dec21x4xMCastAddrGet (DRV_CTRL *pDrvCtrl, 
  532.                                       MULTI_TABLE *pTable);
  533. LOCAL STATUS dec21x4xPollSend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
  534. LOCAL STATUS dec21x4xPollReceive (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
  535. LOCAL STATUS dec21x4xPollStart (DRV_CTRL *pDrvCtrl);
  536. LOCAL STATUS dec21x4xPollStop (DRV_CTRL *pDrvCtrl);
  537. /* 
  538.  * Define the device function table.  This is static across all driver
  539.  * instances.
  540.  */
  541. LOCAL NET_FUNCS netFuncs = 
  542.   {
  543.   (FUNCPTR)dec21x4xStart, /* start func. */                 
  544.   (FUNCPTR)dec21x4xStop, /* stop func. */
  545.   (FUNCPTR)dec21x4xUnload, /* unload func. */                
  546.   (FUNCPTR)dec21x4xIoctl, /* ioctl func. */                 
  547.   (FUNCPTR)dec21x4xSend, /* send func. */                  
  548.   (FUNCPTR)dec21x4xMCastAddrAdd,/* multicast add func. */         
  549.   (FUNCPTR)dec21x4xMCastAddrDel,/* multicast delete func. */      
  550.   (FUNCPTR)dec21x4xMCastAddrGet,/* multicast get fun. */          
  551.   (FUNCPTR)dec21x4xPollSend, /* polling send func. */          
  552.   (FUNCPTR)dec21x4xPollReceive, /* polling receive func. */       
  553.   endEtherAddressForm, /* put address info into a NET_BUFFER */
  554.   endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
  555.   endEtherPacketAddrGet /* Get packet addresses. */
  556.   };
  557. /*******************************************************************************
  558. *
  559. * dec21x4xEndLoad - initialize the driver and device
  560. *
  561. * This routine initializes the driver and the device to the operational state.
  562. * All of the device specific parameters are passed in the initString.
  563. *
  564. * This routine can be called in two modes. If it is called with an empty, but
  565. * allocated string then it places the name of this device (i.e. dc) into the
  566. * initString and returns 0.
  567. *
  568. * If the string is allocated then the routine attempts to perform its load
  569. * functionality.
  570. *
  571. * RETURNS: An END object pointer or NULL on error or 0 and the name of the
  572. * device if the initString was NULL.
  573. */
  574. END_OBJ * dec21x4xEndLoad
  575.     (
  576.     char * initStr /* String to be parse by the driver. */
  577.     )
  578.     {
  579.     DRV_CTRL * pDrvCtrl;
  580.     char eAdrs[EADDR_LEN];            /* ethernet address */
  581.     int retVal;
  582.     char bucket[sizeof(ULONG)];
  583.     DRV_LOG (DRV_DEBUG_LOAD, "Loading dc ...n", 0, 0, 0, 0, 0, 0);
  584.     if (initStr == NULL)
  585.         return (NULL);
  586.     
  587.     if (initStr[0] == NULL)
  588.         {
  589.         memcpy(initStr, (char *) DRV_NAME, DRV_NAME_LEN);
  590.         return (0);
  591.         }
  592.     /* Allocate a control structure for this device */
  593.     pDrvCtrl = calloc (sizeof(DRV_CTRL), 1);
  594.     if (pDrvCtrl == NULL)
  595.         {
  596.         LOG_MSG ("%s - Failed to allocate control structuren",
  597.                 (int) DRV_NAME, 0, 0, 0, 0, 0); 
  598.         return (NULL);
  599.         }
  600. #ifdef DRV_DEBUG
  601.     pDrvCtrlDbg = pDrvCtrl;
  602. #endif
  603.     pDrvCtrl->flags = NULL;
  604.     pDrvCtrl->txCleaning = FALSE;
  605.     pDrvCtrl->rxHandling = FALSE;
  606.     pDrvCtrl->mediaCount = 0xff;
  607.     /* Parse InitString */
  608.     if (dec21x4xInitParse (pDrvCtrl, initStr) == ERROR)
  609.         {
  610.         LOG_MSG ("%s - Failed to parse initialization parametersn",
  611.                 (int) DRV_NAME, 0, 0, 0, 0, 0);
  612.         return (NULL);
  613.         }
  614.     /* callout to perform adapter init */
  615.  
  616.     SYS_DEC21X4X_INIT (pDrvCtrl, &retVal);
  617.     if (retVal == ERROR)
  618.         {
  619.         LOG_MSG ("%s%d - Failed to perform adapter init n", 
  620. (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  621.         return (NULL);
  622.         }
  623.     /* Prevent transmission hanging up later on */
  624.     INITIAL_RESET(pDrvCtrl);
  625.     /* probe for memory-mapped CSR registers */
  626.     if (vxMemProbe ((char *) pDrvCtrl->devAdrs, VX_READ, 
  627. sizeof(ULONG), &bucket[0]) != OK)
  628. {
  629. LOG_MSG ("%s%d - need MMU mapping for address %#xn",
  630. (int)DRV_NAME, pDrvCtrl->unit, (int)pDrvCtrl->devAdrs, 0, 0, 0);
  631. return (NULL);
  632. }
  633.  
  634.     /* endObject Initializations */
  635.     if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ*)pDrvCtrl, DRV_NAME,
  636.                       pDrvCtrl->unit, &netFuncs,
  637.                       "dec21x4x Enhanced Network Driver") == ERROR)
  638.         {
  639.         LOG_MSG ("%s%d - Failed to initialize END objectn",
  640.                 (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  641.         return (NULL);
  642.         }
  643.     /* memory Initializations */
  644.     if (dec21x4xInitMem (pDrvCtrl) == ERROR)
  645.         goto error;
  646.     /* get Ethernet Address */
  647.     if (dec21x4xEnetAddrGet (pDrvCtrl, eAdrs) == ERROR)
  648.         {
  649.         LOG_MSG ("%s%d - Failed to read ethernet addressn",
  650.                 (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  651.         goto error;
  652.         }
  653.     DRV_LOG (DRV_DEBUG_LOAD,
  654.              "ENET: %x:%x:%x:%x:%x:%xn",
  655.              eAdrs[0], eAdrs[1], eAdrs[2], eAdrs[3], eAdrs[4], eAdrs[5]);
  656.     
  657.     /* Initialize MIB-II entries */
  658.     if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,
  659.                       (UINT8*) eAdrs, EADDR_LEN,
  660.                        ETHERMTU, DEC_SPEED_DEF) == ERROR)
  661.         {
  662.         LOG_MSG ("%s%d - MIB-II initializations failedn",
  663.                 (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  664.         goto error;
  665.         }
  666.     /* Mark the device ready with default flags */
  667.     END_OBJ_READY (&pDrvCtrl->endObj,
  668.                    IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);
  669.     /* Successful return */
  670.     return (&pDrvCtrl->endObj);
  671.     /***** Handle error cases *****/
  672. error:
  673. {
  674.         dec21x4xUnload (pDrvCtrl);
  675.         return (NULL);
  676.         }
  677.     }
  678. /*******************************************************************************
  679. *
  680. * dec21x4xUnload - unload a driver from the system
  681. *
  682. * This routine deallocates lists, and free allocated memory.
  683. *
  684. * RETURNS: OK, always.
  685. */
  686. LOCAL STATUS dec21x4xUnload
  687.     (
  688.     DRV_CTRL * pDrvCtrl
  689.     )
  690.     {
  691.     DRV_LOG (DRV_DEBUG_LOAD, "EndUnloadn", 0, 0, 0, 0, 0, 0);
  692.     /* deallocate lists */
  693.     END_OBJ_UNLOAD (&pDrvCtrl->endObj);
  694.     /* deallocate allocated shared memory */
  695.     if (DRV_FLAGS_ISSET (DEC_MEMOWN)  && pDrvCtrl->memBase)
  696.         cacheDmaFree (pDrvCtrl->memBase);
  697.     return (OK);
  698.     }
  699. /*******************************************************************************
  700. *
  701. * dec21x4xInitParse - parse parameter values from initString
  702. *
  703. * Parse the input string.  Fill in values in the driver control structure.
  704. *
  705. * The initialization string format is:
  706. * "<device addr>:<PCI addr>:<ivec>:<ilevel>:<mem base>:<mem size>:
  707. *  <user flags>:<offset>"
  708. *
  709. * .IP <device addr>
  710. * base address of hardware device registers
  711. * .IP <PCI addr>
  712. * main memory address over the PCI bus
  713. * .IP <ivec>
  714. * interrupt vector number
  715. * .IP <ilevel>
  716. * interrupt level
  717. * .IP <mem base>
  718. * base address of a DMA-able, cache free,pre-allocated  memory
  719. * .IP <mem size>
  720. * size of the pre-allocated memory
  721. * .IP <user flags>
  722. * User flags control the run-time characteristics of the chip
  723. * .IP <offset>
  724. * Memory offset for alignment
  725. * .LP
  726. *
  727. * RETURNS: OK or ERROR for invalid arguments.
  728. */
  729. LOCAL STATUS dec21x4xInitParse
  730.     (
  731.     DRV_CTRL * pDrvCtrl,
  732.     char * initString
  733.     )
  734.     {
  735.     char * tok; /* an initString token */
  736.     char * holder=NULL; /* points to initString fragment beyond tok */
  737.     DRV_LOG (DRV_DEBUG_LOAD, "InitParse: Initstr=%sn",
  738.              (int)initString, 0, 0, 0, 0, 0);
  739.     tok = strtok_r(initString, ":", &holder);
  740.     if (tok == NULL)
  741.         return ERROR;
  742.     pDrvCtrl->unit = atoi(tok);
  743.     tok=strtok_r(NULL, ":", &holder);
  744.     if (tok == NULL)
  745.         return ERROR;
  746.     pDrvCtrl->devAdrs = strtoul (tok, NULL, 16);
  747.     
  748.     tok=strtok_r(NULL, ":", &holder);
  749.     if (tok == NULL)
  750.         return ERROR;
  751.     pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16);
  752.     tok=strtok_r(NULL, ":", &holder);
  753.     if (tok == NULL)
  754.         return ERROR;
  755.     pDrvCtrl->ivec = strtoul (tok, NULL, 16);
  756.     tok=strtok_r(NULL, ":", &holder);
  757.     if (tok == NULL)
  758.         return ERROR;
  759.     pDrvCtrl->ilevel = strtoul (tok, NULL, 16);
  760.     
  761.     tok=strtok_r(NULL, ":", &holder);
  762.     if (tok == NULL)
  763.         return ERROR;
  764.     pDrvCtrl->memBase = (char *) strtoul (tok, NULL, 16);
  765.     tok=strtok_r(NULL, ":", &holder);
  766.     if (tok == NULL)
  767.         return ERROR;
  768.     pDrvCtrl->memSize = strtoul (tok, NULL, 16);
  769.     tok=strtok_r(NULL, ":", &holder);
  770.     if (tok == NULL)
  771.         return (ERROR);
  772.     pDrvCtrl->usrFlags = strtoul(tok, NULL, 16);
  773.     tok = strtok_r (NULL, ":", &holder);
  774.     if (tok == NULL)
  775.         return ERROR;
  776.     pDrvCtrl->offset = atoi (tok);
  777.  
  778.     /* decode non-register user flags */
  779.     if (pDrvCtrl->usrFlags & DEC_USR_XEA)
  780.         DRV_FLAGS_SET (DEC_BSP_EADRS);
  781.     
  782.     switch (pDrvCtrl->usrFlags & DEC_USR_VER_MSK)
  783. {
  784. case DEC_USR_21143 :
  785.             DRV_FLAGS_SET (DEC_21143);
  786.     break;
  787. case DEC_USR_21140 :
  788.     DRV_FLAGS_SET (DEC_21140);
  789.     break;
  790. default :
  791.             DRV_FLAGS_SET (DEC_21040);
  792.     break;
  793. }
  794.     /* print debug info */
  795.     DRV_LOG (DRV_DEBUG_LOAD,
  796.             "EndLoad: unit=%d devAdrs=%#x ivec=%#x ilevel=%#x "
  797.             "membase=%#x memSize=%#xn",
  798.             pDrvCtrl->unit, pDrvCtrl->devAdrs, pDrvCtrl->ivec, pDrvCtrl->ilevel,
  799.             (int)pDrvCtrl->memBase, pDrvCtrl->memSize);
  800.     
  801.     DRV_LOG (DRV_DEBUG_LOAD,
  802.              "pciMemBase=%#x flags=%#x usrFlags=%#x offset=%#xn",
  803.              (int)pDrvCtrl->pciMemBase, pDrvCtrl->flags, pDrvCtrl->usrFlags,
  804.              pDrvCtrl->offset, 0, 0);
  805.     return (OK);
  806.     }
  807. /*******************************************************************************
  808. *
  809. * dec21x4xInitMem - initialize memory
  810. *
  811. * Using data in the control structure, setup and initialize the memory
  812. * areas needed.  If the memory address is not already specified, then allocate
  813. * cache safe memory.
  814. *
  815. * RETURNS: OK or ERROR
  816. */
  817. LOCAL STATUS dec21x4xInitMem
  818.     (
  819.     DRV_CTRL * pDrvCtrl
  820.     )
  821.     {
  822.     DEC_RD * pRxD = pDrvCtrl->rxRing;
  823.     DEC_TD * pTxD = pDrvCtrl->txRing;
  824.     M_CL_CONFIG dcMclBlkConfig;
  825.     CL_DESC clDesc;                      /* cluster description */
  826.     char * pBuf;
  827.     int ix;
  828.     int sz;
  829.     char * pShMem;
  830.     
  831.     /* Establish size of shared memory region we require */
  832.     
  833.     DRV_LOG (DRV_DEBUG_LOAD, "InitMemn", 0, 0, 0, 0, 0, 0);
  834.     if ((int)pDrvCtrl->memBase != NONE)  /* specified memory pool */
  835. {
  836. sz  = ((pDrvCtrl->memSize - (RD_SIZ + TD_SIZ)) /
  837.                (((2 + NUM_LOAN) * DEC_BUFSIZ) + RD_SIZ + TD_SIZ));
  838. pDrvCtrl->numRds = max (sz, MIN_RDS);
  839. pDrvCtrl->numTds = max (sz, MIN_TDS);
  840. }
  841.     else
  842.         {
  843.         pDrvCtrl->numRds = NUM_RDS_DEF;
  844.         pDrvCtrl->numTds = NUM_TDS_DEF;
  845.         }
  846.     /* Establish a region of shared memory */
  847.     /*
  848.      * OK. We now know how much shared memory we need.  If the caller
  849.      * provides a specific memory region, we check to see if the provided
  850.      * region is large enough for our needs.  If the caller did not
  851.      * provide a specific region, then we attempt to allocate the memory
  852.      * from the system, using the cache aware allocation system call.
  853.      */
  854.     switch ((int)pDrvCtrl->memBase)
  855.         {
  856.         default :       /* caller provided memory */
  857.             sz = ((pDrvCtrl->numRds * (DEC_BUFSIZ + RD_SIZ + 8)) + 4 +
  858.                   (pDrvCtrl->numTds * (DEC_BUFSIZ + TD_SIZ + 8)) + 4 +
  859.                   (NUM_LOAN * (DEC_BUFSIZ + 8)) + 4);
  860.             if ((int) pDrvCtrl->memSize < sz )     /* not enough space */
  861.                 {
  862.                 LOG_MSG( "%s%d: not enough memory providedn",
  863.                          (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  864.                 return ( ERROR );
  865.                 }
  866.             pShMem = pDrvCtrl->memBase;      /* set the beginning of pool */
  867.             /* assume pool is cache coherent, copy null structure */
  868.             pDrvCtrl->cacheFuncs = cacheNullFuncs;
  869.             break;
  870.         case NONE :     /* get our own memory */
  871.     /*
  872.              * Because the structures that are shared between the device
  873.              * and the driver may share cache lines, the possibility exists
  874.              * that the driver could flush a cache line for a structure and
  875.              * wipe out an asynchronous change by the device to a neighboring
  876.              * structure. Therefore, this driver cannot operate with memory
  877.              * that is not write coherent.  We check for the availability of
  878.              * such memory here, and abort if the system did not give us what
  879.              * we need.
  880.              */
  881.             if (!CACHE_DMA_IS_WRITE_COHERENT ())
  882.                 {
  883.                 LOG_MSG ( "%s%d: device requires cache coherent memoryn",
  884. (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  885.                 return (ERROR);
  886.                 }
  887.             sz = (((pDrvCtrl->numRds + 1) * RD_SIZ) +
  888.                   ((pDrvCtrl->numTds + 1) * TD_SIZ));
  889.             pDrvCtrl->memBase = 
  890.                 pShMem = (char *) cacheDmaMalloc ( sz );
  891.             if ((int)pShMem == NULL)
  892.                 {
  893.                 LOG_MSG ( "%s%d - system memory unavailablen",
  894.                          (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  895.                 return (ERROR);
  896.                 }
  897.             pDrvCtrl->memSize = sz;
  898.             DRV_FLAGS_SET (DEC_MEMOWN);
  899.             /* copy the DMA structure */
  900.             pDrvCtrl->cacheFuncs = cacheDmaFuncs;
  901.             break;
  902.         }
  903.     /* zero the shared memory */
  904.     memset (pShMem, 0, (int) sz);
  905.     /* carve Rx memory structure */
  906.     pRxD =
  907.         pDrvCtrl->rxRing = (DEC_RD *) (((int)pShMem + 0x03) & ~0x03);
  908.     /* carve Tx memory structure */
  909.     pTxD =
  910.         pDrvCtrl->txRing = (DEC_TD *) (pDrvCtrl->rxRing + pDrvCtrl->numRds);
  911.     /* Initialize net buffer pool for tx/rx buffers */
  912.     memset ((char *)&dcMclBlkConfig, 0, sizeof(dcMclBlkConfig));
  913.     memset ((char *)&clDesc, 0, sizeof(clDesc));
  914.     
  915.     dcMclBlkConfig.mBlkNum  = pDrvCtrl->numRds * 4;
  916.     clDesc.clNum      = pDrvCtrl->numRds + pDrvCtrl->numTds + NUM_LOAN;
  917.     dcMclBlkConfig.clBlkNum = clDesc.clNum;
  918.     /*
  919.      * mBlk and cluster configuration memory size initialization
  920.      * memory size adjusted to hold the netPool pointer at the head.
  921.      */
  922.     dcMclBlkConfig.memSize = ((dcMclBlkConfig.mBlkNum *
  923.                                (MSIZE + sizeof (long))) +
  924.                               (dcMclBlkConfig.clBlkNum *
  925.                                (CL_BLK_SZ + sizeof (long))));
  926.     
  927.     if ((dcMclBlkConfig.memArea = (char *)memalign(sizeof (long),
  928.                                             dcMclBlkConfig.memSize)) == NULL)
  929.         return (ERROR);
  930.     clDesc.clSize  = DEC_BUFSIZ;
  931.     clDesc.memSize  = ((clDesc.clNum * (clDesc.clSize + 4)) + 4);
  932.     if (DRV_FLAGS_ISSET(DEC_MEMOWN))
  933.         {
  934.         clDesc.memArea = (char *) cacheDmaMalloc (clDesc.memSize);
  935.         if ((int)clDesc.memArea == NULL)
  936.             {
  937.             LOG_MSG ( "%s%d - system memory unavailablen",
  938.                      (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  939.             return (ERROR);
  940.             }
  941.         }
  942.     else
  943.         clDesc.memArea = (char *) (pDrvCtrl->txRing + pDrvCtrl->numTds);
  944.     
  945.     if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
  946.         return (ERROR);
  947.     /* Initialize the net buffer pool with transmit buffers */
  948.     if (netPoolInit (pDrvCtrl->endObj.pNetPool, &dcMclBlkConfig,
  949.                      &clDesc, 1, NULL) == ERROR)
  950.         {
  951.         LOG_MSG ("%s%d - netPoolInit failedn", 
  952. (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  953.         return (ERROR);
  954.         }
  955.     /* Save the cluster pool id */
  956.     pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,
  957.                                       DEC_BUFSIZ, FALSE);
  958.     /* Clear all indices */
  959.     pDrvCtrl->rxIndex=0;
  960.     pDrvCtrl->txIndex=0;
  961.     pDrvCtrl->txDiIndex=0;
  962.     /* Setup the receive ring */
  963.     for (ix = 0; ix < pDrvCtrl->numRds; ix++, pRxD++)
  964.         {
  965.         pBuf = (char *) NET_BUF_ALLOC();
  966.         if (pBuf == NULL)
  967.             {
  968.             LOG_MSG ("%s%d - netClusterGet failedn", 
  969. (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  970.             return (ERROR);
  971.             }
  972. pRxD->rDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf)); /* buffer 1 */
  973. pRxD->rDesc3 = 0;                    /* no second buffer */
  974. /* buffer size */
  975. pRxD->rDesc1 = PCISWAP (RDESC1_RBS1_VAL (DEC_BUFSIZ) | 
  976.                                 RDESC1_RBS2_VAL (0));
  977. if (ix == (pDrvCtrl->numRds - 1)) /* if its is last one */
  978.     pRxD->rDesc1 |= PCISWAP (RDESC1_RER); /* end of receive ring */
  979. pRxD->rDesc0 = PCISWAP (RDESC0_OWN); /* give ownership to chip */
  980.         }
  981.     /* Setup the transmit ring */
  982.     for (ix = 0; ix < pDrvCtrl->numTds; ix++, pTxD++)
  983.         {
  984.         /* empty -- no buffers at this time */
  985. pTxD->tDesc2 = 0;
  986. pTxD->tDesc3 = 0;
  987. pTxD->tDesc1 = PCISWAP ((TDESC1_TBS1_PUT(0) |   /* buffer1 size */
  988.                                  TDESC1_TBS2_PUT(0) |   /* buffer2 size */
  989.                                  TDESC1_IC          |  /* intrpt on xmit */
  990.                                  TDESC1_LS          | /* last segment */
  991.                                  TDESC1_FS)); /* first segment */
  992. if (ix == (pDrvCtrl->numTds - 1))    /* if its is last one */
  993.     pTxD->tDesc1 |= PCISWAP (TDESC1_TER); /* end of Xmit ring */
  994. pTxD->tDesc0 = 0;                    /* owner is host */
  995.         }
  996.     /* Flush the write pipe */
  997.     CACHE_PIPE_FLUSH ();
  998.     return (OK);
  999.     }
  1000. /*******************************************************************************
  1001. *
  1002. * dec21x4xStart - start the device
  1003. *
  1004. * This function initializes the device and calls BSP functions to connect
  1005. * interrupts and start the device running in interrupt mode.
  1006. *
  1007. * The complement of this routine is dec21x4xStop.  Once a unit is reset by
  1008. * dec21x4xStop, it may be re-initialized to a running state by this routine.
  1009. *
  1010. * RETURNS: OK if successful, otherwise ERROR
  1011. */
  1012. LOCAL STATUS dec21x4xStart
  1013.     (
  1014.     DRV_CTRL * pDrvCtrl
  1015.     )
  1016.     {
  1017.     int retVal;
  1018.     UINT csr6Val=0;
  1019.     UINT usrFlags = pDrvCtrl->usrFlags;
  1020.     DRV_LOG (DRV_DEBUG_LOAD, "Startn", 0, 0, 0, 0, 0, 0);
  1021.     /* Reset the device */
  1022.     dec21x4xChipReset (pDrvCtrl);
  1023.     /* Select the media */
  1024.     if (! DRV_FLAGS_ISSET (DEC_21040))
  1025.         {
  1026.         if (_func_dec2114xMediaSelect != NULL)
  1027.             retVal = (* _func_dec2114xMediaSelect) (pDrvCtrl, &csr6Val);
  1028.         else if (DRV_FLAGS_ISSET (DEC_21140))
  1029.             retVal = dec21140MediaSelect (pDrvCtrl, &csr6Val);
  1030. else
  1031.     retVal = dec21143MediaSelect (pDrvCtrl, &csr6Val);
  1032.         if (retVal == ERROR)
  1033.             return (ERROR);
  1034.         
  1035.         if (csr6Val & CSR6_2114X_PS)
  1036.             {
  1037.             DEC_CSR_UPDATE (CSR6, CSR6_2114X_PS);
  1038.             dec21x4xChipReset (pDrvCtrl);
  1039.             csr6Val |= CSR6_2114X_HBD;
  1040.             }
  1041.         
  1042.         csr6Val &= DEC_USR_CSR6_MSK;
  1043.         csr6Val |= CSR6_2114X_MB1;
  1044.         /* decode CSR6 specific options from userFlags */
  1045.         if (usrFlags & DEC_USR_SF)
  1046.             csr6Val |= CSR6_2114X_SF;
  1047.         if (usrFlags & DEC_USR_THR_MSK)
  1048.             csr6Val |= (usrFlags & DEC_USR_THR_MSK) >> DEC_USR_THR_SHF;
  1049.         if (usrFlags & DEC_USR_SB)
  1050.             csr6Val |= CSR6_SB;
  1051.         if (usrFlags & DEC_USR_PB)
  1052.             csr6Val |= CSR6_PB;
  1053.         if (usrFlags & DEC_USR_SC)
  1054.             csr6Val |= CSR6_2114X_SC;
  1055.         if (usrFlags & DEC_USR_CA)
  1056.             csr6Val |= CSR6_CAE;
  1057.         }
  1058.     else
  1059.         dec21040AuiTpInit (pDrvCtrl);
  1060.     /* Write start of receive ring */
  1061.     DEC_CSR_WRITE (CSR3, DEC_VIRT_TO_PCI(pDrvCtrl->rxRing));
  1062.     /* Write start of transmit ring */
  1063.     DEC_CSR_WRITE (CSR4, DEC_VIRT_TO_PCI(pDrvCtrl->txRing));
  1064.     /* clear the status register */
  1065.     DEC_CSR_WRITE (CSR5, 0xffffffff);
  1066.     /* setup CSR6 - start transmitter */
  1067.     DEC_CSR_WRITE (CSR6, csr6Val | CSR6_ST);
  1068.     /* setup ethernet address and filtering mode */
  1069.     dec21x4xIASetup (pDrvCtrl);
  1070.     /* set operating mode and start the receiver */
  1071.     dec21x4xModeSet (pDrvCtrl);
  1072.     /* set up the interrupts */
  1073.     DEC_CSR_WRITE (CSR7, (CSR7_NIM |         /* normal interrupt mask */
  1074.                           CSR7_RIM |         /* rcv  interrupt mask */
  1075.                           CSR7_TIM |         /* xmit interrupt mask */
  1076.                           CSR7_TUM |         /* xmit buff unavailble mask */
  1077.                           CSR7_AIM |         /* abnormal interrupt mask */
  1078.                           CSR7_SEM |         /* system error mask */
  1079.                           CSR7_RUM ));       /* rcv buff unavailable mask */
  1080.     if (! DRV_FLAGS_ISSET (DEC_21140))
  1081.         DEC_CSR_UPDATE (CSR7, CSR7_21X4X_LFM);   /* link fail mask */
  1082.     /* Connect the interrupt handler */
  1083.     SYS_INT_CONNECT (pDrvCtrl, dec21x4xInt, pDrvCtrl, &retVal);
  1084.     if (retVal == ERROR)
  1085.         return (ERROR);
  1086.     pDrvCtrl->txBlocked = FALSE;
  1087.     /* mark the interface -- up */
  1088.     END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
  1089.     /* Enable LAN interrupts */
  1090.     SYS_INT_ENABLE (pDrvCtrl);
  1091.     return (OK);
  1092.     }
  1093. /*******************************************************************************
  1094. *
  1095. * dec21x4xStop - stop the device
  1096. *
  1097. * This routine marks the interface as down and resets the device.  This
  1098. * includes disabling interrupts, stopping the transmitter and receiver.
  1099. *
  1100. * The complement of this routine is dec21x4xStart.  Once a unit is
  1101. * stop in this routine, it may be re-initialized to a running state by
  1102. * dec21x4xStart.
  1103. *
  1104. * RETURNS: OK or ERROR
  1105. */
  1106. LOCAL STATUS dec21x4xStop
  1107.     (
  1108.     DRV_CTRL * pDrvCtrl
  1109.     )
  1110.     {
  1111.     int retVal=OK;
  1112.     DRV_LOG (DRV_DEBUG_LOAD, "Stopn", 0, 0, 0, 0, 0, 0);
  1113.     /* mark the interface down */
  1114.     END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING);
  1115.     /* Reset the device */
  1116.     dec21x4xChipReset (pDrvCtrl);
  1117.     /* Disable LAN interrupts */
  1118.     SYS_INT_DISABLE (pDrvCtrl);
  1119.     /* disconnect interrupt */
  1120.     SYS_INT_DISCONNECT (pDrvCtrl, dec21x4xInt, (int)pDrvCtrl, &retVal);
  1121.     return (retVal);
  1122.     }
  1123. /*******************************************************************************
  1124. *
  1125. * dec21x4xRestart - restart the device
  1126. *
  1127. * Restarts the device after cleaning up the transmit and receive queues. This
  1128. * routine should be called only after dec21x4xStop().
  1129. *
  1130. * RETURNS: OK or ERROR
  1131. */
  1132. LOCAL void dec21x4xRestart
  1133.     (
  1134.     DRV_CTRL * pDrvCtrl
  1135.     )
  1136.     {
  1137.     DEC_TD * pTxD = pDrvCtrl->txRing;
  1138.     FREE_BUF * pFreeBuf = pDrvCtrl->freeBuf;
  1139.     int count;
  1140.     
  1141.     LOG_MSG ("%s%d - restarting device.n",
  1142.             (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  1143.     
  1144.     /* cleanup the tx and rx queues */
  1145.     dec21x4xTxRingClean (pDrvCtrl);
  1146.     dec21x4xRxIntHandle (pDrvCtrl);
  1147.     /* drop rest of the queued tx packets */
  1148.     for (count = pDrvCtrl->numTds; count; count--, pTxD++, pFreeBuf++)
  1149.         {
  1150.         if (pFreeBuf->pClBuf != NULL)
  1151.             {
  1152.             NET_BUF_FREE(pFreeBuf->pClBuf);
  1153.             pFreeBuf->pClBuf = NULL;
  1154.             }
  1155.         DEC_CACHE_INVALIDATE (pTxD, TD_SIZ);
  1156.         
  1157.         if (pTxD->tDesc1 & PCISWAP(TDESC1_SET))
  1158.             {
  1159.             pTxD->tDesc1 &= PCISWAP(~(TDESC1_SET | TDESC1_FT0));
  1160.             pTxD->tDesc0 = 0;
  1161.             }
  1162.         else if (pTxD->tDesc0 & PCISWAP(TDESC0_OWN|TDESC0_ES))
  1163.             {
  1164.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);
  1165.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);
  1166.             pTxD->tDesc0 = 0;
  1167.             }
  1168.         }
  1169.     /* Reset indices */
  1170.     pDrvCtrl->rxIndex=0;
  1171.     pDrvCtrl->txIndex=0;
  1172.     pDrvCtrl->txDiIndex=0;
  1173.     /* Restart the device */
  1174.     dec21x4xStart (pDrvCtrl);
  1175.     }
  1176. /*******************************************************************************
  1177. *
  1178. * dec21x4xIoctl - interface ioctl procedure
  1179. *
  1180. * Process an interface ioctl request.
  1181. *
  1182. * This routine implements the network interface control functions.
  1183. * It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,
  1184. * EIOCMULTIDEL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.
  1185. *
  1186. * RETURNS: OK if successful, otherwise EINVAL.
  1187. */
  1188. LOCAL int dec21x4xIoctl
  1189.     (
  1190.     DRV_CTRL * pDrvCtrl,
  1191.     int cmd,
  1192.     caddr_t data
  1193.     )
  1194.     {
  1195.     int error=0;
  1196.     long value;
  1197.     int savedFlags;
  1198.     END_OBJ * pEndObj=&pDrvCtrl->endObj;
  1199.     
  1200.     DRV_LOG (DRV_DEBUG_IOCTL,
  1201.              "Ioctl unit=%#x cmd=%d data=%#xn",
  1202.              pDrvCtrl->unit, cmd, (int)data, 0, 0, 0);
  1203.     switch (cmd)
  1204.         {
  1205.         case EIOCSADDR:
  1206.             if (data == NULL)
  1207.                 error = EINVAL;
  1208.             else
  1209.                 {
  1210.                 /* Copy and install the new address */
  1211.                 memcpy ((char *)END_HADDR(pEndObj), (char *)data,
  1212.                        END_HADDR_LEN(pEndObj));
  1213.                 dec21x4xIASetup (pDrvCtrl);
  1214.                 }
  1215.             break;
  1216.             
  1217.         case EIOCGADDR:                      /* HELP: move to mux */
  1218.             if (data == NULL)
  1219.                 error = EINVAL;
  1220.             else
  1221.                 memcpy ((char *)data, (char *)END_HADDR(pEndObj),
  1222.                        END_HADDR_LEN(pEndObj));
  1223. #ifdef DRV_DEBUG
  1224.             {
  1225.             char *cp = (char *)data;
  1226.             DRV_LOG (DRV_DEBUG_IOCTL,
  1227.                           "EIOCGADDR: %x:%x:%x:%x:%x:%xn",
  1228.                           cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
  1229.             }
  1230. #endif /*DRV_DEBUG*/
  1231.             break;
  1232.         case EIOCSFLAGS:
  1233.             value = (long) data;
  1234.             if (value < 0)
  1235.                 {
  1236.                 value = -value;
  1237.                 value--;
  1238.                 END_FLAGS_CLR (pEndObj, value);
  1239.                 }
  1240.             else
  1241.                 END_FLAGS_SET (pEndObj, value);
  1242.             /* handle IIF_PROMISC and IFF_ALLMULTI */
  1243.             savedFlags = DRV_FLAGS_GET();
  1244.             if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC))
  1245.                 DRV_FLAGS_SET (DEC_PROMISC);
  1246.             else
  1247.                 DRV_FLAGS_CLR (DEC_PROMISC);
  1248.             if (END_FLAGS_GET (pEndObj) & (IFF_ALLMULTI | IFF_MULTICAST))
  1249.                 DRV_FLAGS_SET (DEC_MCAST);
  1250.             else
  1251.                 DRV_FLAGS_CLR (DEC_MCAST);
  1252.             DRV_LOG (DRV_DEBUG_IOCTL, 
  1253. "endFlags=%#x savedFlags=%#x newFlags=%#xn",
  1254. END_FLAGS_GET(pEndObj), savedFlags, DRV_FLAGS_GET(), 0, 0, 0);
  1255.             if ((DRV_FLAGS_GET() != savedFlags) &&
  1256. (END_FLAGS_GET(pEndObj) & IFF_UP))
  1257.                 dec21x4xModeSet (pDrvCtrl);
  1258.             break;
  1259.         case EIOCGFLAGS:                     /* move to mux */
  1260.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS: 0x%x: 0x%xn",
  1261.                     pEndObj->flags, *(long *)data, 0, 0, 0, 0);
  1262.             if (data == NULL)
  1263.                 error = EINVAL;
  1264.             else
  1265.                 *(long *)data = END_FLAGS_GET(pEndObj);
  1266.             break;
  1267.         case EIOCMULTIADD:                   /* move to mux */
  1268.             error = dec21x4xMCastAddrAdd (pDrvCtrl, (char *)data);
  1269.             break;
  1270.         case EIOCMULTIDEL:                   /* move to mux */
  1271.             error = dec21x4xMCastAddrDel (pDrvCtrl, (char *)data);
  1272.             break;
  1273.         case EIOCMULTIGET:                   /* move to mux */
  1274.             error = dec21x4xMCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data);
  1275.             break;
  1276.         case EIOCPOLLSTART:                  /* move to mux */
  1277.             dec21x4xPollStart (pDrvCtrl);
  1278.             break;
  1279.         case EIOCPOLLSTOP:                   /* move to mux */
  1280.             dec21x4xPollStop (pDrvCtrl);
  1281.             break;
  1282.         case EIOCGMIB2:                      /* move to mux */
  1283.             if (data == NULL)
  1284.                 error=EINVAL;
  1285.             else
  1286.                 memcpy((char *)data, (char *)&pEndObj->mib2Tbl,
  1287.                       sizeof(pEndObj->mib2Tbl));
  1288.             break;
  1289.         default:
  1290.             error = EINVAL;
  1291.         }
  1292.     return (error);
  1293.     }
  1294. /*******************************************************************************
  1295. *
  1296. * dec21x4xModeSet - promiscuous & multicast operation and start receiver
  1297. *
  1298. * This routine enables promiscuous and multicast mode if corresponding flags 
  1299. * are set and starts the receiver.
  1300. *
  1301. * RETURNS: N/A
  1302. */
  1303. LOCAL void dec21x4xModeSet
  1304.     (
  1305.     DRV_CTRL * pDrvCtrl
  1306.     )
  1307.     {
  1308.     int opMode = CSR6_SR;                    /* start receiver */
  1309.     DRV_LOG (DRV_DEBUG_IOCTL, "ModeSetn", 0, 0, 0, 0, 0, 0);
  1310.     if (DRV_FLAGS_ISSET (DEC_MCAST))
  1311.         opMode |= CSR6_PM;                   /* rx multicast */
  1312.     if (DRV_FLAGS_ISSET (DEC_PROMISC))
  1313.         opMode |= CSR6_PR;                   /* rx promiscuous */
  1314.     
  1315.     DEC_CSR_WRITE (CSR6, (DEC_CSR_READ (CSR6) & ~(CSR6_PM|CSR6_PR)) | opMode);
  1316.     return;
  1317.     }
  1318. /*******************************************************************************
  1319. *
  1320. * dec21x4xHashIndex - compute the hash index for an ethernet address
  1321. *
  1322. * This routine provides the hash index for an given ethernet address. The bit
  1323. * position in the hash table is taken from the CRC32 checksum derived from
  1324. * the first 6 bytes.
  1325. *
  1326. * RETURNS: hash index for an ethernet address.
  1327. */
  1328. LOCAL int dec21x4xHashIndex
  1329.     (
  1330.     char * eAddr
  1331.     )
  1332.     {
  1333.     UINT8 eAddrByte;
  1334.     int index;                       /* hash index - return value */
  1335.     int byte;                        /* loop - counter */
  1336.     int bit;                         /* loop - counter */
  1337.     UINT crc = 0xffffffff;
  1338.     UINT8 msb;
  1339.     for (byte=0; byte<6; byte++)
  1340.         {
  1341.         eAddrByte = eAddr[byte];
  1342.         for (bit=0; bit<8; bit++)
  1343.             {
  1344.             msb = crc >> 31;
  1345.             crc <<= 1;
  1346.             if (msb ^ (eAddrByte & 0x1))
  1347.                 {
  1348.                 crc ^= DEC_CRC_POLY;
  1349.                 crc |= 0x1;
  1350.                 }
  1351.             eAddrByte >>= 1;
  1352.             }
  1353.         }
  1354.     /*
  1355.      * return the upper 9 bits of the CRC in a decreasing order of
  1356.      * significance.
  1357.      * crc <31..23> as index <0..8>
  1358.      */
  1359.     index = 0;
  1360.     for (bit=0; bit<9; bit++)
  1361.         index |= ((crc >> (31-bit)) & 0x1) << bit;
  1362.     return index;
  1363.     }
  1364. /*******************************************************************************
  1365. *
  1366. * dec21x4xIASetup - set up physical and multicast addresses
  1367. *
  1368. * This routine sets up a filter frame to filter the physical addresses
  1369. * and all the current multicast addresses.
  1370. *
  1371. * While the first call to this routine during chip initialization requires
  1372. * that the receiver be turned off, subsequent calls do not.
  1373. * RETURNS: OK on success, ERROR otherwise.
  1374. */
  1375. LOCAL STATUS dec21x4xIASetup
  1376.     (
  1377.     DRV_CTRL * pDrvCtrl  /* pointer to device control structure */
  1378.     )
  1379.     {
  1380.     UINT8 ethBcastAdrs[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  1381.     UINT8 * pFltrFrm;
  1382.     UINT8 * pAdrs;
  1383.     ETHER_MULTI * pMCastNode;
  1384.     DEC_TD * pTxD;
  1385.     ULONG csr7Val;
  1386.     char * pBuf;
  1387.     int index;
  1388.     int timeout;
  1389.     DRV_LOG (DRV_DEBUG_IOCTL, "IASetupn", 0, 0, 0, 0, 0, 0);
  1390.     /* gain exclusive access to transmitter */
  1391.     END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);
  1392.     
  1393.     /* get a free transmit descriptor */
  1394.     pTxD = dec21x4xTxDGet (pDrvCtrl);
  1395.     if (pTxD == NULL)
  1396.         {
  1397.         END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1398.         return (ERROR);
  1399.         }
  1400.     /* get a buffer */
  1401.      pBuf = NET_BUF_ALLOC();
  1402.      if (pBuf == NULL)
  1403.          {
  1404.          DRV_LOG (DRV_DEBUG_LOAD, "netClusterGet failedn", 0, 0, 0, 0, 0, 0);
  1405.          END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1406.          return (ERROR);
  1407.          }
  1408.      /* align the frame */
  1409.      pFltrFrm = (UINT8 *) (((int)pBuf + 0x3) & ~0x3);
  1410.      /* clear all entries */
  1411.      memset (pFltrFrm, 0, FLTR_FRM_SIZE);
  1412.      /* install multicast addresses */
  1413.      for (pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);
  1414.           pMCastNode != NULL;
  1415.           pMCastNode = END_MULTI_LST_NEXT (pMCastNode))
  1416.          {
  1417.          index = dec21x4xHashIndex (pMCastNode->addr);
  1418.          pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8);
  1419.          }
  1420.      /* install an ethernet broadcast address */
  1421.      index = dec21x4xHashIndex (ethBcastAdrs);
  1422.      pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8);
  1423.      /* install the physical address */
  1424.      pAdrs = (UINT8 *)END_HADDR (&pDrvCtrl->endObj);
  1425.      for (index=0; index<6; index++)
  1426.          pFltrFrm [FLTR_FRM_PHY_ADRS_OFF + DEC_FLT_INDEX(index)] = pAdrs[index];
  1427.      /* transmit the frame */
  1428.      pTxD->tDesc2  = PCISWAP (DEC_VIRT_TO_PCI (pFltrFrm));
  1429.      pTxD->tDesc3  = 0;
  1430.      /* frame type is SETUP, filtering mode is HASH + 1 perfect */
  1431.      pTxD->tDesc1 |= PCISWAP (TDESC1_SET | TDESC1_FT0); 
  1432.      pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);
  1433.      pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(FLTR_FRM_SIZE));
  1434.      pTxD->tDesc1 &= PCISWAP (~(TDESC1_LS|TDESC1_FS));
  1435.      pTxD->tDesc0  = PCISWAP(TDESC0_OWN);      /* ready for transmit */
  1436.     /* Flush the write pipe */
  1437.      CACHE_PIPE_FLUSH();
  1438.      /* Advance our management index */
  1439.      pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
  1440.      /* mask interrupts */
  1441.      csr7Val = DEC_CSR_READ (CSR7);
  1442.      DEC_CSR_WRITE (CSR7, 0);
  1443.      /* start tx */
  1444.      if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))
  1445.          DEC_CSR_WRITE (CSR1, CSR1_TPD);
  1446.      /* wait for completion */
  1447.      timeout=0xffffff;
  1448.      while (timeout && (pTxD->tDesc0 != (~PCISWAP (TDESC0_OWN))))
  1449.          timeout--;
  1450.      /* restore TXD bits */
  1451.      pTxD->tDesc0  = 0;
  1452.      pTxD->tDesc1 &= PCISWAP (~(TDESC1_SET | TDESC1_FT0));
  1453.      pTxD->tDesc1 |= PCISWAP (TDESC1_LS | TDESC1_FS);
  1454.      pTxD->tDesc2  = 0;
  1455.      /* restore interrupts */
  1456.      DEC_CSR_WRITE (CSR7, csr7Val);
  1457.      /* free the buffer */
  1458.      NET_BUF_FREE (pBuf);
  1459.     /* release exclusive access */
  1460.     END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1461.     /* return success */
  1462.     return (OK);
  1463.     }
  1464. /*******************************************************************************
  1465. *
  1466. * dec21x4xMCastAddrAdd - add a multicast address
  1467. *
  1468. * This routine adds a multicast address to whatever the driver
  1469. * is already listening for.
  1470. *
  1471. * RETURNS: OK on success, ERROR otherwise.
  1472. */
  1473. LOCAL STATUS dec21x4xMCastAddrAdd
  1474.     (
  1475.     DRV_CTRL * pDrvCtrl,
  1476.     char * pAddr
  1477.     )
  1478.     {
  1479.     int retVal;
  1480.     DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAddn", 0, 0, 0, 0, 0, 0);
  1481.     /* add a multicast address to the list */
  1482.     retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);
  1483.     /* reconfigure the device */
  1484.     if (retVal == ENETRESET)
  1485.         return dec21x4xIASetup (pDrvCtrl);
  1486.     return ((retVal == OK) ? OK : ERROR);
  1487.     }
  1488. /*******************************************************************************
  1489. *
  1490. * dec21x4xMCastAddrDel - remove a multicast address
  1491. *
  1492. * This routine deletes a multicast address from the current list of
  1493. * multicast addresses.
  1494. *
  1495. * RETURNS: OK on success and ERROR otherwise.
  1496. */
  1497. LOCAL STATUS dec21x4xMCastAddrDel
  1498.     (
  1499.     DRV_CTRL * pDrvCtrl,
  1500.     char * pAddr
  1501.     )
  1502.     {
  1503.     int retVal;
  1504.     DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDeln", 0, 0, 0, 0, 0, 0);
  1505.     /* remove a multicast address from the list */
  1506.     retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);
  1507.     /* reconfigure the device */
  1508.  
  1509.     if (retVal == ENETRESET)
  1510.         return dec21x4xIASetup (pDrvCtrl);
  1511.     return ((retVal == OK) ? OK : ERROR);
  1512.     }
  1513. /*******************************************************************************
  1514. *
  1515. * dec21x4xMCastAddrGet - retreive current multicast address list
  1516. *
  1517. * This routine returns the current multicast address list in <pTable>
  1518. *
  1519. * RETURNS: OK on success; otherwise ERROR.
  1520. */
  1521. LOCAL STATUS dec21x4xMCastAddrGet
  1522.     (
  1523.     DRV_CTRL * pDrvCtrl,
  1524.     MULTI_TABLE * pTable
  1525.     )
  1526.     {
  1527.     DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrGetn", 0, 0, 0, 0, 0, 0);
  1528.     return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));
  1529.     }
  1530. /*******************************************************************************
  1531. *
  1532. * dec21x4xSend - transmit an ethernet packet
  1533. *
  1534. * This routine() takes a M_BLK_ID and sends off the data in the M_BLK_ID.
  1535. * The buffer must already have the addressing information properly installed
  1536. * in it. This is done by a higher layer. The last arguments are a free
  1537. * routine to be called when the device is done with the buffer and a pointer
  1538. * to the argument to pass to the free routine.
  1539. *
  1540. * muxSend() calls this routine each time it wants to send a packet.
  1541. * Errors are detected at interrupt level.
  1542. *
  1543. * RETURNS: OK on success; and ERROR otherwise.
  1544. */
  1545. LOCAL STATUS dec21x4xSend
  1546.     (
  1547.     DRV_CTRL * pDrvCtrl,
  1548.     M_BLK * pMblk
  1549.     )
  1550.     {
  1551.     DEC_TD * pTxD;
  1552.     char * pBuf;
  1553.     int len;
  1554.     int         s;
  1555.     DRV_LOG (DRV_DEBUG_TX, "S:%#x ", pDrvCtrl->txIndex, 0, 0, 0, 0, 0);
  1556. #if 0    
  1557.     if (pDrvCtrl->txBlocked)
  1558.         return (END_ERR_BLOCK); /* transmitter not ready */
  1559. #endif    
  1560.     /* Gain exclusive access to transmit */
  1561.     END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);
  1562.     /* Get the next TXD */
  1563.     pTxD = dec21x4xTxDGet (pDrvCtrl);
  1564.     pBuf = NET_BUF_ALLOC();
  1565.     if ((pTxD == NULL) || (pBuf == NULL))
  1566.         {
  1567.         END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);
  1568.         END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1569.         if (pBuf)
  1570.             NET_BUF_FREE (pBuf);
  1571.         if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)
  1572.             dec21x4xTxRingClean (pDrvCtrl);
  1573.         s = intLock();
  1574.         pDrvCtrl->txBlocked = TRUE;        /* transmitter not ready */
  1575.         intUnlock(s);
  1576.         return (END_ERR_BLOCK); /* just return without freeing mBlk chain */
  1577.         }
  1578.     /* copy and free the MBLK */
  1579.     len = netMblkToBufCopy (pMblk, pBuf, NULL);
  1580.     /* setup the transmit buffer pointers */
  1581.     NET_MBLK_CHAIN_FREE (pMblk);
  1582.     /* setup the transmit buffer pointers */
  1583.     pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));
  1584.     pTxD->tDesc3 = 0;
  1585.     /* setup frame len */
  1586.     pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);
  1587.     pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(len));
  1588.     /* transfer ownership to device */
  1589.     pTxD->tDesc0  = PCISWAP(TDESC0_OWN);      
  1590.     /* Flush the write pipe */
  1591.     CACHE_PIPE_FLUSH();
  1592.     /* Save the buf info */
  1593.     pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf = pBuf;
  1594.     /* Advance our management index */
  1595.     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
  1596.      /* start tx */
  1597.     if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))
  1598.         DEC_CSR_WRITE (CSR1, CSR1_TPD);
  1599.     END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1600.     /* update statistics */
  1601.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
  1602.     return (OK);
  1603.     }
  1604. /*******************************************************************************
  1605. *
  1606. * dec21x4xRecv - pass a received frame to the upper layer
  1607. *
  1608. * This routine processes an input frame, then passes it up to the higher
  1609. * level in a form it expects.  Buffer loaning, promiscuous mode are all
  1610. * supported.  Trailer protocols is not supported.
  1611. *
  1612. * RETURNS: OK, always.
  1613. */
  1614. LOCAL STATUS dec21x4xRecv
  1615.     (
  1616.     DRV_CTRL * pDrvCtrl,
  1617.     DEC_RD * pRxD
  1618.     )
  1619.     {
  1620.     END_OBJ * pEndObj = &pDrvCtrl->endObj;
  1621.     M_BLK_ID pMblk;      /* MBLK to send upstream */
  1622.     CL_BLK_ID pClBlk;     /* pointer to clBlk */
  1623.     char * pBuf;     /* A replacement buffer for the current RxD */
  1624.     char * pData;      /* Data pointer for the current RxD */
  1625.     char * pTmp;
  1626.     int      len;     /* Len of the current data */
  1627.     DRV_LOG (DRV_DEBUG_RX, "R", 0, 0, 0, 0, 0, 0); 
  1628.     
  1629.     /* check for errors */
  1630.     if (pRxD->rDesc0 & PCISWAP(RDESC0_ES))
  1631.         {
  1632.         DRV_LOG (DRV_DEBUG_RX, "- ",0, 0, 0, 0, 0, 0);
  1633.         END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);
  1634.         goto cleanRxD;
  1635.         }
  1636.     /* Allocate an MBLK, and a replacement buffer */
  1637.     pMblk = NET_MBLK_ALLOC();
  1638.     pBuf  = NET_BUF_ALLOC();
  1639.     pClBlk = NET_CL_BLK_ALLOC(); 
  1640.     if ((pMblk == NULL) || (pBuf == NULL) || (pClBlk == NULL))
  1641.         {
  1642.         END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);
  1643.         if (pMblk)
  1644.             NET_MBLK_FREE (pMblk);
  1645.         if (pBuf)
  1646.             NET_BUF_FREE (pBuf);
  1647.         if (pClBlk)
  1648.             NET_CL_BLK_FREE (pClBlk);
  1649.         goto cleanRxD;
  1650.         }
  1651.     /* Get the data pointer and len from the current RxD */
  1652.     len   = DEC_FRAME_LEN_GET (PCISWAP (pRxD->rDesc0)) - ETH_CRC_LEN; 
  1653.     pData = (char *) DEC_PCI_TO_VIRT (PCISWAP (pRxD->rDesc2));
  1654.     /*
  1655.      * The code above solves alignment problem when the CPU and the
  1656.      * ethernet chip don't accept longword unaligned addresses.
  1657.      * 
  1658.      * Pb: When the ethernet chip receives a packet from the network,
  1659.      * it needs a longword aligned buffer to copy the data. To process the
  1660.      * IP packet, MUX layer adds a ENET_HDR_REAL_SIZ (0x14) offset to the
  1661.      * data buffer. So the CPU obtains a longword unaligned buffer and
  1662.      * a fault execption occurs when it reads "ip_src" and "ip_dst" fields 
  1663.      * in the IP structure (ip_src and ip_dst fields are longwords).
  1664.      *
  1665.      * The problem is solved copying the data in a new buffer in which
  1666.      * the IP structure is aligned.
  1667.      */  
  1668.     if (pDrvCtrl->offset != 0)
  1669. {
  1670. /* exchange buffer addresses */
  1671. pTmp = pData;
  1672. pData = pBuf;
  1673. pBuf = pTmp;
  1674. /* copy data in new unaligned buffer */
  1675.  
  1676. pData += pDrvCtrl->offset;
  1677. memcpy(pData, pBuf, len);
  1678.         }
  1679.     /* Restore orignal buffer address to be able to free it */
  1680.  
  1681.     pData -= pDrvCtrl->offset; 
  1682.     /* Associate the data pointer with the MBLK */
  1683.     NET_CL_BLK_JOIN (pClBlk, pData, DEC_BUFSIZ); 
  1684.     
  1685.     /* Associate the data pointer with the MBLK */
  1686.     NET_MBLK_CL_JOIN (pMblk, pClBlk);
  1687.     pMblk->mBlkHdr.mData += pDrvCtrl->offset; 
  1688.     pMblk->mBlkHdr.mFlags  |= M_PKTHDR; /* set the packet header */
  1689.     pMblk->mBlkHdr.mLen = len; /* set the data len */
  1690.     pMblk->mBlkPktHdr.len  = len; /* set the total len */
  1691.     /* Make cache consistent with memory */
  1692.     DEC_CACHE_INVALIDATE (pData, len);
  1693.     /* Install the new data buffer */
  1694.     pRxD->rDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));
  1695.     /* mark the descriptor ready to receive */
  1696.     pRxD->rDesc0 = PCISWAP (RDESC0_OWN);
  1697.     /* update statistics */
  1698.     
  1699.     DRV_LOG (DRV_DEBUG_RX, "+ ", 0, 0, 0, 0, 0, 0);
  1700.     END_ERR_ADD (pEndObj, MIB2_IN_UCAST, +1);
  1701.     /* advance management index */
  1702.     pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
  1703.     /* Flush the write pipe */
  1704.     CACHE_PIPE_FLUSH();
  1705.     /* send the frame to the upper layer */
  1706.     END_RCV_RTN_CALL (pEndObj, pMblk);
  1707.     return OK;
  1708. cleanRxD:
  1709.     /* mark the descriptor ready to receive */
  1710.     pRxD->rDesc0 = PCISWAP (RDESC0_OWN);
  1711.     /* update statistics */
  1712.     
  1713.     DRV_LOG (DRV_DEBUG_RX, "+ ", 0, 0, 0, 0, 0, 0);
  1714.     END_ERR_ADD (pEndObj, MIB2_IN_UCAST, +1);
  1715.     /* Flush the write pipe */
  1716.     CACHE_PIPE_FLUSH();
  1717.     /* advance management index */
  1718.     pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
  1719.     return (OK);
  1720.     }
  1721. /*******************************************************************************
  1722. *
  1723. * dec21x4xRxIntHandle - perform receive processing
  1724. *
  1725. * This routine is called at task level indirectly by the interrupt
  1726. * service routine to do any message received processing.
  1727. *
  1728. * RETURNS: N/A
  1729. */
  1730. LOCAL void dec21x4xRxIntHandle
  1731.     (
  1732.     DRV_CTRL * pDrvCtrl
  1733.     )
  1734.     {
  1735.     DEC_RD * pRxD;
  1736.     pDrvCtrl->rxHandling = TRUE;
  1737.     
  1738.     while ((pRxD = dec21x4xRxDGet (pDrvCtrl)))
  1739.             dec21x4xRecv (pDrvCtrl, pRxD);
  1740.     DEC_CSR_UPDATE (CSR7, CSR7_RIM);     /* turn on Rx interrupts */
  1741.     pDrvCtrl->rxHandling = FALSE;
  1742.     }
  1743. /*******************************************************************************
  1744. *
  1745. * dec21x4xRxDGet - get a ready receive descriptor
  1746. *
  1747. * Get next received message descriptor.  Returns NULL if none are
  1748. * ready.
  1749. *
  1750. * RETURNS: a filled receive descriptor, otherwise NULL.
  1751. */
  1752. LOCAL DEC_RD * dec21x4xRxDGet
  1753.     (
  1754.     DRV_CTRL * pDrvCtrl
  1755.     )
  1756.     {
  1757.     DEC_RD * pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;
  1758.     
  1759.     DEC_CACHE_INVALIDATE (pRxD, RD_SIZ);
  1760.     /* check if the descriptor is owned by the chip */
  1761.     if (pRxD->rDesc0 & PCISWAP (RDESC0_OWN))
  1762.         return (NULL);
  1763.     return (pRxD);
  1764.     }
  1765. /*******************************************************************************
  1766. *
  1767. * dec21x4xTxDGet - get an available transmit descriptor
  1768. *
  1769. * Get next transmited message descriptor.  Returns NULL if none are
  1770. * ready.
  1771. *
  1772. * RETURNS: an available transmit descriptor, otherwise NULL.
  1773. */
  1774. LOCAL DEC_TD * dec21x4xTxDGet
  1775.     (
  1776.     DRV_CTRL * pDrvCtrl
  1777.     )
  1778.     {
  1779.     DEC_TD * pTxD = pDrvCtrl->txRing + pDrvCtrl->txIndex;
  1780.     DEC_CACHE_INVALIDATE (pTxD, TD_SIZ);
  1781.     /* check if this descriptor is owned by the chip or is out of bounds */
  1782.     if ((pTxD->tDesc0 & PCISWAP(TDESC0_OWN)) ||
  1783.         (((pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds) == pDrvCtrl->txDiIndex))
  1784.         return (NULL);
  1785.     return (pTxD);
  1786.     }
  1787. /*******************************************************************************
  1788. *
  1789. * dec21x4xTxRingClean - clean up processed tx descriptors
  1790. *
  1791. * This routine processes the transmit queue, freeing all transmitted
  1792. * descriptors.
  1793. *
  1794. * RETURNS: N/A
  1795. */
  1796. LOCAL void dec21x4xTxRingClean
  1797.     (
  1798.     DRV_CTRL * pDrvCtrl
  1799.     )
  1800.     {
  1801.     DEC_TD * pTxD;
  1802.     
  1803.     pDrvCtrl->txCleaning = TRUE;
  1804.     
  1805.     while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)
  1806.         {
  1807.         pTxD = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;
  1808.         DEC_CACHE_INVALIDATE (pTxD, TD_SIZ);
  1809. /* check if this descriptor is owned */
  1810.         if (pTxD->tDesc0 & PCISWAP(TDESC0_OWN))
  1811.             break;
  1812.         DRV_LOG (DRV_DEBUG_TX, "Tc:%#x ", pDrvCtrl->txDiIndex, 0, 0, 0, 0, 0);
  1813.         /* free the buffer */
  1814.         if (pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf != NULL)
  1815.             {
  1816.             NET_BUF_FREE(pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf);
  1817.             pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf = NULL;
  1818.             }
  1819.         
  1820.         pDrvCtrl->txDiIndex =  (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->numTds;
  1821.         /* count collisions */
  1822. #if 0
  1823.         if (! (pTxD->tDesc0 & PCISWAP(TDESC0_EC)))
  1824.             END_ERR_ADD (pEndObj, MIB2_COLLISIONS,
  1825.                          TDESC0_CC_VAL (PCISWAP (pTxD->tDesc0)));
  1826. #endif
  1827.         /* clear frame-type of a setup frame and process errors for others */
  1828.         if (pTxD->tDesc1 & PCISWAP(TDESC1_SET))
  1829.             {
  1830.             pTxD->tDesc1 &= PCISWAP(~(TDESC1_SET | TDESC1_FT0));
  1831.             }
  1832.         else if (pTxD->tDesc0 & PCISWAP(TDESC0_ES))
  1833.             {
  1834.             END_OBJ *pEndObj = &pDrvCtrl->endObj;
  1835.             END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1);
  1836.             END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1);
  1837.             /* count excessive collisions */
  1838. #if 0
  1839.             if (pTxD->tDesc0 & PCISWAP(TDESC0_EC))
  1840.                 END_ERR_ADD (pEndObj, MIB2_COLLISIONS, 16);
  1841.             /* check for no carrier */
  1842.             if (pTxD->tDesc0 & PCISWAP(TDESC0_NC|TDESC0_LO|TDESC0_LF))
  1843.                 LOG_MSG ("%s%d - no carriern",
  1844.                         (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  1845. #endif
  1846.             /* restart if DMA underflow is detected */
  1847.             if (pTxD->tDesc0 & PCISWAP(TDESC0_UF))
  1848.                 {
  1849.                 LOG_MSG ("%s%d - fatal DMA underflown",
  1850.                         (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  1851.                 dec21x4xStop (pDrvCtrl);
  1852.                 pDrvCtrl->txCleaning = FALSE;
  1853.                 netJobAdd ((FUNCPTR)dec21x4xRestart, (int)pDrvCtrl, 0, 0, 0, 0);
  1854.                 return;
  1855.                }
  1856.             }
  1857.         pTxD->tDesc0 = 0;                    /* clear errors and stats */
  1858.         }
  1859.     pDrvCtrl->txCleaning = FALSE;
  1860.     return;
  1861.     }
  1862. /*******************************************************************************
  1863. *
  1864. * dec21x4xInt - handle device interrupts
  1865. *
  1866. * This interrupt service routine, reads device interrupt status, acknowledges
  1867. * the interrupting events, and schedules receive and transmit processing when
  1868. * required.
  1869. *
  1870. * RETURNS: N/A
  1871. */
  1872. LOCAL void dec21x4xInt
  1873.     (
  1874.     DRV_CTRL * pDrvCtrl
  1875.     )
  1876.     {
  1877.     ULONG status;
  1878.     /* get the status bits */
  1879.     status = DEC_CSR_READ (CSR5);
  1880.     /* return on false interrupt */
  1881.  
  1882.     if ((status & (CSR5_NIS | CSR5_AIS)) == NULL)
  1883.         {
  1884.         DRV_LOG (DRV_DEBUG_INT, "false intrn", 0, 0, 0, 0, 0, 0);
  1885.         return;
  1886.         }
  1887.  
  1888.     DRV_LOG (DRV_DEBUG_INT, "i=0x%x:", status, 0, 0, 0, 0, 0);
  1889.     /* Check for system error */
  1890.     if (status & CSR5_SE)
  1891.         {
  1892.         LOG_MSG ("%s%d - fatal system errorn",
  1893.                 (int) DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  1894. /* Acknowledge system error interrupts */
  1895. DEC_CSR_WRITE (CSR5, (CSR5_SE | CSR5_AIS));
  1896.         dec21x4xStop (pDrvCtrl);
  1897.         netJobAdd ((FUNCPTR)dec21x4xRestart, (int)pDrvCtrl, 0, 0, 0, 0);
  1898.         return;
  1899.         }
  1900.     /* Handle received packets */
  1901.     if (status & CSR5_RI)
  1902. {
  1903. DRV_LOG (DRV_DEBUG_INT, "r ", 0, 0, 0, 0, 0, 0);
  1904. if ((! (status & CSR5_RPS)) && (!pDrvCtrl->rxHandling))
  1905.             {
  1906.             pDrvCtrl->rxHandling = TRUE;
  1907.             netJobAdd ((FUNCPTR)dec21x4xRxIntHandle, (int)pDrvCtrl, 0, 0, 0, 0);
  1908.         
  1909.             /* disable Rx intr; re-enable in dec21x4xRxIntHandle() */
  1910.             DEC_CSR_RESET (CSR7, CSR7_RIM);
  1911.             }
  1912. /* Acknowledge receive interrupt */
  1913. DEC_CSR_WRITE (CSR5, (CSR5_RI | CSR5_NIS));
  1914. }
  1915. #ifdef DRV_DEBUG
  1916.     if (status & CSR5_TI)
  1917.         decTxInts++;
  1918. #endif
  1919.     
  1920.     /* Cleanup TxRing */
  1921.     if (status & CSR5_TI)
  1922. {
  1923.         DRV_LOG (DRV_DEBUG_INT, "t ", 0, 0, 0, 0, 0, 0);
  1924. if (!pDrvCtrl->txCleaning)
  1925.             {
  1926.             pDrvCtrl->txCleaning = TRUE;
  1927.             netJobAdd ((FUNCPTR)dec21x4xTxRingClean, (int)pDrvCtrl, 0, 0, 0, 0);
  1928.             }
  1929.         /* Acknowledge transmit interrupts */
  1930. DEC_CSR_WRITE (CSR5, (CSR5_TI | CSR5_NIS));
  1931. }
  1932.     /* Acknowledge all other interrupts - ignore events */
  1933.     DEC_CSR_WRITE (CSR5, (status & ~(CSR5_SE | CSR5_RI | CSR5_TI)));
  1934.     if (_func_dec2114xIntAck != NULL)
  1935. {
  1936. /*
  1937.  * Call BSP specific interrupt ack. routine, if defined.
  1938.  * This must be called after all the interrupt sources
  1939.  * have been cleared
  1940.  */
  1941. (* _func_dec2114xIntAck) ();
  1942. }
  1943.     if (pDrvCtrl->txBlocked)
  1944.         {
  1945.         pDrvCtrl->txBlocked = FALSE;
  1946.         netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0,
  1947.                    0, 0);
  1948.         }
  1949.     return;
  1950.     }
  1951. /*******************************************************************************
  1952. *
  1953. * dec21x4xPollStart - starting polling mode
  1954. *
  1955. * This routine starts polling mode by disabling ethernet interrupts and
  1956. * setting the polling flag in the END_CTRL stucture.
  1957. *
  1958. * RETURNS: OK, always.
  1959. */
  1960. LOCAL STATUS dec21x4xPollStart
  1961.     (
  1962.     DRV_CTRL * pDrvCtrl
  1963.     )
  1964.     {
  1965.     int intLevel;
  1966.     DRV_LOG (DRV_DEBUG_POLL, "dec21x4xPollStartn", 0, 0, 0, 0, 0, 0);
  1967.     intLevel = intLock();
  1968.     /* mask normal and abnormal interrupts */
  1969.     DEC_CSR_RESET (CSR7, CSR7_NIM | CSR7_AIM);
  1970.     /* set polling flag */
  1971.     DRV_FLAGS_SET (DEC_POLLING);
  1972.     intUnlock (intLevel);
  1973.     return (OK);
  1974.     }
  1975. /*******************************************************************************
  1976. *
  1977. * dec21x4xPollStop - stop polling mode
  1978. *
  1979. * This routine stops polling mode by enabling ethernet interrupts and
  1980. * resetting the polling flag in the END_CTRL structure.
  1981. *
  1982. * RETURNS: OK, always.
  1983. */
  1984. LOCAL STATUS dec21x4xPollStop
  1985.     (
  1986.     DRV_CTRL * pDrvCtrl
  1987.     )
  1988.     {
  1989.     int intLevel;
  1990.     DRV_LOG (DRV_DEBUG_POLL, "dec21x4xPollStopn", 0, 0, 0, 0, 0, 0);
  1991.     intLevel = intLock();
  1992.     /* restore normal and abnormal interrupts */
  1993.  
  1994.     DEC_CSR_UPDATE (CSR7, (CSR7_NIM | CSR7_AIM));
  1995.     /* clear polling flag */
  1996.  
  1997.     DRV_FLAGS_CLR (DEC_POLLING);
  1998.     intUnlock (intLevel);
  1999.     DRV_LOG (DRV_DEBUG_POLL, "s", 0, 0, 0, 0, 0, 0);
  2000.     return (OK);
  2001.     }
  2002. /*******************************************************************************
  2003. *
  2004. * dec21x4xPollSend - send a packet in polled mode
  2005. *
  2006. * This routine is called by a user to try and send a packet on the
  2007. * device. It sends a packet directly on the network from the caller without
  2008. * going through the normal processes of queuing a pacet on an output queue
  2009. * and the waiting for the device to decide to transmit it.
  2010. *
  2011. * If it detects a transmission error, the restart command is issued.
  2012. *
  2013. * These routine should not call any kernel functions.
  2014. *
  2015. * RETURNS: OK on success, EAGAIN on failure
  2016. */
  2017. LOCAL STATUS dec21x4xPollSend
  2018.     (
  2019.     DRV_CTRL * pDrvCtrl,
  2020.     M_BLK * pMblk
  2021.     )
  2022.     {
  2023.     DEC_TD * pTxD;
  2024.     char * pBuf;
  2025.     int len;
  2026.     DRV_LOG (DRV_DEBUG_POLL_TX, "dec21x4xPollSendn", 0, 0, 0, 0, 0, 0);
  2027.     /* Get the next TXD */
  2028.     pTxD = dec21x4xTxDGet (pDrvCtrl);
  2029.     pBuf = NET_BUF_ALLOC ();
  2030.     if ((pTxD == NULL) || (pBuf == NULL))
  2031.         {
  2032.         dec21x4xTxRingClean (pDrvCtrl);
  2033.         if (pBuf)
  2034.     NET_BUF_FREE (pBuf);
  2035.         return (EAGAIN);
  2036.         }
  2037.     /* copy and free the MBLK */
  2038.     len = netMblkToBufCopy (pMblk, pBuf, NULL);
  2039.     /* setup the transmit buffer pointers */
  2040.  
  2041.     pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));
  2042.     pTxD->tDesc3 = 0;
  2043.     /* setup descriptor fields for tansmit */
  2044.     pTxD->tDesc0 = 0;
  2045.     pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);
  2046.     pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(len));
  2047.     pTxD->tDesc0 = PCISWAP(TDESC0_OWN);      /* ready for transmit */
  2048.     /* Flush the write pipe */
  2049.     CACHE_PIPE_FLUSH();
  2050.     /* Advance our management index */
  2051.     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
  2052.      /* start tx */
  2053.     if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))
  2054.         DEC_CSR_WRITE (CSR1, CSR1_TPD);
  2055.     /* The buffer does not belong to us; Spin until it can be freed */
  2056.     while (pTxD->tDesc0 & PCISWAP(TDESC0_OWN));
  2057.     NET_BUF_FREE (pBuf);
  2058.     /* Try again on transmit errors */
  2059.     if (pTxD->tDesc0 & PCISWAP(TDESC0_ES))
  2060.         return (EAGAIN);
  2061.     /* update statistics */
  2062.  
  2063.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
  2064.  
  2065.     return (OK);
  2066.     }
  2067. /*******************************************************************************
  2068. *
  2069. * dec21x4xPollReceive - get a packet in polled mode
  2070. *
  2071. * This routine is called by a user to try and get a packet from the
  2072. * device. It returns EAGAIN if no packet is available. The caller must
  2073. * supply a M_BLK_ID with enough space to contain the receiving packet. If
  2074. * enough buffer is not available then EAGAIN is returned.
  2075. *
  2076. * These routine should not call any kernel functions.
  2077. *
  2078. * RETURNS: OK on success, EAGAIN on failure.
  2079. */
  2080. LOCAL STATUS dec21x4xPollReceive
  2081.     (
  2082.     DRV_CTRL * pDrvCtrl,
  2083.     M_BLK  * pMblk
  2084.     )
  2085.     {
  2086.     DEC_RD * pRxD;
  2087.     char * pRxBuf;
  2088.     int len;
  2089.     BOOL gotOne=FALSE;
  2090.     DRV_LOG (DRV_DEBUG_POLL_RX, "dec21x4xPollReceiven", 0, 0, 0, 0, 0, 0);
  2091.     /* Check if the M_BLK has an associated cluster */
  2092.     if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)
  2093.         return (EAGAIN);
  2094.     while (((pRxD = dec21x4xRxDGet (pDrvCtrl)) != NULL) && !gotOne)
  2095.         {
  2096.         /* Check if the packet was received OK */
  2097.         if (pRxD->rDesc0 & PCISWAP (RDESC0_ES))
  2098.             {
  2099.             /* Update the error statistics and discard the packet */
  2100.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  2101.             }
  2102.         else
  2103.             {
  2104.             len = DEC_FRAME_LEN_GET (PCISWAP(pRxD->rDesc0)) - ETH_CRC_LEN;
  2105.             if (pMblk->mBlkHdr.mLen >= len)
  2106.                 {
  2107.                 gotOne = TRUE;
  2108. /* update statistics */
  2109.                 END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  2110. /* Deal with memory alignment */
  2111. if (((int) pMblk->mBlkHdr.mData & 0x3) == 0)
  2112.                     pMblk->mBlkHdr.mData += pDrvCtrl->offset;
  2113. pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
  2114. pMblk->mBlkHdr.mLen = len;    /* set the data len */
  2115. pMblk->mBlkPktHdr.len = len;    /* set the total len */
  2116.  
  2117.                 pRxBuf = (char *) DEC_PCI_TO_VIRT (PCISWAP (pRxD->rDesc2));
  2118.                 DEC_CACHE_INVALIDATE (pRxBuf, len);
  2119.                 memcpy ((char *)pMblk->mBlkHdr.mData , pRxBuf, len);
  2120.                 }
  2121.             }
  2122. /* mark the descriptor ready to receive */
  2123.         pRxD->rDesc0 = PCISWAP (RDESC0_OWN);
  2124. /* flush the write pipe */
  2125.         CACHE_PIPE_FLUSH();
  2126. /* advance management index */
  2127.         pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
  2128.         }
  2129.     return (gotOne ? OK : EAGAIN);
  2130.     }
  2131. /*******************************************************************************
  2132. *
  2133. * dec21x4xCsrRead - read a Command and Status Register
  2134. *
  2135. * RETURNS: contents of the CSR register.
  2136. */
  2137. LOCAL ULONG dec21x4xCsrRead
  2138.     (
  2139.     ULONG devAdrs,                     /* device base address */
  2140.     int reg                          /* register to read */
  2141.     )
  2142.     {
  2143.     ULONG * csrReg;
  2144.     ULONG csrData;
  2145.     
  2146.     csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));
  2147.     csrData = *csrReg;
  2148.     return (PCISWAP (csrData));
  2149.     }
  2150. /*******************************************************************************
  2151. *
  2152. * dec21x4xCsrWrite - write a Command and Status Register
  2153. *
  2154. * RETURNS: N/A
  2155. */
  2156. LOCAL void dec21x4xCsrWrite
  2157.     (
  2158.     ULONG devAdrs,
  2159.     int reg,
  2160.     ULONG value
  2161.     )
  2162.     {
  2163.     ULONG * csrReg;
  2164.     csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));
  2165.     *csrReg = PCISWAP (value);
  2166.     return;
  2167.     }
  2168. /*******************************************************************************
  2169. *
  2170. * dec21040AuiTpInit - initialize either AUI or 10BASE-T connection
  2171. *
  2172. * This function configures 10BASE-T interface. If the link pass state is 
  2173. * not achieved within two seconds then the AUI interface is initialized.
  2174. *
  2175. * RETURNS: N/A
  2176. */
  2177. LOCAL void dec21040AuiTpInit
  2178.     (
  2179.     DRV_CTRL * pDrvCtrl
  2180.     )
  2181.     {
  2182.     /* reset the SIA registers */
  2183.     DEC_CSR_WRITE (CSR13, 0);
  2184.     DEC_CSR_WRITE (CSR14, 0);
  2185.     DEC_CSR_WRITE (CSR15, 0);
  2186.     /* configure 10BASE-T */
  2187.     DEC_CSR_WRITE (CSR13, CSR13_CAC_CSR);    /* 10BT auto configuration */
  2188.     taskDelay (sysClkRateGet() * 2);         /* 2 seconds delay */
  2189.     /* configure AUI if 10BASE-T is not connected */
  2190.     if (DEC_CSR_READ (CSR12) & (CSR12_21040_LKF | CSR12_21040_NCR))
  2191. {
  2192.         /* reset SIA registers */
  2193. DEC_CSR_WRITE (CSR13, 0);            
  2194. DEC_CSR_WRITE (CSR14, 0);
  2195. DEC_CSR_WRITE (CSR15, 0);
  2196. /* AUI auto configuration */
  2197. DEC_CSR_WRITE (CSR13, (CSR13_AUI_TP | CSR13_CAC_CSR));
  2198. }
  2199.     return;
  2200.     }
  2201. /*******************************************************************************
  2202. *
  2203. * dec21x4xEnetAddrGet - gets the ethernet address
  2204. *
  2205. * This routine gets the ethernet address by calling the appropriate
  2206. * EnetAddrGet() routine.
  2207. * RETURNS: OK/ERROR
  2208. *
  2209. * SEE ALSO: dec20140EnetAddrGet(), dec2114xEnetAddrGet(),
  2210. * sysDec21x4xEnetAddrGet()
  2211. */
  2212. LOCAL STATUS dec21x4xEnetAddrGet
  2213.     (
  2214.     DRV_CTRL * pDrvCtrl,
  2215.     char * enetAdrs
  2216.     )
  2217.     {
  2218.     STATUS retVal=ERROR;
  2219.     if (! DRV_FLAGS_ISSET (DEC_BSP_EADRS))
  2220.         {
  2221. /* don't use BSP routine to get ethernet addresse */
  2222.         if (! DRV_FLAGS_ISSET (DEC_21040))
  2223.             retVal=dec2114xEnetAddrGet (pDrvCtrl, enetAdrs);
  2224.         else
  2225.             retVal=dec21040EnetAddrGet (pDrvCtrl, enetAdrs);
  2226.         }
  2227.     /* Use BSP routine to get ethernet addresse */
  2228.     
  2229.     if (retVal == ERROR)
  2230.         retVal=sysDec21x4xEnetAddrGet (pDrvCtrl->unit, enetAdrs);
  2231.     return (retVal);
  2232.     }
  2233. /*******************************************************************************
  2234. *
  2235. * dec21040EnetAddrGet - gets the ethernet address from the ROM register.
  2236. *
  2237. * This routine gets the ethernet address from the ROM register.
  2238. * This routine returns the ethernet address into the pointer supplied to it.
  2239. * RETURNS: OK/ERROR
  2240. */
  2241. LOCAL STATUS dec21040EnetAddrGet
  2242.     (
  2243.     DRV_CTRL * pDrvCtrl,
  2244.     char *  enetAdrs /* pointer to the ethernet address */ 
  2245.     )
  2246.     {
  2247.     ULONG csr9Value; /* register to hold CSR9 */
  2248.     BOOL eRomReady = FALSE; /* ethernet ROM register state */
  2249.     int ix; /* index register */
  2250.     int len = EADDR_LEN;
  2251.     DEC_CSR_WRITE (CSR9, 0); /* reset rom pointer */
  2252.     while (len > 0)
  2253. {
  2254. for (ix = 0; ix < 10; ix++) /* try at least 10 times */
  2255.     {
  2256.     if ((csr9Value = DEC_CSR_READ (CSR9)) & CSR9_21040_DNV)
  2257. {
  2258. eRomReady = FALSE;
  2259.      DELAY(500);
  2260. }
  2261.     else
  2262. {
  2263. *enetAdrs++ = (UCHAR) csr9Value;
  2264. len--;
  2265. eRomReady = TRUE;
  2266. break;
  2267. }
  2268.     }
  2269.         if (!eRomReady)
  2270.             return (ERROR);
  2271. }
  2272.     return (OK);
  2273.     }
  2274. /*******************************************************************************
  2275. *
  2276. * dec2114xEnetAddrGet - gets the ethernet address from the ROM register 
  2277. *
  2278. * This routine reads an ethernet address from the serial ROM. It supports
  2279. * legacy, ver 1/A, and 3.0 serial ROM formats.
  2280. * RETURNS: OK on success, and ERROR if the ethernet address bytes cannot be
  2281. * read.
  2282. */
  2283. LOCAL STATUS dec2114xEnetAddrGet
  2284.     (
  2285.     DRV_CTRL * pDrvCtrl,
  2286.     char *  enetAdrs /* pointer to the ethernet address */ 
  2287.     )
  2288.     {
  2289.     USHORT sromData;
  2290.     int adrsOffset;
  2291.     int len;
  2292.     /* Check if SROM is programmed. */
  2293.     sromData = dec2114xSromWordRead (pDrvCtrl, 0);
  2294.     if ( sromData == 0xFFFF ) 
  2295. return (ERROR);
  2296.     sromData = dec2114xSromWordRead (pDrvCtrl, 13);
  2297.     /*
  2298.      * Set MAC address offset from the ROM format.
  2299.      *  Legacy ROMs have ethernet address start at offset 0,
  2300.      *  while the rest (ver 1/A and 3.0) have it at byte offset 20.
  2301.      */
  2302.     adrsOffset = (sromData == 0xAA55) ? 0: 10;
  2303.     for (len=EADDR_LEN; len; len-=2, adrsOffset++)
  2304.         {
  2305.         sromData = dec2114xSromWordRead (pDrvCtrl, adrsOffset);
  2306. /* copy in byte order, not word order */
  2307. #if (_BYTE_ORDER == _LITTLE_ENDIAN)
  2308.         *enetAdrs++ = MSB(sromData); /* ARM, x86, i960, etc */
  2309.         *enetAdrs++ = LSB(sromData);
  2310. #else
  2311.         *enetAdrs++ = LSB(sromData);
  2312.         *enetAdrs++ = MSB(sromData);
  2313. #endif
  2314.         }
  2315.     return (OK);
  2316.     }
  2317. /*******************************************************************************
  2318. *
  2319. * dec2114xSromWordRead - read 2 bytes from the serial ROM
  2320. *
  2321. * This routine uses the line number passed to the function and returns
  2322. * the two bytes of information that is associated with it.  This will later
  2323. * be used by the dc21140GetEthernetAdr function.  It can also be used to 
  2324. * review the ROM contents itself.
  2325. *
  2326. * The function must first send some initial bit paterns to the CSR9 which 
  2327. * contains the Serial ROM Control bits.  Then the line index into the ROM
  2328. * will be evaluated bit by bit to program the ROM.  The 2 bytes of data
  2329. * will be extracted and processed into a normal pair of bytes. 
  2330. * RETURNS: Short Value in ROM/ERROR
  2331. */
  2332. LOCAL USHORT dec2114xSromWordRead
  2333.     (
  2334.     DRV_CTRL * pDrvCtrl,
  2335.     UCHAR lineCnt  /* Serial ROM line Number */ 
  2336.     )
  2337.     {
  2338.     int ix; /* index register */
  2339.     int loop;           /* address loop counter */
  2340.     ULONG adrsBase;
  2341.     USHORT romData;
  2342.     /* Is the line offset valid, and if so, how large is it */
  2343.     if (lineCnt > DEC2114X_SROM_SIZE)
  2344.      return (ERROR);
  2345.     if (lineCnt < 64)
  2346.      {
  2347. loop = 6;
  2348. lineCnt = lineCnt << 2;  /* Prepare lineCnt for processing */
  2349.      }
  2350.     else
  2351. loop = 8;
  2352.     /* Command the Serial ROM to the correct Line */
  2353.     /* Preamble */
  2354.     DEC_SROM_CMD_WRITE (0x0, 30);           /* Command 1 */
  2355.     DEC_SROM_CMD_WRITE (0x1, 50);           /* Command 2 */
  2356.     DEC_SROM_CMD_WRITE (0x3, 250);          /* Command 3 */
  2357.     DEC_SROM_CMD_WRITE (0x1, 150);          /* Command 4 */
  2358.     /* Command Phase */
  2359.     DEC_SROM_CMD_WRITE (0x5, 150);          /* Command 5 */
  2360.     DEC_SROM_CMD_WRITE (0x7, 250);          /* Command 6 */
  2361.     DEC_SROM_CMD_WRITE (0x5, 250);          /* Command 7 */
  2362.     DEC_SROM_CMD_WRITE (0x7, 250);          /* Command 8 */
  2363.     DEC_SROM_CMD_WRITE (0x5, 100);          /* Command 9 */
  2364.     DEC_SROM_CMD_WRITE (0x1, 150);          /* Command 10 */
  2365.     DEC_SROM_CMD_WRITE (0x3, 250);          /* Command 11 */
  2366.     DEC_SROM_CMD_WRITE (0x1, 100);          /* Command 12 */
  2367.     
  2368.     /* Address Phase */
  2369.     for (ix=0; ix < loop; ix++)
  2370.      {
  2371. adrsBase = ((lineCnt & 0x80) >> 5); 
  2372. /* Write the command */
  2373.         DEC_SROM_CMD_WRITE (adrsBase | 0x1, 150);  /* Command 13 */
  2374.         DEC_SROM_CMD_WRITE (adrsBase | 0x3, 250);  /* Command 14 */
  2375.         DEC_SROM_CMD_WRITE (adrsBase | 0x1, 100);  /* Command 15 */
  2376. lineCnt = lineCnt<<1;
  2377.      }
  2378.     NSDELAY (150);
  2379.     /* Data Phase */
  2380.     romData = 0;
  2381.     for (ix=15; ix >= 0; ix--)
  2382.      {
  2383. /* Write the command */
  2384.         DEC_SROM_CMD_WRITE (0x3, 100);      /* Command 16 */
  2385. /* Extract data */
  2386.      romData |= (DEC_SROM_CMD_READ() << ix);
  2387.      NSDELAY (150);                       /* Command 17 */
  2388.         DEC_SROM_CMD_WRITE (0x1, 250);      /* Command 18 */
  2389.      }
  2390.     /* Finish up command */
  2391.     DEC_SROM_CMD_WRITE (0x0, 100);           /* Command 19 */
  2392.     return (PCISWAP_SHORT(romData));
  2393.     }
  2394. /*******************************************************************************
  2395. *
  2396. * dec21x4xChipReset - Reset the chip and setup CSR0 register
  2397. *
  2398. * This routine stops the transmitter and receiver, masks all interrupts, then
  2399. * resets the ethernet chip. Once the device comes out of the reset state, it
  2400. * initializes CSR0 register.
  2401. *
  2402. * RETURNS: OK, Always. 
  2403. */
  2404. LOCAL STATUS dec21x4xChipReset
  2405.     (
  2406.     DRV_CTRL * pDrvCtrl /* pointer to device control structure */
  2407.     )
  2408.     {
  2409.     ULONG ix; /* index */
  2410.     ULONG usrFlags=pDrvCtrl->usrFlags;
  2411.     ULONG csr0Val=0x0;
  2412.     DEC_CSR_WRITE (CSR6, 0); /* stop rcvr & xmitter */
  2413.     DEC_CSR_WRITE (CSR7, 0); /* mask interrupts */
  2414.     
  2415.     DEC_CSR_WRITE (CSR0, CSR0_SWR);
  2416.     /* Wait Loop, Loop for at least 50 PCI cycles according to chip spec */
  2417.     for (ix = 0; ix < 0x1000; ix++);
  2418.     /* Decode user setting into CSR0 bits */
  2419.     csr0Val |= (usrFlags & DEC_USR_BAR_RX)? 0 : CSR0_BAR;
  2420.     csr0Val |= (usrFlags & DEC_USR_BE)? CSR0_BLE : 0;
  2421.     csr0Val |= (usrFlags & DEC_USR_TAP_MSK) << DEC_USR_TAP_SHF;
  2422.     csr0Val |= (usrFlags & DEC_USR_PBL_MSK) << DEC_USR_PBL_SHF;
  2423.     csr0Val |= (usrFlags & DEC_USR_RML)? CSR0_2114X_RML : 0;
  2424.     if (usrFlags & DEC_USR_CAL_MSK)
  2425.         csr0Val |= (usrFlags & DEC_USR_CAL_MSK) << DEC_USR_CAL_SHF;
  2426.     else
  2427.         {
  2428.         csr0Val &= ~(CSR0_CAL_MSK | CSR0_PBL_MSK);
  2429.         csr0Val |= (CSR0_CAL_32 | CSR0_PBL_32);
  2430.         }
  2431.     
  2432.     if (! (usrFlags & DEC_USR_TAP_MSK))
  2433.         DRV_FLAGS_SET (DEC_TX_KICKSTART);
  2434.     DEC_CSR_WRITE (CSR0, csr0Val);
  2435.     for (ix = 0; ix < 0x1000; ix++); /* loop for some cycles */
  2436.     return (OK);
  2437.     }
  2438. /*******************************************************************************
  2439. *
  2440. * dec21140MediaInit - Initialize media information
  2441. *
  2442. * This routine initializes media information for dec21140 chip.
  2443. *
  2444. * RETURNS: OK or ERROR
  2445. */
  2446. LOCAL STATUS dec21140MediaInit
  2447.     (
  2448.     DRV_CTRL * pDrvCtrl,
  2449.     UCHAR * pSromData
  2450.     )
  2451.     {
  2452.     USHORT * pSromWord = (USHORT *)pSromData;
  2453.     UCHAR * pInfoLeaf0;
  2454.     UCHAR ix;
  2455.     
  2456.     /* read the serial ROM into pSromData */
  2457.     for (ix=0; ix<DEC2114X_SROM_WORDS; ix++)
  2458.         *pSromWord++ = dec2114xSromWordRead (pDrvCtrl, ix);
  2459.     
  2460.     /* Initialize the media summary */
  2461.     if (pDrvCtrl->mediaCount == 0xFF)
  2462.         {
  2463.         /* check version */
  2464.         if (SROM_VERSION( pSromData ) < DEC2114X_SROM_VERSION_3)
  2465.             return (ERROR);
  2466.         /* get the leaf offset */
  2467.         pInfoLeaf0 = pSromData + SROM_ILEAF0_OFFSET( pSromData );
  2468.         pDrvCtrl->gprModeVal = ILEAF_21140_GPR_MODE( pInfoLeaf0 );
  2469.         pDrvCtrl->mediaCount = ILEAF_21140_MEDIA_COUNT( pInfoLeaf0 );
  2470.         pDrvCtrl->mediaCurrent = 0xFF;
  2471.         pDrvCtrl->mediaDefault = 0xFF;
  2472.         DRV_LOG (DRV_DEBUG_LOAD, "gpMask=%#x mediaCount = %dn",
  2473.                     pDrvCtrl->gprModeVal, pDrvCtrl->mediaCount, 0, 0, 0, 0);
  2474.         }
  2475.     return (OK);
  2476.     }
  2477. /*******************************************************************************
  2478. *
  2479. * dec21140MediaSelect - select the current media 21140
  2480. *
  2481. * This routine reads and sets up physical media with configuration
  2482. * information from a Version 3 DEC Serial ROM. Any other media configuration
  2483. * can be supported by initializing <_func_dec2114xMediaSelect>.
  2484. *
  2485. * RETURN: OK or ERROR
  2486. */
  2487. LOCAL STATUS dec21140MediaSelect
  2488.     (
  2489.     DRV_CTRL * pDrvCtrl,
  2490.     UINT * pCsr6Val
  2491.     )
  2492.     {
  2493.     UCHAR sromData[128];
  2494.     UCHAR * pInfoLeaf0;
  2495.     UCHAR * pInfoBlock;
  2496.     UINT8 ix;
  2497.     DRV_LOG (DRV_DEBUG_LOAD, " dec21140MediaSelectn", 0, 0, 0, 0, 0, 0);
  2498.     if (dec21140MediaInit (pDrvCtrl, sromData) == ERROR)
  2499.         return (ERROR);
  2500.     /* Get Info Leaf 0 */
  2501.     pInfoLeaf0 = sromData + SROM_ILEAF0_OFFSET (sromData);
  2502.     /* Get the current media */
  2503.     if ((pDrvCtrl->mediaCurrent == 0) ||
  2504.         (pDrvCtrl->mediaCurrent >= pDrvCtrl->mediaCount))
  2505.         pDrvCtrl->mediaCurrent = pDrvCtrl->mediaCount - 1;
  2506.     else
  2507.         pDrvCtrl->mediaCurrent --;
  2508.     /* Seek to the correct media Info Block */
  2509.     pInfoBlock = ILEAF_21140_INFO_BLK0( pInfoLeaf0);
  2510.     for (ix=0; ix<pDrvCtrl->mediaCurrent; ix++)
  2511.         {
  2512.         if (IBLK_IS_COMPACT (pInfoBlock))
  2513.             pInfoBlock += IBLK_COMPACT_SIZE;
  2514.         else
  2515.             pInfoBlock += IBLK_EXT_SIZE (pInfoBlock) + 1;
  2516.         }
  2517.     /* Convert ext0 into compact */
  2518.     if (IBLK_IS_EXT0 (pInfoBlock))
  2519.         pInfoBlock = IBLK_EXT0_TO_COMPACT (pInfoBlock);
  2520.     /* Setup the GP port */
  2521.     DEC_CSR_WRITE (CSR12, CSR12_21140_GPC | pDrvCtrl->gprModeVal);
  2522.     NSDELAY (150);
  2523.     
  2524.     if (IBLK_IS_COMPACT (pInfoBlock))
  2525.         {
  2526.         USHORT compactCmd;
  2527.         DRV_LOG ( DRV_DEBUG_LOAD,
  2528.                     "COMPACT: mediaCode=%#x gpData=%#x command=%#xn",
  2529.                      IBLK_COMPACT_MCODE(pInfoBlock),
  2530.                      IBLK_COMPACT_GPDATA(pInfoBlock),
  2531.                      IBLK_COMPACT_CMD(pInfoBlock), 0, 0, 0);
  2532.         /* Initialize the PHY interface */
  2533.         DEC_CSR_WRITE (CSR12, IBLK_COMPACT_GPDATA(pInfoBlock));
  2534.         NSDELAY(150);
  2535.         /* Get CSR6 settings */
  2536.         compactCmd = IBLK_COMPACT_CMD( pInfoBlock );
  2537.         if (compactCmd & COMPACT_CMD_SCR)
  2538.             *pCsr6Val |= CSR6_2114X_SCR;
  2539.         if (compactCmd & COMPACT_CMD_PCS)
  2540.             *pCsr6Val |= CSR6_2114X_PCS;
  2541.         if (compactCmd & COMPACT_CMD_PS)
  2542.             *pCsr6Val |= CSR6_2114X_PS;
  2543.         }
  2544.     else
  2545.         {
  2546.         USHORT mediaCap;
  2547.         UCHAR * pGpStr;
  2548.         DRV_LOG (DRV_DEBUG_LOAD,
  2549.                    "EXT1: PHY#=%#x InitLen=%#x resetLen=%#x n",
  2550.                     IBLK_EXT1_PHY(pInfoBlock),
  2551.                     IBLK_EXT1_INIT_LEN(pInfoBlock),
  2552.                     IBLK_EXT1_RESET_LEN(pInfoBlock), 0, 0, 0);
  2553.         DRV_LOG (DRV_DEBUG_LOAD,
  2554.                    "mediaCap=%#x autoAd=%#x FDMap=%#x TTMmap=%#xn",
  2555.                     IBLK_EXT1_MEDIA_CAP(pInfoBlock),
  2556.                     IBLK_EXT1_AUTO_AD(pInfoBlock),
  2557.                     IBLK_EXT1_FD_MAP(pInfoBlock),
  2558.                     IBLK_EXT1_TTM_MAP(pInfoBlock), 0, 0);
  2559.         /* Reset the media */
  2560.         pGpStr = IBLK_EXT1_RESET_STR (pInfoBlock);
  2561.         for (ix=IBLK_EXT1_RESET_LEN(pInfoBlock); ix; ix--, pGpStr++)
  2562.             DEC_CSR_WRITE (CSR12, *pGpStr);
  2563.         NSDELAY(150);
  2564.         
  2565.         /* Initialize the media */
  2566.         pGpStr = IBLK_EXT1_INIT_STR (pInfoBlock);
  2567.         for (ix=IBLK_EXT1_INIT_LEN (pInfoBlock); ix; ix--, pGpStr++)
  2568.             DEC_CSR_WRITE (CSR12, *pGpStr);
  2569.         NSDELAY(150);
  2570.         
  2571. /* 
  2572.          * Get CSR6 settings:
  2573.  * select full duplex mode only if the user esplicitely 
  2574.  * asks it and the device has that capability.
  2575.  */
  2576.         mediaCap = IBLK_EXT1_MEDIA_CAP (pInfoBlock);
  2577. if ((IBLK_EXT1_FD_MAP (pInfoBlock) & mediaCap) &&
  2578.     ((pDrvCtrl->usrFlags & DEC_USR_FD) == DEC_USR_FD))
  2579.     *pCsr6Val |= CSR6_FD;
  2580.         if (IBLK_EXT1_TTM_MAP (pInfoBlock) & mediaCap)
  2581.             *pCsr6Val |= CSR6_2114X_TTM;
  2582.         *pCsr6Val |= CSR6_2114X_PS;
  2583.         }
  2584.     
  2585.     return (OK);
  2586.     }
  2587. /*******************************************************************************
  2588. *
  2589. * dec21143MediaInit - Initialize media information
  2590. *
  2591. * This routine initializes media information for dec21143 chip.
  2592. *
  2593. * RETURNS: OK or ERROR
  2594. */
  2595.  
  2596. LOCAL STATUS dec21143MediaInit
  2597.     (
  2598.     DRV_CTRL *  pDrvCtrl,
  2599.     UCHAR *     pSromData
  2600.     )
  2601.     {
  2602.     USHORT *    pSromWord = (USHORT *)pSromData;
  2603.     UCHAR *     pInfoLeaf0;
  2604.     UCHAR       ix;
  2605.    
  2606.     /* read the serial ROM into pSromData */
  2607.  
  2608.     for (ix=0; ix < DEC2114X_SROM_WORDS; ix++)
  2609.         *pSromWord++ = dec2114xSromWordRead (pDrvCtrl, ix);
  2610.    
  2611.     /* Initialize the media summary */
  2612.  
  2613.     if (pDrvCtrl->mediaCount == 0xFF)
  2614.         {
  2615.         /* check version */
  2616.  
  2617.         if (SROM_VERSION( pSromData ) < DEC2114X_SROM_VERSION_3)
  2618.             return (ERROR);
  2619.  
  2620.         /* get the leaf offset */
  2621.  
  2622.         pInfoLeaf0 = pSromData + SROM_ILEAF0_OFFSET(pSromData);
  2623.  
  2624.         pDrvCtrl->mediaCount = ILEAF_21143_MEDIA_COUNT(pInfoLeaf0);
  2625.  
  2626.         pDrvCtrl->mediaCurrent = 0xFF;
  2627.         pDrvCtrl->mediaDefault = 0xFF;
  2628.  
  2629.         DRV_LOG (DRV_DEBUG_LOAD, "mediaCount = %dn", 
  2630. pDrvCtrl->mediaCount, 0, 0, 0, 0, 0);
  2631.         }
  2632.     return (OK);
  2633.     }
  2634.  
  2635. /*******************************************************************************
  2636. *
  2637. * dec21143MediaSelect - select the current media for dec21143
  2638. *
  2639. * This routine reads and sets up physical media with configuration
  2640. * information from a Version 3 DEC Serial ROM. Any other media configuration
  2641. * can be supported by initializing <_func_dec2114xMediaSelect>.
  2642. *
  2643. * RETURN: OK or ERROR
  2644. */
  2645. LOCAL STATUS dec21143MediaSelect
  2646.     (
  2647.     DRV_CTRL * pDrvCtrl,
  2648.     UINT * pCsr6Val
  2649.     )
  2650.     {
  2651.     UCHAR       sromData[128];
  2652.     UCHAR *     pInfoLeaf0;
  2653.     UCHAR *     pInfoBlock;
  2654.     USHORT mediaCap;
  2655.     UCHAR * pGpStr;
  2656.     UINT mediaCmd;
  2657.     UINT8       ix;
  2658.     DRV_LOG (DRV_DEBUG_LOAD, " dec21143MediaSelectn", 0, 0, 0, 0, 0, 0);
  2659.     if (dec21143MediaInit (pDrvCtrl, sromData) == ERROR)
  2660.         return (ERROR);
  2661.  
  2662.     /* Get Info Leaf 0 */
  2663.  
  2664.     pInfoLeaf0 = sromData + SROM_ILEAF0_OFFSET (sromData);
  2665.  
  2666.     /* Get the current media */
  2667.  
  2668.     if ((pDrvCtrl->mediaCurrent == 0) ||
  2669.         (pDrvCtrl->mediaCurrent >= pDrvCtrl->mediaCount))
  2670.         pDrvCtrl->mediaCurrent = pDrvCtrl->mediaCount - 1;
  2671.     else
  2672.         pDrvCtrl->mediaCurrent --;
  2673.  
  2674.     /* Seek to the correct media Info Block */
  2675.  
  2676.     pInfoBlock = ILEAF_21143_INFO_BLK0( pInfoLeaf0);
  2677.     for (ix=0; ix < pDrvCtrl->mediaCurrent; ix++)
  2678.         pInfoBlock += IBLK_EXT_SIZE (pInfoBlock) + 1;
  2679.     if (IBLK_IS_EXT(pInfoBlock))
  2680. switch (IBLK_EXT_TYPE(pInfoBlock))
  2681.     {
  2682.     case IBLK_IS_EXT2 : /* Extended format block - type 2 */
  2683. DRV_LOG ( DRV_DEBUG_LOAD, "EXT2: mediaCode=%#x EXT=%#xn",
  2684. IBLK_EXT2_MCODE(pInfoBlock),
  2685. IBLK_EXT2_EXT(pInfoBlock), 0, 0, 0, 0);
  2686. /* get Media-specific data */
  2687. if (IBLK_EXT2_EXT(pInfoBlock))
  2688.     {
  2689.     DRV_LOG (DRV_DEBUG_LOAD, 
  2690. "CSR13=%#x CSR14=%#x CSR15=%#xn",
  2691.      IBLK_EXT2_MSD_CSR13(pInfoBlock),
  2692.      IBLK_EXT2_MSD_CSR13(pInfoBlock),
  2693.      IBLK_EXT2_MSD_CSR13(pInfoBlock), 0, 0, 0);
  2694.     DEC_CSR_WRITE (CSR13, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  2695.     DEC_CSR_WRITE (CSR14, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  2696.     DEC_CSR_WRITE (CSR15, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  2697.     }
  2698. /* setup the GP port */
  2699. DRV_LOG ( DRV_DEBUG_LOAD, "GP Ctrl=%#x GP Data=%#xn",
  2700. IBLK_EXT2_GPC(pInfoBlock),
  2701. IBLK_EXT2_GPD(pInfoBlock), 0, 0, 0, 0);
  2702. DEC_CSR_UPDATE(CSR15, IBLK_EXT2_GPC(pInfoBlock) << 8);
  2703. DEC_CSR_UPDATE(CSR15, IBLK_EXT2_GPD(pInfoBlock) << 8);
  2704. NSDELAY(150);
  2705. break;
  2706.     case IBLK_IS_EXT3 : /* Extended format block - type 3 */
  2707. DRV_LOG (DRV_DEBUG_LOAD,
  2708. "EXT3: PHY#=%#x InitLen=%#x resetLen=%#x n",
  2709. IBLK_EXT3_PHY(pInfoBlock),
  2710. IBLK_EXT3_INIT_LEN(pInfoBlock),
  2711. IBLK_EXT3_RESET_LEN(pInfoBlock), 0, 0, 0);
  2712. DRV_LOG (DRV_DEBUG_LOAD,
  2713. "mediaCap=%#x autoAd=%#x FDMap=%#x
  2714. TTMmap=%#x MIIci=%#xn",
  2715. IBLK_EXT3_MEDIA_CAP(pInfoBlock),
  2716. IBLK_EXT3_AUTO_AD(pInfoBlock),
  2717. IBLK_EXT3_FD_MAP(pInfoBlock),
  2718. IBLK_EXT3_TTM_MAP(pInfoBlock),
  2719. IBLK_EXT3_MII_CI(pInfoBlock), 0);
  2720.  
  2721. /* Reset the media */
  2722.  
  2723. pGpStr = IBLK_EXT3_RESET_STR (pInfoBlock);
  2724. for (ix=IBLK_EXT3_RESET_LEN(pInfoBlock); ix; ix--, pGpStr++)
  2725.     DEC_CSR_WRITE (CSR15, *pGpStr);
  2726. NSDELAY(150);
  2727.  
  2728. /* Initialize the media */
  2729.  
  2730. pGpStr = IBLK_EXT3_INIT_STR (pInfoBlock);
  2731. for (ix=IBLK_EXT3_INIT_LEN (pInfoBlock); ix; ix--, pGpStr++)
  2732.     DEC_CSR_WRITE (CSR15, *pGpStr);
  2733. NSDELAY(150);
  2734.  
  2735. /* 
  2736.  * Get CSR6 settings:
  2737.  * select full duplex mode only if the user esplicitely 
  2738.  * asks it and the device has that capability.
  2739.  */
  2740. mediaCap = IBLK_EXT1_MEDIA_CAP (pInfoBlock);
  2741. if ((IBLK_EXT1_FD_MAP (pInfoBlock) & mediaCap) &&
  2742.     ((pDrvCtrl->usrFlags & DEC_USR_FD) == DEC_USR_FD))
  2743.     *pCsr6Val |= CSR6_FD;
  2744. if (IBLK_EXT3_TTM_MAP (pInfoBlock) & mediaCap)
  2745.     *pCsr6Val |= CSR6_2114X_TTM;
  2746.  
  2747. *pCsr6Val |= CSR6_2114X_PS;
  2748. break;
  2749.     case IBLK_IS_EXT4 : /* Extended format block - type 4 */
  2750. DRV_LOG ( DRV_DEBUG_LOAD, 
  2751. "EXT4: mediaCode=%#x GPCtrl=%#x GPData=%#x Cmd=%#xn",
  2752. IBLK_EXT4_MCODE(pInfoBlock),
  2753. IBLK_EXT4_GPC(pInfoBlock),
  2754. IBLK_EXT4_GPD(pInfoBlock),
  2755. IBLK_EXT4_CMD(pInfoBlock), 0, 0);
  2756. /* setup the GP port */
  2757. DEC_CSR_UPDATE (CSR15, IBLK_EXT4_GPC(pInfoBlock) << 8);
  2758. DEC_CSR_UPDATE (CSR15, IBLK_EXT4_GPD(pInfoBlock) << 8);
  2759. NSDELAY(150);
  2760. /* Get CSR6 settings */
  2761. mediaCmd = IBLK_EXT4_CMD(pInfoBlock);
  2762. if (mediaCmd & IBLK_EXT4_CMD_PS)
  2763.     *pCsr6Val |= CSR6_2114X_PS;
  2764. if (mediaCmd & IBLK_EXT4_CMD_TTM)
  2765.     *pCsr6Val |= CSR6_2114X_TTM;
  2766. if (mediaCmd & IBLK_EXT4_CMD_PCS)
  2767.     *pCsr6Val |= CSR6_2114X_PCS;
  2768. if (mediaCmd & IBLK_EXT4_CMD_SCR)
  2769.     *pCsr6Val |= CSR6_2114X_SCR;
  2770. break;
  2771.     case IBLK_IS_EXT5 : /* Extended format block - type 5 */
  2772. DRV_LOG ( DRV_DEBUG_LOAD, "EXT5: Rst Seq length=%#xn",
  2773. IBLK_EXT5_RESET_LEN(pInfoBlock), 0, 0, 0, 0, 0);
  2774. /* Reset the media */
  2775. /* not implemented */
  2776. break;
  2777.     default :
  2778. return (ERROR);
  2779.     }
  2780.     else
  2781. return (ERROR);
  2782.  
  2783.     return (OK);
  2784.     }
  2785. /*******************************************************************************
  2786. *
  2787. * dec21x4xInitialReset - perform an initial reset on the DEC chip
  2788. *
  2789. * This routine performs an initial reset on the DEC chip having started a
  2790. * transmission. This is to prevent subsequent transmissions from hanging
  2791. * up.
  2792. *
  2793. * RETURN: N/A
  2794. */
  2795. LOCAL void dec21x4xInitialReset(DRV_CTRL* pDrvCtrl)
  2796.     {
  2797.     char  dummy_buffer[DUMMY_BUFFER_SIZE];
  2798.     ULONG tmd[4];
  2799.     /* Fill in the dummy buffer transmit descriptor */
  2800.     tmd[TDESC0] = PCISWAP (TDESC0_OWN);
  2801.     tmd[TDESC1] = PCISWAP (TDESC1_IC  |
  2802.            TDESC1_LS  |
  2803.            TDESC1_FS  |
  2804.            TDESC1_TER |
  2805.            (DUMMY_BUFFER_SIZE & TDESC1_TBS1_MSK));
  2806.     tmd[TDESC2] = PCISWAP ((ULONG) dummy_buffer);
  2807.     tmd[TDESC3] = 0;
  2808.     /* Start the transmission */
  2809.     DEC_CSR_WRITE (CSR4, (ULONG) &tmd);
  2810.     DEC_CSR_WRITE (CSR7, 0);
  2811.     DEC_CSR_WRITE (CSR6, CSR6_2114X_MB1 |
  2812.  CSR6_2114X_TTM |
  2813.  CSR6_2114X_SF  |
  2814.  CSR6_2114X_PS  |
  2815.  CSR6_ST        |
  2816.  CSR6_OM_INT);
  2817.     DEC_CSR_WRITE (CSR1, CSR1_TPD);
  2818.     DELAY (0x8000);
  2819.     /* Reset the device while transmitting */
  2820.     DEC_CSR_WRITE (CSR0, DEC_CSR_READ(CSR0) | CSR0_SWR);
  2821.     }
  2822. #ifdef DRV_DEBUG
  2823. /*******************************************************************************
  2824. *
  2825. * dec21x4xDebugCsrShow - show CSRs register
  2826. *
  2827. * This routine shows CSRs registers used for host communication. 
  2828. *
  2829. * RETURNS: N/A
  2830. *
  2831. * NOMANUAL
  2832. */
  2833.  
  2834. void dec21x4xDebugCsrShow (void)
  2835.     {
  2836.     ULONG devAdrs = pDrvCtrlDbg->devAdrs;
  2837.     
  2838.     printf ("n");
  2839.     printf ("CSR0t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR0));
  2840.     printf ("CSR1t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR1));
  2841.     printf ("CSR2t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR2));
  2842.     printf ("CSR3t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR3));
  2843.     printf ("CSR4t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR4));
  2844.     printf ("CSR5t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR5));
  2845.     printf ("CSR6t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR6));
  2846.     printf ("CSR7t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR7));
  2847.     printf ("CSR8t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR8));
  2848.     printf ("CSR9t 0x%xn", (int) dec21x4xCsrRead(devAdrs, CSR9));
  2849.     printf ("CSR10t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR10));
  2850.     printf ("CSR11t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR11));
  2851.     printf ("CSR12t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR12));
  2852.     printf ("CSR13t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR13));
  2853.     printf ("CSR14t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR14));
  2854.     printf ("CSR15t 0x%xn",(int) dec21x4xCsrRead(devAdrs, CSR15));
  2855.     }
  2856. /*******************************************************************************
  2857. *
  2858. * dec21x4xDebugTxDShow - show the transmit descriptor's informations
  2859. *
  2860. * This routine shows the informations of a specific transmit descriptor.
  2861. *
  2862. * RETURNS: N/A
  2863. *
  2864. * NOMANUAL
  2865. */
  2866. void dec21x4xDebugTxDShow
  2867.     (
  2868.     int numTxD
  2869.     )
  2870.     {
  2871.     DEC_TD *pTxD = &pDrvCtrlDbg->txRing[numTxD];
  2872.     printf ("txd[%d] at 0x%x:n", numTxD, (int)pTxD);
  2873.     printf ("tDesc0=0x%x tDesc1=0x%x tDesc2=0x%x tDesc3=0x%xn",
  2874.             (int) PCISWAP (pTxD->tDesc0), (int) PCISWAP (pTxD->tDesc1),
  2875.             (int) PCISWAP (pTxD->tDesc2), (int) PCISWAP (pTxD->tDesc3));
  2876.     }
  2877. /*******************************************************************************
  2878. *
  2879. * dec21x4xDebugRxDShow - show the receive descriptor's informations
  2880. *
  2881. * This routine shows the informations of a specific receive descriptor.
  2882. *
  2883. * RETURNS: N/A
  2884. *
  2885. * NOMANUAL
  2886. */
  2887. void dec21x4xDebugRxDShow
  2888.     (
  2889.     int numRxD
  2890.     )
  2891.     {
  2892.     DEC_RD *pRxD = &pDrvCtrlDbg->rxRing[numRxD];
  2893.     printf ("rxd[%d] at 0x%x:n", numRxD, (int)pRxD);
  2894.     printf ("rDesc0=0x%x rDesc1=0x%x rDesc2=0x%x rDesc3=0x%xn",
  2895.             (int) PCISWAP (pRxD->rDesc0), (int) PCISWAP (pRxD->rDesc1),
  2896.             (int) PCISWAP (pRxD->rDesc2), (int) PCISWAP (pRxD->rDesc3));
  2897.     }
  2898. /*******************************************************************************
  2899. *
  2900. * dec21x4xDebugShow - show the status of the control structure 
  2901. *
  2902. * This routine shows the current status of the driver control structure.
  2903. *
  2904. * RETURNS: N/A
  2905. *
  2906. * NOMANUAL
  2907. */
  2908. void dec21x4xDebugShow(void)
  2909.     {
  2910.     printf ("pDrvCtrl=0x%x txNum=%d txIndex=%d txDiIndex=%dn",
  2911.             (int) pDrvCtrlDbg,
  2912.             pDrvCtrlDbg->numTds,
  2913.             pDrvCtrlDbg->txIndex,
  2914.             pDrvCtrlDbg->txDiIndex);
  2915.     
  2916.     printf ("rxNum=%d rxIndex=%dn",
  2917.             pDrvCtrlDbg->numRds,
  2918.             pDrvCtrlDbg->rxIndex);
  2919.     }
  2920. /*******************************************************************************
  2921. *
  2922. * dec21x4xDebugEAdrsDisplay - display the ethernet address
  2923. *
  2924. * This routine display the physical ethernet address of the board.
  2925. *
  2926. * RETURNS: N/A
  2927. *
  2928. * NOMANUAL
  2929. */
  2930. void dec21x4xDebugEAdrsDisplay
  2931.     (
  2932.     UINT8 *pAddr
  2933.     )
  2934.     {
  2935.     printf ("EtherAddr=%x:%x:%x:%x:%x:%xn",
  2936.             pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);
  2937.     }
  2938. /*******************************************************************************
  2939. *
  2940. * dec21x4xDebugMcAdd - Add a multicast address
  2941. *
  2942. * This routine adds a multicast address to whatever the driver
  2943. * is already listening for.
  2944. *
  2945. * RETURNS: N/A
  2946. *
  2947. * NOMANUAL
  2948. */
  2949. void dec21x4xDebugMcAdd (char *eAddr)
  2950.     {
  2951.     dec21x4xMCastAddrAdd (pDrvCtrlDbg, eAddr);
  2952.     }
  2953. /*******************************************************************************
  2954. *
  2955. * dec21x4xDebugMcDel - delete a multicast address
  2956. *
  2957. * This routine deletes a multicast address from the current list of
  2958. * multicast addresses.
  2959. *
  2960. * RETURNS: N/A
  2961. *
  2962. * NOMANUAL
  2963. */
  2964. void dec21x4xDebugMcDel (char *eAddr)
  2965.     {
  2966.     dec21x4xMCastAddrDel (pDrvCtrlDbg, eAddr);
  2967.     }
  2968. /*******************************************************************************
  2969. *
  2970. * dec21x4xDebugMcShow - show all multicast addresses
  2971. *
  2972. * This routine shows all multicast addresses from the current list of
  2973. * multicast addresses.
  2974. *
  2975. * RETURNS: N/A
  2976. *
  2977. * NOMANUAL
  2978. */
  2979. void dec21x4xDebugMcShow (void)
  2980.     {
  2981.     ETHER_MULTI  *pMCastNode;
  2982.     pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrlDbg->endObj);
  2983.     while (pMCastNode != NULL)
  2984.         {
  2985.         dec21x4xDebugEAdrsDisplay (pMCastNode->addr);
  2986.         pMCastNode = END_MULTI_LST_NEXT (pMCastNode);
  2987.         }
  2988.     }
  2989. char dec21x4xDebugSerialRom[128];
  2990. /*******************************************************************************
  2991. *
  2992. * dec21x4xDebugSerialRomUpload - load data from the serial rom 
  2993. *
  2994. * This routine loads the serial rom into an array. 
  2995. *
  2996. * RETURNS: N/A
  2997. *
  2998. * NOMANUAL
  2999. */
  3000. void dec21x4xDebugSerialRomUpload(void)
  3001.     {
  3002.     int  count;
  3003.     USHORT  *pSerialRom = (USHORT *)dec21x4xDebugSerialRom;
  3004.     memset (dec21x4xDebugSerialRom, 0, 128);
  3005.     for (count=0; count<64; count++)
  3006.         *pSerialRom++ = dec2114xSromWordRead (pDrvCtrlDbg, count);
  3007.     }
  3008. /*******************************************************************************
  3009. *
  3010. * dec21x4xDebugReset - stop and restart the driver 
  3011. *
  3012. * This routine stops and restarts the driver
  3013. *
  3014. * RETURNS: OK always
  3015. *
  3016. * NOMANUAL
  3017. */
  3018. int dec21x4xDebugReset(void)
  3019.     {
  3020.     dec21x4xStop (pDrvCtrlDbg);
  3021.     taskDelay (2);
  3022.     netJobAdd ((FUNCPTR)dec21x4xRestart, (int)pDrvCtrlDbg, 0, 0, 0, 0);
  3023.     return (OK);
  3024.     }
  3025. #endif /* DRV_DEBUG */