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

VxWorks

开发平台:

C/C++

  1. /* if_es.c - ETHERSTAR ethernet network interface for the DLAN */
  2. /* Copyright 1984-1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01i,06oct98,jmp  doc: cleanup.
  8. 01h,19aug98,fle  doc : added routine description for esattach
  9. 01g,15jul97,spm  removed driver initialization from ioctl support (SPR #8831)
  10. 01f,19may97,spm  eliminated all compiler warnings
  11. 01e,15may97,spm  reverted to bcopy routines for mbufs in BSD 4.4
  12. 01d,07apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.4
  13. 01c,26may93,ccc  updated for 5.1.
  14. 01b,03aug92,dyn  modified by Dynatem to support their new version.
  15. 01a,01apr91,ccc  written based on other drivers (if_xx) & ESTAR documentation.
  16. */
  17. /*
  18. DESCRIPTION
  19. The only user callable routine is:
  20.     esattach (unit, devAdrs, ivec, ilevel, memAdrs, memSize, memWidth)
  21. To enable the use of the Dynatem DLAN board the following needs to be
  22. added to the target's config.h file:
  23. .CS
  24. /@ Device controller I/O addresses: @/
  25.   #define INCLUDE_ES
  26.   #define INT_VEC_ES              0xc0 /@ interrupt vector @/
  27.   #define INT_LVL_ES              5 /@ VMEbus interrupt level @/
  28.   #define IO_ADRS_ES              ((char *) 0x70008000) /@ short I/O address @/
  29. .CE
  30.  LANCE defines 
  31. .CS
  32.   #define ES_POOL_ADRS            NONE    /@ malloc the pool @/
  33.   #define ES_POOL_SIZE            NONE    /@ pool will be default size @/
  34.   #define ES_DATA_WIDTH           NONE    /@ all data widths supported @/
  35.   #define ES_PADDING              FALSE   /@ no padding for RAP @/
  36.   #define ES_RING_BUF_SIZE        0       /@ use the default size @/
  37.   #define INCLUDE_IF_USR
  38.   #define IF_USR_NAME     "es"
  39.   #define IF_USR_ATTACH   esattach
  40.   #define IF_USR_ARG1     IO_ADRS_ES
  41.   #define IF_USR_ARG2     INT_VEC_ES
  42.   #define IF_USR_ARG3     INT_LVL_ES
  43.   #define IF_USR_ARG4     ES_POOL_ADRS
  44.   #define IF_USR_ARG5     ES_POOL_SIZE
  45.   #define IF_USR_ARG6     ES_DATA_WIDTH
  46.   #define IF_USR_ARG7     ES_PADDING
  47.   #define IF_USR_ARG8     ES_RING_BUF_SIZE
  48. .CE
  49. The following needs to be added to sysLib.c under global definitions:
  50. .CS
  51.   char  esEnetAddr [6];
  52. .CE
  53. SEE ALSO: ifLib
  54. */
  55. #include "vxWorks.h"
  56. #include "stdlib.h"
  57. #include "netLib.h"
  58. #include "iv.h"
  59. #include "memLib.h"
  60. #include "ioctl.h"
  61. #include "etherLib.h"
  62. #include "logLib.h"
  63. #include "intLib.h"
  64. #include "sysLib.h"
  65. #ifndef DOC /* don't include when building documentation */
  66. #include "net/mbuf.h"
  67. #endif /* DOC */
  68. #include "net/protosw.h"
  69. #include "net/unixLib.h"
  70. #include "socket.h"
  71. #include "errno.h"
  72. #include "net/if.h"
  73. #include "net/route.h"
  74. #include "netinet/in.h"
  75. #include "netinet/in_systm.h"
  76. #include "netinet/in_var.h"
  77. #include "netinet/ip.h"
  78. #include "netinet/if_ether.h"
  79. #include "net/if_subr.h"
  80. #include "drv/netif/if_es.h"
  81. struct dlanptr {
  82. u_char *dlcr0;
  83. u_char *dlcr1;
  84. u_char *dlcr2;
  85. u_char *dlcr3;
  86. u_char *dlcr4;
  87. u_char *dlcr5;
  88. u_char *dlcr6;
  89. u_char *dlcr7;
  90. u_char *dlcr8;
  91. u_char *dlcr9;
  92. u_char *dlcr10;
  93. u_char *dlcr11;
  94. u_char *dlcr12;
  95. u_char *dlcr13;
  96. u_char *dlcr14;
  97. u_char *dlcr15;
  98. } dlan;
  99. IMPORT VOID ether_attach ();
  100. #define MAX_ES 1 /* max number of ESTAR chips on board */
  101. #define ItoKval(p,type,base)    ((type)((ULONG)(p) + (ULONG)(base)))
  102. #define ItoK(p,type,base)       ((p) = ItoKval(p,type,base))
  103. #define ES_RMD_GIVE_TO_ESTAR(pRmd) 
  104.     { 
  105.     pRmd->rbuf_rmd1 &= 0xff; 
  106.     pRmd->rbuf_mcnt = 0; 
  107.     pRmd->es_rmd1.es_rmd1b |= esrmd1_OWN;
  108.     }
  109. IMPORT unsigned char esEnetAddr []; /* ethernet address to load into lance */
  110. /* globals */
  111. int esLogCount = 0;
  112. int dbg_read = 0;
  113. int dbg_output = 0;
  114. int recIndex = 0;
  115. u_short newdlan;
  116. /* locals */
  117. LOCAL int esTsize = ES_TMD_TLEN; /* deflt xmit ring size as power of 2 */
  118. LOCAL int esRsize = ES_RMD_RLEN; /* deflt recv ring size as power of 2 */
  119. LOCAL struct ls_softc  *ls_softc [MAX_ES];
  120. /* forward declarations */
  121. LOCAL VOID esInt ();
  122. LOCAL VOID esHandleRecvInt ();
  123. LOCAL int esInit ();
  124. #ifdef BSD43_DRIVER
  125. LOCAL int esOutput ();
  126. #endif
  127. LOCAL int esIoctl ();
  128. LOCAL VOID esReset ();
  129. #ifdef BSD43_DRIVER
  130. LOCAL VOID esStartOutput ();
  131. #else
  132. LOCAL VOID esStartOutput (struct ls_softc *ls);
  133. #endif
  134. LOCAL es_tmd        *esGetFreeTMD ();
  135. LOCAL es_rmd        *esGetFullRMD ();
  136. LOCAL VOID esRmdFree ();
  137. LOCAL VOID esConfig ();
  138. LOCAL VOID esChipReset ();
  139. LOCAL VOID esChipInit ();
  140. LOCAL STATUS esRecv ();
  141. LOCAL u_short  esReadBmpr0 ();
  142. /*******************************************************************************
  143. *
  144. * esattach - attaches an EtherStar target
  145. *
  146. * Interface exists: make available by filling in network interface
  147. * record.  System will initialize the interface when it is ready
  148. * to accept packets.
  149. * The memory pool will be malloced if NONE is specified.  The memWidth
  150. * determines the data port width (in bytes) of the memory pool.
  151. *
  152. * BUGS:
  153. * Currently uses bzero to zero lance data structures, which ignores the
  154. * specification of memWidth and may use any size data access to write to memory.
  155. *
  156. */
  157. STATUS esattach
  158.     (
  159.     int       unit, /* unit number */
  160.     char     *devAdrs, /* ESTAR i/o address */
  161.     int       ivec, /* interrupt vector */
  162.     int       ilevel, /* interrupt level */
  163.     char     *memAdrs, /* address of memory pool (-1 == malloc it) */
  164.     ULONG     memSize, /* only used if memory pool is NOT malloced */
  165.     int       memWidth, /* byte-width of data (-1 == any width)     */
  166.     BOOL      usePadding, /* use padding when accessing RAP? */
  167.     int       bufSize /* size of a buffer in the ESTAR ring */
  168.     )
  169.     {
  170.     FAST struct ls_softc  *ls;
  171.     FAST struct ifnet   *ifp;
  172.     FAST unsigned int    sz; /* temporary size holder */
  173.     FAST ES_DEVICE   *dv;
  174.     char    *memPool; /* start of the ESTAR memory pool */
  175.     if (bufSize == 0)
  176.         bufSize = ES_BUFSIZE;
  177.     if ((int) memAdrs != NONE) /* specified memory pool */
  178. {
  179. /*
  180.  * With a specified memory pool we want to maximize
  181.  * esRsize and esTsize
  182.  */
  183. sz = (memSize - (sizeof (es_rmd) + sizeof (es_tmd) + sizeof (es_ib)))
  184.        / ((2 * bufSize) + sizeof (es_rmd) + sizeof (es_tmd));
  185. sz >>= 1; /* adjust for roundoff */
  186. for (esRsize = 0; sz != 0; esRsize++, sz >>= 1)
  187.     ;
  188. esTsize = esRsize; /* esTsize = esRsize for convenience */
  189. }
  190.     /* limit ring sizes to reasonable values */
  191.     if (esRsize < 2)
  192.         esRsize = 2; /* 4 buffers is reasonable min */
  193.     if (esRsize > 7)
  194.         esRsize = 7; /* 128 buffers is max for chip */
  195.     /* limit ring sizes to reasonable values */
  196.     if (esTsize < 2)
  197.         esTsize = 2; /* 4 buffers is reasonable min */
  198.     if (esTsize > 7)
  199.         esTsize = 7; /* 128 buffers is max for chip */
  200.     /* calculate the total size of ESTAR memory pool.  (basic softc structure
  201.      * is just allocated from free memory pool since ESTAR never references).
  202.      */
  203.     sz = ((sizeof (es_ib))        + (((1 << esRsize) + 1) * sizeof (es_rmd)) +
  204.   (bufSize << esRsize) + (((1 << esTsize) + 1) * sizeof (es_tmd)) +
  205.   (bufSize << esTsize));
  206.     if ((int) memAdrs == NONE) /* if -1 then allocate memPool from free pool */
  207. {
  208. memPool = (char *) malloc (sz); /* allocate memory */
  209. if ((int)memPool == NULL)
  210.     return (ERROR); /* bail out if we don't get memory */
  211. }
  212.     else
  213. {
  214. if (memSize < sz)
  215.     return (ERROR); /* bail out if memSize specified is too small */
  216. memPool = memAdrs; /* set the beginning of pool */
  217. }
  218.     /*                        memPool partitioning
  219.      *                        --------------------
  220.      *
  221.      *                                                 LOW MEMORY
  222.      *
  223.      *    memPool,ls->ib |-------------------------------------|
  224.      * |       |
  225.      * |         (sizeof (es_ib))       |
  226.      * |       |
  227.      *      ls->ls_rring  |-------------------------------------|
  228.      * |       |
  229.      *  | ((1 << esRsize) + 1)*sizeof (es_rmd)|
  230.      * |       |
  231.      *       ls->rmd_ring.r_bufs |-------------------------------------|
  232.      * |       |
  233.      *  |       (bufSize << esRsize)          |
  234.      * |       |
  235.      *     ls->ls_tring |-------------------------------------|
  236.      * |       |
  237.      * | ((1 << esTsize) + 1)*sizeof (es_tmd)|
  238.      * |       |
  239.      *       ls->tmd_ring.t_bufs |-------------------------------------|
  240.      * |       |
  241.      *  |       (bufSize << esTsize)          |
  242.      * |       |
  243.      *           |-------------------------------------|
  244.      *
  245.      *                                                HIGH MEMORY
  246.      */
  247.     /* allocate basic softc structure */
  248.     ls = (struct ls_softc *)malloc (sizeof (struct ls_softc));
  249.     if (ls == NULL)
  250. {
  251. if ((int) memAdrs == NONE) /* if we malloced memPool */
  252.     (void) free (memPool); /* free the memPool */
  253. return (ERROR);
  254. }
  255.     /* zero out entire softc structure */
  256.     bzero ((char *)ls, sizeof (struct ls_softc));
  257.     /* fill in high byte of memory base (A24:A31) and data port width */
  258.     ls->memBase  = (char *) ((ULONG)memPool & 0xff000000);
  259.     ls->memWidth = memWidth;
  260.     if ((int) memAdrs == NONE)
  261.         ls->ls_flags |= LS_MEM_ALLOC_FLAG;
  262.    
  263.     if (usePadding == TRUE) /* Is CSR padding necessary? */
  264. ls->ls_flags |= LS_PAD_USED_FLAG;
  265.     else
  266.         ls->ls_flags &= ~LS_PAD_USED_FLAG;
  267.     ls->bufSize = bufSize;
  268.     /* if memWidth is NONE (we can copy any byte size/boundaries) and
  269.      * bufSize is big enough to hold the biggest ethernet frame
  270.      * we can loan out rmds.  On systems that cannot afford to have
  271.      * big enough RMD's, ESTAR will use data-chaining on receive
  272.      * buffers.  Our current implementation of RMD loans does not work
  273.      * with receive side data-chains.
  274.      */
  275.     if (ls->memWidth == NONE && ls->bufSize == ES_BUFSIZE)
  276. {
  277. int ix;
  278. char *pBuf;
  279.         ls->canLoanRmds = TRUE;
  280. ls->nFree = ES_NUM_RESERVES;
  281. if ((pBuf = (char *) malloc ((u_int) (ES_NUM_RESERVES * bufSize))) == NULL)
  282.     {
  283.     (void) free (memPool);
  284.     (void) free ((char *) ls);
  285.     return (ERROR);
  286.     }
  287. for (ix = 0; ix < ES_NUM_RESERVES; ix++)
  288.     ls->freeBufs [ix] = (char *) ((int) pBuf + (bufSize * ix));
  289. }
  290.     else
  291.         ls->canLoanRmds = FALSE;
  292.     /* allocate initialization block */
  293.     ls->ib = (es_ib *)memPool;
  294.     sz = sizeof (es_ib); /* size of initialization block */
  295.     bzero ((char *)ls->ib, (int) sz); /* zero out entire ib */
  296.     /* allocate receive message descriptor (RMD) ring structure */
  297.     ls->ls_rpo2 = esRsize; /* remember for esConfig */
  298.     ls->ls_rsize = (1 << esRsize); /* receive msg descriptor ring size */
  299.     /* leave room to adjust low three bits */
  300.     ls->ls_rring = (es_rmd *) ((int)ls->ib + sz);   /* of pointer to be 000 */
  301.     sz = ((1 << esRsize) + 1) * sizeof (es_rmd);
  302.     bzero ((char *)ls->ls_rring, (int)sz); /* zero out entire RMD ring */
  303.     /* allocate receive buffer space */
  304.     ls->rmd_ring.r_bufs = (char *)((int)ls->ls_rring + sz);
  305.     sz = (bufSize << esRsize);  /* room for all the receive buffers */
  306.     bzero (ls->rmd_ring.r_bufs, (int)sz);/* zero out entire rbuf area */
  307.     /* allocate transmit message descriptor (TMD) ring structure */
  308.     ls->ls_tpo2 = esTsize; /* remember for esConfig */
  309.     ls->ls_tsize = (1 << esTsize); /* transmit msg descriptor ring size */
  310.     ls->ls_tring = (es_tmd *) ((int)ls->rmd_ring.r_bufs + sz);
  311.     sz = ((1 << esTsize) + 1) * sizeof (es_tmd);
  312.     bzero ((char *)ls->ls_tring, (int)sz); /* zero out entire TMD ring */
  313.     /* allocate transmit buffer space */
  314.     ls->tmd_ring.t_bufs = (char *)((int)ls->ls_tring + sz);
  315.     sz = (bufSize << esTsize); /* room for all the transmit buffers */
  316.     bzero (ls->tmd_ring.t_bufs, (int)sz); /* zero out entire tbuf area */
  317.     ls_softc [unit] = ls; /* remember address for this unit */
  318.     /* initialize device structure */
  319.     ls->ivec     = ivec; /* interrupt vector */
  320.     ls->ilevel = ilevel; /* interrupt level */
  321.     ls->devAdrs = (ES_DEVICE *)devAdrs; /* ESTAR i/o address */
  322.     /* copy the enet address into the softc */
  323.     dv = ls->devAdrs;
  324.     esEnetAddr[0] = dv->ROM_IDf;
  325.     esEnetAddr[1] = dv->ROM_IDe;
  326.     esEnetAddr[2] = dv->ROM_IDd;
  327.     esEnetAddr[3] = dv->ROM_IDc;
  328.     esEnetAddr[4] = dv->ROM_IDb;
  329.     esEnetAddr[5] = dv->ROM_IDa;
  330.     if (esEnetAddr[3]) {
  331. newdlan = TRUE;
  332. dlan.dlcr0 = &(dv->dlcr0);
  333. dlan.dlcr1 = &(dv->dlcr1);
  334. dlan.dlcr2 = &(dv->dlcr2);
  335. dlan.dlcr3 = &(dv->dlcr3);
  336.   dlan.dlcr4 = &(dv->dlcr4);
  337. dlan.dlcr5 = &(dv->dlcr5);
  338. dlan.dlcr6 = &(dv->dlcr6);
  339. dlan.dlcr7 = &(dv->dlcr7);
  340. dlan.dlcr8 = &(dv->dlcr8);
  341. dlan.dlcr9 = &(dv->dlcr9);
  342. dlan.dlcr10 = &(dv->dlcr10);
  343. dlan.dlcr11 = &(dv->dlcr11);
  344. dlan.dlcr12 = &(dv->dlcr12);
  345. dlan.dlcr13 = &(dv->dlcr13);
  346. dlan.dlcr14 = &(dv->dlcr14);
  347. dlan.dlcr15 = &(dv->dlcr15);
  348.     }
  349.     else {
  350. newdlan = FALSE;
  351. dlan.dlcr0 = &(dv->dlcr1);
  352. dlan.dlcr1 = &(dv->dlcr0);
  353. dlan.dlcr2 = &(dv->dlcr3);
  354. dlan.dlcr3 = &(dv->dlcr2);
  355.   dlan.dlcr4 = &(dv->dlcr5);
  356. dlan.dlcr5 = &(dv->dlcr4);
  357. dlan.dlcr6 = &(dv->dlcr7);
  358. dlan.dlcr7 = &(dv->dlcr6);
  359. dlan.dlcr8 = &(dv->dlcr9);
  360. dlan.dlcr9 = &(dv->dlcr8);
  361. dlan.dlcr10 = &(dv->dlcr11);
  362. dlan.dlcr11 = &(dv->dlcr10);
  363. dlan.dlcr12 = &(dv->dlcr13);
  364. dlan.dlcr13 = &(dv->dlcr12);
  365. dlan.dlcr14 = &(dv->dlcr15);
  366. dlan.dlcr15 = &(dv->dlcr14);
  367.     }
  368.     bcopy ((char *) esEnetAddr, (char *)ls->ls_enaddr, sizeof (ls->ls_enaddr));
  369.     ifp = &ls->ls_if;
  370.     /* attach and enable the ESTAR interrupt service routine to vector */
  371.     esChipReset (ls); /* reset ESTAR */
  372.     (void) intConnect (INUM_TO_IVEC (ivec), esInt, (int)ls);
  373. #ifdef BSD43_DRIVER
  374.     ether_attach (ifp, unit, "es", (FUNCPTR) esInit, (FUNCPTR) esIoctl,
  375.  (FUNCPTR) esOutput, (FUNCPTR) esReset);
  376. #else
  377.     ether_attach (
  378.                  &ls->ls_ac.ac_if, 
  379.                  unit, 
  380.                  "es", 
  381.                  (FUNCPTR) esInit, 
  382.                  (FUNCPTR) esIoctl,
  383.  (FUNCPTR) ether_output,
  384.                  (FUNCPTR) esReset
  385.                  );
  386.     ifp->if_start = (FUNCPTR)esStartOutput;
  387. #endif
  388.     sysIntEnable (ilevel);
  389.     esInit (unit);
  390.     return (OK);
  391.     }
  392. /*******************************************************************************
  393. *
  394. * esReset - reset the interface
  395. *
  396. * Mark interface as inactive & reset the chip
  397. */
  398. LOCAL VOID esReset
  399.     (
  400.     int unit
  401.     )
  402.     {
  403.     FAST struct ls_softc  *ls = ls_softc [unit];
  404.     ls->ls_if.if_flags &= ~IFF_RUNNING;
  405.     esChipReset (ls); /* reset ESTAR */
  406.     }
  407. /*******************************************************************************
  408. *
  409. * esInit - initializes EtherStar connection
  410. *
  411. * Initialization of interface; clear recorded pending operations.
  412. * Called at boot time (with interrupts disabled?),
  413. * and at ifconfig time via esIoctl, with interrupts disabled.
  414. */
  415. LOCAL int esInit
  416.     (
  417.     int unit
  418.     )
  419.     {
  420.     FAST struct ls_softc  *ls = ls_softc [unit];
  421.     FAST struct ifnet   *ifp = &ls->ls_if;
  422.     ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_PROMISC);
  423.     esChipReset (ls); /* disable chip during init */
  424.     esConfig (ls); /* reset all ring structures */
  425.     ifp->if_flags |= (IFF_UP | IFF_RUNNING);
  426.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  427. ifp->if_flags |= (IFF_PROMISC);
  428.     esChipInit (ls); /* on return ESTAR is running */
  429. #ifdef BSD43_DRIVER
  430.     esStartOutput (ls->ls_if.if_unit); /* tell chip about any pending output */
  431. #else
  432.     esStartOutput (ls);
  433. #endif
  434.     return (0);
  435.     }
  436. /*******************************************************************************
  437. *
  438. * esConfig - fill in initialization block with mode information.
  439. *
  440. * Fill in all fields in the Initialization Block with relevant values.
  441. * In addition, fill in all fields in Transmit Message Descriptor ring
  442. * and Receive Message Descriptor ring.
  443. */
  444. LOCAL VOID esConfig
  445.     (
  446.     FAST struct ls_softc  *ls
  447.     )
  448.     {
  449.     FAST es_rmd   *rmd;
  450.     FAST es_tmd   *tmd;
  451.     FAST char   *buf;
  452.     FAST es_ib   *ib;
  453.     int    i;
  454.     rmd = ls->ls_rring; /* receive message descriptor ring */
  455.     rmd = (es_rmd *)(((int)rmd + 7) & ~7); /* low 3 bits must be 000 */
  456.     ls->ls_rring = rmd; /* fix softc as well */
  457.     buf = ls->rmd_ring.r_bufs;
  458.     for (i = 0; i < ls->ls_rsize; i++)
  459.         {
  460. rmd->rbuf_ladr = (u_short)((int)buf); /* bits 15:00 of buffer address */
  461. rmd->rbuf_rmd1 = (u_short)((int)buf >> 16) & 0xff;
  462. /* bits 23:16 of buffer address */
  463. rmd->rbuf_bcnt = -(ls->bufSize);/* neg of buffer byte count */
  464. rmd->rbuf_mcnt = 0; /* no message byte count yet */
  465. rmd->es_rmd1.es_rmd1b |= esrmd1_OWN; /* buffer now owned by ESTAR */
  466. rmd++; /* step to next message descriptor */
  467. buf += (ls->bufSize); /* step to start of next buffer */
  468. ls->loanRefCnt [i] = (u_char) 0;
  469. }
  470.     ls->ls_rindex = 0; /* ESTAR will use at start of ring */
  471.     tmd = ls->ls_tring; /* transmit message descriptor ring */
  472.     tmd = (es_tmd *)(((int)tmd + 7) & ~7); /* low 3 bits must be 000 */
  473.     ls->ls_tring = tmd; /* fix softc as well */
  474.     buf = ls->tmd_ring.t_bufs;
  475.     for (i = 0; i < ls->ls_tsize; i++)
  476.         {
  477. tmd->tbuf_ladr = (u_short)((int)buf); /* bits 15:00 of buffer address */
  478. tmd->tbuf_tmd1 = (u_short)((int)buf >> 16) & 0xff;
  479. /* bits 23:16 of buffer address */
  480. tmd->tbuf_bcnt = 0; /* no message byte count yet */
  481. tmd->tbuf_tmd3 = 0; /* no error status yet */
  482. tmd->es_tmd1.es_tmd1b |= estmd1_ENP; /* buffer is end of packet */
  483. tmd->es_tmd1.es_tmd1b |= estmd1_STP; /* buffer is start of packet */
  484. tmd++; /* step to next message descriptor */
  485. buf += (ls->bufSize); /* step to start of next buffer */
  486. }
  487.     ls->ls_tindex = 0; /* ESTAR */
  488.     ls->ls_dindex = 0; /* buffer disposal will lag tindex */
  489.     ib = ls->ib;
  490.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  491.         ib->esIBMode = 0x8000; /* chip will be in promiscuous receive mode */
  492.     else
  493.         ib->esIBMode = 0; /* chip will be in normal receive mode */
  494.     swab ((char *)ls->ls_enaddr, ib->esIBPadr, 6);
  495.     ib->esIBRdraLow = (u_short)((int)ls->ls_rring);
  496.     ib->esIBRdraHigh = (u_short)(((int)ls->ls_rring >> 16) & 0xff)
  497.         | (ls->ls_rpo2 << 13);
  498.     ib->esIBTdraLow = (u_short)((int)ls->ls_tring);
  499.     ib->esIBTdraHigh = (u_short)(((int)ls->ls_tring >> 16) & 0xff)
  500.         | (ls->ls_tpo2 << 13);
  501.     }
  502. /*******************************************************************************
  503. *
  504. * esInt - handle controller interrupt
  505. *
  506. * This routine is called at interrupt level in response to an interrupt from
  507. * the controller.
  508. */
  509. LOCAL VOID esInt
  510.     (
  511.     FAST struct ls_softc  *ls
  512.     )
  513.     {
  514.     FAST ES_DEVICE *dv;
  515.     FAST es_rmd *rmd;
  516.     FAST es_tmd *tmd;
  517.     FAST int  *pDindex;
  518.     FAST int *pTindex;
  519.     FAST int *pTsize;
  520.     FAST es_tmd *pTring;
  521.     FAST u_short w, temp;
  522.     FAST int i;
  523.     FAST char *buf;
  524.     
  525.     dv = ls->devAdrs;
  526.     *dlan.dlcr1 = 0x00; /* clear transmit masks */
  527.     *dlan.dlcr3 = 0x00; /* clear receive masks */
  528.     /* read any receive packets */
  529.     while (!(*dlan.dlcr5 & 0x40))
  530.     {
  531. *dlan.dlcr2 = 0x80; /* clear pkt_rdy */
  532. rmd = ls->ls_rring + recIndex;
  533. recIndex = (recIndex + 1) & (ls->ls_rsize - 1);
  534. rmd->es_rmd1.es_rmd1b &= ~esrmd1_OWN;  /* rbuf_own = 0; */
  535. buf = (char *) ((u_int) ls->rmd_ring.r_bufs +
  536.       (u_int) ((((u_int)rmd - (u_int)ls->ls_rring) / sizeof(es_rmd))
  537.       * ls->bufSize));
  538. temp = esReadBmpr0 (dv); /* read status */
  539. if (newdlan == TRUE) {
  540. temp = esReadBmpr0 (dv); /* and count */
  541. i = (temp>>8 | temp<<8) & 0xffff;
  542. rmd->rbuf_mcnt = i; /* save count */
  543. rmd->es_rmd1.es_rmd1b |= esrmd1_STP;  /* rbuf_stp = 1; */
  544. rmd->es_rmd1.es_rmd1b |= esrmd1_ENP;  /* rbuf_enp = 1; */
  545. while (i > 0)
  546. {
  547.     w = esReadBmpr0 (dv);
  548.     *(u_short *)buf = w;
  549.     buf +=2;
  550.     i -= 2; /* count down */
  551. }
  552. }
  553. else {
  554. i = esReadBmpr0 (dv); /* and count */
  555. rmd->rbuf_mcnt = i; /* save count */
  556. rmd->es_rmd1.es_rmd1b |= esrmd1_STP;  /* rbuf_stp = 1; */
  557. rmd->es_rmd1.es_rmd1b |= esrmd1_ENP;  /* rbuf_enp = 1; */
  558. while (i > 0)
  559. {
  560.     w = esReadBmpr0 (dv);
  561.     *(u_short *)buf = (w>>8 | w<<8);
  562.     buf +=2;
  563.     i -= 2; /* count down */
  564. }
  565. }
  566.     }
  567.     if (*dlan.dlcr2 & es_bus_rd_err)
  568. *dlan.dlcr2 = es_bus_rd_err;
  569.     if ((rmd = esGetFullRMD (ls)) != NULL)
  570. {
  571. if ((ls->ls_flags & LS_RCV_HANDLING_FLAG) == 0)
  572.     {
  573.     ls->ls_flags |= LS_RCV_HANDLING_FLAG;
  574.     (void) netJobAdd ((FUNCPTR) esHandleRecvInt, (int) ls, 0, 0, 0, 0);
  575.     }
  576. }
  577.     /* Did etherstar update any of the TMD's? */
  578.     if (!(*dlan.dlcr0 & ES_TMT_MASK))
  579. {
  580. *dlan.dlcr3 = ES_RCV_MASK;
  581. return;
  582. }
  583.     *dlan.dlcr1 = 0x00; /* clear transmit mask */
  584.     *dlan.dlcr0 = 0x0f; /* reset error conditions */
  585.     *dlan.dlcr2 = 0x4f; /* reset packet ready */
  586.     pDindex = &ls->ls_dindex;
  587.     pTindex = &ls->ls_tindex;
  588.     pTsize  = &ls->ls_tsize;
  589.     pTring  = ls->ls_tring;
  590.     while (*pDindex != *pTindex)
  591.         {
  592. /* disposal has not caught up */
  593. tmd = pTring + *pDindex;
  594. /* if the buffer is still owned by ESTAR, don't touch it */
  595. if (tmd->tbuf_tmd1 & TMD_OWN)
  596.     {
  597.     break;
  598.     }
  599. /*
  600.  * tbuf_err (TMD1.ERR) is an "OR" of LCOL, LCAR, UFLO or RTRY.
  601.  * Note that BUFF is not indicated in TMD1.ERR.
  602.  * We should therefore check both tbuf_err and tbuf_buff
  603.  * here for error conditions.
  604.  */
  605. if ((tmd->tbuf_tmd1 & TMD_ERR) || (tmd->tbuf_tmd3 & TMD_BUFF))
  606.     {
  607.     ls->ls_if.if_oerrors++; /* output error */
  608.     ls->ls_if.if_opackets--;
  609.     /* check for no carrier */
  610.     if (tmd->tbuf_tmd3 & TMD_LCAR)
  611. logMsg ("es%d: no carriern", ls->ls_if.if_unit, 0, 0, 0, 0, 0);
  612.     /* every esLogCount errors show other interesting bits of tmd3 */
  613.     if ((tmd->tbuf_tmd3 & 0xfc00) && esLogCount &&
  614. (ls->ls_if.if_oerrors % esLogCount) == 0)
  615. logMsg ("es%d: xmit error, status(tmd3)=0x%x, err count=%dn",
  616. ls->ls_if.if_unit, tmd->tbuf_tmd3 & 0xfc00,
  617. ls->ls_if.if_oerrors, 0, 0, 0);
  618.     /* restart chip on fatal errors */
  619.     if ((tmd->tbuf_tmd3 & TMD_BUFF) || (tmd->tbuf_tmd3 & TMD_UFLO))
  620. {
  621. (void) netJobAdd ((FUNCPTR) esInit,
  622.   ls->ls_if.if_unit, 0, 0, 0, 0);
  623. break;
  624. }
  625.     }
  626. tmd->tbuf_tmd1 &= 0xff; /* clear high byte */
  627. tmd->tbuf_tmd3 = 0; /* clear all error & stat stuff */
  628. /* now bump the tmd disposal index pointer around the ring */
  629. *pDindex = (*pDindex + 1) & (*pTsize - 1);
  630. }
  631.     if (ls->ls_if.if_snd.ifq_head != NULL &&
  632. (ls->ls_flags & LS_START_OUTPUT_FLAG) == 0)
  633. {
  634. ls->ls_flags |= LS_START_OUTPUT_FLAG;
  635. #ifdef BSD43_DRIVER
  636.         (void) netJobAdd ( (FUNCPTR) esStartOutput,
  637.                            ls->ls_if.if_unit, 0, 0, 0, 0);
  638. #else
  639.         (void) netJobAdd ( (FUNCPTR) esStartOutput, (int)ls, 0, 0, 0, 0);
  640. #endif
  641. }
  642.     *dlan.dlcr3 = ES_RCV_MASK;
  643.     }
  644. /*******************************************************************************
  645. *
  646. * esReadBmpr0 - prevents optimizer from stripping required accesses to device
  647. *
  648. * prevents optimizer from stripping required accesses to the device
  649. */
  650. LOCAL u_short esReadBmpr0
  651.     (
  652.     FAST ES_DEVICE *dv
  653.     )
  654.     {
  655.     return ( dv->bmpr0);
  656.     }
  657. /*******************************************************************************
  658. *
  659. * esHandleRecvInt - task level interrupt service for input packets
  660. *
  661. * This routine is called at task level indirectly by the interrupt
  662. * service routine to do any message received processing.
  663. */
  664. LOCAL VOID esHandleRecvInt
  665.     (
  666.     FAST struct ls_softc *ls
  667.     )
  668.     {
  669.     FAST es_rmd *rmd;
  670.     FAST int  oldIndex;
  671.     do
  672. {
  673. ls->ls_flags |= LS_RCV_HANDLING_FLAG;
  674. while ((rmd = esGetFullRMD (ls)) != NULL)
  675.     {
  676.     /* RMD available */
  677.     oldIndex = ls->ls_rindex;
  678.     if (esRecv (ls, rmd) == OK)
  679. for (; oldIndex != ls->ls_rindex; 
  680.      oldIndex = (oldIndex + 1) & (ls->ls_rsize - 1))
  681.     {
  682.     rmd = ls->ls_rring + oldIndex;
  683.     ES_RMD_GIVE_TO_ESTAR (rmd);
  684.     }
  685.     else
  686.         break;
  687.     }
  688. /*
  689.  * There is a RACE right here.  The ISR could add a receive packet
  690.  * and check the boolean below, and decide to exit.  Thus the
  691.  * packet could be dropped if we don't double check before we
  692.  * return.
  693.  */
  694. ls->ls_flags &= ~LS_RCV_HANDLING_FLAG;
  695. }
  696.   while (esGetFullRMD (ls) != NULL); /* this double check solves the RACE */
  697. {
  698. }
  699.     *dlan.dlcr3 = ES_RCV_MASK;
  700.     }
  701. /*******************************************************************************
  702. *
  703. * esRecv - process Ethernet receive completion
  704. *
  705. * Process Ethernet receive completion:
  706. * If input error just drop packet.
  707. * Otherwise purge input buffered data path and examine 
  708. * packet to determine type.  If can't determine length
  709. * from type, then have to drop packet.  Otherwise decapsulate
  710. * packet based on type and pass to type-specific higher-level
  711. * input routine.
  712. *
  713. * RETURNS: ERROR if RMD shouldn't be returned back to ESTAR yet.
  714. *          Otherwise, returns OK to return the RMD back to ESTAR.
  715. */
  716. LOCAL STATUS esRecv
  717.     (
  718.     struct ls_softc    *ls,
  719.     FAST es_rmd    *rmd
  720.     )
  721.     {
  722.     FAST struct ether_header *eh;
  723.     FAST struct mbuf *m;
  724.     FAST u_char *pData;
  725.     int len;
  726.     int off;
  727. #ifdef BSD43_DRIVER
  728.     u_short ether_type;
  729. #endif
  730.     /*
  731.      * If both STP and ENP are set, ESTAR didn't try to
  732.      * use data chaining.
  733.      */
  734.     if (((rmd->es_rmd1.es_rmd1b & esrmd1_STP) == esrmd1_STP) &&
  735. ((rmd->es_rmd1.es_rmd1b & esrmd1_ENP) == esrmd1_ENP))
  736. {
  737. len = rmd->rbuf_mcnt;
  738. ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  739. }
  740.     else
  741. {
  742. ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);
  743. ++ls->ls_if.if_ierrors;
  744. if (esLogCount && (ls->ls_if.if_ierrors % esLogCount) == 0)
  745.     logMsg ("es%d: receive error, stp %d enp %dn",
  746.     ls->ls_if.if_unit,
  747.     (rmd->es_rmd1.es_rmd1b & esrmd1_STP) >> 9,
  748.     (rmd->es_rmd1.es_rmd1b & esrmd1_ENP) >> 8, 0, 0, 0);
  749. return (OK); /* intentional */
  750. }
  751.     /*
  752.     eh = (struct ether_header *)(rmd->rbuf_ladr | (rmd->rbuf_hadr << 16));
  753.     ItoK (eh, struct ether_header *, ls->memBase);
  754.     */
  755.     ++ls->ls_if.if_ipackets;    /* bump statistic */
  756.     eh =(struct ether_header *) ((u_int) ls->rmd_ring.r_bufs +
  757. (u_int) ((((u_int)rmd - (u_int)ls->ls_rring) / sizeof(es_rmd))
  758. * ls->bufSize));
  759.     /* call input hook if any */
  760.     if ((etherInputHookRtn != NULL) &&
  761. (* etherInputHookRtn) (&ls->ls_if, (char *)eh, len))
  762. return (OK);
  763. #ifdef BSD43_DRIVER
  764.     /* This legacy code is not correct for the BSD 4.4 stack. It would
  765.      * also treat multicast addresses like alien packets, and not send
  766.      * them up the stack. The higher-level protocols in the new stack
  767.      * can handle these addresses, and will discard them if they do not
  768.      * match an existing multicast group.
  769.      */
  770.     /* do software filter if controller is in promiscuous mode */
  771.     if (ls->ls_flags & LS_PROMISCUOUS_FLAG)
  772. if ( (bcmp ( (char *)eh->ether_dhost, /* not our adrs? */
  773.      (char *)ls->ls_enaddr,
  774.     sizeof (eh->ether_dhost)) != 0) &&
  775.      (bcmp ( (char *)eh->ether_dhost, /* not broadcast? */
  776.                      (char *)etherbroadcastaddr,
  777.     sizeof (eh->ether_dhost)) != 0))
  778.             return (OK);
  779. #endif
  780.     if (len >= sizeof (struct ether_header))
  781.         len -= sizeof (struct ether_header);
  782.     else
  783.         len = 0;
  784.     pData = ((u_char *) eh) + (sizeof (struct ether_header));
  785. #ifdef BSD43_DRIVER
  786.     check_trailer (eh, pData, &len, &off, &ls->ls_if);
  787.     if (len == 0)
  788. return (OK);
  789.     ether_type = eh->ether_type;
  790. #endif
  791.     m = NULL;
  792.     /* we can loan out receive buffers from ESTAR receive ring if:
  793.      *
  794.      * 1) canLoanRmd is TRUE.  canLoanRmd is set to TRUE if memWidth
  795.      *    is NONE (no special restriction in copying data in terms of
  796.      *    size and boundary conditions) and each of the buffers in the
  797.      *    ESTAR ring is big enough to hold the maximum sized ethernet
  798.      *    frame (data-chaining is not being used for the input).
  799.      * 2) trailer protocol is not being used for the given input ethernet frame.
  800.      * 3) there is available free buffers that can be used to replace the
  801.      *    rbuf to be loaned out in the free list 'freeBufs'.
  802.      * 4) size of the input ethernet frame is large enough to be used with
  803.      *    clustering.
  804.      */
  805.     
  806.     if (ls->canLoanRmds && off == 0 && ls->nFree > 0 && USE_CLUSTER (len))
  807. {
  808.         m = build_cluster (pData, len, &ls->ls_if, MC_LANCE,
  809.    &(ls->loanRefCnt [ls->ls_rindex]),
  810.    (FUNCPTR)esRmdFree, (int) ls, (int) eh, NULL);
  811. if (m != NULL)
  812.     {
  813.     FAST char *pBuf;
  814.     
  815.     /* get a free buffer from the free list to replace the
  816.      * rbuf loaned out.  replace the rbuf pointers in the RMD
  817.      * to point to the new buffer.
  818.      */
  819.     
  820.     pBuf = ls->freeBufs [--ls->nFree];
  821.     
  822.     rmd->rbuf_ladr = (u_short) ((int) pBuf & 0xff);
  823.     rmd->es_rmd1.es_rmd1b = (rmd->es_rmd1.es_rmd1b & ~esrmd1_HADR)
  824.     | (((int) pBuf >> 16) & esrmd1_HADR);
  825.     }
  826. }
  827.     if (m == NULL)
  828. #ifdef BSD43_DRIVER
  829. /* Instead of calling copy_to_mbufs (), we call bcopy_to_mbufs ()
  830.  * with ls->memWidth as an addtional argument to specify unit of a
  831.  * copy op.
  832.  *
  833.  * Most drivers would use macro copy_to_mbufs (), which will in turn
  834.  * call bcopy_to_mbufs () telling it to use the normal bcopy ().  Some
  835.  * of the on-board ESTAR hardware implementations require that you
  836.  * copy the data by certain number of bytes from dedicated memory
  837.  * to system memory, so ESTAR driver has a es_bcopy () routine that
  838.  * conforms to this requirement.
  839.  */
  840. m = bcopy_to_mbufs (pData, len, off, (struct ifnet *) &ls->ls_if,
  841.     ls->memWidth);
  842. #else
  843.         m = bcopy_to_mbufs (pData, len, 0, &ls->ls_if, ls->memWidth);
  844. #endif
  845.     if (m == NULL)
  846.         ++ls->ls_if.if_ierrors;    /* bump error counter */
  847.     else
  848. #ifdef BSD43_DRIVER
  849.         do_protocol_with_type (ether_type, m, &ls->ls_ac, len);
  850. #else
  851.         do_protocol (eh, m, &ls->ls_ac, len);
  852. #endif
  853.     return (OK);
  854.     }
  855. #ifdef BSD43_DRIVER
  856. /*******************************************************************************
  857. *
  858. * esOutput - Ethernet output routine
  859. *
  860. * Ethernet output routine.
  861. * Encapsulate a packet of type family for the local net.
  862. * Use trailer local net encapsulation if enough data in first
  863. * packet leaves a multiple of 512 bytes of data in remainder.
  864. */
  865. LOCAL int esOutput
  866.     (
  867.     FAST struct ifnet *ifp,
  868.     FAST struct mbuf *m0,
  869.     struct sockaddr *dst
  870.     )
  871.     {
  872.     return (ether_output (ifp, m0, dst, (FUNCPTR) esStartOutput, 
  873.   &ls_softc [ifp->if_unit]->ls_ac));
  874.     }
  875. #endif
  876. /*******************************************************************************
  877. *
  878. * esStartOutput - start pending output
  879. *
  880. * Start output to ESTAR.
  881. * Queue up all pending datagrams for which transmit buffers are available.
  882. * Kick start the transmitter to avoid the polling interval latency.
  883. * This routine is called by esInit (). With BSD 4.3 drivers, it is also called
  884. * by esOutput (). BSD 4.4 drivers use a slightly different model in which it
  885. * is called directly from the generic ether_output() routine.
  886. * It is very important that this routine be executed with splimp set.
  887. * If this is not done, another task could allocate the same tmd!
  888. */
  889. #ifdef BSD43_DRIVER
  890. LOCAL VOID esStartOutput
  891.     (
  892.     int unit
  893.     )
  894.     {
  895.     FAST struct ls_softc *ls = ls_softc [unit];
  896. #else
  897. LOCAL VOID esStartOutput
  898.     (
  899.     struct ls_softc *  ls
  900.     )
  901.     {
  902. #endif
  903.     FAST struct mbuf *m;
  904.     FAST es_tmd *tmd;
  905.     char *buf, *buf0;
  906.     u_short *temp, temp1;
  907.     FAST int len, i;
  908.     FAST int sx;
  909.     FAST int oldLevel;
  910.     ES_DEVICE *dv;
  911.     sx = splimp ();
  912.     dv = ls->devAdrs;
  913.     ls->ls_flags |= LS_START_OUTPUT_FLAG;
  914.     /* Loop placing message buffers in output ring until no more or no room */
  915.     while (ls->ls_if.if_snd.ifq_head != NULL)
  916.         {
  917. /* there is something to send */
  918. if ((tmd = esGetFreeTMD (ls)) == NULL) /* get a transmit buffer */
  919.     break;
  920. IF_DEQUEUE (&ls->ls_if.if_snd, m); /* get head of next mbuf chain */
  921. buf = (char *) ( (u_int) ls->tmd_ring.t_bufs +
  922.                          (u_int) ( ( ( (u_int)tmd - (u_int)ls->ls_tring) / 
  923.                                     sizeof (es_tmd)) * 
  924.                          ls->bufSize));
  925. buf0 = buf;
  926. /* copy packet to write buffer */
  927. temp = (u_short *)buf;
  928. #ifdef BSD43_DRIVER
  929. bcopy_from_mbufs (buf, m, len, ls->memWidth);
  930. #else
  931.         bcopy_from_mbufs (buf, m, len, ls->memWidth);
  932. #endif
  933. len = max (ETHERSMALL, len);
  934. buf += len;
  935. /* call output hook if any */
  936.     
  937. if ((etherOutputHookRtn != NULL) &&
  938.     (* etherOutputHookRtn) (&ls->ls_if, buf, len))
  939.     continue;
  940. /* place a transmit request */
  941.     
  942. oldLevel = intLock (); /* disable ints during update */
  943. tmd->tbuf_tmd3 = 0; /* clear buffer error status */
  944. tmd->tbuf_bcnt = -len; /* negative message byte count */
  945. tmd->es_tmd1.es_tmd1b |= estmd1_ENP; /* buffer is end of packet */
  946. tmd->es_tmd1.es_tmd1b |= estmd1_STP; /* buffer is start of packet */
  947. tmd->es_tmd1.es_tmd1b &= ~estmd1_DEF; /* clear status bit */
  948. tmd->es_tmd1.es_tmd1b &= ~estmd1_MORE;
  949. tmd->es_tmd1.es_tmd1b &= ~estmd1_ERR;
  950. /* try to output here */
  951. *dlan.dlcr1 = 0; /* disable ints during update */
  952. i=0; /* extract the buffer */
  953. if (newdlan == TRUE) 
  954.             {
  955.             while (i*2 < len)
  956.                 {
  957.                 if (i*2 < (buf - buf0))
  958.                     dv->bmpr0 = *temp++;
  959.                 else 
  960.                     dv->bmpr0 = 0;
  961.                 i += 1;
  962. }
  963.             temp1 = (u_short)((len>>8) | (len<<8) | 0x80); /* set TMST */
  964.             dv->bmpr2 = temp1;
  965.             }
  966.         else 
  967.             {
  968.             while (i*2 < len)
  969.                 {
  970.                 if (i*2 < (buf - buf0))
  971.                     {
  972.                     dv->bmpr0 = (*temp>>8 | *temp<<8);
  973.                     temp++;
  974.                     }
  975.                 else 
  976.                     dv->bmpr0 = 0;
  977.                 i += 1;
  978.                 }
  979.             dv->bmpr2 = (u_short)(len | 0x8000); /* set TMST */
  980.             }
  981. while ( (*dlan.dlcr0 & es_tmt_ok) == es_tmt_ok)
  982.             ;
  983. intUnlock (oldLevel); /* now esInt won't get confused */
  984. ls->ls_tindex = (ls->ls_tindex + 1) & (ls->ls_tsize - 1);
  985. #ifndef BSD43_DRIVER    /* BSD 4.4 ether_output() doesn't bump statistic. */
  986.         ls->ls_if.if_opackets++;
  987. #endif
  988.         }
  989.     ls->ls_flags &= ~LS_START_OUTPUT_FLAG;
  990.     *dlan.dlcr1 = ES_TMT_MASK; /* set transmit interrupt mask */
  991.     splx (sx);
  992.     }
  993. /*******************************************************************************
  994. *
  995. * esIoctl - Process an ioctl request
  996. *
  997. * Process an ioctl request.
  998. */
  999. LOCAL int esIoctl
  1000.     (
  1001.     FAST struct ifnet *ifp,
  1002.     int  cmd,
  1003.     caddr_t  data
  1004.     )
  1005.     {
  1006.     int    unit = ifp->if_unit;
  1007.     FAST struct ls_softc  *ls = ls_softc [unit];
  1008.     int    s = splimp ();
  1009.     int    error = 0;
  1010.     switch (cmd)
  1011. {
  1012. case SIOCSIFADDR:
  1013.             ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;
  1014.             arpwhohas (ifp, &IA_SIN (data)->sin_addr);
  1015.     break;
  1016. case SIOCGIFADDR:
  1017.     bcopy((caddr_t) ls->ls_enaddr,
  1018.   (caddr_t) ((struct ifreq *)data)->ifr_addr.sa_data, 6);
  1019.     break;
  1020. case SIOCGIFFLAGS:
  1021.     *(short *)data = ifp->if_flags;
  1022.     break;
  1023. case SIOCSIFFLAGS:
  1024.     ls->ls_if.if_flags = ifp->if_flags;
  1025.     if (ifp->if_flags & IFF_PROMISC)
  1026.         ls->ls_flags |= LS_PROMISCUOUS_FLAG;
  1027.     else
  1028.         ls->ls_flags &= ~LS_PROMISCUOUS_FLAG;
  1029.     if (ifp->if_flags & IFF_UP)
  1030. ls->ls_if.if_flags |= (IFF_UP|IFF_RUNNING);
  1031.     else
  1032.         ls->ls_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
  1033.     break;
  1034. default:
  1035.     error = EINVAL;
  1036. }
  1037.     splx (s);
  1038.     return (error);
  1039.     }
  1040. /*******************************************************************************
  1041. *
  1042. * esChipReset - hardware reset of chip (stop it)
  1043. */
  1044. LOCAL VOID esChipReset
  1045.     (
  1046.     struct ls_softc  *ls
  1047.     )
  1048.     {
  1049.     *dlan.dlcr1 = 0; /* reset transmit interrupt mask */
  1050.     *dlan.dlcr3 = 0; /* reset receive interrupt mask  */
  1051.     *dlan.dlcr6 = es_ena_dlc; /* stop the etherstar            */
  1052.     *dlan.dlcr2 = 0xcf; /* clear interrupts */
  1053.     *dlan.dlcr0 = 0x0f;
  1054.     }
  1055. /*******************************************************************************
  1056. *
  1057. * esChipInit - hardware init of chip (init & start it)
  1058. */
  1059. LOCAL VOID esChipInit
  1060.     (
  1061.     FAST struct ls_softc  *ls
  1062.     )
  1063.     {
  1064.     u_short temp;
  1065.     FAST ES_DEVICE *dv = ls->devAdrs;
  1066.     /* setup vector */
  1067.     dv->eth_vector =  ls->ivec;
  1068.  
  1069.     *dlan.dlcr6 = es_ena_dlc; /* stop the etherstar */
  1070.     *dlan.dlcr2 = 0xcf; /* clear all receive errors */
  1071.     *dlan.dlcr3 = 0x8f; /* reset receive interrupt mask */
  1072.     *dlan.dlcr0 = 0x0f; /* clear all transmit errors  */
  1073.     *dlan.dlcr1 = 0x00; /* reset transmit interrupt mask */
  1074.     /* flush the receive buffer memory of the etherstar */
  1075.     temp = esReadBmpr0 (dv);
  1076.     while ( !(*dlan.dlcr5 & 0x40) ) temp = esReadBmpr0 (dv);
  1077.     temp = esReadBmpr0 (dv);
  1078.     temp = esReadBmpr0 (dv);
  1079.     /* configure etherstar in normal mode */
  1080.     *dlan.dlcr4 = es_lbc; /* loopback disabled, byte swap enabled */
  1081.     *dlan.dlcr5 = 0x02; /* physical, multicast and broadcast  */
  1082.     /* copy the enet address into the softc */
  1083.     *dlan.dlcr8 = esEnetAddr[0];
  1084.     *dlan.dlcr9 = esEnetAddr[1]; /* setting these registers is only */
  1085.     *dlan.dlcr10 = esEnetAddr[2]; /* possible when etherstar is stopped */
  1086.     *dlan.dlcr11 = esEnetAddr[3];
  1087.     *dlan.dlcr12 = esEnetAddr[4];
  1088.     *dlan.dlcr13 = esEnetAddr[5];
  1089.     for ( temp = 20000; temp > 0; temp-- );
  1090.     /* start chip */
  1091.     *dlan.dlcr6 = 0x00; /* start the etherstar */
  1092.     *dlan.dlcr1 = ES_TMT_MASK; /* set transmit interrupt mask */
  1093.     *dlan.dlcr3 = ES_RCV_MASK; /* set receive interrupt mask */
  1094.     }
  1095. /*******************************************************************************
  1096. *
  1097. * esGetFreeTMD - get next available TMD
  1098. */
  1099. LOCAL es_tmd *esGetFreeTMD
  1100.     (
  1101.     FAST struct ls_softc  *ls
  1102.     )
  1103.     {
  1104.     FAST es_tmd   *tmd;
  1105.     /* check if buffer is available (owned by host) */
  1106.     /* also check for tindex overrun onto dindex */
  1107.     tmd = ls->ls_tring + ls->ls_tindex;
  1108.     if (((tmd->es_tmd1.es_tmd1b & estmd1_OWN) != 0)
  1109. || (((ls->ls_tindex + 1) & (ls->ls_tsize - 1)) == ls->ls_dindex))
  1110.         tmd = (es_tmd *) NULL;
  1111.     return (tmd);
  1112.     }
  1113. /*******************************************************************************
  1114. *
  1115. * esGetFullRMD - get next received message RMD
  1116. */
  1117. LOCAL es_rmd *esGetFullRMD
  1118.     (
  1119.     FAST struct ls_softc  *ls
  1120.     )
  1121.     {
  1122.     FAST es_rmd   *rmd;
  1123.     /* check if buffer is full (owned by host) */
  1124.     rmd = ls->ls_rring + ls->ls_rindex;
  1125.     if ((rmd->es_rmd1.es_rmd1b & esrmd1_OWN) == 0)
  1126. return (rmd);
  1127.     else
  1128. return ((es_rmd *) NULL);
  1129.     }
  1130. /*******************************************************************************
  1131. *
  1132. * esRmdFree - called when loaned out rbuf is freed by MCLFREE.
  1133. *
  1134. * Puts the loaned out rbuf into free list to be reused as loan replacements.
  1135. */
  1136. LOCAL VOID esRmdFree
  1137.     (
  1138.     FAST struct ls_softc *ls,
  1139.     FAST char  *pBuf
  1140.     )
  1141.     {
  1142.     ls->freeBufs [ls->nFree++] = pBuf;
  1143.     }