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

VxWorks

开发平台:

C/C++

  1.  /* if_dcFast.c - DEC 21040 PCI Ethernet LAN network interface driver */
  2. /* Copyright 1984-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01e,06mar96,rcp  added support for the DEC21140 100Mbit Controller
  8. 01d,05sep95,vin  added filter Frame setup, added PROMISCOUS MODE to ioctl,
  9.  changed all ln references to dc, added flag DC_MULTICAST_FLAG.
  10. 01c,05apr95,vin  added AUI/10BASE-T dynamic configuration support. 
  11. 01b,31mar95,caf  changed name from "dcPci" to "dc".
  12. 01a,03mar95,vin  written.
  13. */
  14. /* FROM ROB PERSONS - Motorola Computer Group (March 06, 1996)
  15. The comments below describe the primary operation and configuration of
  16. the DEC 21X40 driver.  Differences between the two DEC parts will be 
  17. outlined in this section and how the original driver was modified to
  18. accomodate the differences.
  19. The DEC21140 is very similar to the original DEC21040 but it also has the
  20. ability to operate on networks at 100-Mb/s along with 10-Mb/s.  The
  21. physical interface is no longer part of the chip so configuration of
  22. the CSR registers which control the AUI and TP interfaces is no longer
  23. applicable.  This part now provides 100-Mb/s MII/SYM 10-Mb/s Serial
  24. intefaces which are then converted to the appropriate external interface
  25. with some additional hardware.  Most of the driver will be uneffected
  26. by the new part.  
  27. In the early stages of the driver initialization, the driver will
  28. use the Configuration ID Register (CFID) to determine which of the
  29. two parts is to be used.  A global flag will indicate which device
  30. is in use and its state will be used along with the driver modifications
  31. to accomodate the DEC21140. 
  32. The Status Register (CSR5) has three bits which have different behavior.
  33. Bit 12 (Link Fail Status) and Bit 10 (AUI/TP Status) are no longer used
  34. by the DEC21140.  Bit 11 in the DEC21040 indicates a Full-Duplex Short
  35. Frame was Received which in the DEC21140 it indicates the General Purpose
  36. Timer(GPT)  has expired.  The GPT is a new feature with the DEC21140.  Bit 
  37. 11 is currently not used in the drive and there are no plans on adding support 
  38. for the GPT so at this time it will be ignored.
  39. The Operating Mode Register (CSR6) is significantly different.  Many of the
  40. bits reflect the difference in the MII/SYM interface for the 100-Mb/s 
  41. interface.  To make the driver as flexible as possible, logic will be added 
  42. to the dcattach function to allow for the configuration of all these 
  43. control bits at driver configuration.  The following modes will be added:
  44. DEC21140 Flag - This flag indicates the driver will be operating with
  45.   a DEC21140 chip and not the DEC21040.
  46. 100Mb/s Mode - This flag will be used to set a bits in the CSR6 for the
  47.   DEC21140.  The Transmit Threshold Mode and Heartbeat Disable
  48.   bits will be effect.
  49. Scramble Mode  - The scrambler function is active and the MII/SYM port 
  50.           transmits and received scrambled symbols.
  51. PCS Function - The PCS functions are active and MII/SYM port operates
  52.   in symbol mode.  All MII/SYM port cont andol signals are 
  53.   generated internally bits will be effect.
  54. Port Select - When selected the MII/SYM mode is active.  All 100-Mb/s
  55.   modes require this.
  56. Full Duplex Mode- When selected the Lance Chip Operates in Full Duplex Mode.
  57.   It is important that the can operate in Full Duplex mode
  58.   as well. 
  59. Int Loopback    - An additional mode was added for doing internal loopback.
  60. Ext Loopback    - An additional mode was added for doing external loopback.
  61. HB Enable - An additional mode was added for testing, enableing heartb.
  62. If none of these mode bits are selected, the DEC21140 will default to the
  63. MII interface with transmit FIFO thresholds appropriate for 10-Mb/s.
  64. Additional code will be added to deal with the different Serial ROM interface.
  65. The DEC21140 now has a new interface to access a R/W ROM part to store ethernet
  66. addresses.  The dcEnetAddrGet will be modified to add the proper logic to
  67. read the DEC21140 Serial ROM interface.  No logic will be added to reprogram
  68. the value.  It turns out the DEC PMC 520-AA only stores the last 2 bytes of the
  69. ethernet address in the ROM.  The driver will make the assumption that the
  70. VENDOR ID portion extends to from 0-3 where bytes 0-2 are the manufacturers
  71. assigned values and byte 3 is assigned by DEC for the class of products.
  72. The remaining Host to Controller interface is identical and should not be 
  73. effected by the new part.
  74. */
  75. /*
  76. This module implements the DEC 21040-PCI Ethernet 32 bit network interface
  77. driver.
  78. The DEC 21040-PCI ethernet controller is inherently little endian because
  79. the chip is designed to operate on a PCI bus which is a little endian
  80. bus. The software interface to the driver is divided into three parts.
  81. The first part is the PCI configuration registers and their set up. 
  82. This part is done at the BSP level in the various BSPs which use this
  83. driver. The second and third part are dealt in the driver. The second
  84. part of the interface comprises of the I/O control registers and their
  85. programming. The third part of the interface comprises of the descriptors
  86. and the buffers. 
  87. This driver is designed to be moderately generic, operating unmodified
  88. across the range of architectures and targets supported by VxWorks.  To
  89. achieve this, the driver must be given several target-specific parameters,
  90. and some external support routines must be provided.  These parameters,
  91. and the mechanisms used to communicate them to the driver, are detailed
  92. below.  If any of the assumptions stated below are not true for your
  93. particular hardware, this driver will probably not function correctly with
  94. it.
  95. This driver supports upto 4 lance units per CPU.  The driver can be
  96. configured to support big-endian or little-endian architectures.  It
  97. contains error recovery code to handle known device errata related to DMA
  98. activity.
  99. This driver configures the 10BASE-T interface by default and waits for
  100. two seconds to check the status of the link. If the link status is fail
  101. then it configures the AUI interface. 
  102. Big endian processors can be connected to the PCI bus through some controllers
  103. which take care of hardware byte swapping. In such cases all the registers 
  104. which the chip DMA s to have to be swapped and written to, so that when the
  105. hardware swaps the accesses, the chip would see them correctly. The chip still
  106. has to be programmed to operated in little endian mode as it is on the PCI bus.
  107. If the cpu board hardware automatically swaps all the accesses to and from the
  108. PCI bus, then input and output byte stream need not be swapped. 
  109. BOARD LAYOUT
  110. This device is on-board.  No jumpering diagram is necessary.
  111. EXTERNAL INTERFACE
  112. This driver provides the standard external interface with the following
  113. exceptions.  All initialization is performed within the attach routine;
  114. there is no separate initialization routine.  Therefore, in the global interface
  115. structure, the function pointer to the initialization routine is NULL.
  116. The only user-callable routine is dcattach(), which publishes the `dc'
  117. interface and initializes the driver and device.
  118. TARGET-SPECIFIC PARAMETERS
  119. .iP "bus mode"
  120. This parameter is a global variable that can be modified at run-time.
  121. The LAN control register #0 determines the bus mode of the device,
  122. allowing the support of big-endian and little-endian architectures.
  123. This parameter, defined as "ULONG dcCSR0Bmr", is the value that will
  124. be placed into LANCE control register #0. The default is mode is little
  125. Endian.
  126. For information about changing this parameter, see the manual
  127. .I "DEC  Local Area Network Controller DEC21040 or DEC21140 for PCI."
  128. .iP "base address of device registers"
  129. This parameter is passed to the driver by dcattach().
  130. .iP "interrupt vector"
  131. This parameter is passed to the driver by dcattach().
  132. This driver configures the LANCE device to generate hardware interrupts
  133. for various events within the device; thus it contains
  134. an interrupt handler routine.  The driver calls intConnect() to connect 
  135. its interrupt handler to the interrupt vector generated as a result of 
  136. the LANCE interrupt.
  137. .iP "interrupt level"
  138. This parameter is passed to the driver by dcattach().
  139. Some targets use additional interrupt controller devices to help organize
  140. and service the various interrupt sources.  This driver avoids all
  141. board-specific knowledge of such devices.  During the driver's
  142. initialization, the external routine sysLanIntEnable() is called to
  143. perform any board-specific operations required to allow the servicing of a
  144. LANCE interrupt.  For a description of sysLanIntEnable(), see "External
  145. Support Requirements" below.
  146. This parameter is passed to the external routine.
  147. .iP "shared memory address"
  148. This parameter is passed to the driver by dcattach().
  149. The LANCE device is a DMA type of device and typically shares access to
  150. some region of memory with the CPU.  This driver is designed for systems
  151. that directly share memory between the CPU and the LANCE.  It
  152. assumes that this shared memory is directly available to it
  153. without any arbitration or timing concerns.
  154. This parameter can be used to specify an explicit memory region for use
  155. by the LANCE.  This should be done on hardware that restricts the LANCE
  156. to a particular memory region.  The constant NONE can be used to indicate
  157. that there are no memory limitations, in which case, the driver 
  158. attempts to allocate the shared memory from the system space.
  159. .iP "shared memory size"
  160. This parameter is passed to the driver by dcattach().
  161. This parameter can be used to explicitly limit the amount of shared
  162. memory (bytes) this driver will use.  The constant NONE can be used to
  163. indicate no specific size limitation.  This parameter is used only if
  164. a specific memory region is provided to the driver.
  165. .iP "shared memory width"
  166. This parameter is passed to the driver by dcattach().
  167. Some target hardware that restricts the shared memory region to a
  168. specific location also restricts the access width to this region by
  169. the CPU.  On these targets, performing an access of an invalid width
  170. will cause a bus error.
  171. This parameter can be used to specify the number of bytes of access
  172. width to be used by the driver during access to the shared memory.
  173. The constant NONE can be used to indicate no restrictions.
  174. Current internal support for this mechanism is not robust; implementation 
  175. may not work on all targets requiring these restrictions.
  176. .iP "shared memory buffer size"
  177. This parameter is passed to the driver by dcattach().
  178. The driver and LANCE device exchange network data in buffers.  This
  179. parameter permits the size of these individual buffers to be limited.
  180. A value of zero indicates that the default buffer size should be used.
  181. The default buffer size is large enough to hold a maximum-size Ethernet
  182. packet.
  183. .iP "pci Memory base"
  184. This parameter is passed to the driver by dcattach(). This parameter
  185. gives the base address of the main memory on the PCI bus. 
  186. .iP "dcOpMode"
  187. This parameter is passed to the driver by dcattach(). This parameter
  188. gives the mode of initialization of the device. The mode flags for both
  189. the DEC21040 and DEC21140 interfaces are listed below.  
  190. DC_PROMISCUOUS_FLAG     0x01 
  191. DC_MULTICAST_FLAG 0x02
  192. The mode flags specific to the DEC21140 interface are listed below.
  193. DC_100_MB_FLAG          0X04
  194. DC_21140_FLAG           0x08
  195. DC_SCRAMBLER_FLAG       0X10
  196. DC_PCS_FLAG             0x20
  197. DC_PS_FLAG              0x40
  198. The Full Duplex Mode was added to the driver.
  199. DC_FULLDUPLEX_FLAG      0x80
  200. Loopback mode flags
  201. DC_ILOOPB_FLAG          0x100 
  202. DC_ELOOPB_FLAG          0x200
  203. DC_HBE_FLAG         0x400
  204. .iP "Ethernet address"
  205. This is obtained by the driver by reading an ethernet ROM register 
  206. interfaced with the device.
  207. .LP
  208. EXTERNAL SUPPORT REQUIREMENTS
  209. This driver requires one external support function:
  210. .iP "void sysLanIntEnable (int level)" "" 9 -1
  211. This routine provides a target-specific enable of the interrupt for
  212. the LANCE device.  Typically, this involves interrupt controller hardware,
  213. either internal or external to the CPU.
  214. This routine is called once, from the dcattach() routine.
  215. .LP
  216. SEE ALSO: ifLib, 
  217. .I "DECchip 21040 or 21140 Ethernet LAN Controller for PCI."
  218. */
  219. #include "vxWorks.h"
  220. #include "stdlib.h"
  221. #include "taskLib.h"
  222. #include "logLib.h"
  223. #include "intLib.h"
  224. #include "netLib.h"
  225. #include "stdio.h"
  226. #include "stdlib.h"
  227. #include "sysLib.h"
  228. #include "iv.h"
  229. #include "memLib.h"
  230. #include "cacheLib.h"
  231. #include "sys/ioctl.h"
  232. #include "etherLib.h"
  233. #ifndef DOC             /* don't include when building documentation */
  234. #include "net/mbuf.h"
  235. #endif  /* DOC */
  236. #include "net/protosw.h"
  237. #include "sys/socket.h"
  238. #include "errno.h"
  239. #include "net/if.h"
  240. #include "net/route.h"
  241. #include "netinet/in.h"
  242. #include "netinet/in_systm.h"
  243. #include "netinet/in_var.h"
  244. #include "netinet/ip.h"
  245. #include "netinet/if_ether.h"
  246. #include "net/if_subr.h"
  247. #include "semLib.h"
  248. #include "drv/netif/if_dcFast.h" /* device description header */
  249. /* defines */
  250. #define DC_BUFSIZ      (ETHERMTU + SIZEOF_ETHERHEADER + 6)
  251. #define MAX_UNITS       4 /* maximum units supported */
  252. #define DC_L_POOL 0x10 /* number of Rx loaner buffers in pool */
  253. #define LOOP_PER_NS 4
  254. #define DELAY(count) {
  255. volatile int cx = 0;
  256. for (cx = 0; cx < (count); cx++);
  257. }
  258. #define NSDELAY(nsec) {
  259. volatile int nx = 0;
  260. volatile int loop = (int)(nsec*LOOP_PER_NS);
  261. for (nx = 0; nx < loop; nx++);
  262. }
  263. /* RCP: Added DEC Part Check */
  264. #define DEC21140(x)  ((x & DC_21140_FLAG) && (x != NONE)) 
  265. /*
  266.  * If DC_KICKSTART_TX is TRUE the transmitter is kick-started to force a
  267.  * read of the transmit descriptors, otherwise the internal polling (1.6msec)
  268.  * will initiate a read of the descriptors.  This should be FALSE is there
  269.  * is any chance of memory latency or chip accesses detaining the LANCE DMA,
  270.  * which results in a transmitter UFLO error.  This can be changed with the
  271.  * global dcKickStartTx below.
  272.  */
  273. #define DC_KICKSTART_TX TRUE
  274. /* Cache macros */
  275. #define DC_CACHE_INVALIDATE(address, len) 
  276.         CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))
  277. #define DC_CACHE_VIRT_TO_PHYS(address) 
  278.         CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))
  279. #define DC_CACHE_PHYS_TO_VIRT(address) 
  280.         CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))
  281. /* memory to PCI address translation macros */
  282. #define PCI_TO_MEM_PHYS(pciAdrs) 
  283. ((pciAdrs) - (pDrvCtrl->pciMemBase))
  284. #define MEM_TO_PCI_PHYS(memAdrs) 
  285. ((memAdrs) + (pDrvCtrl->pciMemBase))
  286. /* Typedefs for external structures that are not typedef'd in their .h files */
  287. typedef struct mbuf MBUF;
  288. typedef struct arpcom IDR;                  /* Interface Data Record wrapper */
  289. typedef struct ifnet IFNET;                 /* real Interface Data Record */
  290. typedef struct sockaddr SOCK;
  291. /* The definition of the driver control structure */
  292. typedef struct drv_ctrl
  293.     {
  294.     IDR idr; /* Interface Data Record */
  295.     int dcNumRds; /* RMD ring size */
  296.     int rxIndex;                /* index into RMD ring */
  297.     DC_RDE * rxRing; /* RMD ring */
  298.     int dcNumTds; /* TMD ring size */
  299.     int txIndex; /* index into TMD ring */
  300.     int txDiIndex; /* disposal index into TMD ring */
  301.     DC_TDE * txRing; /* TMD ring */
  302.     BOOL        attached;               /* indicates unit is attached */
  303.     SEM_ID      TxSem;                  /* transmitter semaphore */
  304.     ULONG dcOpMode; /* mode of operation */
  305.     int         ivec;                   /* interrupt vector */
  306.     int         ilevel;                 /* interrupt level */
  307.     ULONG devAdrs;                /* device structure address */
  308.     ULONG pciMemBase; /* memory base as seen from PCI*/
  309.     int         memWidth;               /* width of data port */
  310.     CACHE_FUNCS cacheFuncs;             /* cache function pointers */
  311.     int nLoanRx; /* number of Rx buffers left to loan */
  312.     char *lPool[DC_L_POOL]; /* receive loaner pool ptrs */
  313.     UINT8 *pRefCnt[DC_L_POOL]; /* stack of reference count pointers */
  314.     UINT8 refCnt[DC_L_POOL]; /* actual reference count values */
  315.     ULONG * pFltrFrm; /* pointer to setup filter frame */
  316.     } DRV_CTRL;
  317. #define DRV_CTRL_SIZ sizeof(DRV_CTRL)
  318. #define RMD_SIZ sizeof(DC_RDE)
  319. #define TMD_SIZ sizeof(DC_TDE)
  320. /* globals */
  321. /*  RCP: Reference Removed for new function
  322. IMPORT void sysLanIntEnable ();
  323. */
  324. IMPORT BOOL arpresolve ();
  325. /*
  326. IMPORT unsigned char dcEnetAddr []; *//* Ethernet address to load into lance */
  327. BOOL  dcKickStartTx  = DC_KICKSTART_TX;
  328. ULONG dcCSR0Bmr = 0;
  329. /* locals */
  330. LOCAL DRV_CTRL  drvCtrl [MAX_UNITS]; /* array of driver control structs */
  331. LOCAL int dcNumRds  = NUM_RDS; /* number of ring descriptors */
  332. LOCAL int dcNumTds  = NUM_TDS; /* number of xmit descriptors */
  333. LOCAL int  dcLPool = DC_L_POOL;
  334. /* forward static functions */
  335. LOCAL void  dcReset (int unit);
  336. LOCAL void  dcInt (DRV_CTRL *pDrvCtrl);
  337. LOCAL void  dcHandleRecvInt (DRV_CTRL *pDrvCtrl);
  338. LOCAL STATUS  dcRecv (DRV_CTRL *pDrvCtrl, DC_RDE *rmd);
  339. LOCAL int  dcOutput (IDR *ifp, MBUF *m0, SOCK *dst);
  340. LOCAL int  dcIoctl (IDR *ifp, int cmd, caddr_t data);
  341. LOCAL int  dcChipReset (DRV_CTRL *pDrvCtrl);
  342. LOCAL DC_RDE * dcGetFullRMD (DRV_CTRL *pDrvCtrl);
  343. LOCAL void dcAuiTpInit (ULONG devAdrs);
  344. LOCAL void  dcCsrWrite (ULONG devAdrs, int reg, ULONG value);
  345. LOCAL ULONG  dcCsrRead (ULONG devAdrs, int reg);
  346. LOCAL void  dcRestart (int unit);
  347. LOCAL STATUS  dcEnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);
  348. LOCAL STATUS  dc21140EnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);
  349. LOCAL BOOL  convertDestAddr (IDR * pIDR, SOCK * pDestSktAddr,
  350.  char * pDestEnetAddr, u_short * pPacketType,
  351.  MBUF * pMbuf);
  352. LOCAL void  dcLoanFree (DRV_CTRL *pDrvCtrl, char *pRxBuf, UINT8 *pRef);
  353. LOCAL int dcFltrFrmSetup (DRV_CTRL * pDrvCtrl, char * pPhysAdrsTbl, 
  354. int tblLen);
  355. LOCAL int dcFltrFrmXmit (DRV_CTRL * pDrvCtrl, char * pPhysAdrsTbl,
  356.        int tblLen);
  357. #ifdef DC_DEBUG
  358. void dcCsrShow (ULONG devAdrs);
  359. #endif /* DC_DEBUG */
  360. /* RCP: Add utilities to read entries in Serial ROM for DEC21140 */
  361. USHORT dcReadRom (ULONG devAdrs, UCHAR lineCnt);
  362. int dcViewRom (ULONG devAdrs, UCHAR lineCnt, int cnt);
  363. /* RCP: Temporary reference of new global symbol */
  364. LOCAL STATUS sysLanIntEnable (int Level);
  365. /*******************************************************************************
  366. *
  367. * dcattach - publish the `dc' network interface.
  368. *
  369. * This routine publishes the `dc' interface by filling in a network interface
  370. * record and adding this record to the system list.  This routine also
  371. * initializes the driver and the device to the operational state.
  372. *
  373. * The <unit> parameter is used to specify the device unit to initialize.
  374. *
  375. * The <devAdrs> is used to specify the I/O address base of the device.
  376. *
  377. * The <ivec> parameter is used to specify the interrupt vector associated
  378. * with the device interrupt.
  379. *
  380. * The <ilevel> parater is used to specify the level of the interrupt which
  381. * the device would use.
  382. *
  383. * The <memAdrs> parameter can be used to specify the location of the
  384. * memory that will be shared between the driver and the device.  The value
  385. * NONE is used to indicate that the driver should obtain the memory.
  386. *
  387. * The <memSize> parameter is valid only if the <memAdrs> parameter is not
  388. * set to NONE, in which case <memSize> indicates the size of the
  389. * provided memory region.
  390. *
  391. * The <memWidth> parameter sets the memory pool's data port width (in bytes);
  392. * if it is NONE, any data width is used.
  393. *
  394. * The <pciMemBase> parameter defines the main memory base as seen from PCI bus.
  395. * The <dcOpMode> parameter defines the mode in which the device should be
  396. * operational.
  397. *
  398. * RCP:  Added for DEC21140 Serial ROM
  399. *
  400. * BUGS
  401. * To zero out LANCE data structures, this routine uses bzero(), which
  402. * ignores the <memWidth> specification and uses any size data access to
  403. * write to memory.
  404. *
  405. * RETURNS: OK or ERROR.
  406. */
  407. STATUS dcattach
  408.     (
  409.     int unit, /* unit number */
  410.     ULONG devAdrs, /* LANCE I/O address */
  411.     int ivec, /* interrupt vector */
  412.     int ilevel, /* interrupt level */
  413.     char * memAdrs, /* address of memory pool (-1 = malloc it) */
  414.     ULONG memSize, /* only used if memory pool is NOT malloc()'d */
  415.     int memWidth, /* byte-width of data (-1 = any width) */
  416.     ULONG pciMemBase, /* main memory base as seen from PCI bus */
  417.     int dcOpMode /* mode of operation */
  418.     )
  419.     {
  420.     DRV_CTRL * pDrvCtrl; /* pointer to drvctrl */
  421.     unsigned int sz; /* temporary size holder */
  422.     char * pShMem; /* start of the LANCE memory pool */
  423.     char * buf; /* temp buffer pointer */
  424.     void * pTemp; /* temp pointer */
  425.     DC_RDE * rmd; /* pointer to rcv descriptor */
  426.     DC_TDE * tmd; /* pointer to xmit descriptor */
  427.     int ix; /* counter */
  428. /* RCP: Added temporary value */
  429.     ULONG uTemp; /* temporary storage */
  430.     
  431.     /* Sanity check the unit number */
  432.     if (unit < 0 || unit >= MAX_UNITS)
  433.         return (ERROR);
  434.     /* Ensure single invocation per system life */
  435.     pDrvCtrl = & drvCtrl [unit];
  436.     if (pDrvCtrl->attached)
  437.         return (OK);
  438.     pDrvCtrl->ivec = ivec; /* interrupt vector */
  439.     pDrvCtrl->ilevel = ilevel; /* interrupt level */
  440.     pDrvCtrl->devAdrs = devAdrs; /* LANCE I/O address */
  441.     pDrvCtrl->pciMemBase  = pciMemBase; /* pci memory base */
  442.     pDrvCtrl->memWidth  = memWidth; /* memory width */
  443.     pDrvCtrl->dcOpMode = dcOpMode; /* mode of operation */
  444.     /* Publish the interface data record */
  445.     ether_attach (
  446.   & pDrvCtrl->idr.ac_if,
  447.   unit,
  448.   "dc",
  449.   (FUNCPTR) NULL,
  450.   (FUNCPTR) dcIoctl,
  451.   (FUNCPTR) dcOutput,
  452.   (FUNCPTR) dcReset
  453.  );
  454.     /* Create the transmit semaphore. */
  455.     if ((pDrvCtrl->TxSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  456.        SEM_INVERSION_SAFE)) == NULL)
  457.         {
  458.         printf ("dc: error creating transmitter semaphoren");
  459.         return (ERROR);
  460.         }
  461.     /* Establish size of shared memory region we require */
  462.     
  463.     if ((int) memAdrs != NONE)  /* specified memory pool */
  464. {
  465. sz  = (memSize - (RMD_SIZ + TMD_SIZ + (dcLPool * DC_BUFSIZ) + 
  466.   FLTR_FRM_SIZE))
  467.       / ((2 * DC_BUFSIZ) + RMD_SIZ + TMD_SIZ);
  468. dcNumRds = max (sz, MIN_RDS);
  469. dcNumTds = max (sz, MIN_TDS);
  470. }
  471.     /* add it all up - allow for alignment adjustment */
  472.     sz = ((dcNumRds + 1) * RMD_SIZ) + (dcNumRds * DC_BUFSIZ) +
  473.  ((dcNumTds + 1) * TMD_SIZ) + (dcNumTds * DC_BUFSIZ) + 
  474.  (DC_BUFSIZ * dcLPool) + FLTR_FRM_SIZE;
  475.     /* Establish a region of shared memory */
  476.     /* OK. We now know how much shared memory we need.  If the caller
  477.      * provides a specific memory region, we check to see if the provided
  478.      * region is large enough for our needs.  If the caller did not
  479.      * provide a specific region, then we attempt to allocate the memory
  480.      * from the system, using the cache aware allocation system call.
  481.      */
  482.     switch ( (int) memAdrs )
  483.         {
  484.         default :       /* caller provided memory */
  485.             if ( memSize < sz )     /* not enough space */
  486.                 {
  487.                 printf ( "dc: not enough memory providedn" );
  488.                 return ( ERROR );
  489.                 }
  490.             pShMem = memAdrs;             /* set the beginning of pool */
  491.             /* assume pool is cache coherent, copy null structure */
  492.             pDrvCtrl->cacheFuncs = cacheNullFuncs;
  493.             break;
  494.         case NONE :     /* get our own memory */
  495.             /* Because the structures that are shared between the device
  496.              * and the driver may share cache lines, the possibility exists
  497.              * that the driver could flush a cache line for a structure and
  498.              * wipe out an asynchronous change by the device to a neighboring
  499.              * structure. Therefore, this driver cannot operate with memory
  500.              * that is not write coherent.  We check for the availability of
  501.              * such memory here, and abort if the system did not give us what
  502.              * we need.
  503.              */
  504.             if (!CACHE_DMA_IS_WRITE_COHERENT ())
  505.                 {
  506.                 printf ( "dc: device requires cache coherent memoryn" );
  507.                 return (ERROR);
  508.                 }
  509.             pShMem = (char *) cacheDmaMalloc ( sz );
  510.             if ((int)pShMem == NULL)
  511.                 {
  512.                 printf ( "dc: system memory unavailablen" );
  513.                 return (ERROR);
  514.                 }
  515.             /* copy the DMA structure */
  516.             pDrvCtrl->cacheFuncs = cacheDmaFuncs;
  517.             break;
  518.         }
  519.     if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),dcInt,(int)pDrvCtrl)
  520.         == ERROR)
  521.         return (ERROR);
  522.     /*                        Turkey Carving
  523.      *                        --------------
  524.      *
  525.      *                          LOW MEMORY
  526.      *             |-------------------------------------|
  527.      *             |         The Rx descriptors          |
  528.      *             | (dcNumRds * sizeof (DC_RDE))        |
  529.      *             |-------------------------------------|
  530.      *             |          The receive buffers        |
  531.      *             |       (DC_BUFSIZ * dcNumRds)        |
  532.      *             |-------------------------------------|
  533.      *             |         The Rx loaner pool          |
  534.      *             |        (DC_BUFSIZ * dcLPool)        |
  535.      *             |-------------------------------------|
  536.      *             |         The Tx descriptors          |
  537.      *             | (dcNumTds *  sizeof (DC_TDE))       |
  538.      *             |-------------------------------------|
  539.      *             |           The transmit buffers      |
  540.      *             |       (DC_BUFSIZ * dcNumTds)        |
  541.      *             |-------------------------------------|
  542.      *             |           Setup Filter Frame        |
  543.      *             |           (FLTR_FRM_SIZE)           |
  544.      *             |-------------------------------------|
  545.      */
  546.     /* zero the shared memory */
  547.     bzero ( (char *) pShMem, (int) sz );
  548.     /* carve Rx memory structure */
  549.     pDrvCtrl->rxRing = (DC_RDE *) (((int)pShMem + 0x03) & ~0x03); /* wd align */
  550.     pDrvCtrl->dcNumRds = dcNumRds; /* receive ring size */
  551.     pDrvCtrl->rxIndex = 0;
  552.     /* Set up the Rx descriptors */
  553.     rmd = pDrvCtrl->rxRing;                      /* receive ring */
  554.     buf = (char *)(rmd + pDrvCtrl->dcNumRds);
  555.     for (ix = 0; ix < pDrvCtrl->dcNumRds; ix++, rmd++, buf += DC_BUFSIZ)
  556.         {
  557.         pTemp = DC_CACHE_VIRT_TO_PHYS (buf); /* convert to PCI  phys addr */
  558. pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  559. rmd->rDesc2 = PCISWAP((ULONG)pTemp); /* buffer address 1 */
  560. rmd->rDesc3 = 0; /* no second buffer */
  561. /* buffer size */
  562. rmd->rDesc1 = PCISWAP(RDESC1_RBS1_VAL(DC_BUFSIZ) | 
  563.       RDESC1_RBS2_VAL(0));
  564. if (ix == (pDrvCtrl->dcNumRds - 1)) /* if its is last one */
  565.     rmd->rDesc1 |= PCISWAP(RDESC1_RER); /* end of receive ring */
  566. rmd->rDesc0 = PCISWAP(RDESC0_OWN); /* give ownership to lance */
  567.         }
  568.     /* setup Rx loaner pool */
  569.     pDrvCtrl->nLoanRx = dcLPool;
  570.     for (ix = 0; ix < dcLPool; ix++, buf += DC_BUFSIZ)
  571. {
  572.         pDrvCtrl->lPool[ix] = buf;
  573.         pDrvCtrl->refCnt[ix] = 0;
  574.         pDrvCtrl->pRefCnt[ix] = & pDrvCtrl->refCnt[ix];
  575. }
  576.     /* carve Tx memory structure */
  577.     pDrvCtrl->txRing = (DC_TDE *) (((int)buf + 0x03) & ~0x03); /* word align */
  578.     pDrvCtrl->dcNumTds = dcNumTds; /* transmit ring size */
  579.     pDrvCtrl->txIndex = 0;
  580.     pDrvCtrl->txDiIndex = 0;
  581.     /* Setup the Tx descriptors */
  582.     tmd = pDrvCtrl->txRing;                 /* transmit ring */
  583.     buf = (char *)(tmd + pDrvCtrl->dcNumTds);
  584.     for (ix = 0; ix < pDrvCtrl->dcNumTds; ix++, tmd++, buf += DC_BUFSIZ)
  585.         {
  586.         pTemp = DC_CACHE_VIRT_TO_PHYS (buf); /* convert to PCI phys addr */
  587. pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  588. tmd->tDesc2 = PCISWAP((ULONG)pTemp); /* buffer address 1 */
  589. tmd->tDesc3 = 0; /* no second buffer */
  590. tmd->tDesc1 = PCISWAP((TDESC1_TBS1_PUT(0) |
  591.        TDESC1_TBS2_PUT(0) |
  592.        TDESC1_IC   |  /* intrpt on xmit */
  593.        TDESC1_LS          | /* last segment */
  594.        TDESC1_FS)); /* first segment */
  595. if (ix == (pDrvCtrl->dcNumTds - 1)) /* if its is last one */
  596.     tmd->tDesc1 |= PCISWAP(TDESC1_TER); /* end of Xmit ring */
  597. tmd->tDesc0 = 0 ; /* clear status */
  598.         }
  599.     /* carve Setup Filter Frame buffer */
  600.     
  601.     pDrvCtrl->pFltrFrm = (ULONG *)(((int)buf + 0x03) & ~0x03); /* word align */
  602.     buf += FLTR_FRM_SIZE;
  603.     /* Flush the write pipe */
  604.     CACHE_PIPE_FLUSH ();
  605.     /* Device Initialization */
  606.     dcChipReset (pDrvCtrl); /* reset the chip */
  607.     pTemp = DC_CACHE_VIRT_TO_PHYS (pDrvCtrl->rxRing);
  608.     pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  609.     dcCsrWrite (devAdrs, CSR3, ((ULONG)pTemp)); /* recv descriptor */
  610.     pTemp = DC_CACHE_VIRT_TO_PHYS (pDrvCtrl->txRing);
  611.     pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  612.     dcCsrWrite (devAdrs, CSR4, ((ULONG)pTemp)); /* xmit descriptor */
  613.     /* get the ethernet address */
  614. /* RCP: If DEC21140 make an alternate call */
  615.     if (!DEC21140(pDrvCtrl->dcOpMode))
  616.     {
  617.        if (dcEnetAddrGet (devAdrs, (char *) pDrvCtrl->idr.ac_enaddr, 6) != OK)
  618.    logMsg ("dc: error reading ethernet romn", 0,0,0,0,0,0);
  619.     }
  620.     else
  621. /* Get the ethernet address for the DEC21140 */
  622.     {
  623.        if (dc21140EnetAddrGet (devAdrs, (char *) pDrvCtrl->idr.ac_enaddr, 6) 
  624.    != OK)
  625.    logMsg ("dc21140: error reading ethernet romn", 0,0,0,0,0,0);
  626.     }
  627. /* RCP: Check to see if Full Duplex mode set */
  628.     if ((pDrvCtrl->dcOpMode & DC_FULLDUPLEX_FLAG) && 
  629. (pDrvCtrl->dcOpMode != NONE))
  630.      dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_FD));
  631. /* RCP: DEC21040 Specific Setup */
  632.     if (!DEC21140(pDrvCtrl->dcOpMode))
  633.     {
  634.         dcAuiTpInit (devAdrs); /* configure AUI or 10BASE-T */
  635. /* RCP: Added initialization of CSR6 to turn off Promiscuous and Multicast */
  636. dcCsrWrite (devAdrs, CSR6, 0x0);
  637.     }
  638.     else
  639.     {
  640. /* RCP: DEC21140 Setup - these modes must be set before start Xmitter */
  641. /* Default to 10BT */
  642.      uTemp = dcCsrRead(devAdrs, CSR6);
  643.         uTemp = uTemp | CSR6_TTM | CSR6_BIT25;
  644. /* Now verify the parameters passed to configure the interface further */
  645.     if ((pDrvCtrl->dcOpMode & DC_100_MB_FLAG) &&
  646.     (pDrvCtrl->dcOpMode != NONE))
  647. {
  648. /* Hard Coded values from SROM offset to start 100MB testing.  The actual code should
  649.    be imbellished to handle the configuration for other possible interfaces other then
  650.    100BaseTx.  This information will be stored in the DC21140 Info Leaf of the SROM.
  651.    In the case of the DEC520-AA PMC, the starting offset for the DEC21140 Info Leaf
  652.    is 0x41.  This location contains some basic capabilities of the interface and the
  653.    initial state of CSR12.  Also there is a block count for the total number of interfaces
  654.    supported by the interface card.  For testing the default values for the SYM_SCR 
  655.    (100MBaseTx) port will be used.  The information for this interface starts in offset
  656.    0x49. The configuration for Full Duplex starts in offset 0x4D.  Potentially the driver
  657.    could be altered to do some autosensing and configuration, but for now arguments will
  658.    be passed to the driver to configure it.
  659. */
  660.    dcCsrWrite (devAdrs, CSR12, INIT_CSR12);
  661.    dcCsrWrite (devAdrs, CSR12, SYM_MODE);
  662.    
  663.        if ((pDrvCtrl->dcOpMode & DC_HBE_FLAG) &&
  664. (pDrvCtrl->dcOpMode != NONE))
  665. uTemp = (uTemp & ~CSR6_TTM) | CSR6_PS;
  666.    else
  667. uTemp = (uTemp & ~CSR6_TTM) | CSR6_PS | CSR6_HBD ;
  668.    uTemp = uTemp | (((pDrvCtrl->dcOpMode & DC_SCRAMBLER_FLAG) &&
  669.   (pDrvCtrl->dcOpMode != NONE)) ? CSR6_SCR : 0) |
  670.   (((pDrvCtrl->dcOpMode & DC_PCS_FLAG) &&
  671.   (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PCS : 0);
  672. }
  673. dcCsrWrite (devAdrs, CSR6, uTemp);
  674.     }
  675. /* RCP: End of DEC21140 Code Addition */
  676.     /* clear the status register */
  677.     dcCsrWrite (devAdrs, CSR5, 0xffffffff);
  678.     /* set the operating mode to start Xmitter only */
  679. /* RCP: Modify this call to accomodate DEC21140 , add the Setting of Bit 25*/
  680.     dcCsrWrite (devAdrs, CSR6, 
  681.        (dcCsrRead (devAdrs, CSR6) |  CSR6_ST | CSR6_BIT25));
  682. /* RCP: Added Loopback modes */
  683.     if ((pDrvCtrl->dcOpMode & DC_ILOOPB_FLAG) &&
  684. (pDrvCtrl->dcOpMode != NONE))
  685. /* RCP: Internal loopback selected */
  686.      dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_OM_ILB));
  687.     else
  688.      if ((pDrvCtrl->dcOpMode & DC_ELOOPB_FLAG) &&
  689.     (pDrvCtrl->dcOpMode != NONE))
  690. /* RCP: External loopback selected */
  691.    dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_OM_ELB));
  692.     /* Xmit a Filter Setup Frame */
  693.     dcFltrFrmXmit (pDrvCtrl, (char *) pDrvCtrl->idr.ac_enaddr, 1);
  694.     /* set operating mode any additional operational mode set by user */
  695.     dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | 
  696.                                CSR6_SR                   | /* start receiver */
  697.            (((pDrvCtrl->dcOpMode & DC_MULTICAST_FLAG) &&
  698.  (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PM: 0) |
  699.            (((pDrvCtrl->dcOpMode & DC_PROMISCUOUS_FLAG) &&
  700.  (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PR: 0)
  701.       )); 
  702.     /* set up the interrupts */
  703. /* RCP: Modified to accomodate DEC21140 */
  704.     if (!DEC21140(pDrvCtrl->dcOpMode))
  705.      dcCsrWrite (devAdrs, CSR7, (
  706.        CSR7_NIM | /* normal interrupt mask */
  707.        CSR7_RIM | /* rcv  interrupt mask */
  708.        CSR7_TIM | /* xmit interrupt mask */
  709.        CSR7_TUM | /* xmit buff unavailble mask */
  710.        CSR7_AIM | /* abnormal interrupt mask */
  711.        CSR7_SEM | /* system error mask */
  712.        CSR7_LFM | /* link fail mask */
  713.        CSR7_RUM /* rcv buff unavailable mask */
  714.        ));
  715. /* RCP: Removed CSR7_LFM for DEC21140 */
  716.     else
  717.      dcCsrWrite (devAdrs, CSR7, (
  718.        CSR7_NIM | /* normal interrupt mask */
  719.        CSR7_RIM | /* rcv  interrupt mask */
  720.        CSR7_TIM | /* xmit interrupt mask */
  721.        CSR7_TUM | /* xmit buff unavailble mask */
  722.        CSR7_AIM | /* abnormal interrupt mask */
  723.        CSR7_SEM | /* system error mask */
  724.        CSR7_RUM /* rcv buff unavailable mask */
  725.        ));
  726.     sysLanIntEnable (ilevel);                   /* enable LANCE interrupts */
  727.     pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);
  728.     /* Set our flag */
  729.     pDrvCtrl->attached = TRUE;
  730.     return (OK);
  731.     }
  732. /*******************************************************************************
  733. *
  734. * dcReset - reset the interface
  735. *
  736. * Mark interface as inactive & reset the chip
  737. */
  738. LOCAL void dcReset
  739.     (
  740.     int unit
  741.     )
  742.     {
  743.     DRV_CTRL *pDrvCtrl = & drvCtrl [unit];
  744.     pDrvCtrl->idr.ac_if.if_flags = 0;
  745.     dcChipReset (pDrvCtrl);                           /* reset LANCE */
  746.     }
  747. /*******************************************************************************
  748. *
  749. * dcInt - handle controller interrupt
  750. *
  751. * This routine is called at interrupt level in response to an interrupt from
  752. * the controller.
  753. */
  754. LOCAL void dcInt
  755.     (
  756.     DRV_CTRL * pDrvCtrl /* pointer to device control struct */
  757.     )
  758.     {
  759.     DC_TDE * tmd; /* pointer to Xmit ring descriptor */
  760.     ULONG stat; /* status register */
  761.     ULONG devAdrs; /* device address */
  762.     devAdrs = pDrvCtrl->devAdrs;
  763.     /* Read the device status register */
  764.     stat = dcCsrRead(devAdrs, CSR5);
  765.     /* clear the interrupts */
  766.     dcCsrWrite(devAdrs, CSR5, stat);
  767.     /* If false interrupt, return. */
  768.     if ( ! (stat & (CSR5_NIS | CSR5_AIS)) )
  769.         return;
  770.     /* Check for system error */
  771.     if (stat & CSR5_SE)
  772.         {
  773.         ++pDrvCtrl->idr.ac_if.if_ierrors;
  774.         /* restart chip on fatal error */
  775. pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
  776. (void) netJobAdd (
  777.  (FUNCPTR)dcRestart,
  778.  pDrvCtrl->idr.ac_if.if_unit,
  779.  0,0,0,0
  780.  );
  781. return;
  782.         }
  783.     /* Have netTask handle any input packets */
  784.     if ((stat & CSR5_RI) && (!(stat & CSR5_RPS)))
  785.         {
  786. (void) netJobAdd (
  787.  (FUNCPTR)dcHandleRecvInt,
  788.  (int)pDrvCtrl,
  789.  0,0,0,0
  790.  );
  791. /* disable the Rx intr, re-enable in dcHandleRecvInt() */
  792. dcCsrWrite(devAdrs, CSR7, (stat & ~CSR7_RIM));
  793.         }
  794.     /*
  795.      * Did LANCE update any of the TMD's?
  796.      * If not then don't bother continuing with transmitter stuff
  797.      */
  798.     if (!(stat & CSR5_TI))
  799.         return;
  800.     while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)
  801.         {
  802.         /* disposal has not caught up */
  803.         tmd = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;
  804.         /* if the buffer is still owned by LANCE, don't touch it */
  805.         DC_CACHE_INVALIDATE (tmd, TMD_SIZ);
  806.         if (tmd->tDesc0 & PCISWAP(TDESC0_OWN))
  807.             break;
  808.         /* now bump the tmd disposal index pointer around the ring */
  809.         pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->dcNumTds;
  810.         /*
  811.          * TDESC0.ES is an "OR" of LC, NC, UF, EC.
  812.          * here for error conditions.
  813.          */
  814.         if (tmd->tDesc0 & PCISWAP(TDESC0_ES))
  815.             {
  816.             pDrvCtrl->idr.ac_if.if_oerrors++;     /* output error */
  817.             pDrvCtrl->idr.ac_if.if_opackets--;
  818.             /* If error was due to excess collisions, bump the collision
  819.              * counter.
  820.              */
  821.             if (tmd->tDesc0 & PCISWAP(TDESC0_EC))
  822.                 pDrvCtrl->idr.ac_if.if_collisions += 16;
  823.     /* bump the collision counter if late collision */
  824.             if (tmd->tDesc0 & PCISWAP(TDESC0_LC))
  825.                 pDrvCtrl->idr.ac_if.if_collisions++;
  826.             /* check for no carrier */
  827.             if (tmd->tDesc0 & PCISWAP(TDESC0_NC | TDESC0_LO | TDESC0_LF))
  828.                 logMsg ("dc%d: no carriern",
  829.                     pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0);
  830.             /* Restart chip on fatal errors.
  831.              * The following code handles the situation where the transmitter
  832.              * shuts down due to an underflow error.  This is a situation that
  833.              * will occur if the DMA cannot keep up with the transmitter.
  834.              * It will occur if the LANCE is being held off from DMA access
  835.              * for too long or due to significant memory latency.  DRAM
  836.              * refresh or slow memory could influence this.  Many
  837.              * implementation use a dedicated LANCE buffer.  This can be
  838.              * static RAM to eliminate refresh conflicts; or dual-port RAM
  839.              * so that the LANCE can have free run of this memory during its
  840.              * DMA transfers.
  841.              */
  842.             if (tmd->tDesc0 & PCISWAP(TDESC0_UF))
  843.                 {
  844.                 pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
  845.                 (void) netJobAdd (
  846.                                  (FUNCPTR)dcRestart,
  847.                                  pDrvCtrl->idr.ac_if.if_unit,
  848.                                  0,0,0,0
  849.                                  );
  850.                 return;
  851.                 }
  852.             }
  853. tmd->tDesc0 = 0; /* clear all error & stat stuff */
  854.         }
  855.     /* Flush the write pipe */
  856.     CACHE_PIPE_FLUSH ();
  857.     }
  858. /*******************************************************************************
  859. *
  860. * dcHandleRecvInt - task level interrupt service for input packets
  861. *
  862. * This routine is called at task level indirectly by the interrupt
  863. * service routine to do any message received processing.
  864. */
  865. LOCAL void dcHandleRecvInt
  866.     (
  867.     DRV_CTRL * pDrvCtrl /* pointer to device control struct */
  868.     )
  869.     {
  870.     DC_RDE * rmd; /* pointer to Rx ring descriptor */
  871.     while ((rmd = dcGetFullRMD (pDrvCtrl)) != NULL)
  872.      dcRecv (pDrvCtrl, rmd);
  873.     /* re-enable the Rx interrupt */
  874.     dcCsrWrite (pDrvCtrl->devAdrs, CSR7, (dcCsrRead (pDrvCtrl->devAdrs, CSR7) |
  875.   CSR7_RIM));
  876.     }
  877. /*******************************************************************************
  878. *
  879. * dcGetFullRMD - get next received message RMD
  880. *
  881. * Returns ptr to next Rx desc to process, or NULL if none ready.
  882. */
  883. LOCAL DC_RDE * dcGetFullRMD
  884.     (
  885.     DRV_CTRL * pDrvCtrl /* pointer to device control struct */
  886.     )
  887.     {
  888.     DC_RDE * rmd; /* pointer to Rx ring descriptor */
  889.     /* Refuse to do anything if flags are down */
  890.     if  (
  891.         (pDrvCtrl->idr.ac_if.if_flags & (IFF_UP | IFF_RUNNING) ) !=
  892.         (IFF_UP | IFF_RUNNING)
  893.         )
  894.         return ((DC_RDE *) NULL);
  895.     rmd = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;       /* form ptr to Rx desc */
  896.     DC_CACHE_INVALIDATE (rmd, RMD_SIZ);
  897.     if ((rmd->rDesc0 & PCISWAP(RDESC0_OWN)) == 0)
  898.         return (rmd);
  899.     else
  900.         return ((DC_RDE *) NULL);
  901.     }
  902. /*******************************************************************************
  903. *
  904. * dcRecv - process the next incoming packet
  905. *
  906. */
  907. LOCAL STATUS dcRecv
  908.     (
  909.     DRV_CTRL * pDrvCtrl, /* pointer to device control struct */
  910.     DC_RDE * rmd /* pointer to Rx ring descriptor */
  911.     )
  912.     {
  913.     ENET_HDR * pEnetHdr; /* pointer to ethernet header */
  914.     MBUF * pMbuf = NULL; /* pointer to mbuf */
  915.     u_long pPhys;
  916.     UCHAR * pData; /* pointer to data */
  917.     int len; /* length */
  918.     USHORT ether_type; /* ether packet type */
  919.     /* Packet must be checked for errors. */
  920.     if  (rmd->rDesc0 & PCISWAP(RDESC0_ES)) /* If error flag */
  921.         {
  922. /* error can occur on overflow, crc error, collision, 
  923.  * frame too long, runt frame or length error
  924.  */
  925.         ++pDrvCtrl->idr.ac_if.if_ierrors;       /* bump error stat */
  926.         goto cleanRXD;                          /* skip to clean up */
  927.         }
  928.     ++pDrvCtrl->idr.ac_if.if_ipackets; /* bump statistic */
  929.     len = RDESC0_FL_GET(PCISWAP(rmd->rDesc0)); /* frame length */
  930.     len -= 4;  /* Frame length includes CRC in it so subtract it */
  931.     /* Get pointer to packet */
  932.     pEnetHdr = DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(rmd->rDesc2)));
  933.     DC_CACHE_INVALIDATE (pEnetHdr, len);   /* make the packet data coherent */
  934.     /* call input hook if any */
  935.     if ((etherInputHookRtn == NULL) || ((*etherInputHookRtn)
  936.        (& pDrvCtrl->idr.ac_if, (char *) pEnetHdr, len)) == 0)
  937.         {
  938.         /* Adjust length to size of data only */
  939.         len -= SIZEOF_ETHERHEADER;
  940.         /* Get pointer to packet data */
  941.         pData = ((u_char *) pEnetHdr) + SIZEOF_ETHERHEADER;
  942.         ether_type = ntohs ( pEnetHdr->type );
  943.         /* OK to loan out buffer ? -> build an mbuf cluster */
  944.     
  945. if ((pDrvCtrl->nLoanRx > 0) && (USE_CLUSTER (len))
  946.     &&
  947.     ((pMbuf = build_cluster (pData, len, & pDrvCtrl->idr, MC_LANCE,
  948.      pDrvCtrl->pRefCnt [(pDrvCtrl->nLoanRx - 1)], dcLoanFree,
  949.      (int) pDrvCtrl, (int) pEnetHdr,
  950.      (int) pDrvCtrl->pRefCnt [(pDrvCtrl->nLoanRx - 1)])) != NULL))
  951.     {
  952.             pPhys = (u_long) DC_CACHE_VIRT_TO_PHYS(MEM_TO_PCI_PHYS(
  953.     (pDrvCtrl->lPool[--pDrvCtrl->nLoanRx])));
  954.     rmd->rDesc2 = PCISWAP(pPhys);
  955.     }
  956.         else
  957.             {
  958.             if ((pMbuf = bcopy_to_mbufs (pData, len, 0, & pDrvCtrl->idr.ac_if,
  959.                 pDrvCtrl->memWidth)) == NULL)
  960. {
  961.                 ++pDrvCtrl->idr.ac_if.if_ierrors; /* bump error stat */
  962.                 goto cleanRXD;
  963. }
  964.             }
  965.         /* send on up... */
  966.         do_protocol_with_type (ether_type, pMbuf, & pDrvCtrl->idr, len);
  967. /* RCP: This is a redundant increment of incoming packets, removed from original driver */
  968. /*        ++pDrvCtrl->idr.ac_if.if_ipackets;*/ /* bump statistic */
  969.         }
  970.     /* Done with descriptor, clean up and give it to the device. */
  971.     cleanRXD:
  972.     /* clear status bits and give ownership to device */
  973.     rmd->rDesc0 = PCISWAP(RDESC0_OWN);
  974.     /* Flush the write pipe */
  975.     CACHE_PIPE_FLUSH ();
  976.     /* Advance our management index */
  977.     pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->dcNumRds;
  978.     return (OK);
  979.     }
  980. /*******************************************************************************
  981. *
  982. * dcOutput - the driver output routine
  983. *
  984. */
  985. LOCAL int dcOutput
  986.     (
  987.     IDR  * pIDR, /* pointer to interface data record */
  988.     MBUF * pMbuf, /* pointer to mbuf */
  989.     SOCK * pDest /* pointer to destination sock */
  990.     )
  991.     {
  992.     char  destEnetAddr [6]; /* space for enet addr */
  993.     USHORT packetType; /* type field for the packet */
  994.     DRV_CTRL * pDrvCtrl; /* pointer to device control struct */
  995.     DC_TDE * tmd; /* pointer to Tx ring descriptor */
  996.     char * buf; /* pointer to buffer */
  997.     int len; /* length */
  998.     /* Check ifnet flags. Return error if incorrect. */
  999.     if  (
  1000.         (pIDR->ac_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
  1001.         (IFF_UP | IFF_RUNNING)
  1002.         )
  1003.         return (ENETDOWN);
  1004.     /* Attempt to convert socket addr into enet addr and packet type.
  1005.      * Note that if ARP resolution of the address is required, the ARP
  1006.      * module will call our routine again to transmit the ARP request
  1007.      * packet.  This means we may actually call ourselves recursively!
  1008.      */
  1009.     if (convertDestAddr (pIDR,pDest, destEnetAddr, &packetType, pMbuf) == FALSE)
  1010.         return (OK);    /* I KNOW returning OK is stupid, but it is correct */
  1011.     /* Get driver control pointer */
  1012.     pDrvCtrl = & drvCtrl [pIDR->ac_if.if_unit];
  1013.     /* Obtain exclusive access to transmitter.  This is necessary because
  1014.      * certain events can cause netTask to run a job that attempts to transmit
  1015.      * a packet.  We can only allow one task here at a time.
  1016.      */
  1017.     semTake (pDrvCtrl->TxSem, WAIT_FOREVER);
  1018.     /* See if next TXD is available */
  1019.     tmd = pDrvCtrl->txRing + pDrvCtrl->txIndex;
  1020.     DC_CACHE_INVALIDATE (tmd, TMD_SIZ);
  1021.     if  (
  1022.         ((tmd->tDesc0 & PCISWAP(TDESC0_OWN)) != 0) ||
  1023.         (
  1024.         ((pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds) == pDrvCtrl->txDiIndex
  1025. )
  1026.         )
  1027.         {
  1028.         m_freem (pMbuf);            /* Discard data */
  1029.         goto outputDone;
  1030.         }
  1031.     /* Get pointer to transmit buffer */
  1032.     buf = (char *)DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(tmd->tDesc2)));
  1033.     /* Copy packet from MBUFs to our transmit buffer.  MBUFs are
  1034.      * transparently freed.
  1035.      */
  1036.     bcopy_from_mbufs ((buf + SIZEOF_ETHERHEADER), pMbuf, len,
  1037.       pDrvCtrl->memWidth);
  1038.     /* Fill in the Ethernet header */
  1039.     bcopy (destEnetAddr, buf, 6);
  1040.     bcopy ( (char *) pIDR->ac_enaddr, (buf + 6), 6);
  1041.     ((ENET_HDR *)buf)->type = packetType;
  1042.     tmd->tDesc0 = 0; /* clear buffer error status */
  1043.     tmd->tDesc1 &= PCISWAP(~TDESC1_TBS1_MSK);
  1044.     tmd->tDesc1 |= PCISWAP(TDESC1_TBS1_PUT(max (ETHERSMALL, 
  1045. (len + SIZEOF_ETHERHEADER))));
  1046.     tmd->tDesc0 = PCISWAP(TDESC0_OWN);  /* give ownership to device */
  1047.     CACHE_PIPE_FLUSH (); /* Flush the write pipe */
  1048.     /* Advance our management index */
  1049.     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds;
  1050.     
  1051.     if (dcKickStartTx)
  1052.      dcCsrWrite(pDrvCtrl->devAdrs, CSR1, CSR1_TPD); /* xmit poll demand */
  1053.     /* Bump the statistic counter. */
  1054.     pIDR->ac_if.if_opackets++;
  1055.     outputDone:
  1056.     /* Release exclusive access. */
  1057.     semGive (pDrvCtrl->TxSem);
  1058.     return (OK);
  1059.     }
  1060. /*******************************************************************************
  1061. *
  1062. * dcIoctl - the driver I/O control routine
  1063. *
  1064. * Process an ioctl request.
  1065. */
  1066. LOCAL int dcIoctl
  1067.     (
  1068.     IDR  * ifp, /* pointer interface data record */
  1069.     int cmd, /* command */
  1070.     caddr_t data /* data */
  1071.     )
  1072.     {
  1073.     int  error = 0;
  1074.     DRV_CTRL *  pDrvCtrl = (DRV_CTRL *)ifp; /* pointer to device */
  1075.     switch (cmd)
  1076.         {
  1077.         case SIOCSIFADDR:
  1078.             ifp->ac_ipaddr = IA_SIN (data)->sin_addr;
  1079.             break;
  1080.         case SIOCSIFFLAGS:
  1081.             /* No further work to be done */
  1082.             break;
  1083.         case IFF_PROMISC: /* set device in promiscuous mode */
  1084.     dcCsrWrite (pDrvCtrl->devAdrs, CSR6, 
  1085. (dcCsrRead(pDrvCtrl->devAdrs, CSR6) | CSR6_PR));
  1086.     break;
  1087.         default:
  1088.             error = EINVAL;
  1089.         }
  1090.     return (error);
  1091.     }
  1092. /*******************************************************************************
  1093. *
  1094. * dcChipReset - hardware reset of chip (stop it)
  1095. */
  1096. LOCAL int dcChipReset
  1097.     (
  1098.     DRV_CTRL * pDrvCtrl /* pointer to device control structure */
  1099.     )
  1100.     {
  1101.     ULONG   devAdrs = pDrvCtrl->devAdrs; /* device base address */
  1102.     ULONG ix; /* index */
  1103.     dcCsrWrite(devAdrs, CSR6, 0); /* stop rcvr & xmitter */
  1104.     dcCsrWrite(devAdrs, CSR7, 0); /* mask interrupts */
  1105.     
  1106.     dcCsrWrite(devAdrs, CSR0, CSR0_SWR);
  1107.     /* Wait Loop, Loop for at least 50 PCI cycles according to chip spec */
  1108.     for (ix = 0; ix < 0x1000; ix++)
  1109. ;
  1110.     /* any additional bus mode | give xmit & rcv process equal priority */
  1111.     dcCsrWrite (devAdrs, CSR0, dcCSR0Bmr | CSR0_BAR);
  1112.     for (ix = 0; ix < 0x1000; ix++) /* loop for some cycles */
  1113. ;
  1114.     return (OK);
  1115.     }
  1116. /*******************************************************************************
  1117. *
  1118. * dcAuiTpInit - initialize either AUI or 10BASE-T connection
  1119. *
  1120. * This function configures 10BASE-T interface. If the link pass state is 
  1121. * not achieved within two seconds then the AUI interface is initialized.
  1122. */
  1123. LOCAL void dcAuiTpInit
  1124.     (
  1125.     ULONG       devAdrs        /* device base I/O address */
  1126.     )
  1127.     {
  1128.     /* reset the SIA registers */
  1129.     dcCsrWrite (devAdrs, CSR13, 0);
  1130.     dcCsrWrite (devAdrs, CSR14, 0);
  1131.     dcCsrWrite (devAdrs, CSR15, 0);
  1132.     /* configure for the 10BASE-T */
  1133.     dcCsrWrite (devAdrs, CSR13, CSR13_CAC_CSR); /* 10BT auto configuration */
  1134.     taskDelay (sysClkRateGet() * 2); /* 2 second delay */
  1135.     if (dcCsrRead (devAdrs, CSR12) & (CSR12_LKF | CSR12_NCR))
  1136. {
  1137. /* 10BASE-T not connected initialize interface for AUI */
  1138. dcCsrWrite (devAdrs, CSR13, 0); /* reset SIA registers */
  1139. dcCsrWrite (devAdrs, CSR14, 0);
  1140. dcCsrWrite (devAdrs, CSR15, 0);
  1141. /* AUI auto configuration */
  1142. dcCsrWrite (devAdrs, CSR13, (CSR13_AUI_TP | CSR13_CAC_CSR));
  1143. }
  1144.     }
  1145. /*******************************************************************************
  1146. *
  1147. * dcCsrWrite - select and write a CSR register
  1148. *
  1149. */
  1150. LOCAL void dcCsrWrite
  1151.     (
  1152.     ULONG  devAdrs, /* device address base */
  1153.     int  reg, /* register to select */
  1154.     ULONG  value /* value to write */
  1155.     )
  1156.     {
  1157.     ULONG * csrReg;
  1158.     csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));
  1159.     /* write val to CSR */
  1160.     *(csrReg) = PCISWAP(value);
  1161.     }
  1162. /*******************************************************************************
  1163. *
  1164. * dcCsrRead - select and read a CSR register
  1165. *
  1166. */
  1167. LOCAL ULONG dcCsrRead
  1168.     (
  1169.     ULONG devAdrs, /* device address base */
  1170.     int reg /* register to select */
  1171.     )
  1172.     {
  1173.     ULONG * csrReg; /* csr register */
  1174.     ULONG csrData; /* data in csr register */
  1175.     csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));
  1176.     csrData = *csrReg;
  1177.     /* get contents of CSR */
  1178.     return ( PCISWAP(csrData));
  1179.     }
  1180. /*******************************************************************************
  1181. *
  1182. * dcRestart - restart the device after a fatal error
  1183. *
  1184. * This routine takes care of all the messy details of a restart.  The device
  1185. * is reset and re-initialized.  The driver state is re-synchronized.
  1186. */
  1187. LOCAL void dcRestart
  1188.     (
  1189.     int  unit /* unit to restart */
  1190.     )
  1191.     {
  1192.     ULONG status; /* status register */
  1193.     int ix; /* index variable */
  1194.     DC_RDE * rmd; /* pointer to receive descriptor */
  1195.     DC_TDE * tmd; /* pointer to Xmit descriptor */
  1196.     DRV_CTRL * pDrvCtrl = & drvCtrl [unit];
  1197.     rmd = pDrvCtrl->rxRing;      /* receive ring */
  1198.     tmd = pDrvCtrl->txRing;      /* transmit ring */
  1199.     pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING );
  1200.     fprintf (stderr, "Fatal Error. DEC Ethernet Chip Restartedn");
  1201.     status = dcCsrRead(pDrvCtrl->devAdrs, CSR6);
  1202.     dcCsrWrite (pDrvCtrl->devAdrs, CSR6, 0); /* reset mode register */
  1203.     for (ix = 0; ix < pDrvCtrl->dcNumRds; ix++, rmd++)
  1204.         {
  1205. /* buffer size */
  1206. rmd->rDesc1 = PCISWAP(RDESC1_RBS1_VAL(DC_BUFSIZ) | 
  1207.       RDESC1_RBS2_VAL(0));
  1208. if (ix == (pDrvCtrl->dcNumRds - 1)) /* if its is last one */
  1209. rmd->rDesc1 |= PCISWAP(RDESC1_RER); /* end of receive ring */
  1210. rmd->rDesc0 = PCISWAP(RDESC0_OWN); /* give ownership to lance */
  1211.         }
  1212.     for (ix = 0; ix < pDrvCtrl->dcNumTds; ix++, tmd++)
  1213.         {
  1214. tmd->tDesc1 = PCISWAP((TDESC1_TBS1_PUT(0) |
  1215.        TDESC1_TBS2_PUT(0) |
  1216.        TDESC1_IC   |  /* intrpt on xmit */
  1217.        TDESC1_LS          | /* last segment */
  1218.        TDESC1_FS)); /* first segment */
  1219. if (ix == (pDrvCtrl->dcNumTds - 1)) /* if its is last one */
  1220.     tmd->tDesc1 |= PCISWAP(TDESC1_TER); /* end of Xmit ring */
  1221. tmd->tDesc0 = 0 ; /* clear status */
  1222.         }
  1223.     /* clear the status register */
  1224.     dcCsrWrite (pDrvCtrl->devAdrs, CSR5, 0xffffffff);
  1225.     dcCsrWrite (pDrvCtrl->devAdrs, CSR6, status); /* restore mode */
  1226.     pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);
  1227.     }
  1228. /*******************************************************************************
  1229. *
  1230. * dcLoanFree - return the given buffer to loaner pool
  1231. *
  1232. * This routine returns <pRxBuf> to the pool of available loaner buffers.
  1233. * It also returns <pRef> to the pool of available loaner reference counters,
  1234. * then zeroes the reference count.
  1235. *
  1236. * RETURNS: N/A
  1237. */
  1238.  
  1239. LOCAL void dcLoanFree
  1240.     (
  1241.     DRV_CTRL * pDrvCtrl, /* pointer to device control structure */
  1242.     char * pRxBuf, /* pointer to receive buffer to free */
  1243.     UINT8 * pRef /* pointer to reference count */
  1244.     )
  1245.     {
  1246.     /* return loaned buffer to pool */
  1247.  
  1248.     pDrvCtrl->lPool[pDrvCtrl->nLoanRx] = pRxBuf;
  1249.  
  1250.     /* return loaned reference count to pool */
  1251.  
  1252.     pDrvCtrl->pRefCnt[pDrvCtrl->nLoanRx++] = pRef;
  1253.     /* reset reference count - should have been done from above, but... */
  1254.  
  1255.     *pRef = 0;
  1256.     }
  1257. /*******************************************************************************
  1258. *
  1259. * dcEnetAddrGet - gets the ethernet address from the ROM register.
  1260. *
  1261. * This routine gets the ethernet address from the ROM register.
  1262. * This routine returns the ethernet address into the pointer supplied to it.
  1263. * RETURNS: OK/ERROR
  1264. */
  1265. LOCAL STATUS dcEnetAddrGet
  1266.     (
  1267.     ULONG devAdrs, /* device base I/O address */
  1268.     char *  enetAdrs, /* pointer to the ethernet address */ 
  1269.     int len /* number of bytes to read */
  1270.     )
  1271.     {
  1272.     FAST ULONG csr9Value; /* register to hold CSR9 */
  1273.     int ix; /* index register */
  1274.     BOOL eRomReady = FALSE; /* ethernet ROM register state */
  1275.     dcCsrWrite (devAdrs, CSR9, 0); /* reset rom pointer */
  1276.     while (len > 0)
  1277. {
  1278. for (ix = 0; ix < 10; ix++) /* try at least 10 times */
  1279.     {
  1280.     if ((csr9Value = dcCsrRead (devAdrs, CSR9)) & CSR9_DNV)
  1281. {
  1282. eRomReady = FALSE;
  1283.      DELAY(500);
  1284. }
  1285.     else
  1286. {
  1287. *enetAdrs++ = (UCHAR) csr9Value;
  1288. len--;
  1289. eRomReady = TRUE;
  1290. break;
  1291. }
  1292.     }
  1293. }
  1294.     if (!eRomReady)
  1295.      return (ERROR);
  1296.     else
  1297. return (OK);
  1298.     }
  1299. /*******************************************************************************
  1300. *
  1301. * RCP : New utility for DEC21140
  1302. * dc21140EnetAddrGet - gets the ethernet address from the ROM register 
  1303. *
  1304. * This routine gets the last two bytes of the ethernet address from the ROM
  1305. * register and concantenates this value to the predefined values for DEC PMCs..
  1306. * This routine returns the ethernet address into the pointer supplied to it.
  1307. *
  1308. * The procedure could be expanded in the future to allow for modification of
  1309. * Ethernet addresses in the serial ROM.  It will have to be modified to
  1310. * accomodate the differences in the onboard 100Mb/s ethernet on future 
  1311. * Motorola products.
  1312. * RETURNS: OK/ERROR
  1313. */
  1314. LOCAL STATUS dc21140EnetAddrGet
  1315.     (
  1316.     ULONG devAdrs, /* device base I/O address */
  1317.     char *  enetAdrs, /* pointer to the ethernet address */ 
  1318.     int len /* number of bytes to read */
  1319.     )
  1320.     {
  1321.     int i,ix, /* index register */
  1322.      tmpInt; /* temporary int */
  1323.     union mixed
  1324.     {
  1325.      char Char[4]; /* temporary 2 by char */
  1326. USHORT Short[2]; /* temporary USHORT */
  1327. ULONG   Long; /* temporay ULONG */
  1328.     } tmp;
  1329.     for (i = DEC_PMC_POS, ix = 0; i<(3+DEC_PMC_POS); i++, ix++)
  1330.     {
  1331.      if ((tmp.Short[0] = dcReadRom (devAdrs, i)) == ERROR)
  1332.    return (ERROR);
  1333. enetAdrs[ix++] = tmp.Char[1];
  1334. enetAdrs[ix] = tmp.Char[0];
  1335.     }
  1336.     tmpInt = -1;
  1337.     return (OK);
  1338.     }
  1339. /*******************************************************************************
  1340. *
  1341. * dcFltrFrmXmit - Transmit the setup filter frame.
  1342. *
  1343. * This routine transmits the setup filter frame.
  1344. * The setup frame is not transmitted actually over the wire. The setup frame
  1345. * which is transmitted is 192 bytes. The tranmitter should be in an on state
  1346. * before this function is called. This call has been coded so that the 
  1347. * setup frame can be transmitted after the chip is done with the 
  1348. * intialization taking into consideration for adding multicast support.
  1349. * RETURNS: OK/ERROR
  1350. */
  1351. LOCAL int dcFltrFrmXmit
  1352.     (
  1353.     DRV_CTRL * pDrvCtrl,  /* pointer to device control structure */
  1354.     char *  pPhysAdrsTbl,  /* pointer to physical address table */ 
  1355.     int  tblLen /* size of the physical address table */
  1356.     )
  1357.     {
  1358.     DC_TDE * tmd; /* pointer to Tx ring descriptor */
  1359.     ULONG *  pBuff; /* pointer to the Xmit buffer */
  1360.     int status = OK; /* intialize status as OK */
  1361.     ULONG csr7Val; /* value in CSR7 */
  1362.     semTake (pDrvCtrl->TxSem, WAIT_FOREVER);
  1363.     if (dcFltrFrmSetup (pDrvCtrl, pPhysAdrsTbl, tblLen) != OK)
  1364. {
  1365. status = ERROR; /* not able to set up filter frame */
  1366. goto setupDone; /* set up done */
  1367. }
  1368.     /* See if next TXD is available */
  1369.     tmd = pDrvCtrl->txRing + pDrvCtrl->txIndex;
  1370.     DC_CACHE_INVALIDATE (tmd, TMD_SIZ);
  1371.     if  (
  1372.         ((tmd->tDesc0 & PCISWAP(TDESC0_OWN)) != 0) ||
  1373.         (
  1374.         ((pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds) == pDrvCtrl->txDiIndex
  1375. )
  1376.         )
  1377. {
  1378. status = ERROR; /* not able to set up filter frame */
  1379. goto setupDone; /* set up done */
  1380. }
  1381.     /* Get pointer to transmit buffer */
  1382.     pBuff = DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(tmd->tDesc2)));
  1383.     /* copy into Xmit buffer */
  1384.     bcopyLongs ((char *)pDrvCtrl->pFltrFrm, (char *)pBuff, 
  1385. FLTR_FRM_SIZE_ULONGS);
  1386.     tmd->tDesc0 = 0; /* clear buffer error status */
  1387.     tmd->tDesc1 |= PCISWAP(TDESC1_SET); /* frame type as set up */
  1388.     tmd->tDesc1 &= PCISWAP(~TDESC1_TBS1_MSK);
  1389.     tmd->tDesc1 |= PCISWAP(TDESC1_TBS1_PUT(FLTR_FRM_SIZE));
  1390.     tmd->tDesc0 = PCISWAP(TDESC0_OWN);  /* give ownership to device */
  1391.     CACHE_PIPE_FLUSH (); /* Flush the write pipe */
  1392.     /* Advance our management index */
  1393.     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds;
  1394.     pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->dcNumTds;
  1395.     csr7Val = dcCsrRead (pDrvCtrl->devAdrs, CSR7);
  1396.     dcCsrWrite(pDrvCtrl->devAdrs, CSR7, 0); /* mask interrupts */
  1397.     
  1398.     if (dcKickStartTx)
  1399.      dcCsrWrite(pDrvCtrl->devAdrs, CSR1, CSR1_TPD); /* xmit poll demand */
  1400.     /* wait for the own bit to change */
  1401.     while (tmd->tDesc0 & PCISWAP (TDESC0_OWN))
  1402. ;
  1403.     tmd->tDesc0 = 0; /* clear status bits */
  1404.     tmd->tDesc1 &= PCISWAP(~TDESC1_SET);
  1405.     dcCsrWrite(pDrvCtrl->devAdrs, CSR7, csr7Val); /* restore value */
  1406.     setupDone:
  1407.     /* Release exclusive access. */
  1408.     semGive (pDrvCtrl->TxSem);
  1409.     return (status);
  1410.     }
  1411. /*******************************************************************************
  1412. *
  1413. * dcFltrFrmSetup - set up the filter frame.
  1414. *
  1415. * This routine sets up the filter frame to filter the physical addresses
  1416. * on the incoming frames. The setup filter frame buffer is 192 bytes. This
  1417. * setup frame needs to be transmitted before transmitting and receiving 
  1418. * any frames. 
  1419. * RETURNS: OK/ERROR
  1420. */
  1421. LOCAL int dcFltrFrmSetup
  1422.     (
  1423.     DRV_CTRL * pDrvCtrl,  /* pointer to device control structure */
  1424.     char *  pPhysAdrsTbl,  /* pointer to physical address table */ 
  1425.     int  tblLen /* size of the physical address table */
  1426.     )
  1427.     {
  1428.     int ix; /* index variable */
  1429.     int jx;  /* inner index variable */
  1430.     ULONG * pFltrFrm; /* pointer to the filter frame */
  1431.     USHORT * pPhysAddrs; /* pointer to the physical addresses */
  1432.     if (tblLen > FLTR_FRM_ADRS_NUM)
  1433. return (ERROR);
  1434.     pFltrFrm = pDrvCtrl->pFltrFrm;
  1435.     for (ix = 0; ix < FLTR_FRM_SIZE_ULONGS; ix++)
  1436. *pFltrFrm++ = FLTR_FRM_DEF_ADRS;
  1437.     pFltrFrm = pDrvCtrl->pFltrFrm;
  1438.     pPhysAddrs = (USHORT *) (pPhysAdrsTbl);
  1439.     for (ix = 0; ix < tblLen; ix++)
  1440. {
  1441. for (jx = 0; jx < (FLTR_FRM_ADRS_SIZE/sizeof (USHORT)); jx++)
  1442.     {
  1443. #if (_BYTE_ORDER == _BIG_ENDIAN)
  1444.     *pFltrFrm =  (*pPhysAddrs << 16);
  1445. #else
  1446.     *pFltrFrm = ((LSB(*pPhysAddrs) << 8) | MSB(*pPhysAddrs));
  1447. #endif
  1448.     pPhysAddrs++;
  1449.     pFltrFrm++;
  1450.     }
  1451. }
  1452.     return (OK);
  1453.     }
  1454. #include "sys/socket.h"
  1455. /*******************************************************************************
  1456. *
  1457. * convertDestAddr - converts socket addr into enet addr and packet type
  1458. *
  1459. */
  1460. LOCAL BOOL convertDestAddr
  1461.     (
  1462.     IDR *pIDR,                          /* ptr to i/f data record */
  1463.     SOCK *pDestSktAddr,                 /* ptr to a generic sock addr */
  1464.     char *pDestEnetAddr,                /* where to write enet addr */
  1465.     u_short *pPacketType,               /* where to write packet type */
  1466.     MBUF *pMbuf                         /* ptr to mbuf data */
  1467.     )
  1468.     {
  1469.     /***** Internet family *****/
  1470.     {
  1471.     struct in_addr destIPAddr;              /* not used */
  1472.     int trailers;                           /* not supported */
  1473.      if (pDestSktAddr->sa_family == AF_INET)
  1474.         {
  1475.         *pPacketType = ETHERTYPE_IP;            /* stuff packet type */
  1476.         destIPAddr = ((struct sockaddr_in *) pDestSktAddr)->sin_addr;
  1477.         if (!arpresolve (pIDR, pMbuf, &destIPAddr, pDestEnetAddr, &trailers))
  1478.             return (FALSE);     /* if not yet resolved */
  1479.         return (TRUE);
  1480.         }
  1481.     }
  1482.     /***** Generic family *****/
  1483.     {
  1484.     ENET_HDR *pEnetHdr;
  1485.     if (pDestSktAddr->sa_family == AF_UNSPEC)
  1486.         {
  1487.         pEnetHdr = (ENET_HDR *) pDestSktAddr->sa_data;      /* ptr to hdr */
  1488.         bcopy (pEnetHdr->dst, pDestEnetAddr, 6);            /* copy dst addr */
  1489.         *pPacketType = pEnetHdr->type;                      /* copy type */
  1490.         return (TRUE);
  1491.         }
  1492.     }
  1493.     /* Unsupported family */
  1494.     return (FALSE);
  1495.     } /* End of convertDestAddr() */
  1496. /* END OF FILE */
  1497. /*******************************************************************************
  1498. *
  1499. * RCP : New utility for DEC21140
  1500. * dcReadRom - reads an specified entry in the Serial ROM 
  1501. *
  1502. * This routine uses the line number passed to the function and returns
  1503. * the two bytes of information that is associated with it.  This will later
  1504. * be used by the dc21140GetEthernetAdr function.  It can also be used to 
  1505. * review the ROM contents itself.
  1506. *
  1507. * The function must first send some initial bit paterns to the CSR9 which 
  1508. * contains the Serial ROM Control bits.  Then the line index into the ROM
  1509. * will be evaluated bit by bit to program the ROM.  The 2 bytes of data
  1510. * will be extracted and processed into a normal pair of bytes. 
  1511. * RETURNS: Short Value in ROM/ERROR
  1512. */
  1513. #define BASE CSR9_SSR_FLAG|CSR9_SWO_FLAG
  1514. USHORT dcReadRom
  1515.     (
  1516.     ULONG devAdrs, /* device base I/O address */
  1517.     UCHAR lineCnt  /* Serial ROM line Number */ 
  1518.     )
  1519.     {
  1520.     int ix,  /* index register */
  1521.      intCnt; /* address loop count */
  1522.     USHORT tmpShort;
  1523.     ULONG tmpLong; 
  1524. /* Is the line offset valid, and if so, how large is it */
  1525.     if (lineCnt > SROM_SIZE || lineCnt < 0)
  1526.     {
  1527. printf ("dcReadRom FAILED, bad lineCntn");
  1528.      return (ERROR);
  1529.     }
  1530.     if (lineCnt < 64)
  1531.     {
  1532. intCnt = 6;
  1533. lineCnt = lineCnt << 2;  /* Prepare lineCnt for processing */
  1534.     }
  1535.     else
  1536. intCnt = 8;
  1537. /* Command the Serial ROM to the correct Line */
  1538. /* Preamble of Command */
  1539.     dcCsrWrite (devAdrs, CSR9, 0x00000000|BASE); /* Command 1 */
  1540.     NSDELAY (30);
  1541.     dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 2 */
  1542.     NSDELAY (50);
  1543.     dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 3 */
  1544.     NSDELAY (250);
  1545.     dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 4 */
  1546.     NSDELAY (100);
  1547. /* Command Phase */
  1548.     dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 5 */
  1549.     NSDELAY (150);
  1550.     dcCsrWrite (devAdrs, CSR9, 0x00000007|BASE); /* Command 6 */
  1551.     NSDELAY (250);
  1552.     dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 7 */
  1553.     NSDELAY (250);
  1554.     dcCsrWrite (devAdrs, CSR9, 0x00000007|BASE); /* Command 8 */
  1555.     NSDELAY (250);
  1556.     dcCsrWrite (devAdrs, CSR9, 0x00000005|BASE); /* Command 9 */
  1557.     NSDELAY (100);
  1558.     dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 10 */
  1559.     NSDELAY (150);
  1560.     dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 11 */
  1561.     NSDELAY (250);
  1562.     dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 12 */
  1563.     NSDELAY (100);
  1564.     
  1565. /* Address Phase */
  1566.     for (ix=0; ix < intCnt; ix++)
  1567.     {
  1568. tmpLong = (lineCnt & 0x80)>>5; /* Extract and move bit to bit 3)
  1569. /* Write the command */
  1570.      dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000001|BASE);/* Command 13 */
  1571.      NSDELAY (150);
  1572.      dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000003|BASE);/* Command 14 */
  1573.      NSDELAY (250);
  1574.      dcCsrWrite (devAdrs, CSR9, tmpLong | 0x00000001|BASE);/* Command 15 */
  1575.      NSDELAY (100);
  1576. lineCnt = lineCnt<<1;  /* Adjust significant address bit */
  1577.     }
  1578.      NSDELAY (150);
  1579. /* Data Phase */
  1580.     tmpShort =0;
  1581.     for (ix=15; ix >= 0; ix--)
  1582.     {
  1583. /* Write the command */
  1584.      dcCsrWrite (devAdrs, CSR9, 0x00000003|BASE); /* Command 16 */
  1585.      NSDELAY (100);
  1586. /* Extract the data */
  1587.      tmpShort |= (((dcCsrRead (devAdrs, CSR9) & 0x00000008)>>3)
  1588.    <<ix);  /* Command 17 */
  1589.      NSDELAY (150);
  1590.      dcCsrWrite (devAdrs, CSR9, 0x00000001|BASE); /* Command 18 */
  1591.      NSDELAY (250);
  1592.     }
  1593. /* Finish up command */
  1594.     dcCsrWrite (devAdrs, CSR9, 0x00000000); /* Command 19 */
  1595.     NSDELAY (100);
  1596.     return (tmpShort);
  1597.     }
  1598. /* RCP: Function to read all of serial rom and store the data in the
  1599.         data structure passed to the function.  The count value will
  1600.         indicate how much of the serial rom to read.  The routine with also
  1601.         swap the the bytes as the come in. */
  1602. void dcReadAllRom
  1603.     (
  1604.     ULONG devAdrs, /* device base I/O address */
  1605.     UCHAR *buffer, /* destination bufferr */ 
  1606.     int cnt             /* Amount to extract in bytes */
  1607.     )
  1608.     {
  1609.     USHORT total, index;
  1610.     union tmp_type {
  1611.         USHORT Short;
  1612.      char   Byte [2]; /* temporary 2 by char */
  1613.     } tmp;
  1614.     total = 0;
  1615.     for (index=0, total=0; total < cnt/2; index+=2, total++)
  1616.     {
  1617. tmp.Short = dcReadRom (devAdrs, total);
  1618. buffer[index]=tmp.Byte[1];
  1619. buffer[index+1]=tmp.Byte[0];
  1620.     }
  1621.     }
  1622. #ifdef DC_DEBUG
  1623. int dcViewRom
  1624.     (
  1625.     ULONG devAdrs, /* device base I/O address */
  1626.     UCHAR lineCnt, /* Serial ROM line Number */ 
  1627.     int cnt             /* Amount to display */
  1628.     )
  1629.     {
  1630.     USHORT total;
  1631.     union tmp_type {
  1632.         USHORT Short;
  1633.      char   Byte [2]; /* temporary 2 by char */
  1634.     } tmp;
  1635.     if (lineCnt/2 < 0 || lineCnt/2 > SROM_SIZE)
  1636. return (ERROR);
  1637.     total = 0;
  1638.     while (lineCnt/2 < SROM_SIZE && cnt > 0)
  1639.     {
  1640. if (!(total%16))
  1641.    printf ("nValues for line %2d =>0x  ", total);
  1642. tmp.Short = dcReadRom (devAdrs, lineCnt);
  1643. printf ("%4x ",tmp.Short);
  1644. lineCnt++ ;
  1645. total +=2;
  1646. cnt -=2;
  1647.     }
  1648.     printf ("n");
  1649.     return (total);
  1650.     }
  1651. void dcCsrShow
  1652.     (
  1653.     ULONG devAdrs
  1654.     )
  1655.     {
  1656.     printf ("n");
  1657.     printf ("CSR0t 0x%xn", dcCsrRead(devAdrs, CSR0));
  1658.     printf ("CSR1t 0x%xn", dcCsrRead(devAdrs, CSR1));
  1659.     printf ("CSR2t 0x%xn", dcCsrRead(devAdrs, CSR2));
  1660.     printf ("CSR3t 0x%xn", dcCsrRead(devAdrs, CSR3));
  1661.     printf ("CSR4t 0x%xn", dcCsrRead(devAdrs, CSR4));
  1662.     printf ("CSR5t 0x%xn", dcCsrRead(devAdrs, CSR5));
  1663.     printf ("CSR6t 0x%xn", dcCsrRead(devAdrs, CSR6));
  1664.     printf ("CSR7t 0x%xn", dcCsrRead(devAdrs, CSR7));
  1665.     printf ("CSR8t 0x%xn", dcCsrRead(devAdrs, CSR8));
  1666.     printf ("CSR9t 0x%xn", dcCsrRead(devAdrs, CSR9));
  1667.     printf ("CSR10t 0x%xn", dcCsrRead(devAdrs, CSR10));
  1668.     printf ("CSR11t 0x%xn", dcCsrRead(devAdrs, CSR11));
  1669.     printf ("CSR12t 0x%xn", dcCsrRead(devAdrs, CSR12));
  1670.     printf ("CSR13t 0x%xn", dcCsrRead(devAdrs, CSR13));
  1671.     printf ("CSR14t 0x%xn", dcCsrRead(devAdrs, CSR14));
  1672.     printf ("CSR15t 0x%xn", dcCsrRead(devAdrs, CSR15));
  1673.     }
  1674. #endif /* DC_DEBUG */
  1675. /*  RCP:  New Versions of code that will be added to the BSP later. */
  1676. /******************************************************************************
  1677. *
  1678. * sysLanIntEnable - enable the LAN interrupt
  1679. *
  1680. * This routine enables interrupts at a specified level for the on-board
  1681. * LAN chip.  LAN interrupts are controlled by the IBC chip.
  1682. * The LANCE chip on this board is on the PCI bus. The PCI interrupts should
  1683. * be routed through the IBC to the processor. LANCE chip asserts PCI IRQ0
  1684. * which has to be routed through IBC to generate ISA IRQ10. This routing 
  1685. * done through programming the PCI route registers in the IBC chip.
  1686. *
  1687. * RETURNS: OK, always.
  1688. *
  1689. * SEE ALSO: sysLanIntDisable()
  1690. */
  1691. LOCAL STATUS sysLanIntEnable
  1692.     (
  1693.      int intLevel  /* interrupt level to enable */
  1694.     )
  1695.     {
  1696.     sysIntEnablePIC (intLevel);
  1697.     return (OK);
  1698.     }