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

VxWorks

开发平台:

C/C++

  1. /* if_lnPci.c - AMD Am79C970 PCnet-PCI Ethernet network interface driver */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01j,19oct01,dat  Documentation formatting
  8. 01i,17oct00,spm  merged from version 01j of tor2_0_x branch (base version 01h):
  9.                  removed obsolete ether_attach prototype
  10. 01h,26aug98,sut  Renamed lnCSR_3B to lnPciCSR_3B DOC required
  11. 01g,15jul97,spm  added ARP request to SIOCSIFADDR ioctl handler
  12. 01f,19may97,spm  removed compiler warnings and unused function lnBcrRead()
  13. 01e,15may97,spm  reverted to bcopy routines for mbufs in BSD 4.4
  14. 01d,13may97,map  made ethernet addr copy, and ether packet type endian safe;
  15.                  reinit BCNT for Rx descriptors  [SPR# 8431]
  16. 01c,28apr97,map  added lnRestart functionality [SPR# 8223]
  17. 01b,01apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.4
  18. 01a,11jan95,vin  written from 02q of if_ln.c with minimal clean up.
  19. */
  20. /*
  21. This module implements the Advanced Micro Devices Am79C970 PCnet-PCI
  22. Ethernet 32 bit network interface driver.
  23. The PCnet-PCI ethernet controller is inherently little endian because
  24. the chip is designed to operate on a PCI bus which is a little endian
  25. bus. The software interface to the driver is divided into three parts.
  26. The first part is the PCI configuration registers and their set up. 
  27. This part is done at the BSP level in the various BSPs which use this
  28. driver. The second and third part are dealt in the driver. The second
  29. part of the interface comprises of the I/O control registers and their
  30. programming. The third part of the interface comprises of the descriptors
  31. and the buffers. 
  32. This driver is designed to be moderately generic, operating unmodified
  33. across the range of architectures and targets supported by VxWorks.  To
  34. achieve this, the driver must be given several target-specific parameters,
  35. and some external support routines must be provided.  These parameters,
  36. and the mechanisms used to communicate them to the driver, are detailed
  37. below.  If any of the assumptions stated below are not true for your
  38. particular hardware, this driver will probably not function correctly with
  39. it.
  40. This driver supports only one LANCE unit per CPU.  The driver can be
  41. configured to support big-endian or little-endian architectures.  It
  42. contains error recovery code to handle known device errata related to DMA
  43. activity. 
  44. Big endian processors can be connected to the PCI bus through some controllers
  45. which take care of hardware byte swapping. In such cases all the registers 
  46. which the chip DMA s to have to be swapped and written to, so that when the
  47. hardware swaps the accesses, the chip would see them correctly. The chip still
  48. has to be programmed to operated in little endian mode as it is on the PCI bus.
  49. If the cpu board hardware automatically swaps all the accesses to and from the
  50. PCI bus, then input and output byte stream need not be swapped. 
  51. BOARD LAYOUT
  52. This device is on-board.  No jumpering diagram is necessary.
  53. EXTERNAL INTERFACE
  54. This driver provides the standard external interface with the following
  55. exceptions.  All initialization is performed within the attach routine;
  56. there is no separate initialization routine.  Therefore, in the global interface
  57. structure, the function pointer to the initialization routine is NULL.
  58. The only user-callable routine is lnPciattach(), which publishes the `lnPci'
  59. interface and initializes the driver and device.
  60. TARGET-SPECIFIC PARAMETERS
  61. .iP "bus mode"
  62. This parameter is a global variable that can be modified at run-time.
  63. The LANCE control register #3 determines the bus mode of the device,
  64. allowing the support of big-endian and little-endian architectures.
  65. This parameter, defined as "u_long lnPciCSR_3B", is the value that will
  66. be placed into LANCE control register #3.  The default value supports
  67. Motorola-type buses.  For information about changing this parameter, see 
  68. the manual
  69. .I "Advanced Micro Devices Local Area Network Controller Am79C970 (PCnet-PCI)."
  70. .iP "base address of device registers"
  71. This parameter is passed to the driver by lnPciattach().  It 
  72. indicates to the driver where to find the RDP register.
  73. The LANCE presents two registers to the external interface, the RDP (register
  74. data port) and RAP (register address port) registers.  This driver assumes 
  75. that these two registers occupy two unique addresses in a memory space
  76. that is directly accessible by the CPU executing this driver.  The driver
  77. assumes that the RDP register is mapped at a lower address than the RAP
  78. register; the RDP register is therefore considered the "base address."
  79. .iP "interrupt vector"
  80. This parameter is passed to the driver by lnPciattach().
  81. This driver configures the LANCE device to generate hardware interrupts
  82. for various events within the device; thus it contains
  83. an interrupt handler routine.  The driver calls intConnect() to connect 
  84. its interrupt handler to the interrupt vector generated as a result of 
  85. the LANCE interrupt.
  86. .iP "interrupt level"
  87. This parameter is passed to the driver by lnPciattach().
  88. Some targets use additional interrupt controller devices to help organize and
  89. service the various interrupt sources.  This driver avoids all board-specific
  90. knowledge of such devices.  During the driver's initialization, the external
  91. routine sysLanIntEnable() is called to perform any board-specific operations
  92. required to turn on LANCE interrupt generation. A similar routine,
  93. sysLanIntDisable(), is called by the driver before a LANCE reset to perform
  94. board-specific operations required to turn off LANCE interrupt generation.
  95. For a description of sysLanIntEnable(), and sysLanIntDisable(), see "External
  96. Support Requirements" below.
  97. This parameter is passed to the external routine.
  98. .iP "shared memory address"
  99. This parameter is passed to the driver by lnPciattach().
  100. The LANCE device is a DMA type of device and typically shares access to
  101. some region of memory with the CPU.  This driver is designed for systems
  102. that directly share memory between the CPU and the LANCE.  It
  103. assumes that this shared memory is directly available to it
  104. without any arbitration or timing concerns.
  105. This parameter can be used to specify an explicit memory region for use
  106. by the LANCE.  This should be done on hardware that restricts the LANCE
  107. to a particular memory region.  The constant NONE can be used to indicate
  108. that there are no memory limitations, in which case, the driver 
  109. attempts to allocate the shared memory from the system space.
  110. .iP "shared memory size"
  111. This parameter is passed to the driver by lnPciattach().
  112. This parameter can be used to explicitly limit the amount of shared
  113. memory (bytes) this driver will use.  The constant NONE can be used to
  114. indicate no specific size limitation.  This parameter is used only if
  115. a specific memory region is provided to the driver.
  116. .iP "shared memory width"
  117. This parameter is passed to the driver by lnPciattach().
  118. Some target hardware that restricts the shared memory region to a
  119. specific location also restricts the access width to this region by
  120. the CPU.  On these targets, performing an access of an invalid width
  121. will cause a bus error.
  122. This parameter can be used to specify the number of bytes of access
  123. width to be used by the driver during access to the shared memory.
  124. The constant NONE can be used to indicate no restrictions.
  125. Current internal support for this mechanism is not robust; implementation 
  126. may not work on all targets requiring these restrictions.
  127. .iP "shared memory buffer size"
  128. This parameter is passed to the driver by lnPciattach().
  129. The driver and LANCE device exchange network data in buffers.  This
  130. parameter permits the size of these individual buffers to be limited.
  131. A value of zero indicates that the default buffer size should be used.
  132. The default buffer size is large enough to hold a maximum-size Ethernet
  133. packet.
  134. Use of this parameter should be rare.  Network performance
  135. will be affected, since the target will no longer be able to receive
  136. all valid packet sizes.
  137. .iP "Ethernet address"
  138. This parameter is obtained directly from a global memory location.
  139. During initialization, the driver needs to know the Ethernet address for
  140. the LANCE device.  The driver assumes that this address is available in
  141. a global, six-byte character array, lnEnetAddr[].  This array is
  142. typically created and stuffed by the BSP code.
  143. .LP
  144. EXTERNAL SUPPORT REQUIREMENTS
  145. This driver requires one external support function:
  146. .iP "void sysLanIntEnable (int level)" "" 9 -1
  147. This routine provides a target-specific enable of the interrupt for the LANCE
  148. device.  Typically, this involves programming an interrupt controller
  149. hardware, either internal or external to the CPU.
  150. This routine is called during chip initialization, at startup and each LANCE
  151. device reset.
  152. .iP "void sysLanIntDisable (int level)" "" 9 -1
  153. This routine provides a target-specific disable of the interrupt for the LANCE
  154. device.  Typically, this involves programming an interrupt controller
  155. hardware, either internal or external to the CPU.
  156. This routine is called before a LANCE device reset.
  157. .LP
  158. SYSTEM RESOURCE USAGE
  159. When implemented, this driver requires the following system resources:
  160.     - one mutual exclusion semaphore
  161.     - one interrupt vector
  162.     - 24 bytes in the initialized data section (data)
  163.     - 208 bytes in the uninitialized data section (BSS)
  164. The above data and BSS requirements are for the MC68020 architecture 
  165. and may vary for other architectures.  Code size (text) varies greatly between
  166. architectures and is therefore not quoted here.
  167. If the driver is not given a specific region of memory via the lnPciattach()
  168. routine, then it calls cacheDmaMalloc() to allocate the memory to be shared 
  169. with the LANCE.  The size requested is 80,542 bytes.  If a memory region
  170. is provided to the driver, the size of this region is adjustable to suit
  171. user needs.
  172. The LANCE can only be operated if the shared memory region is write-coherent
  173. with the data cache.  The driver cannot maintain cache coherency
  174. for the device for data that is written by the driver because fields
  175. within the shared structures are asynchronously modified by both the driver
  176. and the device, and these fields may share the same cache line.
  177. SEE ALSO: ifLib, 
  178. .I "Advanced Micro Devices PCnet-PCI Ethernet Controller for PCI."
  179. */
  180. #include "vxWorks.h"
  181. #include "stdlib.h"
  182. #include "taskLib.h"
  183. #include "logLib.h"
  184. #include "intLib.h"
  185. #include "netLib.h"
  186. #include "stdio.h"
  187. #include "stdlib.h"
  188. #include "sysLib.h"
  189. #include "iv.h"
  190. #include "memLib.h"
  191. #include "cacheLib.h"
  192. #include "sys/ioctl.h"
  193. #include "etherLib.h"
  194. #ifndef DOC             /* don't include when building documentation */
  195. #include "net/mbuf.h"
  196. #endif  /* DOC */
  197. #include "net/protosw.h"
  198. #include "sys/socket.h"
  199. #include "errno.h"
  200. #include "net/if.h"
  201. #include "net/route.h"
  202. #include "netinet/in.h"
  203. #include "netinet/in_systm.h"
  204. #include "netinet/in_var.h"
  205. #include "netinet/ip.h"
  206. #include "netinet/if_ether.h"
  207. #include "net/if_subr.h"
  208. #include "semLib.h"
  209. #include "drv/netif/if_lnPci.h" /* device description header */
  210. /***** LOCAL DEFINITIONS *****/
  211. /* descriptor size */
  212. #define RMD_SIZ  sizeof(ln_rmd)
  213. #define TMD_SIZ  sizeof(ln_tmd)
  214. /* Configuration items */
  215. #define LN_MIN_FIRST_DATA_CHAIN 96      /* min size of 1st buf in data-chain */
  216. #define LN_MAX_MDS              128     /* max number of [r|t]md's for LANCE */
  217. #define LN_BUFSIZ      (ETHERMTU + ENET_HDR_REAL_SIZ + 6)
  218. #define LN_RMD_RLEN     5       /* ring size as a power of 2 -- 32 RMD's */
  219. #define LN_TMD_TLEN     5       /* same for transmit ring    -- 32 TMD's */
  220. #define MAX_UNITS       1       /* maximum units supported */
  221. /*
  222.  * If LN_KICKSTART_TX is TRUE the transmitter is kick-started to force a
  223.  * read of the transmit descriptors, otherwise the internal polling (1.6msec)
  224.  * will initiate a read of the descriptors.  This should be FALSE is there
  225.  * is any chance of memory latency or chip accesses detaining the LANCE DMA,
  226.  * which results in a transmitter UFLO error.  This can be changed with the
  227.  * global lnKickStartTx below.
  228.  */
  229. #define LN_KICKSTART_TX TRUE
  230. /* Cache macros */
  231. #define LN_CACHE_INVALIDATE(address, len) 
  232.         CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))
  233. #define LN_CACHE_VIRT_TO_PHYS(address) 
  234.         CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))
  235. #define LN_CACHE_PHYS_TO_VIRT(address) 
  236.         CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))
  237. /* memory to PCI address translation macros */
  238. #define PCI_TO_MEM_PHYS(pciAdrs) 
  239. ((pciAdrs) - (pDrvCtrl->pciMemBase))
  240. #define MEM_TO_PCI_PHYS(memAdrs) 
  241. ((memAdrs) + (pDrvCtrl->pciMemBase))
  242. /* Typedefs for external structures that are not typedef'd in their .h files */
  243. typedef struct mbuf MBUF;
  244. typedef struct arpcom IDR;                  /* Interface Data Record wrapper */
  245. typedef struct ifnet IFNET;                 /* real Interface Data Record */
  246. typedef struct sockaddr SOCK;
  247. #ifdef BSD43_DRIVER
  248. /* The Ethernet header */
  249. typedef struct enet_hdr
  250.     {
  251.     char dst [6];
  252.     char src [6];
  253.     u_short type;
  254.     } ENET_HDR;
  255. #define ENET_HDR_SIZ        sizeof(ENET_HDR)
  256. #endif            /* BSD43_DRIVER */
  257. #define ENET_HDR_REAL_SIZ   14
  258. /* The definition of the driver control structure */
  259. typedef struct drv_ctrl
  260.     {
  261.     IDR         idr;                /* Interface Data Record */
  262.     ln_ib       *ib;                 /* ptr to Initialization Block */
  263.     struct
  264.         {
  265.         int     r_po2;                  /* RMD ring size as a power of 2! */
  266.         int     r_size;                 /* RMD ring size (power of 2!) */
  267.         int     r_index;                /* index into RMD ring */
  268.         ln_rmd  *r_ring;                /* RMD ring */
  269.         char    *r_bufs;                /* receive buffers base */
  270.         } rmd_ring;
  271.     struct
  272.         {
  273.         int     t_po2;                  /* TMD ring size as a power of 2! */
  274.         int     t_size;                 /* TMD ring size (power of 2!) */
  275.         int     t_index;                /* index into TMD ring */
  276.         int     d_index;                /* index into TMD ring */
  277.         ln_tmd  *t_ring;                /* TMD ring */
  278.         char    *t_bufs;                /* transmit buffers base */
  279.         } tmd_ring;
  280.     BOOL        attached;               /* indicates unit is attached */
  281.     SEM_ID      TxSem;                  /* transmitter semaphore */
  282.     u_char      flags;                  /* misc control flags */
  283.     int         ivec;                   /* interrupt vector */
  284.     int         ilevel;                 /* interrupt level */
  285.     LN_DEVICE   *devAdrs;               /* device structure address */
  286.     char        *memBase;               /* LANCE memory pool base */
  287.     int         memWidth;               /* width of data port */
  288.     ULONG pciMemBase; /* memory base as seen from PCI*/
  289.     int         bufSize;                /* size of buffer in the LANCE ring */
  290.     CACHE_FUNCS cacheFuncs;             /* cache function pointers */
  291.     } DRV_CTRL;
  292. #define DRV_CTRL_SIZ    sizeof(DRV_CTRL)
  293. /* Definitions for the flags field */
  294. #define LS_PROMISCUOUS_FLAG     0x1
  295. #define LS_MEM_ALLOC_FLAG       0x2
  296. #define LS_PAD_USED_FLAG        0x4
  297. #define LS_RCV_HANDLING_FLAG    0x8
  298. #define LS_START_OUTPUT_FLAG    0x10
  299. /* Shorthand structure references */
  300. #define rpo2         rmd_ring.r_po2
  301. #define rsize        rmd_ring.r_size
  302. #define rindex       rmd_ring.r_index
  303. #define rring        rmd_ring.r_ring
  304. #define tpo2         tmd_ring.t_po2
  305. #define tsize        tmd_ring.t_size
  306. #define tindex       tmd_ring.t_index
  307. #define dindex       tmd_ring.d_index
  308. #define tring        tmd_ring.t_ring
  309. /***** GLOBALS *****/
  310. IMPORT unsigned char lnEnetAddr []; /* Ethernet address to load into lance */
  311. ULONG lnPciCSR_3B = 0 ;    /* allows external setting of bus modes */
  312. void panic ();
  313. void sysLanIntEnable (int ilevel);
  314. void sysLanIntDisable (int ilevel);
  315. BOOL arpresolve ();
  316. /***** LOCALS *****/
  317. static int lnTsize = LN_TMD_TLEN;    /* deflt xmit ring size as power of 2 */
  318. static int lnRsize = LN_RMD_RLEN;    /* deflt recv ring size as power of 2 */
  319. static BOOL lnKickStartTx = LN_KICKSTART_TX;
  320. /* The array of driver control structures */
  321. static DRV_CTRL  drvCtrl [MAX_UNITS];
  322. /* initial word offsets from LANCE base address to access these registers */
  323. static u_int CSROffset = 0;
  324. static u_int RAPOffset = 1;
  325. static u_int BDPOffset = 3;
  326. /* forward static functions */
  327. static void  lnReset (int unit);
  328. static void  lnInt (DRV_CTRL *pDrvCtrl);
  329. static void  lnHandleRecvInt (DRV_CTRL *pDrvCtrl);
  330. static STATUS  lnRecv (DRV_CTRL *pDrvCtrl, ln_rmd *rmd);
  331. #ifdef BSD43_DRIVER
  332. static int  lnOutput (IDR *ifp, MBUF *m0, SOCK *dst);
  333. #else
  334. LOCAL  void  lnPciStartOutput (DRV_CTRL *  pDrvCtrl);
  335. #endif /* BSD43_DRIVER */
  336. static int  lnIoctl (IDR *ifp, int cmd, caddr_t data);
  337. static int  lnChipReset (DRV_CTRL *pDrvCtrl);
  338. static ln_rmd * lnGetFullRMD (DRV_CTRL *pDrvCtrl);
  339. static void  lnCsrWrite (DRV_CTRL * pDrvCtrl, int reg, ULONG value);
  340. static ULONG  lnCsrRead (DRV_CTRL * pDrvCtrl, int reg);
  341. static void  lnBcrWrite (DRV_CTRL * pDrvCtrl, int reg, ULONG value);
  342. static STATUS   lnRestartSetup (DRV_CTRL *pDrvCtrl);
  343. static void     lnRestart (DRV_CTRL *pDrvCtrl);
  344. #ifdef BSD43_DRIVER
  345. static BOOL  convertDestAddr (IDR *pIDR, SOCK *pDestSktAddr,
  346.                                  char *pDestEnetAddr, u_short *pPacketType,
  347.                                  MBUF *pMbuf);
  348. #endif
  349. /*******************************************************************************
  350. *
  351. * lnPciattach - publish the `lnPci' network interface and initialize the driver and device
  352. *
  353. * This routine publishes the `ln' interface by filling in a network interface
  354. * record and adding this record to the system list.  This routine also
  355. * initializes the driver and the device to the operational state.
  356. *
  357. * The <memAdrs> parameter can be used to specify the location of the
  358. * memory that will be shared between the driver and the device.  The value
  359. * NONE is used to indicate that the driver should obtain the memory.
  360. *
  361. * The <memSize> parameter is valid only if the <memAdrs> parameter is not
  362. * set to NONE, in which case <memSize> indicates the size of the
  363. * provided memory region.
  364. *
  365. * The <memWidth> parameter sets the memory pool's data port width (in bytes);
  366. * if it is NONE, any data width is used.
  367. *
  368. * BUGS
  369. * To zero out LANCE data structures, this routine uses bzero(), which
  370. * ignores the <memWidth> specification and uses any size data access to
  371. * write to memory.
  372. *
  373. * RETURNS: OK or ERROR.
  374. */
  375. STATUS lnPciattach
  376.     (
  377.     int unit, /* unit number */
  378.     char * devAdrs, /* LANCE I/O address */
  379.     int ivec, /* interrupt vector */
  380.     int ilevel, /* interrupt level */
  381.     char * memAdrs, /* address of memory pool (-1 = malloc it) */
  382.     ULONG memSize, /* used if memory pool is NOT malloc()'d */
  383.     int memWidth, /* byte-width of data (-1 = any width)     */
  384.     ULONG     pciMemBase, /* memory base as seen from PCI*/
  385.     int spare2 /* not used */
  386.     )
  387.     {
  388.     DRV_CTRL     *pDrvCtrl;
  389.     unsigned int sz;           /* temporary size holder */
  390.     char         *pTurkey;     /* start of the LANCE memory pool */
  391.     /* Sanity check the unit number */
  392.     if (unit < 0 || unit >= MAX_UNITS)
  393.         return (ERROR);
  394.     /* Ensure single invocation per system life */
  395.     pDrvCtrl = & drvCtrl [unit];
  396.     if (pDrvCtrl->attached)
  397.         return (OK);
  398.     /* Publish the interface data record */
  399. #ifdef BSD43_DRIVER
  400.     ether_attach (& pDrvCtrl->idr.ac_if, unit, "lnPci", (FUNCPTR) NULL,
  401.                   (FUNCPTR) lnIoctl, (FUNCPTR) lnOutput, (FUNCPTR) lnReset);
  402. #else
  403.     ether_attach    (
  404.                     &pDrvCtrl->idr.ac_if,
  405.                     unit,
  406.                     "lnPci",
  407.                     (FUNCPTR) NULL,
  408.                     (FUNCPTR) lnIoctl,
  409.                     (FUNCPTR) ether_output,  /* generic output for Ethernet */
  410.                     (FUNCPTR) lnReset
  411.                     );
  412.     pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)lnPciStartOutput;
  413. #endif
  414.     /* Create the transmit semaphore. */
  415.     pDrvCtrl->TxSem = semMCreate    (
  416.                                     SEM_Q_PRIORITY |
  417.                                     SEM_DELETE_SAFE |
  418.                                     SEM_INVERSION_SAFE
  419.                                     );
  420.     if (pDrvCtrl->TxSem == NULL)
  421.         {
  422.         printf ("lnPci: error creating transmitter semaphoren");
  423.         return (ERROR);
  424.         }
  425.     { /***** Establish size of shared memory region we require *****/
  426.     if ((int) memAdrs != NONE)  /* specified memory pool */
  427.         {
  428.         /*
  429.          * With a specified memory pool we want to maximize
  430.          * lnRsize and lnTsize
  431.          */
  432.         sz = (memSize - (RMD_SIZ + TMD_SIZ + sizeof (ln_ib)))
  433.                / ((2 * LN_BUFSIZ) + RMD_SIZ + TMD_SIZ);
  434.         sz >>= 1;               /* adjust for roundoff */
  435.         for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)
  436.             ;
  437.         lnTsize = lnRsize;      /* lnTsize = lnRsize for convenience */
  438.         }
  439.     /* limit ring sizes to reasonable values */
  440.     if (lnRsize < 2)
  441.         lnRsize = 2;            /* 4 buffers is reasonable min */
  442.     if (lnRsize > 7)
  443.         lnRsize = 7;            /* 128 buffers is max for chip */
  444.     /* limit ring sizes to reasonable values */
  445.     if (lnTsize < 2)
  446.         lnTsize = 2;            /* 4 buffers is reasonable min */
  447.     if (lnTsize > 7)
  448.         lnTsize = 7;            /* 128 buffers is max for chip */
  449.     /* Add it all up */
  450.     sz = (sizeof (ln_ib)) +
  451.          ( ((1 << lnRsize) + 1) * RMD_SIZ ) +
  452.          (LN_BUFSIZ << lnRsize) +
  453.          ( ((1 << lnTsize) + 1) * TMD_SIZ ) +
  454.          (LN_BUFSIZ << lnTsize) +
  455.          6;                        /* allow for alignment adjustment */
  456.     }
  457.     { /***** Establish a region of shared memory *****/
  458.     /* OK. We now know how much shared memory we need.  If the caller
  459.      * provides a specific memory region, we check to see if the provided
  460.      * region is large enough for our needs.  If the caller did not
  461.      * provide a specific region, then we attempt to allocate the memory
  462.      * from the system, using the cache aware allocation system call.
  463.      */
  464.     switch ( (int) memAdrs )
  465.         {
  466.         default :       /* caller provided memory */
  467.             if ( memSize < sz )     /* not enough space */
  468.                 {
  469.                 printf ( "lnPci: not enough memory providedn" );
  470.                 return ( ERROR );
  471.                 }
  472.             pTurkey = memAdrs;             /* set the beginning of pool */
  473.             /* assume pool is cache coherent, copy null structure */
  474.             pDrvCtrl->cacheFuncs = cacheNullFuncs;
  475.             break;
  476.         case NONE :     /* get our own memory */
  477.             /* Because the structures that are shared between the device
  478.              * and the driver may share cache lines, the possibility exists
  479.              * that the driver could flush a cache line for a structure and
  480.              * wipe out an asynchronous change by the device to a neighboring
  481.              * structure. Therefore, this driver cannot operate with memory
  482.              * that is not write coherent.  We check for the availability of
  483.              * such memory here, and abort if the system did not give us what
  484.              * we need.
  485.              */
  486.             if (!CACHE_DMA_IS_WRITE_COHERENT ())
  487.                 {
  488.                 printf ( "lnPci: device requires cache coherent memoryn" );
  489.                 return (ERROR);
  490.                 }
  491.             pTurkey = (char *) cacheDmaMalloc ( sz );
  492.             if ((int)pTurkey == NULL)
  493.                 {
  494.                 printf ( "lnPci: system memory unavailablen" );
  495.                 return (ERROR);
  496.                 }
  497.             /* copy the DMA structure */
  498.             pDrvCtrl->cacheFuncs = cacheDmaFuncs;
  499.             break;
  500.         }
  501.     }
  502.     /*                        Turkey Carving
  503.      *                        --------------
  504.      *
  505.      *                          LOW MEMORY
  506.      *
  507.      *             |-------------------------------------|
  508.      *             |       The initialization block      |
  509.      *             |         (sizeof (ln_ib))            |
  510.      *             |-------------------------------------|
  511.      *             |         The Rx descriptors          |
  512.      *             | (1 << lnRsize) * sizeof (ln_rmd)|
  513.      *             |-------------------------------------|
  514.      *             |          The receive buffers        |
  515.      *             |       (LN_BUFSIZ << lnRsize)        |
  516.      *             |-------------------------------------|
  517.      *             |         The Tx descriptors          |
  518.      *             | (1 << lnTsize) * sizeof (ln_tmd)|
  519.      *             |-------------------------------------|
  520.      *             |           The transmit buffers      |
  521.      *             |       (LN_BUFSIZ << lnTsize)        |
  522.      *             |-------------------------------------|
  523.      */
  524.     /* Save some things */
  525.     pDrvCtrl->memBase  = (char *)((ULONG)pTurkey & 0xff000000);
  526.     pDrvCtrl->memWidth = memWidth;
  527.     pDrvCtrl->bufSize = LN_BUFSIZ;
  528.     pDrvCtrl->pciMemBase  = pciMemBase; /* pci memory base */
  529.     if ((int) memAdrs == NONE)
  530.         pDrvCtrl->flags |= LS_MEM_ALLOC_FLAG;
  531.     { /***** Carve up the turkey *****/
  532.     /* First let's clean the whole turkey */
  533.     bzero ( (char *) pTurkey, (int) sz );
  534.     /* carve out initialization block */
  535.     pDrvCtrl->ib = (ln_ib *)pTurkey;
  536.     sz = sizeof (ln_ib);                /* size of initialization block */
  537.     /* carve out receive message descriptor (RMD) ring structure */
  538.     pDrvCtrl->rpo2 = lnRsize;              /* remember for lnConfig */
  539.     pDrvCtrl->rsize = (1 << lnRsize);      /* receive ring size */
  540.     /* make it 16 byte aligned */
  541.     pDrvCtrl->rring = (ln_rmd *) (((int)pDrvCtrl->ib + sz + 0x0f) & ~0x0f);
  542.     sz = (1 << lnRsize) * RMD_SIZ;
  543.     pDrvCtrl->rmd_ring.r_bufs = (char *)((int)pDrvCtrl->rring + sz);
  544.     sz = (LN_BUFSIZ << lnRsize);   /* room for all the receive buffers */
  545.     /* carve out transmit message descriptor (TMD) ring structure */
  546.     pDrvCtrl->tpo2 = lnTsize;              /* remember for lnConfig */
  547.     pDrvCtrl->tsize = (1 << lnTsize);      /* transmit ring size */
  548.     pDrvCtrl->tring = (ln_tmd *) (((int)pDrvCtrl->rmd_ring.r_bufs + sz + 0x0f)
  549.   & ~0x0f);
  550.     sz = (1 << lnTsize) * TMD_SIZ;
  551.     /* carve out transmit buffer space */
  552.     pDrvCtrl->tmd_ring.t_bufs = (char *)((int)pDrvCtrl->tring + sz);
  553.     }
  554.     /* Save some values */
  555.     pDrvCtrl->ivec       = ivec;                 /* interrupt vector */
  556.     pDrvCtrl->ilevel     = ilevel;               /* interrupt level */
  557.     pDrvCtrl->devAdrs    = (LN_DEVICE *)devAdrs; /* LANCE I/O address */
  558.     /* Obtain our Ethernet address and save it */
  559.     bcopy ((char *) lnEnetAddr, (char *)pDrvCtrl->idr.ac_enaddr, 6);
  560.     /***** Device Initializations *****/
  561.     if (lnChipReset (pDrvCtrl) == ERROR) /* reset lance device */
  562.      {
  563.         logMsg ("lnPci: Device failed to resetn", 0,0,0,0,0,0);
  564.   return (ERROR);
  565. }
  566.     if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),lnInt,(int)pDrvCtrl)
  567.         == ERROR)
  568.         return (ERROR);
  569.     if (lnRestartSetup (pDrvCtrl) == ERROR)
  570.         return (ERROR);
  571.     pDrvCtrl->attached = TRUE;
  572.     return (OK);
  573.     }
  574. /*******************************************************************************
  575. *
  576. * lnReset - reset the interface
  577. *
  578. * Mark interface as inactive & reset the chip
  579. */
  580. static void lnReset
  581.     (
  582.     int unit
  583.     )
  584.     {
  585.     DRV_CTRL *pDrvCtrl = & drvCtrl [unit];
  586.     pDrvCtrl->idr.ac_if.if_flags = 0;
  587.     lnChipReset (pDrvCtrl);                           /* reset LANCE */
  588.     }
  589. /*******************************************************************************
  590. *
  591. * lnInt - handle controller interrupt
  592. *
  593. * This routine is called at interrupt level in response to an interrupt from
  594. * the controller.
  595. */
  596. static void lnInt
  597.     (
  598.     DRV_CTRL  *pDrvCtrl
  599.     )
  600.     {
  601.     ln_tmd         *tmd;
  602.     int            *pDindex;
  603.     int            *pTindex;
  604.     int            *pTsize;
  605.     ln_tmd         *pTring;
  606.     ULONG    stat;
  607.     /* Read the device status register */
  608.     stat = lnCsrRead (pDrvCtrl, 0);
  609.     /* If false interrupt, return. */
  610.     if ( ! (stat & CSR0_INTR) )
  611.         return;
  612.     /*
  613.      * enable interrupts, clear receive and/or transmit interrupts, and clear
  614.      * any errors that may be set.
  615.      */
  616.     lnCsrWrite (pDrvCtrl, 0, ((stat &
  617.             (CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|
  618.              CSR0_RINT|CSR0_TINT|CSR0_IDON)) | CSR0_INEA));
  619.     /* Check for errors */
  620.     if (stat & (CSR0_BABL | CSR0_MISS | CSR0_MERR))
  621.         {
  622.         ++pDrvCtrl->idr.ac_if.if_ierrors;
  623.         /* restart chip on fatal error */
  624.         if (stat & CSR0_MERR)        /* memory error */
  625.             {
  626.             pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
  627.             (void) netJobAdd (
  628.                              (FUNCPTR)lnRestart,
  629.                              pDrvCtrl->idr.ac_if.if_unit,
  630.                              0,0,0,0
  631.                              );
  632.             }
  633.         }
  634.     /* Have netTask handle any input packets */
  635.     if ((stat & CSR0_RINT) && (stat & CSR0_RXON))
  636.         {
  637.         if ( ! (pDrvCtrl->flags & LS_RCV_HANDLING_FLAG) )
  638.             {
  639.             pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;
  640.             (void) netJobAdd (
  641.                              (FUNCPTR)lnHandleRecvInt,
  642.                              (int)pDrvCtrl,
  643.                              0,0,0,0
  644.                              );
  645.             }
  646.         }
  647.     /*
  648.      * Did LANCE update any of the TMD's?
  649.      * If not then don't bother continuing with transmitter stuff
  650.      */
  651.     if (!(stat & CSR0_TINT))
  652.         return;
  653.     pDindex = &pDrvCtrl->dindex;
  654.     pTindex = &pDrvCtrl->tindex;
  655.     pTsize  = &pDrvCtrl->tsize;
  656.     pTring  = pDrvCtrl->tring;
  657.     while (*pDindex != *pTindex)
  658.         {
  659.         /* disposal has not caught up */
  660.         tmd = pTring + *pDindex;
  661.         /* if the buffer is still owned by LANCE, don't touch it */
  662.         LN_CACHE_INVALIDATE (tmd, TMD_SIZ);
  663.         if (PCISWAP(tmd->tbuf_tmd1) & TMD1_OWN)
  664.             break;
  665.         /*
  666.          * tbuf_err (TMD1.ERR) is an "OR" of LCOL, LCAR, UFLO or RTRY.
  667.          * Note that BUFF is not indicated in TMD1.ERR.
  668.          * We should therefore check both tbuf_err and tbuf_buff
  669.          * here for error conditions.
  670.          */
  671.         if ((PCISWAP(tmd->tbuf_tmd1) & TMD1_ERR) || 
  672.     (PCISWAP(tmd->tbuf_tmd2) & TMD2_BUFF))
  673.             {
  674.             pDrvCtrl->idr.ac_if.if_oerrors++;     /* output error */
  675.             pDrvCtrl->idr.ac_if.if_opackets--;
  676.             /* If error was due to excess collisions, bump the collision
  677.              * counter.  The LANCE does not keep an individual counter of
  678.              * collisions, so in this driver, the collision statistic is not
  679.              * an accurate count of total collisions.
  680.              */
  681.             if (PCISWAP(tmd->tbuf_tmd2) & TMD2_RTRY)
  682.                 pDrvCtrl->idr.ac_if.if_collisions++;
  683.             /* check for no carrier */
  684.             if (PCISWAP(tmd->tbuf_tmd2) & TMD2_LCAR)
  685.                 logMsg ("ln%d: no carriern",
  686.                     pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0);
  687.             /* Restart chip on fatal errors.
  688.              * The following code handles the situation where the transmitter
  689.              * shuts down due to an underflow error.  This is a situation that
  690.              * will occur if the DMA cannot keep up with the transmitter.
  691.              * It will occur if the LANCE is being held off from DMA access
  692.              * for too long or due to significant memory latency.  DRAM
  693.              * refresh or slow memory could influence this.  Many
  694.              * implementation use a dedicated LANCE buffer.  This can be
  695.              * static RAM to eliminate refresh conflicts; or dual-port RAM
  696.              * so that the LANCE can have free run of this memory during its
  697.              * DMA transfers.
  698.              */
  699.             if ((PCISWAP(tmd->tbuf_tmd2) & TMD2_BUFF) || 
  700. (PCISWAP(tmd->tbuf_tmd2) & TMD2_UFLO))
  701.                 {
  702.                 pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
  703.                 (void) netJobAdd (
  704.                                  (FUNCPTR)lnRestart,
  705.                                  pDrvCtrl->idr.ac_if.if_unit,
  706.                                  0,0,0,0
  707.                                  );
  708.                 return;
  709.                 }
  710.             }
  711.         tmd->tbuf_tmd1 = 0; /* clear tmd1 */
  712.         tmd->tbuf_tmd2 = 0; /* clear all error & stat stuff */
  713.         /* now bump the tmd disposal index pointer around the ring */
  714.         *pDindex = (*pDindex + 1) & (*pTsize - 1);
  715.         }
  716.     /* Flush the write pipe */
  717.     CACHE_PIPE_FLUSH ();
  718.     }
  719. /*******************************************************************************
  720. *
  721. * lnHandleRecvInt - task level interrupt service for input packets
  722. *
  723. * This routine is called at task level indirectly by the interrupt
  724. * service routine to do any message received processing.
  725. */
  726. static void lnHandleRecvInt
  727.     (
  728.     DRV_CTRL *pDrvCtrl
  729.     )
  730.     {
  731.     ln_rmd *rmd;
  732.     do
  733.         {
  734.         pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;
  735.         while ((rmd = lnGetFullRMD (pDrvCtrl)) != NULL)
  736.             lnRecv (pDrvCtrl, rmd);
  737.         /*
  738.          * There is a RACE right here.  The ISR could add a receive packet
  739.          * and check the boolean below, and decide to exit.  Thus the
  740.          * packet could be dropped if we don't double check before we
  741.          * return.
  742.          */
  743.         pDrvCtrl->flags &= ~LS_RCV_HANDLING_FLAG;
  744.         }
  745.     while (lnGetFullRMD (pDrvCtrl) != NULL);
  746.     /* this double check solves the RACE */
  747.     }
  748. /*******************************************************************************
  749. *
  750. * lnGetFullRMD - get next received message RMD
  751. *
  752. * Returns ptr to next Rx desc to process, or NULL if none ready.
  753. */
  754. static ln_rmd *lnGetFullRMD
  755.     (
  756.     DRV_CTRL  *pDrvCtrl
  757.     )
  758.     {
  759.     ln_rmd   *rmd;
  760.     /* Refuse to do anything if flags are down */
  761.     if  (
  762.         (pDrvCtrl->idr.ac_if.if_flags & (IFF_UP | IFF_RUNNING) ) !=
  763.         (IFF_UP | IFF_RUNNING)
  764.         )
  765.         return ((ln_rmd *) NULL);
  766.     rmd = pDrvCtrl->rring + pDrvCtrl->rindex;       /* form ptr to Rx desc */
  767.     LN_CACHE_INVALIDATE (rmd, RMD_SIZ);
  768.     if ((PCISWAP(rmd->rbuf_rmd1) & RMD1_OWN) == 0)
  769.         return (rmd);
  770.     else
  771.         return ((ln_rmd *) NULL);
  772.     }
  773. /*******************************************************************************
  774. *
  775. * lnRecv - process the next incoming packet
  776. *
  777. */
  778. static STATUS lnRecv
  779.     (
  780.     DRV_CTRL *pDrvCtrl,
  781.     ln_rmd *rmd
  782.     )
  783.     {
  784.     struct ether_header *  pEnetHdr;
  785.     MBUF        *pMbuf;
  786.     u_char      *pData;
  787.     int         len;
  788.     u_short     ether_type;
  789.     BOOL        hookAte;
  790.     /* Packet must be checked for errors. */
  791.     if  (
  792.         /* If error flag */
  793.         (PCISWAP(rmd->rbuf_rmd1) & (RMD1_ERR | RMD1_FRAM)) ||
  794.         /* OR if packet is not completely in one buffer */
  795.         (
  796.         (PCISWAP(rmd->rbuf_rmd1) & (RMD1_STP | RMD1_ENP) ) !=
  797.         (RMD1_STP | RMD1_ENP)
  798.         )
  799.         )
  800.         {
  801.         ++pDrvCtrl->idr.ac_if.if_ierrors;       /* bump error stat */
  802.         goto cleanRXD;                          /* skip to clean up */
  803.         }
  804.     len = PCISWAP(rmd->rbuf_mcnt) & RMD2_MCNT_MSK; /* get packet length */
  805.     /* Get pointer to packet */
  806.     pEnetHdr = (struct ether_header *)
  807.                 (pDrvCtrl->rmd_ring.r_bufs + (pDrvCtrl->rindex * LN_BUFSIZ));
  808.     LN_CACHE_INVALIDATE (pEnetHdr, len);   /* make the packet data coherent */
  809.     ++pDrvCtrl->idr.ac_if.if_ipackets; /* bump statistic */
  810.     /* call input hook if any */
  811.     hookAte = FALSE;
  812.     if  (etherInputHookRtn != NULL)
  813.         {
  814.         if  (
  815.             (* etherInputHookRtn) (&pDrvCtrl->idr.ac_if, (char *)pEnetHdr, len)
  816.             )
  817.             hookAte = TRUE;
  818.         }
  819.     /* Normal path; send packet upstairs */
  820.     if (hookAte == FALSE)
  821.         {
  822.         /* Adjust length to size of data only */
  823.         len -= ENET_HDR_REAL_SIZ;
  824.         /* Get pointer to packet data */
  825.         pData = ((u_char *) pEnetHdr) + ENET_HDR_REAL_SIZ;
  826.         ether_type = ntohs ( pEnetHdr->ether_type );
  827. #ifdef BSD43_DRIVER
  828.         /* Copy packet data into MBUFs, using the specified width */
  829.         pMbuf = bcopy_to_mbufs (pData, len, 0, (IFNET *) & pDrvCtrl->idr.ac_if,
  830.                             pDrvCtrl->memWidth);
  831.         if (pMbuf != NULL)
  832.             do_protocol_with_type (ether_type, pMbuf, & pDrvCtrl->idr, len);
  833.         else
  834.             ++pDrvCtrl->idr.ac_if.if_ierrors;    /* bump error statistic */
  835. #else
  836.         pMbuf = bcopy_to_mbufs (pData, len, 0, &pDrvCtrl->idr.ac_if, 
  837.                                 pDrvCtrl->memWidth);
  838.         if (pMbuf != NULL)
  839.             do_protocol (pEnetHdr, pMbuf, &pDrvCtrl->idr, len);
  840.         else
  841.             ++pDrvCtrl->idr.ac_if.if_ierrors;    /* bump error statistic */
  842. #endif
  843.         }
  844.     /* Done with descriptor, clean up and give it to the device. */
  845.     cleanRXD:
  846.     /* reset statistics counters and message byte count */
  847.     rmd->rbuf_mcnt = 0;
  848.     /* reset status bits, reinitialize buffer size, and give device ownership */
  849.     rmd->rbuf_rmd1 = PCISWAP((RMD1_BCNT_MSK & - (pDrvCtrl->bufSize)) |
  850.                               RMD1_CNST | RMD1_OWN);
  851.     /* Flush the write pipe */
  852.     CACHE_PIPE_FLUSH ();
  853.     /* Advance our management index */
  854.     pDrvCtrl->rindex = (pDrvCtrl->rindex + 1) & (pDrvCtrl->rsize - 1);
  855.     return (OK);
  856.     }
  857. #ifdef BSD43_DRIVER
  858. /*******************************************************************************
  859. *
  860. * lnOutput - the driver output routine
  861. *
  862. */
  863. static int lnOutput
  864.     (
  865.     IDR  *pIDR,
  866.     MBUF *pMbuf,
  867.     SOCK *pDest
  868.     )
  869.     {
  870.     char destEnetAddr [6];                  /* space for enet addr */
  871.     u_short packetType;                     /* type field for the packet */
  872.     DRV_CTRL    *pDrvCtrl;
  873.     ln_tmd      *tmd;
  874.     char        *buf;
  875.     int         len;
  876.     int         oldLevel;
  877.     /* Check ifnet flags. Return error if incorrect. */
  878.     if  (
  879.         (pIDR->ac_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
  880.         (IFF_UP | IFF_RUNNING)
  881.         )
  882.         return (ENETDOWN);
  883.     /* Attempt to convert socket addr into enet addr and packet type.
  884.      * Note that if ARP resolution of the address is required, the ARP
  885.      * module will call our routine again to transmit the ARP request
  886.      * packet.  This means we may actually call ourselves recursively!
  887.      */
  888.     if (convertDestAddr (pIDR,pDest, destEnetAddr, &packetType, pMbuf) == FALSE)
  889.         return (OK);    /* I KNOW returning OK is stupid, but it is correct */
  890.     /* Get driver control pointer */
  891.     pDrvCtrl = & drvCtrl [pIDR->ac_if.if_unit];
  892.     /* Obtain exclusive access to transmitter.  This is necessary because
  893.      * certain events can cause netTask to run a job that attempts to transmit
  894.      * a packet.  We can only allow one task here at a time.
  895.      */
  896.     semTake (pDrvCtrl->TxSem, WAIT_FOREVER);
  897.     pDrvCtrl->flags |= LS_START_OUTPUT_FLAG;
  898.     /* See if next TXD is available */
  899.     tmd = pDrvCtrl->tring + pDrvCtrl->tindex;
  900.     LN_CACHE_INVALIDATE (tmd, TMD_SIZ);
  901.     if  (
  902.         ((PCISWAP(tmd->tbuf_tmd1) & TMD1_OWN) != 0) ||
  903.         (
  904.         ((pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1)) ==
  905.         pDrvCtrl->dindex
  906.         )
  907.         )
  908.         {
  909.         m_freem (pMbuf);            /* Discard data */
  910.         pIDR->ac_if.if_oerrors++;
  911.         goto outputDone;
  912.         }
  913.     /* Get pointer to transmit buffer */
  914.     buf = (char *)
  915.         (pDrvCtrl->tmd_ring.t_bufs + (pDrvCtrl->tindex * LN_BUFSIZ));
  916.     /* Fill in the Ethernet header */
  917.     bcopy (destEnetAddr, buf, 6);
  918.     bcopy ( (char *) pIDR->ac_enaddr, (buf + 6), 6);
  919.     ((ENET_HDR *)buf)->type = htons (packetType);
  920.     /* Copy packet from MBUFs to our transmit buffer.  MBUFs are
  921.      * transparently freed.
  922.      */
  923.     bcopy_from_mbufs    (
  924.                         (buf + ENET_HDR_REAL_SIZ),
  925.                         pMbuf,
  926.                         len,                            /* stuffed by macro */
  927.                         pDrvCtrl->memWidth
  928.                         );
  929.     /* Ensure we send a legal size frame. */
  930.     len += ENET_HDR_REAL_SIZ;
  931.     len = max (ETHERSMALL, len);
  932.     /* place a transmit request */
  933.     oldLevel = intLock ();          /* disable ints during update */
  934.     tmd->tbuf_tmd3 = 0;                     /* clear buffer error status */
  935.     /* negative message byte count */
  936.     tmd->tbuf_tmd1 &= PCISWAP(~TMD1_BCNT_MSK);
  937.     tmd->tbuf_tmd1 |= PCISWAP((TMD1_CNST | TMD1_BCNT_MSK) & -len);
  938.     tmd->tbuf_tmd1 |= PCISWAP(TMD1_ENP);    /* buffer is end of packet */
  939.     tmd->tbuf_tmd1 |= PCISWAP(TMD1_STP);    /* buffer is start of packet */
  940.     tmd->tbuf_tmd1 &= PCISWAP(~TMD1_DEF);   /* clear status bit */
  941.     tmd->tbuf_tmd1 &= PCISWAP(~TMD1_MORE);
  942.     tmd->tbuf_tmd1 &= PCISWAP(~TMD1_ERR);
  943.     tmd->tbuf_tmd1 |= PCISWAP(TMD1_OWN);
  944.     /* Flush the write pipe */
  945.     CACHE_PIPE_FLUSH ();
  946.     intUnlock (oldLevel);   /* now lnInt won't get confused */
  947.     /* Advance our management index */
  948.     pDrvCtrl->tindex = (pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1);
  949.     /* kick start the transmitter, if selected */
  950.     if (lnKickStartTx)
  951.         lnCsrWrite (pDrvCtrl, 0, (CSR0_INEA | CSR0_TDMD));
  952.     pDrvCtrl->flags &= ~LS_START_OUTPUT_FLAG;
  953.     /* Bump the statistic counter. */
  954.     pIDR->ac_if.if_opackets++;
  955.     outputDone:
  956.     /* Release exclusive access. */
  957.     semGive (pDrvCtrl->TxSem);
  958.     return (OK);
  959.     }
  960. #else           /* BSD43_DRIVER */
  961. /*******************************************************************************
  962. *
  963. * lnPciStartOutput - the driver output routine
  964. *
  965. */
  966. LOCAL void lnPciStartOutput
  967.     (
  968.     DRV_CTRL *  pDrvCtrl        /* pointer to driver control structure */
  969.     )
  970.     {
  971.     struct mbuf * pMbuf;
  972.     ln_tmd      *tmd;
  973.     char        *buf;
  974.     int         len;
  975.     int         oldLevel;
  976.     pDrvCtrl->flags |= LS_START_OUTPUT_FLAG;        /* ??? */
  977.     /* See if next TXD is available */
  978.    while (pDrvCtrl->idr.ac_if.if_snd.ifq_head)
  979.         {
  980.         /* Dequeue a packet from the transmit queue. */
  981.   
  982.         IF_DEQUEUE (&pDrvCtrl->idr.ac_if.if_snd, pMbuf);
  983.         tmd = pDrvCtrl->tring + pDrvCtrl->tindex;
  984.         LN_CACHE_INVALIDATE (tmd, TMD_SIZ);
  985.         if ( ( (PCISWAP(tmd->tbuf_tmd1) & TMD1_OWN) != 0) ||
  986.               ( ( (pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1)) ==
  987.                                                            pDrvCtrl->dindex))
  988.             {
  989.             m_freem (pMbuf);
  990.             pDrvCtrl->idr.ac_if.if_oerrors++;
  991.             break;
  992.             }
  993.         /* Get pointer to transmit buffer */
  994.         buf = (char *)
  995.             (pDrvCtrl->tmd_ring.t_bufs + (pDrvCtrl->tindex * LN_BUFSIZ));
  996.         /* Copy packet from MBUFs to transmit buffer. */
  997.         bcopy_from_mbufs (buf, pMbuf, len, pDrvCtrl->memWidth);
  998.         /* Ensure we send a legal size frame. */
  999.         len = max (ETHERSMALL, len);
  1000.         /* place a transmit request */
  1001.         oldLevel = intLock ();          /* disable ints during update */
  1002.         tmd->tbuf_tmd3 = 0;             /* clear buffer error status */
  1003.         /* negative message byte count */
  1004.         tmd->tbuf_tmd1 &= PCISWAP(~TMD1_BCNT_MSK);
  1005.         tmd->tbuf_tmd1 |= PCISWAP((TMD1_CNST | TMD1_BCNT_MSK) & -len);
  1006.         tmd->tbuf_tmd1 |= PCISWAP(TMD1_ENP);    /* buffer is end of packet */
  1007.         tmd->tbuf_tmd1 |= PCISWAP(TMD1_STP);    /* buffer is start of packet */
  1008.         tmd->tbuf_tmd1 &= PCISWAP(~TMD1_DEF);   /* clear status bit */
  1009.         tmd->tbuf_tmd1 &= PCISWAP(~TMD1_MORE);
  1010.         tmd->tbuf_tmd1 &= PCISWAP(~TMD1_ERR);
  1011.         tmd->tbuf_tmd1 |= PCISWAP(TMD1_OWN);
  1012.         /* Flush the write pipe */
  1013.         CACHE_PIPE_FLUSH ();
  1014.         intUnlock (oldLevel);   /* now lnInt won't get confused */
  1015.         /* Advance our management index */
  1016.         pDrvCtrl->tindex = (pDrvCtrl->tindex + 1) & (pDrvCtrl->tsize - 1);
  1017.         /* kick start the transmitter, if selected */
  1018.         if (lnKickStartTx)
  1019.             lnCsrWrite (pDrvCtrl, 0, (CSR0_INEA | CSR0_TDMD));
  1020.         pDrvCtrl->flags &= ~LS_START_OUTPUT_FLAG;
  1021.         /* Bump the statistic counter. */
  1022.         pDrvCtrl->idr.ac_if.if_opackets++;   /* bump the statistic counter. */
  1023.         }
  1024.     return;
  1025.     }
  1026. #endif
  1027. /*******************************************************************************
  1028. *
  1029. * lnIoctl - the driver I/O control routine
  1030. *
  1031. * Process an ioctl request.
  1032. */
  1033. static int lnIoctl
  1034.     (
  1035.     IDR  *ifp,
  1036.     int            cmd,
  1037.     caddr_t        data
  1038.     )
  1039.     {
  1040.     int error = 0;
  1041.     switch (cmd)
  1042.         {
  1043.         case SIOCSIFADDR:
  1044.            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;
  1045.             arpwhohas (ifp, &IA_SIN (data)->sin_addr);
  1046.             break;
  1047.         case SIOCSIFFLAGS:
  1048.             /* No further work to be done */
  1049.             break;
  1050.         default:
  1051.             error = EINVAL;
  1052.         }
  1053.     return (error);
  1054.     }
  1055. /*******************************************************************************
  1056. *
  1057. * lnChipReset - hardware reset of chip (stop it)
  1058. */
  1059. static int lnChipReset
  1060.     (
  1061.     DRV_CTRL  *pDrvCtrl
  1062.     )
  1063.     {
  1064.     ULONG * dv = (ULONG *)pDrvCtrl->devAdrs;
  1065.     /* Enable 32 bit access by doing a 32 bit write */
  1066.     * (dv) = 0;
  1067.     lnCsrWrite (pDrvCtrl, CSR(0), CSR0_STOP);
  1068.     lnBcrWrite (pDrvCtrl, BCR(20), BCR20_SWSTYLE_PCNET);
  1069.     return (OK);
  1070.     }
  1071. /*******************************************************************************
  1072. *
  1073. * lnCsrWrite - select and write a CSR register
  1074. *
  1075. */
  1076. static void lnCsrWrite
  1077.     (
  1078.     DRV_CTRL *  pDrvCtrl, /* driver control */
  1079.     int  reg, /* register to select */
  1080.     ULONG  value /* value to write */
  1081.     )
  1082.     {
  1083.     ULONG *dv = (ULONG *)pDrvCtrl->devAdrs;
  1084.     /* select CSR */
  1085.     *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF));
  1086.     /* write val to CSR */
  1087.     *(dv+CSROffset) = PCISWAP(((ULONG)value & 0x0000FFFF));
  1088.     }
  1089. /*******************************************************************************
  1090. *
  1091. * lnCsrRead - select and read a CSR register
  1092. *
  1093. */
  1094. static ULONG lnCsrRead
  1095.     (
  1096.     DRV_CTRL * pDrvCtrl, /* driver control */
  1097.     int reg /* register to select */
  1098.     )
  1099.     {
  1100.     ULONG *dv = (ULONG *)pDrvCtrl->devAdrs;
  1101.     *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF)); /* select CSR */
  1102.     /* get contents of CSR */
  1103.     return ( PCISWAP(*(dv+CSROffset)) & (0x0000FFFF));
  1104.     }
  1105. /*******************************************************************************
  1106. *
  1107. * lnBcrWrite - select and write a CSR register
  1108. *
  1109. */
  1110. static void lnBcrWrite
  1111.     (
  1112.     DRV_CTRL *  pDrvCtrl, /* driver control */
  1113.     int  reg, /* register to select */
  1114.     ULONG  value /* value to write */
  1115.     )
  1116.     {
  1117.     ULONG *dv = (ULONG *)pDrvCtrl->devAdrs;
  1118.     /* select CSR */
  1119.     *(dv+RAPOffset) = PCISWAP(((ULONG)reg & 0x000000FF));
  1120.     /* write val to BCR */
  1121.     *(dv+BDPOffset) = PCISWAP(((ULONG)value & 0x0000FFFF));
  1122.     }
  1123. /******************************************************************************
  1124. *
  1125. * lnRestartSetup - setup memory descriptors and turn on chip
  1126. *
  1127. * Initializes all the shared memory structures and turns on the chip.
  1128. */
  1129. LOCAL STATUS lnRestartSetup
  1130.     (
  1131.     DRV_CTRL *pDrvCtrl
  1132.     )
  1133.     {
  1134.     ULONG       stat = 0;
  1135.     char        *buf;
  1136.     int         loopy;
  1137.     int         timeoutCount = 0;
  1138.     ln_ib       *ib;
  1139.     ln_rmd      *rmd;
  1140.     ln_tmd      *tmd;
  1141.     void        *pTemp;
  1142.     /* Set up the Rx descriptors */
  1143.     rmd = pDrvCtrl->rring;                      /* receive ring */
  1144.     buf = pDrvCtrl->rmd_ring.r_bufs;
  1145.     for (loopy = 0; loopy < pDrvCtrl->rsize; loopy++)
  1146.       {
  1147.         pTemp = LN_CACHE_VIRT_TO_PHYS (buf);     /* convert to physical addr */
  1148.         pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  1149.         rmd->rbuf_adr = PCISWAP((ULONG) pTemp); /* bits 31:00 of buf addr */
  1150.         rmd->rbuf_rmd1 = 0;
  1151.         /* neg of buffer byte count */
  1152.         rmd->rbuf_rmd1 = PCISWAP((RMD1_BCNT_MSK & -(pDrvCtrl->bufSize)) | 
  1153.                                   RMD1_CNST);
  1154.         rmd->rbuf_mcnt = 0;                     /* no message byte count yet */
  1155.         rmd->rbuf_rmd1 |= PCISWAP(RMD1_OWN);    /* buffer now owned by LANCE */
  1156.         rmd++;                                  /* step to next descriptor */
  1157.         buf += (pDrvCtrl->bufSize);             /* step to the next buffer */
  1158.       }
  1159.     pDrvCtrl->rindex = 0;
  1160.     /* Setup the Tx descriptors */
  1161.     tmd = pDrvCtrl->tring;                 /* transmit ring */
  1162.     buf = pDrvCtrl->tmd_ring.t_bufs;
  1163.     for (loopy = 0; loopy < pDrvCtrl->tsize; loopy++)
  1164.       {
  1165.         pTemp = LN_CACHE_VIRT_TO_PHYS (buf);     /* convert to physical addr */
  1166.         pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  1167.         tmd->tbuf_adr = PCISWAP((ULONG) pTemp); /* bits 31:00 of buf addr */
  1168.         tmd->tbuf_tmd1 = PCISWAP(TMD1_CNST);    /* no message byte count yet */
  1169.         tmd->tbuf_tmd2 = 0;                     /* no error status yet */
  1170.         tmd->tbuf_tmd1 |= PCISWAP(TMD1_ENP);    /* buffer is end of packet */
  1171.         tmd->tbuf_tmd1 |= PCISWAP(TMD1_STP);    /* buffer is start of packet */
  1172.         tmd++;                                  /* step to next descriptor */
  1173.         buf += (pDrvCtrl->bufSize);             /* step to next buffer */
  1174.       }
  1175.     pDrvCtrl->tindex =
  1176.         pDrvCtrl->dindex = 0;
  1177.     /* Setup the initialization block */
  1178.     ib = pDrvCtrl->ib;
  1179.     ib->lnIBMode = 0;       /* chip will be in normal receive mode */
  1180. #if (_BYTE_ORDER == _BIG_ENDIAN)
  1181.     bcopy ((char *)pDrvCtrl->idr.ac_enaddr, ib->lnIBPadr, 6);
  1182. #else
  1183.     swab ((char *)pDrvCtrl->idr.ac_enaddr, ib->lnIBPadr, 4);
  1184.     swab ((char *)&pDrvCtrl->idr.ac_enaddr[4], &ib->lnIBPadr[6], 2);
  1185. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  1186.     pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->rring ); /* point to Rx ring */
  1187.     pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  1188.     ib->lnIBRdra = PCISWAP((ULONG)pTemp);
  1189.     ib->lnIBMode |=  PCISWAP((IB_MODE_RLEN_MSK & (pDrvCtrl->rpo2 << 20)));
  1190.     pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->tring ); /* point to Tx ring */
  1191.     pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  1192.     ib->lnIBTdra = PCISWAP((ULONG)pTemp);
  1193.     ib->lnIBMode |= PCISWAP((IB_MODE_TLEN_MSK & (pDrvCtrl->tpo2 << 28)));
  1194.     /* Flush the write pipe */
  1195.     CACHE_PIPE_FLUSH ();
  1196.     lnCsrWrite (pDrvCtrl, 0, CSR0_STOP);        /* set the stop bit */
  1197.     /* set the bus mode to little endian */
  1198.     lnCsrWrite (pDrvCtrl, 3, lnPciCSR_3B);
  1199.     /* Point the device to the initialization block */
  1200.     pTemp = LN_CACHE_VIRT_TO_PHYS ( pDrvCtrl->ib );
  1201.     pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
  1202.     lnCsrWrite (pDrvCtrl, 2, (((ULONG)pTemp >> 16) & 0x0000ffff));
  1203.     lnCsrWrite (pDrvCtrl, 1, ((ULONG)pTemp & 0x0000ffff));
  1204.     lnCsrWrite (pDrvCtrl, 0, CSR0_INIT);            /* init chip (read IB) */
  1205.     while (((stat = lnCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0)
  1206.       {
  1207.         if (timeoutCount++ > 0x10000) break;
  1208.         taskDelay(100);
  1209.       }
  1210.     if ((stat & CSR0_ERR) == CSR0_ERR)
  1211.       {
  1212.         if ((stat & CSR0_MERR)  == CSR0_MERR)
  1213.   {
  1214.             logMsg ("lnPci: Lance memory error while initialization:t0x%xn",
  1215.                     stat, 0,0,0,0,0);
  1216.   }
  1217.         else
  1218.   {
  1219.             logMsg ("lnPci: Lance error while initialization:t0x%xn",
  1220.                     stat, 0,0,0,0,0);
  1221.   }
  1222.       }
  1223.     /* log chip initialization failure */
  1224.     if ( (stat & CSR0_ERR) || (timeoutCount >= 0x10000) )
  1225.       {
  1226.         logMsg ("lnPci%d: Device initialization failedn",
  1227.                     pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0);
  1228.         return (ERROR);
  1229.       }
  1230.     /* Device is initialized.  Start transmitter and receiver.  The device
  1231.      * RAP register is left selecting CSR 0.
  1232.      */
  1233.     lnCsrWrite(pDrvCtrl, 0, CSR0_IDON | CSR0_INEA | CSR0_STRT);
  1234.     sysLanIntEnable (pDrvCtrl->ilevel);           /* enable LANCE interrupts */
  1235.  
  1236.     pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);
  1237.     return (OK);
  1238.     }
  1239. /*******************************************************************************
  1240. *
  1241. * lnRestart - restart the device after a fatal error
  1242. *
  1243. * This routine takes care of all the messy details of a restart.  The device
  1244. * is reset and re-initialized.  The driver state is re-synchronized.
  1245. */
  1246. static void lnRestart
  1247.     (
  1248.     DRV_CTRL *pDrvCtrl
  1249.     )
  1250.     {
  1251.     printf ("lnPci: device resetn");
  1252.     if (lnChipReset (pDrvCtrl) == ERROR)        /* reset lance device */
  1253.         {
  1254.         logMsg ("lnPci: Device failed to resetn", 0,0,0,0,0,0);
  1255.         return;
  1256.         }
  1257.     lnRestartSetup (pDrvCtrl);
  1258.     return;
  1259.     }
  1260. #ifdef BSD43_DRIVER
  1261. #include "sys/socket.h"
  1262. /*******************************************************************************
  1263. *
  1264. * convertDestAddr - converts socket addr into enet addr and packet type
  1265. *
  1266. */
  1267. static BOOL convertDestAddr
  1268.     (
  1269.     IDR *pIDR,                          /* ptr to i/f data record */
  1270.     SOCK *pDestSktAddr,                 /* ptr to a generic sock addr */
  1271.     char *pDestEnetAddr,                /* where to write enet addr */
  1272.     u_short *pPacketType,               /* where to write packet type */
  1273.     MBUF *pMbuf                         /* ptr to mbuf data */
  1274.     )
  1275.     {
  1276.     /***** Internet family *****/
  1277.     {
  1278.     struct in_addr destIPAddr;              /* not used */
  1279.     int trailers;                           /* not supported */
  1280.      if (pDestSktAddr->sa_family == AF_INET)
  1281.         {
  1282.         *pPacketType = ETHERTYPE_IP;            /* stuff packet type */
  1283.         destIPAddr = ((struct sockaddr_in *) pDestSktAddr)->sin_addr;
  1284.         if (!arpresolve (pIDR, pMbuf, &destIPAddr, pDestEnetAddr, &trailers))
  1285.             return (FALSE);     /* if not yet resolved */
  1286.         return (TRUE);
  1287.         }
  1288.     }
  1289.     /***** Generic family *****/
  1290.     {
  1291.     ENET_HDR *pEnetHdr;
  1292.     if (pDestSktAddr->sa_family == AF_UNSPEC)
  1293.         {
  1294.         pEnetHdr = (ENET_HDR *) pDestSktAddr->sa_data;      /* ptr to hdr */
  1295.         bcopy (pEnetHdr->dst, pDestEnetAddr, 6);            /* copy dst addr */
  1296.         *pPacketType = pEnetHdr->type;                      /* copy type */
  1297.         return (TRUE);
  1298.         }
  1299.     }
  1300.     /* Unsupported family */
  1301.     return (FALSE);
  1302.     } /* End of convertDestAddr() */
  1303. /* END OF FILE */
  1304. #endif