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

VxWorks

开发平台:

C/C++

  1. /* if_lnsgi.c - AMD Am7990 LANCE Ethernet (for SGI) network interface driver */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01k,15jul97,spm  removed driver initialization from ioctl support (SPR #8831);
  8.                  added ARP request to SIOCSIFADDR ioctl handler
  9. 01j,08apr97,spm  removed compiler warnings, and errors from changes in if_ln.h
  10. 01i,07apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.4
  11. 01h,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h
  12. 01g,22feb93,jdi  documentation cleanup.
  13. 01f,09sep92,gae  documentation tweaks.
  14. 01e,29jul92,rfs  Moved driver specific items here from the header file.
  15. 01d,22jul92,gae  fixed number of parameters to logMsg().
  16. 01c,23jun92,ajm  upgraded to 5.1, ansiized.
  17. 01b,28apr92,ajm  changed lnEnetAddr to lnsgiEnetAddr for board specific driver
  18. 01a,30mar92,ajm  modified if_ln.c 01x for SGI VIP10, becomes target specific
  19. */
  20. /*
  21. DESCRIPTION
  22. This module implements the
  23. Advanced Micro Devices Am7990 LANCE Ethernet network interface driver for the
  24. Silicon Graphics VIP10 board.  The only user-callable routine is lnsgiattach(),
  25. which publishes the `lnsgi' interface and initializes the driver and device.
  26. This driver is a special variant of if_ln, designed for the Silicon Graphics 
  27. (SGI) VIP10 board.
  28. BOARD LAYOUT
  29. This device is on-board.  No jumpering diagram is necessary.
  30. SEE ALSO: ifLib
  31. */
  32. #include "vxWorks.h"
  33. #include "iv.h"
  34. #include "memLib.h"
  35. #include "cacheLib.h"
  36. #include "sys/ioctl.h"
  37. #include "intLib.h"
  38. #include "logLib.h"
  39. #include "netLib.h"
  40. #include "taskLib.h"
  41. #include "etherLib.h"
  42. #include "net/mbuf.h"
  43. #include "net/protosw.h"
  44. #include "net/unixLib.h"
  45. #include "sys/socket.h"
  46. #include "errno.h"
  47. #include "net/if.h"
  48. #include "net/route.h"
  49. #include "netinet/in.h"
  50. #include "netinet/in_systm.h"
  51. #include "netinet/in_var.h"
  52. #include "netinet/ip.h"
  53. #include "netinet/if_ether.h"
  54. #include "net/if_subr.h"
  55. #include "drv/netif/if_ln.h"
  56. /***** LOCAL DEFINITIONS *****/
  57. #define RMD_SIZ sizeof(ln_rmd)
  58. #define TMD_SIZ sizeof(ln_tmd)
  59. /* Configuration items */
  60. #define LN_MIN_FIRST_DATA_CHAIN 96 /* min size of 1st buf in data-chain */
  61. #define LN_MAX_MDS 128 /* max number of [r|t]md's for LANCE */
  62. #define LN_BUFSIZE (ETHERMTU + sizeof (struct ether_header) + 6)
  63. #define LN_RMD_RLEN 5 /* ring size as a power of 2 -- 32 RMD's */
  64. #define LN_TMD_TLEN 5 /* same for transmit ring    -- 32 TMD's */
  65. #define LN_NUM_RESERVES 8 /* have up to 8 reserved RMD's for loans */
  66. #define MAX_LN 1 /* max number of LANCE chips on board */
  67. /*
  68.  * If LN_KICKSTART_TX is TRUE the transmitter is kick-started to force a
  69.  * read of the transmit descriptors, otherwise the internal polling (1.6msec)
  70.  * will initiate a read of the descriptors.  This should be FALSE is there
  71.  * is any chance of memory latency or chip accesses detaining the LANCE DMA,
  72.  * which results in a transmitter UFLO error.  This can be changed with the
  73.  * global lnKickStartTx below.
  74.  */
  75. #define LN_KICKSTART_TX FALSE /* TRUE:  kick-start transmitter,
  76.    FALSE: wait for internal poll */
  77. /* The definition of the driver control structure */
  78. typedef struct ls_softc
  79.     {
  80.     struct arpcom  ls_ac; /* ethernet common part */
  81.     ln_ib   *ib; /* ptr to Initialization Block */
  82.     struct
  83. {
  84.         int r_po2; /* RMD ring size as a power of 2! */
  85. int r_size; /* RMD ring size (power of 2!) */
  86. int r_index; /* index into RMD ring */
  87. ln_rmd *r_ring; /* RMD ring */
  88. char *r_bufs; /* receive buffers base */
  89.         } rmd_ring;
  90.     struct
  91. {
  92.         int t_po2; /* TMD ring size as a power of 2! */
  93. int t_size; /* TMD ring size (power of 2!) */
  94. int t_index; /* index into TMD ring */
  95. int d_index; /* index into TMD ring */
  96. ln_tmd *t_ring; /* TMD ring */
  97. char *t_bufs; /* transmit buffers base */
  98.         } tmd_ring;
  99.     u_char ls_flags; /* misc control flags */
  100.     int ivec; /* interrupt vector */
  101.     int ilevel; /* interrupt level */
  102.     LN_DEVICE *devAdrs; /* device structure address */
  103.     char *memBase; /* LANCE memory pool base */
  104.     int    memWidth; /* width of data port */
  105.     int csr0Errs; /* count of csr0 errors */
  106.     int bufSize; /* size of buffer in the LANCE ring */
  107.     BOOL canLoanRmds; /* can we loan out rmd's as clusters? */
  108.     char *freeBufs[LN_NUM_RESERVES]; /* available reserve buffers */
  109.     int nFree; /* number of free reserve buffers */
  110.     u_char loanRefCnt[LN_MAX_MDS]; /* reference counts for loaned RMD's */
  111.     } DRV_CTRL;
  112. #define DRV_CTRL_SIZ sizeof(DRV_CTRL)
  113. /* Definitions for the flags field */
  114. #define LS_PROMISCUOUS_FLAG 0x1
  115. #define LS_MEM_ALLOC_FLAG 0x2
  116. #define LS_PAD_USED_FLAG 0x4
  117. #define LS_RCV_HANDLING_FLAG 0x8
  118. #define LS_START_OUTPUT_FLAG 0x10
  119. /* Shorthand structure references */
  120. #define ls_if ls_ac.ac_if /* network-visible interface */
  121. #define ls_enaddr  ls_ac.ac_enaddr /* hardware ethernet address */
  122. #define ls_rpo2 rmd_ring.r_po2
  123. #define ls_rsize rmd_ring.r_size
  124. #define ls_rindex rmd_ring.r_index
  125. #define ls_rring rmd_ring.r_ring
  126. #define ls_tpo2 tmd_ring.t_po2
  127. #define ls_tsize tmd_ring.t_size
  128. #define ls_tindex tmd_ring.t_index
  129. #define ls_dindex tmd_ring.d_index
  130. #define ls_tring tmd_ring.t_ring
  131. #define LN_RMD_GIVE_TO_LANCE(pRmd) 
  132.     { 
  133.     pRmd->lnRMD1 &= 0xff; 
  134.     pRmd->rbuf_mcnt = 0; 
  135.     pRmd->lnRMD1 |= lnrmd1_OWN;      
  136.     }
  137. /*
  138. * The following macros let the MIPS architecture allocate and free dymanic
  139. * memory from uncached space.  The calls calloc, and cfree do the same
  140. * as malloc, and free, they are merely there to aviod macro recursion.
  141. */
  142. #define malloc(x)        K0_TO_K1(calloc((size_t) (x),
  143.  (size_t) sizeof(char)))
  144. #define free(x)          cfree((void *) (K1_TO_K0((x))))
  145. #define cacheClearEntry(x,y)
  146. #define EMAP_ADDR       0xbf920802              /* memory map memory */
  147. LOCAL volatile u_short *pEmap = (volatile u_short *) EMAP_ADDR;
  148. /* buffer address to emap translation */
  149. #define EMAP_PG_SZ (4096)
  150. #define EMAP_OFFSET(index)      ((index) << 1)
  151. #define EMAP_VALUE(buffaddr)    ((u_int)(buffaddr) >> 12)
  152. /* lance address to physical translation */
  153. #define EMAP_PG(addr)       (((addr) >> 12) & 0xff)
  154. #define EMAP_ENTRY(addr)    (pEmap[(EMAP_PG(addr))])
  155. #define EADDR(addr)         (((EMAP_ENTRY(addr)) << 12) | 
  156.  ((u_int)(addr) & 0xfff))
  157. #define LNADDR(index,addr) (((index) << 12) | ((u_int)(addr) & 0xfff))
  158. /* emap indexes */
  159. #define EMAPLEN         256
  160. #define IBUF_SZ         2
  161. #define RBUF_SZ         64
  162. #define TBUF_SZ         64
  163. #define RBUF_INDEX      0                       /* location of init block */
  164. #define TBUF_INDEX      (RBUF_INDEX + RBUF_SZ)  /* location of rec mbufs */
  165. #define IBUF_INDEX      (TBUF_INDEX + TBUF_SZ)  /* location of xmit mbufs */
  166. /* imports */
  167. IMPORT void sysWbFlush ();
  168. IMPORT void sysLanIntEnable (int ilevel);
  169. IMPORT unsigned char lnsgiEnetAddr []; /* ethernet address to load into LANCE */
  170. /* globals */
  171. int lnsgiLogCount = 0;
  172. /* locals */
  173. LOCAL int lnTsize = LN_TMD_TLEN; /* deflt xmit ring size as power of 2 */
  174. LOCAL int lnRsize = LN_RMD_RLEN; /* deflt recv ring size as power of 2 */
  175. LOCAL struct ls_softc  *ls_softc [MAX_LN];
  176. LOCAL u_int RAPOffset = 128; /* XXX initially 1, calculated in lnReset */
  177. LOCAL u_int CSROffset = 0; /* XXX initially 0, calculated in lnReset */
  178. /* forward declarations */
  179. static int        lnInit (int unit);
  180. static int        lnIoctl (struct ifnet *ifp, int cmd, caddr_t data);
  181. #ifdef BSD43_DRIVER
  182. static int        lnOutput (struct ifnet *ifp, struct mbuf *m0, 
  183.                             struct sockaddr *dst);
  184. #endif
  185. static void       lnReset(int unit);
  186. static ln_rmd    *lnGetFullRMD (struct ls_softc  *ls);
  187. static ln_tmd    *lnGetFreeTMD (struct ls_softc  *ls);
  188. static STATUS     lnRecv (struct ls_softc *ls, ln_rmd *rmd);
  189. static void       lnChipInit (struct ls_softc  *ls);
  190. static void       lnChipReset (struct ls_softc *ls);
  191. static void       lnConfig (struct ls_softc *ls);
  192. static void       lnHandleCsr0Err (struct ls_softc *ls, u_short status);
  193. static void       lnHandleRecvInt (struct ls_softc *ls);
  194. static void       lnInt (struct ls_softc  *ls);
  195. static void       lnRmdFree (struct ls_softc *ls, char *pBuf);
  196. #ifdef BSD43_DRIVER
  197. static void       lnStartOutput (int unit);
  198. #else
  199. static void       lnStartOutput (DRV_CTRL *ls);
  200. #endif
  201. static void       lnCsrWrite (struct ls_softc *ls, int reg, u_short value);
  202. static u_short    lnCsrRead (struct ls_softc *ls, int reg);
  203. static void       lnCsrIntWrite (struct ls_softc *ls, int reg, u_short value);
  204. static u_short    lnCsrIntRead (struct ls_softc *ls, int reg);
  205. /*******************************************************************************
  206. *
  207. * lnsgiattach - publish the `lnsgi' network interface and initialize the driver and device
  208. *
  209. * This routine attaches an `lnsgi' Ethernet interface to the network if the
  210. * interface exists.  It makes the interface available by filling in
  211. * the network interface record.  The system will initialize the interface
  212. * when it is ready to accept packets.
  213. *
  214. * The <memAdrs> parameter specifies the location of the interface memory pool;
  215. * if NONE, the memory pool will be malloc'ed.
  216. *
  217. * The <memWidth> parameter sets the memory pool's data port width (in bytes);
  218. * if NONE, any data width will be used.
  219. *
  220. * BUGS
  221. * To zero out LANCE data structures, this routine uses bzero(), which
  222. * ignores the <memWidth> specification and uses any size data access to
  223. * write to memory.
  224. *
  225. * RETURNS: OK or ERROR.
  226. */
  227. STATUS lnsgiattach
  228.     (
  229.     int       unit, /* unit number */
  230.     char     *devAdrs, /* LANCE i/o address */
  231.     int       ivec, /* interrupt vector */
  232.     int       ilevel, /* interrupt level */
  233.     char     *memAdrs, /* address of memory pool (-1 = malloc it) */
  234.     ULONG     memSize, /* only used if memory pool is NOT malloc()'d */
  235.     int       memWidth, /* byte-width of data (-1 = any width)     */
  236.     BOOL      usePadding,       /* use padding when accessing RAP? */
  237.     int       bufSize  /* size of a buffer in the LANCE ring */
  238.     )
  239.     {
  240.     FAST DRV_CTRL *  ls;
  241.     FAST struct ifnet   *ifp;
  242.     FAST unsigned int    sz; /* temporary size holder */
  243.     char    *memPool; /* start of the LANCE memory pool */
  244.     if (bufSize == 0)
  245.         bufSize = LN_BUFSIZE;
  246.     if ((int) memAdrs != NONE) /* specified memory pool */
  247. {
  248. /*
  249.  * With a specified memory pool we want to maximize
  250.  * lnRsize and lnTsize
  251.  */
  252. sz = (memSize - (sizeof (ln_rmd) + sizeof (ln_tmd) + sizeof (ln_ib)))
  253.        / ((2 * bufSize) + sizeof (ln_rmd) + sizeof (ln_tmd));
  254. sz >>= 1; /* adjust for roundoff */
  255. for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)
  256.     ;
  257. lnTsize = lnRsize; /* lnTsize = lnRsize for convenience */
  258. }
  259.     /* limit ring sizes to reasonable values */
  260.     if (lnRsize < 2)
  261.         lnRsize = 2; /* 4 buffers is reasonable min */
  262.     if (lnRsize > 7)
  263.         lnRsize = 7; /* 128 buffers is max for chip */
  264.     /* limit ring sizes to reasonable values */
  265.     if (lnTsize < 2)
  266.         lnTsize = 2; /* 4 buffers is reasonable min */
  267.     if (lnTsize > 7)
  268.         lnTsize = 7; /* 128 buffers is max for chip */
  269.     /* calculate the total size of LANCE memory pool.  (basic softc structure
  270.      * is just allocated from free memory pool since LANCE never references).
  271.      */
  272.     sz = ((sizeof (ln_ib))        + (((1 << lnRsize) + 1) * sizeof (ln_rmd)) +
  273.   (bufSize << lnRsize) + (((1 << lnTsize) + 1) * sizeof (ln_tmd)) +
  274.   (bufSize << lnTsize));
  275.     sz = sz + 6; /* allow for alignment adjustment */
  276.     if ((int) memAdrs == NONE) /* if -1 then allocate memPool from free pool */
  277. {
  278. memPool = (char *) malloc (sz); /* allocate memory */
  279. if ((int)memPool == NULL)
  280.     return (ERROR); /* bail out if we don't get memory */
  281. }
  282.     else
  283. {
  284. if (memSize < sz)
  285.     return (ERROR); /* bail out if memSize specified is too small */
  286. memPool = memAdrs; /* set the beginning of pool */
  287. }
  288.     /*                        memPool partitioning
  289.      *                        --------------------
  290.      *
  291.      *                                                 LOW MEMORY
  292.      *
  293.      *    memPool,ls->ib |-------------------------------------|
  294.      * |       |
  295.      * |         (sizeof (ln_ib))       |
  296.      * |       |
  297.      *      ls->ls_rring  |-------------------------------------|
  298.      * |       |
  299.      *  | ((1 << lnRsize) + 1)*sizeof (ln_rmd)|
  300.      * |       |
  301.      *       ls->rmd_ring.r_bufs |-------------------------------------|
  302.      * |       |
  303.      *  |       (bufSize << lnRsize)          |
  304.      * |       |
  305.      *     ls->ls_tring |-------------------------------------|
  306.      * |       |
  307.      * | ((1 << lnTsize) + 1)*sizeof (ln_tmd)|
  308.      * |       |
  309.      *       ls->tmd_ring.t_bufs |-------------------------------------|
  310.      * |       |
  311.      *  |       (bufSize << lnTsize)          |
  312.      * |       |
  313.      *           |-------------------------------------|
  314.      *
  315.      *                                                HIGH MEMORY
  316.      */
  317.     /* allocate basic softc structure */
  318.     ls = (DRV_CTRL *)malloc (sizeof (DRV_CTRL));
  319.     if (ls == NULL)
  320. {
  321. if ((int) memAdrs == NONE) /* if we malloced memPool */
  322.     (void) free (memPool); /* free the memPool */
  323. return (ERROR);
  324. }
  325.     /* zero out entire softc structure */
  326.     bzero ( (char *)ls, sizeof (DRV_CTRL));
  327.     /* fill in high byte of memory base (A24:A31) and data port width */
  328.     ls->memBase  = (char *)((ULONG)memPool & 0xff000000);
  329.     ls->memWidth = memWidth;
  330.     if ((int) memAdrs == NONE)
  331.         ls->ls_flags |= LS_MEM_ALLOC_FLAG;
  332.     
  333.     ls->bufSize = bufSize;
  334.     /* if memWidth is NONE (we can copy any byte size/boundaries) and
  335.      * bufSize is big enough to hold the biggest ethernet frame
  336.      * we can loan out rmds.  On systems that cannot afford to have
  337.      * big enough RMD's, LANCE will use data-chaining on receive
  338.      * buffers.  Our current implementation of RMD loans does not work
  339.      * with receive side data-chains.
  340.      */
  341.     if (ls->memWidth == NONE && ls->bufSize == LN_BUFSIZE)
  342. {
  343. int ix;
  344. char *pBuf;
  345.         ls->canLoanRmds = TRUE;
  346. ls->nFree = LN_NUM_RESERVES;
  347. if ((pBuf = (char *) malloc ((u_int) (LN_NUM_RESERVES * bufSize))) 
  348.     == NULL)
  349.     {
  350.     (void) free (memPool);
  351.     (void) free ((char *) ls);
  352.     return (ERROR);
  353.     }
  354. for (ix = 0; ix < LN_NUM_RESERVES; ix++)
  355.     ls->freeBufs [ix] = (char *) ((int) pBuf + (bufSize * ix));
  356. }
  357.     else
  358.         ls->canLoanRmds = FALSE;
  359.     /* allocate initialization block */
  360.     ls->ib = (ln_ib *)memPool;
  361.     sz = sizeof (ln_ib); /* size of initialization block */
  362.     bzero ((char *)ls->ib, (int) sz); /* zero out entire ib */
  363.     /* allocate receive message descriptor (RMD) ring structure */
  364.     ls->ls_rpo2 = lnRsize; /* remember for lnConfig */
  365.     ls->ls_rsize = (1 << lnRsize); /* receive msg descriptor ring size */
  366.     /* leave room to adjust low three bits */
  367.     ls->ls_rring = (ln_rmd *) ((int)ls->ib + sz);   /* of pointer to be 000 */
  368.     sz = ((1 << lnRsize) + 1) * sizeof (ln_rmd);
  369.     bzero ((char *)ls->ls_rring, (int)sz); /* zero out entire RMD ring */
  370.     /* allocate receive buffer space */
  371.     sz = sz + 2; /* this makes the rx_buffers un-aligned, */
  372.                                 /* but with ether-header prepended, they are */
  373.     ls->rmd_ring.r_bufs = (char *)((int)ls->ls_rring + sz);
  374.     sz = (bufSize << lnRsize);  /* room for all the receive buffers */
  375.     bzero (ls->rmd_ring.r_bufs, (int)sz);/* zero out entire rbuf area */
  376.     /* allocate transmit message descriptor (TMD) ring structure */
  377.     ls->ls_tpo2 = lnTsize; /* remember for lnConfig */
  378.     ls->ls_tsize = (1 << lnTsize); /* transmit msg descriptor ring size */
  379.     sz = sz + 2; /* make ls_tring aligned again */
  380.     ls->ls_tring = (ln_tmd *) ((int)ls->rmd_ring.r_bufs + sz);
  381.     sz = ((1 << lnTsize) + 1) * sizeof (ln_tmd);
  382.     bzero ((char *)ls->ls_tring, (int)sz); /* zero out entire TMD ring */
  383.     /* allocate transmit buffer space */
  384.     sz = sz + 2; /* this makes the tx_buffers un-aligned, */
  385.         /* but with ether-header prepended, they are */
  386.     ls->tmd_ring.t_bufs = (char *)((int)ls->ls_tring + sz);
  387.     sz = (bufSize << lnTsize); /* room for all the transmit buffers */
  388.     bzero (ls->tmd_ring.t_bufs, (int)sz); /* zero out entire tbuf area */
  389.     ls_softc [unit] = ls; /* remember address for this unit */
  390.     /* initialize device structure */
  391.     ls->ivec     = ivec; /* interrupt vector */
  392.     ls->ilevel = ilevel; /* interrupt level */
  393.     ls->devAdrs = (LN_DEVICE *)devAdrs; /* LANCE i/o address */
  394.     /* copy the enet address into the softc */
  395.     bcopy ((char *) lnsgiEnetAddr, (char *)ls->ls_enaddr, sizeof (ls->ls_enaddr));
  396.     ifp = &ls->ls_if;
  397.     /* attach and enable the LANCE interrupt service routine to vector */
  398.     lnChipReset (ls); /* reset LANCE */
  399.     (void) intConnect (INUM_TO_IVEC (ivec), lnInt, (int)ls);
  400. #ifdef BSD43_DRIVER
  401.     ether_attach (ifp, unit, "lnsgi", (FUNCPTR) lnInit, (FUNCPTR) lnIoctl, 
  402.   (FUNCPTR) lnOutput, (FUNCPTR) lnReset);
  403. #else
  404.     ether_attach (
  405.                  ifp, 
  406.                  unit, 
  407.                  "lnsgi",
  408.                  (FUNCPTR) lnInit, 
  409.                  (FUNCPTR) lnIoctl, 
  410.  (FUNCPTR) ether_output, 
  411.                  (FUNCPTR) lnReset
  412.                  );
  413.     ifp->if_start = (FUNCPTR) lnStartOutput; 
  414. #endif
  415.     sysLanIntEnable (ilevel);
  416.     lnInit (unit);
  417.     return (OK);
  418.     }
  419. /*******************************************************************************
  420. *
  421. * lnReset - reset the interface
  422. *
  423. * Mark interface as inactive & reset the chip
  424. */
  425. LOCAL void lnReset
  426.     (
  427.     int unit 
  428.     )
  429.     {
  430.     FAST DRV_CTRL *  ls = ls_softc [unit];
  431.     ls->ls_if.if_flags &= ~IFF_RUNNING;
  432.     lnChipReset (ls); /* reset LANCE */
  433.     }
  434. /*******************************************************************************
  435. *
  436. * lnInit -
  437. *
  438. * Initialization of interface; clear recorded pending operations.
  439. * Called during driver attach routine at boot time and by interrupt service
  440. * routines when fatal errors occur.
  441. */
  442. LOCAL int lnInit
  443.     (
  444.     int unit 
  445.     )
  446.     {
  447.     FAST DRV_CTRL *  ls = ls_softc [unit];
  448.     FAST struct ifnet * ifp = &ls->ls_if;
  449.     ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_PROMISC);
  450.     lnChipReset (ls); /* disable chip during init */
  451.     lnConfig (ls); /* reset all ring structures */
  452.     ifp->if_flags |= (IFF_UP | IFF_RUNNING);
  453.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  454. ifp->if_flags |= (IFF_PROMISC);
  455.     lnChipInit (ls); /* on return LANCE is running */
  456. #ifdef BSD43_DRIVER
  457.     lnStartOutput (ls->ls_if.if_unit); /* tell chip about any pending output */
  458. #else
  459.     lnStartOutput (ls);
  460. #endif
  461.     return (0);
  462.     }
  463. /*******************************************************************************
  464. *
  465. * lnConfig - fill in initialization block with mode information.
  466. *
  467. * Fill in all fields in the Initialization Block with relevant values.
  468. * In addition, fill in all fields in Transmit Message Descriptor ring
  469. * and Receive Message Descriptor ring.
  470. */
  471. LOCAL void lnConfig
  472.     (
  473.     FAST struct ls_softc  *ls 
  474.     )
  475.     {
  476.     FAST ln_rmd   *rmd;
  477.     FAST ln_tmd   *tmd;
  478.     FAST char   *buf;
  479.     FAST ln_ib   *ib;
  480.     FAST int    index;
  481.     int    i;
  482.     rmd = ls->ls_rring; /* receive message descriptor ring */
  483.     rmd = (ln_rmd *)(((int)rmd + 7) & ~7); /* low 3 bits must be 000 */
  484.     ls->ls_rring = rmd; /* fix softc as well */
  485.     sysWbFlush ();
  486.     buf = ls->rmd_ring.r_bufs; 
  487.     for (i = 0; i < ls->ls_rsize; i++)
  488.         {
  489.         /* fill VIP10 dma table entry */
  490. index = RBUF_INDEX + i;
  491. pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(buf);
  492. sysWbFlush ();
  493. /* bits 15:00 of buffer address */
  494. rmd->rbuf_ladr = (u_short) LNADDR(index, buf);
  495. /* bits 23:16 of buffer address */
  496. rmd->lnRMD1 = (u_short) ((u_int) (LNADDR(index, buf) >> 16) & 0xff);
  497. rmd->rbuf_bcnt = -(ls->bufSize);/* neg of buffer byte count */
  498. rmd->rbuf_mcnt = 0; /* no message byte count yet */
  499. rmd->lnRMD1 |= lnrmd1_OWN; /* buffer now owned by LANCE */
  500. sysWbFlush (); /* make sure it gets out */
  501. rmd++; /* step to next message descriptor */
  502. buf += (ls->bufSize); /* step to start of next buffer */
  503. ls->loanRefCnt [i] = (u_char) 0;
  504. }
  505.     ls->ls_rindex = 0; /* LANCE will use at start of ring */
  506.     sysWbFlush ();
  507.     tmd = ls->ls_tring; /* transmit message descriptor ring */
  508.     tmd = (ln_tmd *)(((int)tmd + 7) & ~7); /* low 3 bits must be 000 */
  509.     ls->ls_tring = tmd; /* fix softc as well */
  510.     sysWbFlush ();
  511.     buf = ls->tmd_ring.t_bufs; 
  512.     for (i = 0; i < ls->ls_tsize; i++)
  513.         {
  514. /* fill VIP10 dma table entry */
  515. index = TBUF_INDEX + i;
  516.         pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(buf);
  517. sysWbFlush ();
  518. /* bits 15:00 of buffer address */
  519. tmd->tbuf_ladr = (u_short) LNADDR(index, buf);
  520. /* bits 23:16 of buffer address */
  521. tmd->lnTMD1 = (u_short) ((u_int) (LNADDR(index, buf) >> 16) & 0xff);
  522. tmd->tbuf_bcnt = 0; /* no message byte count yet */
  523. tmd->lnTMD3 = 0; /* no error status yet */
  524. tmd->lnTMD1 |= lntmd1_ENP; /* buffer is end of packet */
  525. tmd->lnTMD1 |= lntmd1_STP; /* buffer is start of packet */
  526. sysWbFlush (); /* make sure it gets out */
  527. tmd++; /* step to next message descriptor */
  528. buf += (ls->bufSize); /* step to start of next buffer */
  529. }
  530.     ls->ls_tindex = 0; /* LANCE will use at start of ring */
  531.     ls->ls_dindex = 0; /* buffer disposal will lag tindex */
  532.     sysWbFlush ();
  533.     ib = ls->ib;
  534.     /* fill VIP10 dma table entry for initialization block */
  535.     index = IBUF_INDEX;
  536.     pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ib);
  537.     sysWbFlush ();
  538.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  539.         ib->lnIBMode = 0x8000; /* chip will be in promiscuous receive mode */
  540.     else
  541.         ib->lnIBMode = 0; /* chip will be in normal receive mode */
  542.     swab ((char *)ls->ls_enaddr, ib->lnIBPadr, 6);
  543.     /* 
  544.     *  Fill VIP10 RMD Desc and Bufs. Two buffers are allocated to accomadate
  545.     *  the crossing page boundries.  RMD Desc and buffers should come right 
  546.     *  after IB 
  547.     */
  548.     index++;
  549.     pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ls->ls_rring);
  550.     sysWbFlush ();
  551.     pEmap [EMAP_OFFSET(index + 1)] = (u_short) (EMAP_VALUE(ls->ls_rring) + 1);
  552.     sysWbFlush ();
  553.     ib->lnIBRdraLow = (u_short) LNADDR(index, ls->ls_rring);
  554.     ib->lnIBRdraHigh = (u_short) ((u_int) (LNADDR(index, ls->ls_rring) >> 16) 
  555. & 0xff) | (ls->ls_rpo2 << 13);
  556.     sysWbFlush ();
  557.     index += 2;
  558.     pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ls->ls_tring);
  559.     sysWbFlush ();
  560.     pEmap [EMAP_OFFSET(index + 1)] = (u_short) (EMAP_VALUE(ls->ls_tring) + 1);
  561.     sysWbFlush ();
  562.     ib->lnIBTdraLow = (u_short) LNADDR(index, ls->ls_tring);
  563.     ib->lnIBTdraHigh = (u_short) ((u_int) (LNADDR(index, ls->ls_tring) >> 16) 
  564. & 0xff) | (ls->ls_tpo2 << 13);
  565.     sysWbFlush ();
  566.     }
  567. /*******************************************************************************
  568. *
  569. * lnInt - handle controller interrupt
  570. *
  571. * This routine is called at interrupt level in response to an interrupt from
  572. * the controller.
  573. */
  574. LOCAL void lnInt
  575.     (
  576.     FAST struct ls_softc  *ls 
  577.     )
  578.     {
  579.     FAST ln_rmd *rmd;
  580.     FAST ln_tmd *tmd;
  581.     FAST int  *pDindex;
  582.     FAST int *pTindex;
  583.     FAST int *pTsize;
  584.     FAST ln_tmd *pTring;
  585.     FAST u_short stat;
  586.    
  587.     if (!((stat = lnCsrIntRead (ls, 0)) & lncsr_INTR))
  588.         {
  589.         return;
  590.         }
  591.     /*
  592.      * enable interrupts, clear receive and/or transmit interrupts, 
  593.      * and clear any errors that may be set.
  594.      */
  595.     lnCsrIntWrite (ls, 0, ((stat & 
  596.     (lncsr_BABL | lncsr_CERR | lncsr_MISS | lncsr_MERR |
  597.      lncsr_RINT | lncsr_TINT | lncsr_IDON)) | lncsr_INEA));
  598.     /*
  599.      * have task level handle csr0 errors;
  600.      */
  601.     if (stat & lncsr_ERR)
  602.         {
  603. lnHandleCsr0Err (ls, stat);
  604. }
  605.     /* have task level handle any input packets */
  606.     if ((stat & lncsr_RINT) && (stat & lncsr_RXON))
  607. {
  608. if ((rmd = lnGetFullRMD (ls)) != NULL)
  609.     {
  610.     /* discard error input ASAP - don't queue it */
  611.     if (rmd->lnRMD1 & RMD_ERR) 
  612. {
  613. if (lnsgiLogCount && (ls->ls_if.if_ierrors % lnsgiLogCount) == 0)
  614.             logMsg ("ln%d lnInt: ERROR rmd1=0x%x mcnt %dn", 
  615.     ls->ls_if.if_unit, rmd->lnRMD1 & 0xff00, 
  616.     rmd->rbuf_mcnt, 0, 0, 0);
  617. ls->ls_if.if_ierrors++;
  618. ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  619.      sysWbFlush ();
  620. rmd->lnRMD1 &= ~RMD_ERR;
  621. LN_RMD_GIVE_TO_LANCE (rmd); sysWbFlush ();
  622. }
  623.     else if ((ls->ls_flags & LS_RCV_HANDLING_FLAG) == 0)
  624. {
  625. ls->ls_flags |= LS_RCV_HANDLING_FLAG;
  626. (void) netJobAdd ((FUNCPTR) lnHandleRecvInt, (int) ls, 
  627.   0, 0, 0, 0);
  628. }
  629.     }
  630. }
  631.     /* 
  632.      * Did LANCE update any of the TMD's?
  633.      * If not then don't bother continuing with transmitter stuff 
  634.      */
  635.     
  636.     if (!(stat & lncsr_TINT))
  637. { /* common return path */
  638.         return;
  639. }
  640.     pDindex = &ls->ls_dindex;
  641.     pTindex = &ls->ls_tindex;
  642.     pTsize  = &ls->ls_tsize;
  643.     pTring  = ls->ls_tring;
  644.     while (*pDindex != *pTindex)
  645.         {
  646. /* disposal has not caught up */
  647. tmd = pTring + *pDindex;
  648.         cacheClearEntry(tmd, sizeof(ln_tmd));
  649. /* if the buffer is still owned by LANCE, don't touch it */
  650. if (tmd->lnTMD1 & TMD_OWN)
  651.     break;
  652. /*
  653.  * tbuf_err (TMD1.ERR) is an "OR" of LCOL, LCAR, UFLO or RTRY.
  654.  * Note that BUFF is not indicated in TMD1.ERR.
  655.  * We should therefore check both tbuf_err and tbuf_buff
  656.  * here for error conditions.
  657.  */
  658. if ((tmd->lnTMD1 & TMD_ERR) || (tmd->lnTMD3 & TMD_BUFF))
  659.     {
  660.     ls->ls_if.if_oerrors++; /* output error */
  661.     ls->ls_if.if_opackets--;
  662.     /* check for no carrier */
  663.     if (tmd->lnTMD3 & TMD_LCAR)
  664. logMsg ("ln%d lnInt: no carriern", ls->ls_if.if_unit, 0, 0, 0, 0, 0);
  665.     /* every lnsgiLogCount errors show other interesting bits of tmd3 */
  666.     if ((tmd->lnTMD3 & 0xfc00) && lnsgiLogCount &&
  667. (ls->ls_if.if_oerrors % lnsgiLogCount) == 0)
  668. logMsg ("ln%d lnInt: xmit error, status(tmd3)=0x%x, err count=%dn",
  669. ls->ls_if.if_unit, tmd->lnTMD3 & 0xfc00,
  670. ls->ls_if.if_oerrors, 0, 0, 0);
  671.     /* restart chip on fatal errors */
  672.     /*
  673.      * The following code handles the situation where the transmitter 
  674.      * shuts down due to an underflow error.  This is a situation that 
  675.      * will occur if the DMA cannot keep up with the transmitter.
  676.      * It will occur if the LANCE is being held off from DMA access 
  677.      * for too long or due to significant memory latency.  DRAM fresh
  678.      * or slow memory could influence this.  Many implementation use a 
  679.      * dedicated LANCE buffer.  This can be static RAM to eliminate 
  680.      * refresh conflicts or dual-port RAM so that the LANCE can have 
  681.      * free run of this memory during its DMA transfers.
  682.      */
  683.     if ((tmd->lnTMD3 & TMD_BUFF) || (tmd->lnTMD3 & TMD_UFLO))
  684. {
  685. /* logMsg ("ln%d lnInt: xmit error, tmd3=0x%x. (%s/%d)n",
  686.  * ls->ls_if.if_unit, tmd->tbuf_tmd3 & 0xffff,
  687.  *                        __FILE__, __LINE__);
  688.  */
  689.   lnCsrIntWrite (ls, 0, lncsr_STOP); /* stop the LANCE */
  690. (void) netJobAdd ((FUNCPTR) lnInit, ls->ls_if.if_unit, 
  691.   0, 0, 0, 0);
  692. return;
  693. }
  694.     }
  695. tmd->lnTMD1 &= 0xff; /* clear high byte */
  696. tmd->lnTMD3 = 0; /* clear all error & stat stuff */
  697. sysWbFlush ();
  698. /* now bump the tmd disposal index pointer around the ring */
  699. *pDindex = (*pDindex + 1) & (*pTsize - 1);
  700. }
  701.     if (ls->ls_if.if_snd.ifq_head != NULL &&
  702. (ls->ls_flags & LS_START_OUTPUT_FLAG) == 0)
  703. {
  704. ls->ls_flags |= LS_START_OUTPUT_FLAG;
  705. #ifdef BSD43_DRIVER
  706.         (void) netJobAdd ( (FUNCPTR)lnStartOutput, ls->ls_if.if_unit, 
  707.   0, 0, 0, 0);
  708. #else
  709.         (void) netJobAdd ( (FUNCPTR)lnStartOutput, (int)ls, 0, 0, 0, 0);
  710. #endif
  711. }
  712.     }
  713. /*******************************************************************************
  714. *
  715. * lnHandleCsr0Err - task level interrupt service for csr0 errors
  716. */
  717. LOCAL void lnHandleCsr0Err
  718.     (
  719.     FAST struct ls_softc *ls,
  720.     u_short status 
  721.     )
  722.     {
  723.     if (status & lncsr_CERR) /* collision error */
  724. ls->ls_if.if_collisions++;
  725.     if (status & (lncsr_BABL | lncsr_MISS | lncsr_MERR))
  726. {
  727. ++ls->csr0Errs;
  728. ++ls->ls_if.if_ierrors;
  729. /* every lnsgiLogCount errors show interesting bits of csr0 */
  730. if (lnsgiLogCount && (ls->csr0Errs % lnsgiLogCount) == 0)
  731.     logMsg ("ln%d lnInt: csr0 error, csr0=0x%x, err count=%dn",
  732.     ls->ls_if.if_unit, status, ls->csr0Errs, 0, 0, 0);
  733. /*
  734.  * restart chip on fatal error 
  735.  */
  736. if (status & lncsr_MERR) /* memory error */
  737.     (void) netJobAdd ((FUNCPTR) lnInit, ls->ls_if.if_unit, 0, 0, 0, 0);
  738. }
  739.     }
  740. /*******************************************************************************
  741. *
  742. * lnHandleRecvInt - task level interrupt service for input packets
  743. *
  744. * This routine is called at task level indirectly by the interrupt
  745. * service routine to do any message received processing.
  746. */
  747. LOCAL void lnHandleRecvInt
  748.     (
  749.     FAST struct ls_softc *ls 
  750.     )
  751.     {
  752.     FAST ln_rmd         *rmd;
  753.     FAST int oldIndex;
  754.     do
  755. {
  756. ls->ls_flags |= LS_RCV_HANDLING_FLAG;
  757. while ((rmd = lnGetFullRMD (ls)) != NULL)
  758.     {
  759.     /* RMD available */
  760.     oldIndex = ls->ls_rindex;
  761.     if (lnRecv (ls, rmd) == OK)
  762. {
  763. for (; oldIndex != ls->ls_rindex; 
  764.      oldIndex = (oldIndex + 1) & (ls->ls_rsize - 1))
  765.     {
  766.     rmd = ls->ls_rring + oldIndex;
  767.          cacheClearEntry (rmd, sizeof(ln_rmd));
  768.     LN_RMD_GIVE_TO_LANCE (rmd); sysWbFlush ();
  769.     }
  770. }
  771.     else
  772.         break;
  773.     }
  774. /*
  775.  * There is a RACE right here.  The ISR could add a receive packet
  776.  * and check the boolean below, and decide to exit.  Thus the
  777.  * packet could be dropped if we don't double check before we
  778.  * return.
  779.  */
  780. ls->ls_flags &= ~LS_RCV_HANDLING_FLAG;
  781. }
  782.     while (lnGetFullRMD (ls) != NULL); /* this double check solves the RACE */
  783.     }
  784. /*******************************************************************************
  785. *
  786. * lnRecv -
  787. *
  788. * Process Ethernet receive completion:
  789. * If input error just drop packet.
  790. * Otherwise purge input buffered data path and examine 
  791. * packet to determine type.  If can't determine length
  792. * from type, then have to drop packet.  Otherwise decapsulate
  793. * packet based on type and pass to type-specific higher-level
  794. * input routine.
  795. *
  796. * RETURNS: ERROR if RMD shouldn't be returned back to LANCE yet.
  797. *          Otherwise, returns OK to return the RMD back to LANCE.
  798. */
  799. LOCAL STATUS lnRecv
  800.     (
  801.     struct ls_softc    *ls,
  802.     FAST ln_rmd    *rmd 
  803.     )
  804.     {
  805.     FAST struct ether_header *eh;
  806.     FAST struct mbuf *m;
  807.     FAST u_char *pData;
  808.     FAST ln_rmd *nextRmd;
  809.     int ix, len;
  810.     int off = 0;
  811. #ifdef BSD43_DRIVER
  812.     u_short ether_type;
  813. #endif
  814.     /*
  815.      * If both STP and ENP are set, LANCE didn't try to
  816.      * use data chaining.
  817.      */
  818.     if (((rmd->lnRMD1 & lnrmd1_STP) == lnrmd1_STP) &&
  819. ((rmd->lnRMD1 & lnrmd1_ENP) == lnrmd1_ENP))
  820. {
  821. len = rmd->rbuf_mcnt;
  822. ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  823.      sysWbFlush ();
  824. }
  825.     else if (((rmd->lnRMD1 & lnrmd1_STP) == lnrmd1_STP) &&
  826.      ((rmd->lnRMD1 & lnrmd1_ENP) == 0))
  827. {
  828. /* STP is set but ENP is not set, so LANCE is trying
  829.  * to use data chaining.  We scan the following sequence of
  830.  * RMD's to find the last buffer in this data chain.
  831.  */
  832. ix = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  833. do
  834.     {
  835.     nextRmd = ls->ls_rring + ix; /* next rmd */
  836.     /* Return if the next rmd is not ready.  Try later. */
  837.         cacheClearEntry(rmd, sizeof(ln_rmd));
  838.     if ((nextRmd->lnRMD1 & lnrmd1_OWN) != 0)
  839.         return (ERROR);
  840.     ix = (ix + 1) & (ls->ls_rsize - 1);
  841.     }
  842. /* end of packet? */
  843. while ((nextRmd->lnRMD1 & lnrmd1_ENP) == 0);
  844. /* This last RMD contains the valid MCNT. */
  845. ls->ls_rindex = ix;
  846.         sysWbFlush ();
  847. len = nextRmd->rbuf_mcnt;
  848. }
  849.     else
  850. {
  851. ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  852.         sysWbFlush ();
  853. ++ls->ls_if.if_ierrors;
  854. if (lnsgiLogCount && (ls->ls_if.if_ierrors % lnsgiLogCount) == 0)
  855.     logMsg ("ln%d lnRecv: receive error, stp %d enp %dn",
  856.     ls->ls_if.if_unit,
  857.             (rmd->lnRMD1 & lnrmd1_STP) >> 9,
  858.             (rmd->lnRMD1 & lnrmd1_ENP) >> 8, 0, 0, 0);
  859. return (OK); /* intentional */
  860. }
  861.     /*
  862.     eh = (struct ether_header *)(rmd->rbuf_ladr | (rmd->rbuf_hadr << 16));
  863.     ItoK (eh, struct ether_header *, ls->memBase);
  864.     */
  865.     ++ls->ls_if.if_ipackets;    /* bump statistic */
  866.     eh = (struct ether_header *) ((u_int) ls->rmd_ring.r_bufs + 
  867. (u_int) ((((u_int)rmd - (u_int)ls->ls_rring) / sizeof(ln_rmd)) 
  868. * ls->bufSize));
  869.     cacheClearEntry (eh, len);
  870.     /* call input hook if any */
  871.     if ((etherInputHookRtn != NULL) &&
  872. (* etherInputHookRtn) (&ls->ls_if, (char *)eh, len))
  873. return (OK);
  874. #ifdef BSD43_DRIVER
  875.     /* This legacy code is not correct for the BSD 4.4 stack. It would
  876.      * also treat multicast addresses like alien packets, and not send
  877.      * them up the stack. The higher-level protocols in the new stack
  878.      * can handle these addresses, and will discard them if they do not
  879.      * match an existing multicast group.
  880.      */
  881.     /* do software filter if controller is in promiscuous mode */
  882.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  883.         if ( (bcmp ( (char *)eh->ether_dhost, /* not our adrs? */
  884.                      (char *)ls->ls_enaddr,
  885.                     sizeof (eh->ether_dhost)) != 0) &&
  886.              (bcmp ( (char *)eh->ether_dhost, /* not broadcast? */
  887.                      (char *)etherbroadcastaddr,
  888.                     sizeof (eh->ether_dhost)) != 0))
  889.             return (OK);
  890. #endif
  891.     if (len >= sizeof (struct ether_header))
  892.         len -= sizeof (struct ether_header);
  893.     else
  894.         len = 0;
  895.     pData = ( (u_char *)eh) + (sizeof (struct ether_header)); 
  896. #ifdef BSD43_DRIVER
  897.     check_trailer (eh, pData, &len, &off, &ls->ls_if);
  898.     if (len == 0)
  899. return (OK);
  900.     ether_type = eh->ether_type;
  901. #endif
  902.     m = NULL;
  903.     /*
  904.      * we can loan out receive buffers from LANCE receive ring if:
  905.      *
  906.      * 1) canLoanRmd is TRUE.  canLoanRmd is set to TRUE if memWidth
  907.      *    is NONE (no special restriction in copying data in terms of
  908.      *    size and boundary conditions) and each of the buffers in the
  909.      *    LANCE ring is big enough to hold the maximum sized ethernet
  910.      *    frame (data-chaining is not being used for the input).
  911.      * 2) trailer protocol is not being used for the given input ethernet frame.
  912.      * 3) there is available free buffers that can be used to replace the
  913.      *    rbuf to be loaned out in the free list 'freeBufs'.
  914.      * 4) size of the input ethernet frame is large enough to be used with
  915.      *    clustering.
  916.      */
  917.     
  918.     if (ls->canLoanRmds && off == 0 && ls->nFree > 0 && USE_CLUSTER (len))
  919. {
  920.         m = build_cluster (pData, len, &ls->ls_if, MC_LANCE,
  921.                            &(ls->loanRefCnt [ls->ls_rindex]),
  922.                            lnRmdFree, (int) ls, (int) eh, NULL);
  923.         if (m != NULL)
  924.             {
  925.             FAST char *pBuf;
  926.             /* get a free buffer from the free list to replace the
  927.              * rbuf loaned out.  replace the rbuf pointers in the RMD
  928.              * to point to the new buffer.
  929.      */
  930.     
  931.             pBuf = ls->freeBufs [--ls->nFree];
  932.     
  933.             rmd->rbuf_ladr = (int) pBuf;
  934.             rmd->lnRMD1 = (rmd->lnRMD1 & ~lnrmd1_HADR)
  935.                     | (((int) pBuf >> 16) & lnrmd1_HADR);
  936.             sysWbFlush ();
  937.             }
  938.         }
  939.     if (m == NULL)
  940. #ifdef BSD43_DRIVER
  941.         /*
  942.          * Instead of calling copy_to_mbufs (), we call bcopy_to_mbufs ()
  943.          * with ls->memWidth as an addtional argument to specify unit of a
  944.          * copy op.
  945.          *
  946.          * Most drivers would use macro copy_to_mbufs (), which will in turn
  947.          * call bcopy_to_mbufs () telling it to use the normal bcopy ().  Some
  948.          * of the on-board LANCE hardware implementations require that you
  949.          * copy the data by certain number of bytes from dedicated memory
  950.          * to system memory, so LANCE driver has a ln_bcopy () routine that
  951.          * conforms to this requirement.
  952.          */
  953.         m = bcopy_to_mbufs (pData, len, off, (struct ifnet *) &ls->ls_if,
  954.                             ls->memWidth);
  955. #else
  956.         m = copy_to_mbufs (pData, len, 0, &ls->ls_if);
  957. #endif
  958.     if (m == NULL)
  959.         ls->ls_if.if_ierrors++;
  960.     else
  961. #ifdef BSD43_DRIVER
  962.         do_protocol_with_type (ether_type, m, &ls->ls_ac, len);
  963. #else
  964.         do_protocol (eh, m, &ls->ls_ac, len);
  965. #endif        
  966.     return (OK);
  967.     }
  968. #ifdef BSD43_DRIVER
  969. /*******************************************************************************
  970. *
  971. * lnOutput -
  972. *
  973. * Ethernet output routine.
  974. * Encapsulate a packet of type family for the local net.
  975. * Use trailer local net encapsulation if enough data in first
  976. * packet leaves a multiple of 512 bytes of data in remainder.
  977. */
  978. LOCAL int lnOutput
  979.     (
  980.     FAST struct ifnet *ifp,
  981.     FAST struct mbuf *m0,
  982.     struct sockaddr *dst 
  983.     )
  984.     {
  985.     return (ether_output (ifp, m0, dst, (FUNCPTR) lnStartOutput, 
  986.   &ls_softc [ifp->if_unit]->ls_ac));
  987.     }
  988. #endif
  989. /*******************************************************************************
  990. *
  991. * lnStartOutput - start pending output
  992. *
  993. * Start output to LANCE.
  994. * Queue up all pending datagrams for which transmit buffers are available.
  995. * Kick start the transmitter to avoid the polling interval latency.
  996. * This routine is called by lnInit () and lnOutput ().
  997. * It is very important that this routine be executed with splimp set.
  998. * If this is not done, another task could allocate the same tmd!
  999. */
  1000. #ifdef BSD43_DRIVER
  1001. LOCAL void lnStartOutput
  1002.     (
  1003.     int unit 
  1004.     )
  1005.     {
  1006.     FAST DRV_CTRL *  ls = ls_softc [unit];
  1007. #else
  1008. LOCAL void lnStartOutput
  1009.     (
  1010.     DRV_CTRL *  ls
  1011.     )
  1012.     {
  1013. #endif
  1014.     FAST struct mbuf *m;
  1015.     FAST ln_tmd *tmd;
  1016.     FAST char *buf;
  1017.     FAST int len;
  1018.     FAST int sx;
  1019.     FAST int oldLevel;
  1020.     sx = splimp ();
  1021.     ls->ls_flags |= LS_START_OUTPUT_FLAG;
  1022.     /* Loop placing message buffers in output ring until no more or no room */
  1023.     while (ls->ls_if.if_snd.ifq_head != NULL)
  1024.         {
  1025. /* there is something to send so get a transmit buffer */
  1026. if ((tmd = lnGetFreeTMD (ls)) == NULL)
  1027.     break;
  1028. IF_DEQUEUE (&ls->ls_if.if_snd, m); /* get head of next mbuf chain */
  1029.         buf = (char *) ((u_int) ls->tmd_ring.t_bufs + 
  1030.     (u_int) ((((u_int)tmd - (u_int)ls->ls_tring) / sizeof(ln_tmd)) 
  1031.     * ls->bufSize));
  1032. /* Copy packet to write buffer */
  1033. #ifdef BSD43_DRIVER
  1034. bcopy_from_mbufs (buf, m, len, ls->memWidth);
  1035. #else
  1036.         copy_from_mbufs (buf, m, len);
  1037. #endif
  1038. len = max (ETHERSMALL, len);
  1039. /* call output hook if any */
  1040.     
  1041. if ((etherOutputHookRtn != NULL) &&
  1042.     (* etherOutputHookRtn) (&ls->ls_if, buf, len))
  1043.     continue;
  1044. /* place a transmit request */
  1045.     
  1046. oldLevel = intLock (); /* disable ints during update */
  1047. tmd->lnTMD3 = 0; /* clear buffer error status */
  1048. tmd->tbuf_bcnt = -len; /* negative message byte count */
  1049. tmd->lnTMD1 |= lntmd1_ENP; /* buffer is end of packet */
  1050. tmd->lnTMD1 |= lntmd1_STP; /* buffer is start of packet */
  1051.         tmd->lnTMD1 &= ~lntmd1_DEF;   /* clear status bit */
  1052.         tmd->lnTMD1 &= ~lntmd1_MORE;
  1053.         tmd->lnTMD1 &= ~lntmd1_ERR;
  1054.         tmd->lnTMD1 |= lntmd1_OWN;
  1055. sysWbFlush ();
  1056. intUnlock (oldLevel); /* now lnInt won't get confused */
  1057. ls->ls_tindex = (ls->ls_tindex + 1) & (ls->ls_tsize - 1);
  1058.         sysWbFlush ();
  1059. #ifndef BSD43_DRIVER    /* BSD 4.4 ether_output() doesn't bump statistic. */
  1060.         ls->ls_if.if_opackets++;
  1061. #endif
  1062.         }
  1063. /*
  1064.  * to minimize chip accesses, don't kick start the transmitter.
  1065.  * it will start after the next internal poll.
  1066.  */
  1067.     ls->ls_flags &= ~LS_START_OUTPUT_FLAG;
  1068.     splx (sx);
  1069.     }
  1070. /*******************************************************************************
  1071. *
  1072. * lnIoctl -
  1073. *
  1074. * Process an ioctl request.
  1075. */
  1076. LOCAL int lnIoctl
  1077.     (
  1078.     FAST struct ifnet *ifp,
  1079.     int  cmd,
  1080.     caddr_t  data 
  1081.     )
  1082.     {
  1083.     int    unit = ifp->if_unit;
  1084.     FAST struct ls_softc  *ls = ls_softc [unit];
  1085.     int    s = splimp ();
  1086.     int    error = 0;
  1087.     switch (cmd)
  1088. {
  1089. case SIOCSIFADDR:
  1090.             ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;
  1091.             arpwhohas (ifp, &IA_SIN (data)->sin_addr);
  1092.     break;
  1093. case SIOCGIFADDR:
  1094.     bcopy((caddr_t) ls->ls_enaddr,
  1095.   (caddr_t) ((struct ifreq *)data)->ifr_addr.sa_data, 6);
  1096.     break;
  1097. case SIOCGIFFLAGS:
  1098.     *(short *)data = ifp->if_flags;
  1099.     break;
  1100. case SIOCSIFFLAGS:
  1101.     ls->ls_if.if_flags = ifp->if_flags;
  1102.     if (ifp->if_flags & IFF_PROMISC)
  1103.         ls->ls_flags |= LS_PROMISCUOUS_FLAG;
  1104.     else
  1105.         ls->ls_flags &= ~LS_PROMISCUOUS_FLAG;
  1106.     if (ifp->if_flags & IFF_UP)
  1107. ls->ls_if.if_flags |= (IFF_UP|IFF_RUNNING);
  1108.     else
  1109.         ls->ls_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
  1110.     break;
  1111. default:
  1112.     error = EINVAL;
  1113. }
  1114.     splx (s);
  1115.     return (error);
  1116.     }
  1117. /*******************************************************************************
  1118. *
  1119. * lnChipReset - hardware reset of chip (stop it)
  1120. */
  1121. LOCAL void lnChipReset
  1122.     (
  1123.     struct ls_softc  *ls 
  1124.     )
  1125.     {
  1126.     lnCsrWrite (ls, 0, lncsr_STOP);     /* set the stop bit */
  1127.     }
  1128. /*******************************************************************************
  1129. *
  1130. * lnChipInit - hardware init of chip (init & start it)
  1131. */
  1132. LOCAL void lnChipInit
  1133.     (
  1134.     FAST struct ls_softc  *ls 
  1135.     )
  1136.     {
  1137.     FAST u_short stat;
  1138.     int timeoutCount = 0;
  1139.     lnCsrWrite (ls, 0, lncsr_STOP); /* set the stop bit */
  1140. /* can't write csr1..3 if not stopped */
  1141.     lnCsrWrite (ls, 3, lncsr3_BSWP);
  1142.     lnCsrWrite (ls, 2, (u_short) ((u_int) (LNADDR(IBUF_INDEX, ls->ib) >> 16) 
  1143. & 0xff));
  1144.     lnCsrWrite (ls, 1, (u_short) (LNADDR(IBUF_INDEX, ls->ib)));
  1145.     lnCsrWrite (ls, 0, lncsr_INIT); /* init chip (read IB) */
  1146.     /* hang until Initialization done, error, or timeout */
  1147.     while (((stat = lnCsrRead (ls, 0)) & (lncsr_IDON | lncsr_ERR)) == 0)
  1148.         {
  1149.         if (timeoutCount++ > 0x10000) break;
  1150.         taskDelay(100);
  1151.         }
  1152.     /* log chip initialization failure */
  1153.     if (stat & lncsr_ERR)
  1154.         {
  1155.         logMsg ("ln%d: ERROR: Lance chip initialization failure, csr0=0x%xn",
  1156.                 ls->ls_if.if_unit, stat, 0, 0, 0, 0);
  1157.         }
  1158.     else if (timeoutCount >= 0x10000)
  1159.         {
  1160.         logMsg ("ln%d: ERROR: Lance chip initialization time-outn",
  1161. 0, 0, 0, 0, 0, 0);
  1162.         }
  1163.     /* start chip */
  1164.     ls->ls_rindex = 0; /* chip will start at beginning */
  1165.     ls->ls_tindex = 0;
  1166.     ls->ls_dindex = 0;
  1167.     sysWbFlush ();
  1168.     lnCsrWrite(ls, 0, lncsr_IDON | lncsr_INEA | lncsr_STRT);
  1169. /* reset IDON state */
  1170. /* enable interrupts from LANCE */
  1171. /* start chip operation */
  1172.     }
  1173. /*******************************************************************************
  1174. *
  1175. * lnGetFreeTMD - get next available TMD
  1176. */
  1177. LOCAL ln_tmd *lnGetFreeTMD
  1178.     (
  1179.     FAST struct ls_softc  *ls 
  1180.     )
  1181.     {
  1182.     FAST ln_tmd   *tmd;
  1183.     /* check if buffer is available (owned by host) */
  1184.     /* also check for tindex overrun onto dindex */
  1185.     tmd = ls->ls_tring + ls->ls_tindex;
  1186.     cacheClearEntry(tmd, sizeof(ln_tmd));
  1187.     if (((tmd->lnTMD1 & lntmd1_OWN) != 0)
  1188. || (((ls->ls_tindex + 1) & (ls->ls_tsize - 1)) == ls->ls_dindex))
  1189. {
  1190.         tmd = (ln_tmd *) NULL;
  1191. }
  1192.     return (tmd);
  1193.     }
  1194. /*******************************************************************************
  1195. *
  1196. * lnGetFullRMD - get next received message RMD
  1197. */
  1198. LOCAL ln_rmd *lnGetFullRMD
  1199.     (
  1200.     FAST struct ls_softc  *ls 
  1201.     )
  1202.     {
  1203.     FAST ln_rmd   *rmd;
  1204.     /* check if buffer is full (owned by host) */
  1205.     rmd = ls->ls_rring + ls->ls_rindex;
  1206.     cacheClearEntry(rmd, sizeof(ln_rmd));
  1207.     if ((rmd->lnRMD1 & lnrmd1_OWN) == 0)
  1208. {
  1209.         return (rmd);
  1210. }
  1211.     else
  1212. {
  1213.         return ((ln_rmd *) NULL);
  1214. }
  1215.     }
  1216. /*******************************************************************************
  1217. *
  1218. * lnCsrRead - select and read a CSR register 
  1219. *
  1220. * NOTE: LANCE must already be stopped to read CSR1, CSR2 or CSR3.
  1221. */
  1222. LOCAL u_short lnCsrRead
  1223.     (
  1224.     FAST struct ls_softc  *ls, /* LANCE device software structure */
  1225.     int reg  /* which CSR to be selected */
  1226.     )
  1227.     {
  1228.     FAST u_short value;
  1229.     FAST u_short *dv = (u_short *)ls->devAdrs;
  1230.     volatile u_short *pRAP;
  1231.     volatile u_short *pCSR0;
  1232.     pRAP  = (volatile u_short *) (dv + RAPOffset);
  1233.     pCSR0 = (volatile u_short *) (dv + CSROffset);
  1234.     *pRAP = reg; /* select CSR */
  1235.     sysWbFlush ();
  1236.     value = *pCSR0; /* get contents of CSR */
  1237.     return(value); /* return contents of CSR */
  1238.     }
  1239. /*******************************************************************************
  1240. *
  1241. * lnCsrWrite - select and write a CSR register 
  1242. *
  1243. */
  1244. LOCAL void lnCsrWrite
  1245.     (
  1246.     FAST struct ls_softc  *ls, /* LANCE device software structure */
  1247.     int reg, /* which CSR to be selected */
  1248.     u_short value  /* value to write */
  1249.     )
  1250.     {
  1251.     FAST u_short *dv = (u_short *)ls->devAdrs;
  1252.     volatile u_short *pRAP;
  1253.     volatile u_short *pCSR0;
  1254.     pRAP  = (volatile u_short *) (dv + RAPOffset);
  1255.     pCSR0 = (volatile u_short *) (dv + CSROffset);
  1256.     *pRAP = reg; /* select CSR */
  1257.     sysWbFlush ();
  1258.     *pCSR0 = value; /* write value to CSR */
  1259.     sysWbFlush ();
  1260.     }
  1261. /*******************************************************************************
  1262. *
  1263. * lnCsrIntRead - select and read a CSR register in an ISR 
  1264. *
  1265. * NOTE: LANCE must already be stopped to read CSR1, CSR2 or CSR3.
  1266. */
  1267. LOCAL u_short lnCsrIntRead
  1268.     (
  1269.     FAST struct ls_softc  *ls, /* LANCE device software structure */
  1270.     FAST int reg  /* which CSR to be selected */
  1271.     )
  1272.     {
  1273.     FAST u_short value;
  1274.     FAST u_short *dv = (u_short *)ls->devAdrs;
  1275.     volatile u_short *pRAP;
  1276.     volatile u_short *pCSR0;
  1277.     pRAP  = (volatile u_short *) (dv + RAPOffset);
  1278.     pCSR0 = (volatile u_short *) (dv + CSROffset);
  1279.     *pRAP = reg; /* select CSR */
  1280.     sysWbFlush ();
  1281.     value = *pCSR0; /* get contents of CSR */
  1282.     return(value); /* return contents of CSR */
  1283.     }
  1284. /*******************************************************************************
  1285. *
  1286. * lnCsrIntWrite - select and write a CSR register in an ISR.
  1287. *
  1288. */
  1289. LOCAL void lnCsrIntWrite
  1290.     (
  1291.     FAST struct ls_softc  *ls, /* LANCE device software structure */
  1292.     FAST int reg, /* which CSR to be selected */
  1293.     FAST u_short value  /* value to write */
  1294.     )
  1295.     {
  1296.     FAST u_short *dv = (u_short *)ls->devAdrs;
  1297.     volatile u_short *pRAP;
  1298.     volatile u_short *pCSR0;
  1299.     pRAP  = (volatile u_short *) (dv + RAPOffset);
  1300.     pCSR0 = (volatile u_short *) (dv + CSROffset);
  1301.     *pRAP = reg; /* select CSR */
  1302.     sysWbFlush ();
  1303.     *pCSR0 = value; /* write value to CSR */
  1304.     sysWbFlush ();
  1305.     }
  1306. /*******************************************************************************
  1307. *
  1308. * lnRmdFree - called when loaned out rbuf is freed by MCLFREE.
  1309. *
  1310. * Puts the loaned out rbuf into free list to be reused as loan replacements.
  1311. */
  1312. LOCAL void lnRmdFree
  1313.     (
  1314.     FAST struct ls_softc *ls,
  1315.     FAST char  *pBuf 
  1316.     )
  1317.     {
  1318.     ls->freeBufs [ls->nFree++] = pBuf;
  1319.     }