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

VxWorks

开发平台:

C/C++

  1. /* gei82543End.c - Intel PRO/1000 F/T/XF/XT/MT/MF network adapter END driver */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01m,23may02,jln  support 82545/82546 fiber-based adapter(spr 78084)
  8.                  clean interrupts only when packets can be processed 
  9. 01l,02may02,jln  support 82540/82545/82546 based adapters spr # 76739;
  10.                  stop device only after device has been started spr # 76511
  11.                  change input argument from vector to unit in SYS_INT_ENABLE
  12.                  and SYS_INT_DISABLE macros
  13. 01k,22apr02,rcs  changed gei82543MemAllFree() to use free for 
  14.                  pDrvCtrl->pTxDesCtlBase SPR# 76130   
  15. 01j,22apr02,rcs  removed taskDelay() from gei82543EndPollSend() SPR# 76102
  16. 01i,14jan02,dat  Removing warnings from Diab compiler
  17. 01h,08nov01,jln  coding workaround for TBI compatibility HW bug (spr# 71363),
  18.                  but disable it by default for testing issues. 
  19. 01g,01sep01,jln  clean up documentation
  20. 01f,10aug01,jln  add support for 82544-based adapters spr# 69774; remove 
  21.                  copying method for transmitting; add support for jumbo 
  22.                  frames spr# 67477 
  23. 01e,03may01,jln  fix memory leak in gei82543EndStop (spr# 67116);
  24.                  added read operation before exit ISR to flush write buffer
  25.                  for PCI bridge; polish TX/RX handling
  26. 01d,01may01,jln  change MACRO(s) GEI_READ_REG, GEI_READ_DESC_WORD, and 
  27.                  GEI_READ_DESC_LONG for coding convention
  28. 01c,19apr01,jln  clean up for spr#65326
  29. 01b,01apr01,jln  clean up after code review (partial spr#65326).
  30. 01a,08jan01,jln  created based on templateEnd.c and fei82557End.c END scheme
  31. */
  32. /*
  33. DESCRIPTION
  34. The gei82543End driver supports Intel PRO1000 T/F/XF/XT/MT/MF adaptors
  35. These adaptors use Intel 82543GC, 82544GC/EI, or 82540/82545/82546EB Gigabit 
  36. Ethernet controllers.The 8254x are highly integrated, high-performance LAN 
  37. controllers for 1000/100/10Mb/s transfer rates. They provide 32/64 bit 33/66Mhz 
  38. interfaces to the PCI bus with 32/64 bit addressing and are fully compliant 
  39. with PCI bus specification version 2.2. The 82544, 82545 and 82546 also 
  40. provide PCI-X interface.
  41. The 8254x controllers implement all IEEE 802.3 receive and transmit 
  42. MAC functions. They provide a Ten-Bit Interface (TBI) as specified in the IEEE 
  43. 802.3z standard for 1000Mb/s full-duplex operation with 1.25 GHz Ethernet 
  44. transceivers (SERDES), as well as a GMII interface as specified in 
  45. IEEE 802.3ab for 10/100/1000 BASE-T transceivers, and also an MII interface as 
  46. specified in IEEE 802.3u for 10/100 BASE-T transceivers. 
  47. The 8254x controllers offer auto-negotiation capability for TBI and GMII/MII 
  48. modes and also support IEEE 802.3x compliant flow control. Although these 
  49. devices also support other advanced features such as receive and transmit 
  50. IP/TCP/UDP checksum offloading, jumbo frames, and provide flash support up 
  51. to 512KB and EEPROM support, this driver does NOT support these features. 
  52. The 8254x establishes a shared memory communication system with the 
  53. CPU, which is divided into two parts: the control/status registers and the
  54. receive/transmit descriptors/buffers. The control/status registers
  55. are on the 8254x chips and are only accessible with PCI or PCI-X 
  56. memory cycles, whereas the other structures reside on the host. The buffer 
  57. size can be programmed between 256 bytes to 16k bytes. This driver uses the
  58. receive buffer size of 2048 bytes for an MTU of 1500. 
  59. The Intel PRO/1000 F/XF/MF adapters only implement the TBI mode of the
  60. 8254x controller with built-in SERDESs in the adaptors.
  61. The Intel PRO/1000 T adapters based on 82543GC implement the GMII mode with 
  62. a Gigabit Ethernet Transceiver (PHY) of MARVELL's Alaska 88E1000/88E1000S. 
  63. However, the PRO/1000 XT/MT adapters based on 82540/82544/82545/82546 use 
  64. the built-in PHY in controllers.
  65. The driver on the current release supports both GMII mode for Intel 
  66. PRO1000T/XT/MT adapers and TBI mode for Intel PRO1000 F/XF/MF adapters. However,
  67. it requires the target-specific initialization code (sys543BoardInit ()) 
  68. to distinguish these kinds of adapters by PCI device IDs. 
  69. EXTERNAL INTERFACE
  70. The driver provides the standard external interface, gei82543EndLoad(), which
  71. takes a string of colon separated parameters. The parameter string is parsed 
  72. using strtok_r() and each parameter in converted from a string representation
  73. to a binary.
  74. The format of the parameter string is:
  75.  "<memBase>:<memSize>:<nRxDes>:<nTxDes>:<flags>:<offset>:<mtu>"
  76.  
  77. TARGET-SPECIFIC PARAMETERS
  78. .IP <memBase>
  79. This parameter is passed to the driver via gei82543EndLoad().
  80. The 8254x is a DMA-type device and typically shares access to some region of
  81. memory with the CPU. This driver is designed for systems that directly share 
  82. memory between the CPU and the 8254x.
  83. This parameter can be used to specify an explicit memory region for use
  84. by the 8254x chip.  This should be done on targets that restrict the 8254x
  85. to a particular memory region.  The constant `NONE' can be used to indicate 
  86. that there are such memory, in which case the driver will allocate cache safe
  87. memory for its use using cacheDmaAlloc().
  88. .IP <memSize>
  89. The memory size parameter specifies the size of the pre-allocated memory 
  90. region. The driver checks the size of the provided memory region is adequate 
  91. with respect to the given number of transmit Descriptor and Receive 
  92. Descriptor.
  93. .IP <nRxDes>
  94. This parameter specifies the number of transmit descriptors to be
  95. allocated. If this number is 0, a default value of 24 will be used.
  96. .IP <nTxDes>
  97. This parameter specifies the number of receive descriptors to be
  98. allocated. If this parameter is 0, a default of 24 is used.
  99. .IP <flags>
  100. This parameter is provided for user to customize this device driver for their
  101. application. 
  102. GEI_END_SET_TIMER (0x01): a timer will be started to constantly free back the 
  103. loaned transmit mBlks.
  104. GEI_END_SET_RX_PRIORITY (0x02): packet transfer (receive) from device to host
  105. memory will have higher priority than the packet transfer (transmit) from host
  106. memory to device in the PCI bus. For end-station application, it is suggested
  107. to set this priority in favor of receive operation to avoid receive overrun.
  108. However, for routing applications, it is not necessary to use this priority.
  109. This option is only for 82543-based adapters. 
  110. GEI_END_FREE_RESOURCE_DELAY (0x04): when transmitting larger packets, the 
  111. driver will hold mblks(s) from the network stack and return them after the 
  112. driver has completed transmitting the packet, and either the timer has expired 
  113. or there are no more available descriptors. If this option is not used, the 
  114. driver will free mblk(s) when ever the packet transmission is done. This option
  115. will place greater demands on the network pool and should only be used in 
  116. systems which have sufficient memory to allocate a large network pool. It is 
  117. not advised for the memory-limited target systems.
  118. GEI_END_TBI_COMPATIBILITY (0x200): if this driver enables the workaround for 
  119. TBI compatibility HW bugs (#define INCLUDE_TBI_COMPATIBLE), user can set 
  120. this bit to enable a software workaround for the well-known TBI compatibility 
  121. HW bug in the Intel PRO1000 T adapter. This bug is only occured in the 
  122. copper-and-82543-based adapter, and the link partner has advertised only 
  123. 1000Base-T capability.
  124.  
  125. .IP <offset>
  126. This parameter is provided for the architectures which need DWORD (4 byte) 
  127. alignment of the IP header. In that case, the value of OFFSET should be two, 
  128. otherwise, the default value is zero.
  129. .LP
  130.  
  131. EXTERNAL SUPPORT REQUIREMENTS
  132. This driver requires one external support function:
  133. .CS
  134. STATUS sys82543BoardInit (int unit, ADAPTOR_INFO *pBoard)
  135. .CE
  136. This routine performs some target-specific initialization such as EEPROM 
  137. validation and obtaining ETHERNET address and initialization control words 
  138. (ICWs) from EEPROM. The routine also initializes the adaptor-specific data 
  139. structure. Some target-specific functions used later in driver operation 
  140. are hooked up to that structure. It's strongly recommended that users provide
  141. a delay function with higher timing resolution. This delay function will be 
  142. used in the PHY's read/write operations if GMII is used. The driver will use 
  143. taskDelay() by default if user can NOT provide any delay function, and 
  144. this will probably result in very slow PHY initialization process. The user 
  145. should also specify the PHY's type of MII or GMII. This routine returns OK, 
  146. or ERROR if it fails.
  147. .LP
  148. SYSTEM RESOURCE USAGE
  149. The driver uses cacheDmaMalloc() to allocate memory to share with the 8254xGC.
  150. The size of this area is affected by the configuration parameters specified
  151. in the gei82543EndLoad() call. 
  152. Either the shared memory region must be non-cacheable, or else the hardware 
  153. must implement bus snooping. The driver cannot maintain cache coherency for 
  154. the device because fields within the command structures are asynchronously 
  155. modified by both the driver and the device, and these fields may share the 
  156. same cache line.
  157. SYSTEM TUNING HINTS
  158. Significant performance gains may be had by tuning the system and network stack.
  159. This may be especially necessary for achiving gigabit transfer rates. 
  160. Increasing the network stack's pools are strongly recommended. This driver 
  161. borrows mblks from the network stack to accerlate packet transmitting. 
  162. Theoretically, the number borrowed clusters could be the same as the number of 
  163. the device's transmit descriptors. However, if the network stack has fewer 
  164. available clusters than available transmit descriptors then this will result 
  165. in reduced throughput. Therefore, increasing the network stack's number of 
  166. clusters relative to the number of transmit descriptors will increase bandwidth.
  167. Of course this technique will eventually reach a point of diminishing return. 
  168. There are actually several sizes of clusters available in the network pool.
  169. Increasing any or all of these cluster sizes will result in some increase in 
  170. performance. However, increasing the 2048-byte cluster size will likely have 
  171. the greatest impact since this size will hold an entire MTU and header.
  172. Increasing the number of receive descriptors and clusters may also have 
  173. positive impact.
  174. Increasing the buffer size of sockets can also be beneficial. This can
  175. significantly improve performance for a target system under higher transfer 
  176. rates. However, it should be noted that large amounts of unread buffers idling 
  177. in sockets reduces the resources available to the rest of the stack. This can, 
  178. in fact, have a negative impact on bandwidth.  One method to reduce this effect
  179. is to carefully adjust application tasks' priorities and possibly increase 
  180. number of receive clusters.
  181. Callback functions defined in the sysGei82543End.c can be used to dynamically 
  182. and/or statically change the internal timer registers such as ITR, RADV, and 
  183. RDTR to reduce RX interrupt rate.
  184. INTERNAL
  185. This library contains two conditional compilation switchs: DRV_DEBUG and  
  186. INCLUDE_GEI82543_DEBUG_ROUTINE. If defined, debug routines will be included.
  187. And output message can be selected by gei82543GCDebug variable.
  188. SEE ALSO: muxLib, endLib
  189. .I "RS-82543GC GIGABIT ETHERNET CONTROLLER NETWORKING DEVELOPER'S MANUAL"
  190. */
  191. /* includes */
  192. #include "vxWorks.h"
  193. #include "stdlib.h"
  194. #include "cacheLib.h"
  195. #include "intLib.h"
  196. #include "end.h"                /* common END structures. */
  197. #include "endLib.h"
  198. #include "lstLib.h"             /* needed to maintain protocol list. */
  199. #include "wdLib.h"
  200. #include "iv.h"
  201. #include "semLib.h"
  202. #include "logLib.h"
  203. #include "netLib.h"
  204. #include "stdio.h"
  205. #include "sysLib.h"
  206. #include "errno.h"
  207. #include "errnoLib.h"
  208. #include "memLib.h"
  209. #include "iosLib.h"
  210. #undef    ETHER_MAP_IP_MULTICAST
  211. #include "etherMultiLib.h"      /* multicast stuff. */
  212. #include "net/mbuf.h"
  213. #include "net/unixLib.h"
  214. #include "net/protosw.h"
  215. #include "net/systm.h"
  216. #include "net/if_subr.h"
  217. #include "net/route.h"
  218. #include "sys/socket.h"
  219. #include "sys/ioctl.h"
  220. #include "sys/times.h"
  221. #include "drv/end/gei82543End.h"
  222. /* IMPORT */
  223. IMPORT STATUS sys82543BoardInit (int, ADAPTOR_INFO *);
  224. IMPORT    int endMultiLstCnt (END_OBJ* pEnd);
  225.  
  226. /* defines */
  227. #undef INCLUDE_TBI_COMPATIBLE
  228. /* all 8254x chip registers are 32 bit long*/
  229. #if (_BYTE_ORDER == _BIG_ENDIAN)
  230. #define GEI_READ_REG(offset,result)     
  231.         do {                         
  232.            UINT32 temp;              
  233.            temp = ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset)))); 
  234.            result = LONGSWAP(temp); /* swap the data */  
  235.            } while (0)
  236. #define GEI_WRITE_REG(offset, value) 
  237.         ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset))) = 
  238.         (UINT32) LONGSWAP(value))
  239. #define GEI_WRITE_DESC_WORD(pDesc, offset, value)      
  240.         (*(UINT16 *)((UINT32)pDesc + offset) =    
  241.         (MSB(value) | LSB(value)<<8) & 0xffff)
  242. #define GEI_WRITE_DESC_LONG(pDesc, offset, value)      
  243.         (*(UINT32 *)((UINT32)pDesc + offset) =    
  244.         (UINT32) LONGSWAP(value))
  245. #define GEI_READ_DESC_WORD(pDesc, offset, result)             
  246.         do {                                                  
  247.            UINT16 temp;                                       
  248.            temp = *(UINT16 *)((UINT32)pDesc + offset);        
  249.            result = (MSB(temp) | (LSB(temp) << 8)) & 0xffff;  
  250.            } while (0)
  251. #define GEI_READ_DESC_LONG(pDesc, offset, result)              
  252.         do {                         
  253.            UINT32 temp;              
  254.            temp = *(UINT32 *)((UINT32)pDesc + offset);   
  255.            result = LONGSWAP(temp); /* swap the data */  
  256.            } while (0)
  257. #else /* (_BYTE_ORDER == _BIG_ENDIAN) */
  258. #define GEI_READ_REG(offset, result)     
  259.         result = (*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset)))
  260. #define GEI_WRITE_REG(offset, value) 
  261.         ((*(volatile UINT32 *)(pDrvCtrl->devRegBase + (offset))) = 
  262.         (UINT32)(value))
  263. #define GEI_WRITE_DESC_WORD(pDesc, offset, value)      
  264.         (*(UINT16 *)((UINT32)pDesc + offset) = (UINT16)(value & 0xffff))
  265. #define GEI_WRITE_DESC_LONG(pDesc, offset, value)      
  266.         (*(UINT32 *)((UINT32)pDesc + offset) = (UINT32)value)
  267. #define GEI_READ_DESC_WORD(pDesc, offset, result)              
  268.         result = ((UINT16)(*(UINT16 *)((UINT32)pDesc + offset)) & 0xffff)
  269. #define GEI_READ_DESC_LONG(pDesc, offset, result)              
  270.         result = ((UINT32)( *(UINT32 *)((UINT32)pDesc + offset)))
  271.  
  272. #endif /* (_BYTE_ORDER == _BIG_ENDIAN) */
  273. #define GEI_WRITE_DESC_BYTE(pDesc, offset, value)      
  274.         (*(UINT8 *)((UINT32)pDesc + offset) = (UINT8) (value & 0xff))
  275. #define GEI_READ_DESC_BYTE(pDesc, offset)              
  276.         ((UINT8)( *(UINT8 *)((UINT32)pDesc + offset)) & 0xff)
  277. #define GEI_GET_RX_DESC_ADDR(offset)          
  278.         (pDrvCtrl->pRxDescBase + ((offset) * RXDESC_SIZE))
  279. #define GEI_GET_TX_DESC_ADDR(offset)          
  280.         (pDrvCtrl->pTxDescBase + ((offset) * TXDESC_SIZE))
  281. #define GEI_GET_TX_DESC_CTL_ADDR(offset)      
  282.         (pDrvCtrl->pTxDesCtlBase + (offset));
  283. #define GEI_GET_TX_DESC_TAIL_UPDATE(tmp, num)     
  284.          (tmp) = (pDrvCtrl->txDescTail + (num)) % (pDrvCtrl->txDescNum) 
  285. #define GEI_GET_RX_DESC_TAIL_UPDATE(tmp, num)        
  286.         (tmp) = (pDrvCtrl->rxDescTail + (num)) % (pDrvCtrl->rxDescNum)
  287. #define ROUND_UP_MULTIPLE(x, y)          
  288.         ( ( ( x + ( y - 1 ) ) / y ) * y )
  289. /* bus/CPU address translation macros */
  290. #define GEI_VIRT_TO_BUS(virtAddr)                                           
  291.         (GEI_PHYS_TO_BUS (((UINT32) GEI_VIRT_TO_PHYS (virtAddr))))
  292. #define GEI_BUS_TO_VIRT(busAddr)                                            
  293.         ((GEI_PHYS_TO_VIRT ((UINT32) GEI_BUS_TO_PHYS (busAddr))))
  294. #define GEI_PHYS_TO_VIRT(physAddr)                                          
  295.         END_CACHE_PHYS_TO_VIRT ((char *)(physAddr))
  296. #define GEI_VIRT_TO_PHYS(virtAddr)                                          
  297.         END_CACHE_VIRT_TO_PHYS ((char *)(virtAddr))
  298. #define GEI_PHYS_TO_BUS(physAddr)                                          
  299.         PHYS_TO_BUS_ADDR (pDrvCtrl->unit, (physAddr))
  300. #define GEI_BUS_TO_PHYS(busAddr)                                           
  301.         BUS_TO_PHYS_ADDR (pDrvCtrl->unit, (busAddr))
  302. /* cache macros */
  303. #define END_CACHE_INVALIDATE(address, len) 
  304.         CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))
  305. #define END_CACHE_PHYS_TO_VIRT(address) 
  306.         CACHE_DRV_PHYS_TO_VIRT (&pDrvCtrl->cacheFuncs, (address))
  307. #define END_CACHE_VIRT_TO_PHYS(address) 
  308.         CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))
  309. /* misc. */
  310. #define GEI_DESC_ALIGN_BYTE         (128)
  311. /*
  312.  * Default macro definitions for BSP interface.
  313.  * These macros can be redefined in a wrapper file, to generate
  314.  * a new module with an optimized interface.
  315.  */
  316. /* macro to connect interrupt handler to vector */
  317. #ifndef SYS_INT_CONNECT
  318. #define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)          
  319.     {                                                      
  320.     *pResult = OK;                                         
  321.     if (pDrvCtrl->adaptor.intConnect)                                  
  322.        *pResult = (pDrvCtrl->adaptor.intConnect) ((VOIDFUNCPTR *)      
  323.           INUM_TO_IVEC (pDrvCtrl->adaptor.vector), 
  324.               rtn, (int)arg);                          
  325.     }
  326. #endif
  327. /* macro to disconnect interrupt handler from vector */
  328. #ifndef SYS_INT_DISCONNECT
  329. #define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)        
  330.     {                                                                 
  331.     *pResult = OK;                                                    
  332.     if (pDrvCtrl->adaptor.intDisConnect)                               
  333.        *pResult =  (pDrvCtrl->adaptor.intDisConnect) ((VOIDFUNCPTR *)  
  334.                   INUM_TO_IVEC (pDrvCtrl->adaptor.vector), 
  335.                rtn, (int)arg);                         
  336.     }
  337. #endif
  338. /* macro to enable the appropriate interrupt level */
  339. #ifndef SYS_INT_ENABLE
  340. #define SYS_INT_ENABLE(pDrvCtrl)                            
  341.     {                                                       
  342.     pDrvCtrl->adaptor.intEnable(pDrvCtrl->unit);  
  343.     }
  344. #endif
  345. #ifndef SYS_INT_DISABLE
  346. #define SYS_INT_DISABLE(pDrvCtrl)                           
  347.     {                                                       
  348.     pDrvCtrl->adaptor.intDisable(pDrvCtrl->unit); 
  349.     }
  350. #endif
  351. /* 
  352.  * a shortcut for getting the hardware address
  353.  * from the MIB II stuff. 
  354.  */
  355. #define END_HADDR(pEnd)     
  356.     ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
  357. #define END_HADDR_LEN(pEnd) 
  358.     ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
  359. /* device structure */
  360. typedef struct end_device
  361.     {
  362.     END_OBJ     end;            /* the class we inherit from. */
  363.     int         unit;           /* unit number */
  364.     UINT32      flags;          /* flags for device configuration */
  365.     UINT32      usrFlags;       /* flags for user customization */ 
  366.     CACHE_FUNCS cacheFuncs;     /* cache function pointers */ 
  367.     CL_POOL_ID  pClPoolId;      /* cluster pool ID */
  368.     ADAPTOR_INFO adaptor;       /* adaptor information */
  369.     UINT32      devRegBase;     /* virtual base address for registers */
  370.     P_TX_DESCTL pTxDesCtlBase;  /* pointer to the TX management array base */
  371.     char        *pTxDescBase;   /* pointer to the TX descriptor base */
  372.     char        *pRxDescBase;   /* pointer to the RX descriptor base */
  373.     char *      pRxBufBase;     /* pointer to the RX buffer base */
  374.     volatile int txDescTail;    /* index to the TX tail */
  375.     volatile int rxDescTail;    /* index to the RX tail */    
  376.     int         txDescNum;      /* num of TX descriptors */
  377.     int         rxDescNum;      /* num of RX descriptors */
  378.     UINT32      rxBufSize;      /* RX buffer size */
  379.     UINT32      txReqDescNum;   /* request number for TX descriptor */        
  380.     int         mtu;            /* maximum transfer unit */
  381.     volatile int rxtxHandling;  /* indicator for RX handling */
  382.     volatile BOOL txStall;      /* indicator for transmit stall */
  383.     BOOL        txActivity;     /* TX activity flag */
  384.     int         txIntDelay;     /* delay time for TX interrupt */
  385.     int         rxIntDelay;     /* delay time for RX interrupt */
  386.     int         maxRxNumPerInt; /* maximum RX packets processed per Int */     
  387.     BOOL        dmaPriority;    /* indicator for TX/RX DMA prefer */
  388.     UINT32      timerInterval;  /* interval for timer interrupt */
  389.     BOOL        timerCheckTxStall; /* indicator for txStall checking */
  390.     UINT32      multiCastFilterType; /* indicator of multicast table type */ 
  391.     int         flowCtrl;       /* flow control setting */
  392.     STATUS      linkInitStatus; /* the status of first link */
  393.     volatile UINT32 linkStatus; /* indicator for link status */
  394.     BOOL        linkMethod;     /* indicator for link approaches */
  395.     WDOG_ID     timerId;        /* timer ID */
  396.     UINT32      txConfigureWord; /* copy of TX configuration word register */
  397.     UINT32      devCtrlRegVal;  /* control register value */
  398.     UINT32      speed;          /* device speed */
  399.     UINT32      duplex;         /* device duplex mode */
  400.     UINT32      offset;         /* offset for IP header */
  401.     UINT32      cableType;      /* cable type (Fiber or Copper) */
  402.     BOOL        memAllocFlag;   /* indicator that the shared memory */
  403.                                    /* allocated by driver */
  404.     char *      pMemBase;       /* memory base for TX/RX area */
  405.     int         memSize;        /* total memory size for RX/TX area */
  406.     char *      pMclkArea;      /* address of Mclk */
  407.     char *      pTxPollBufAdr;   /* address for TX buffer in polling mode */
  408.     PHY_INFO *  pPhyInfo;       /* pointer to phyInfo structure */
  409.     UINT32      phyInitFlags;   /* Initial PHY flags for phyInfo */
  410.     volatile UINT32 txDescLastCheck; /* index of the last checked TX desc */
  411.     volatile UINT32 txDescFreeNum;   /* available/usable TX desc number */
  412.     STA_REG     staRegs;         /* statistic register structure */
  413.     BOOL        txResoFreeQuick; /* flag to free loaned mBlk quickly */  
  414.     volatile BOOL attach;        /* indicator for drive attach */
  415.     volatile BOOL devStartFlag;  /* indicator for device start */
  416.     UINT32      rxtxHandlerNum;  /* num of rxtx handler calling */
  417.     UINT32      rxIntCount;      /* receive interrupt count */
  418.     UINT32      txIntCount;  /* transmit interrupt count */
  419.     UINT32      rxORunIntCount;  /* num of RX overrun interrupt count */
  420.     UINT32      rxPacketNum;  /* statistic RX packet number */
  421.     UINT32      rxPacketDrvErr ; /* num of RX packet drop due to no resc */
  422. #ifdef INCLUDE_TBI_COMPATIBLE
  423.     BOOL        tbiCompatibility; /* TBI compatibility for HW bug */
  424. #endif
  425.     } END_DEVICE;
  426. /* DEBUG MACROS */
  427. #undef  DRV_DEBUG
  428. #undef  INCLUDE_GEI82543_DEBUG_ROUTINE
  429. #undef  GEI82543_NO_LOCAL
  430. #ifdef DEBUG 
  431. #define LOGMSG(x,a,b,c,d,e,f) 
  432.    if (endDebug)               
  433.       {                       
  434.       logMsg (x,a,b,c,d,e,f); 
  435.       }
  436. #else
  437. #define LOGMSG(x,a,b,c,d,e,f)
  438. #endif /* DEBUG */
  439. #ifdef GEI82543_NO_LOCAL
  440. #undef     LOCAL
  441. #define    LOCAL
  442. #endif
  443. #ifdef  DRV_DEBUG
  444. #define DRV_DEBUG_OFF           0x0000
  445. #define DRV_DEBUG_RX            0x0001
  446. #define DRV_DEBUG_TX            0x0002
  447. #define DRV_DEBUG_INT           0x0004
  448. #define DRV_DEBUG_POLL          (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)
  449. #define DRV_DEBUG_POLL_RX       0x0008
  450. #define DRV_DEBUG_POLL_TX       0x0010
  451. #define DRV_DEBUG_LOAD          0x0020
  452. #define DRV_DEBUG_IOCTL         0x0040
  453. #define DRV_DEBUG_TIMER         0x20000
  454. int     gei82543GCDebug = 0x0;
  455. #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)    
  456.     if (gei82543GCDebug & FLG)                      
  457.        logMsg(X0, X1, X2, X3, X4, X5, X6);
  458. #define DRV_PRINT(FLG,X)                            
  459.     if (gei82543GCDebug & FLG) printf X;
  460. #else /* DRV_DEBUG */
  461. #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
  462. #define DRV_PRINT(DBG_SW,X)
  463. #endif /* DRV_DEBUG */      
  464. #ifdef INCLUDE_GEI82543_DEBUG_ROUTINE
  465. LOCAL void gei82543LedOff                         (int);
  466. LOCAL void gei82543LedOn                          (int);
  467. LOCAL void gei82543StatusShow                     (int);
  468. LOCAL UINT32 gei82543RegGet                       (int,UINT32);
  469. LOCAL void gei82543RegSet                         (int,UINT32, UINT32); 
  470. #ifdef INCLUDE_TBI_COMPATIBLE
  471. LOCAL void gei82543TbiCompWr                      (int, int);
  472. #endif /* INCLUDE_TBI_COMPATIBLE */
  473. #endif /* INCLUDE_GEI82543_DEBUG_ROUTINE */
  474. /* forward functions */
  475. LOCAL void      gei82543EndTimerHandler     (END_DEVICE *);
  476. LOCAL void      gei82543MemAllFree          (END_DEVICE *);
  477. LOCAL STATUS    gei82543linkStatusCheck     (END_DEVICE *);
  478. LOCAL void      gei82543TxRxEnable          (END_DEVICE *);
  479. LOCAL void      gei82543TxRxDisable         (END_DEVICE *);
  480. LOCAL void      gei82543Delay               (END_DEVICE *, UINT32);
  481. LOCAL void      gei82543RxSetup             (END_DEVICE *);
  482. LOCAL void      gei82543TxSetup             (END_DEVICE *);
  483. LOCAL STATUS    gei82543HwInit              (END_DEVICE *);
  484. LOCAL void      gei82543RxDesUpdate         (END_DEVICE *,char *); 
  485. LOCAL void      gei82543DuplexGet           (END_DEVICE *);
  486. LOCAL void      gei82543SpeedGet            (END_DEVICE *);
  487. LOCAL void      gei82543HwStatusDump        (END_DEVICE *);
  488. LOCAL STATUS    gei82543linkInit            (END_DEVICE *);
  489. LOCAL STATUS    gei82543linkTBISetup        (END_DEVICE *,BOOL);
  490. LOCAL STATUS    gei82543TBIlinkForce        (END_DEVICE *,BOOL, BOOL);
  491. LOCAL STATUS    gei82543TBIHwAutoNegotiate  (END_DEVICE *,BOOL, BOOL);
  492. LOCAL void      gei82543EtherRxAdrSet       (END_DEVICE *,UINT8 adr[],int);
  493. LOCAL void      gei82543AllRxAdrClean       (END_DEVICE *);
  494. LOCAL void      gei82543McastAdrClean       (END_DEVICE *);
  495. LOCAL void      gei82543AllMtaAdrClean      (END_DEVICE *);
  496. LOCAL void      gei82543AllVlanClean        (END_DEVICE *);
  497. LOCAL UINT32    gei82543DisableChipInt      (END_DEVICE *);
  498. LOCAL void      gei82543EnableChipInt       (END_DEVICE *);
  499. LOCAL void      gei82543Reset               (END_DEVICE *);
  500. LOCAL void      gei82543TxMblkFree          (END_DEVICE *,int);
  501. LOCAL void      gei82543TxMblkWaitClean     (END_DEVICE *);
  502. LOCAL STATUS    gei82543EndMCastAdd         (END_DEVICE *,char*);
  503. LOCAL STATUS    gei82543EndMCastDel         (END_DEVICE *,char*);
  504. LOCAL STATUS    gei82543EndMCastGet         (END_DEVICE *,MULTI_TABLE*);
  505. LOCAL void      gei82543EndInt              (END_DEVICE *);
  506. LOCAL void      gei82543RxTxIntHandle       (END_DEVICE *);
  507. LOCAL STATUS    gei82543Recv                (END_DEVICE *,char *, UINT8);
  508. LOCAL void      gei82543EndConfigure        (END_DEVICE *);
  509. LOCAL void      gei82543FlowCtrlRegsSet     (END_DEVICE *);
  510. LOCAL STATUS    gei82543PhyWrite            (END_DEVICE *,UINT8,UINT8,UINT16);
  511. LOCAL STATUS    gei82543PhyRead             (END_DEVICE *,UINT8,UINT8, 
  512.                                                           UINT16 *);
  513. LOCAL STATUS    gei82544PhyWrite            (END_DEVICE *,UINT8,UINT8,UINT16);
  514. LOCAL STATUS    gei82544PhyRead             (END_DEVICE *,UINT8,UINT8, 
  515.                                                           UINT16 *);
  516. LOCAL void      gei82543LoanTransmit        (END_DEVICE *,M_BLK_ID);
  517. LOCAL void      gei82543TxResoFree          (END_DEVICE *);
  518. LOCAL int       gei82543TxDesCleanGet       (END_DEVICE *,int);
  519. LOCAL UINT32    gei82543TxStallCheck        (END_DEVICE *);
  520. LOCAL void      gei82543GMIIphyConfig       (END_DEVICE *);
  521. LOCAL void      gei82543GMIIphyReConfig     (END_DEVICE *);
  522. LOCAL STATUS    gei82543linkGMIISetup       (END_DEVICE *);
  523. LOCAL STATUS    gei82543linkGMIIPreInit     (END_DEVICE *);
  524. /* END specific interfaces. */
  525. /* This is the only externally visible interface. */
  526. END_OBJ*        gei82543EndLoad             (char* initString);
  527. LOCAL STATUS    gei82543EndStart            (END_DEVICE* pDrvCtrl);
  528. LOCAL STATUS    gei82543EndStop             (END_DEVICE* pDrvCtrl);
  529. LOCAL int       gei82543EndIoctl            (END_DEVICE* pDrvCtrl, int cmd, 
  530.                                                          caddr_t data);
  531. LOCAL STATUS    gei82543EndUnload           (END_DEVICE* pDrvCtrl);
  532. LOCAL STATUS    gei82543EndSend             (END_DEVICE* pDrvCtrl, 
  533.                                                          M_BLK_ID pBuf);
  534. LOCAL STATUS    gei82543EndMCastAdd         (END_DEVICE* pDrvCtrl, 
  535.                                                          char* pAddress);
  536. LOCAL STATUS    gei82543EndMCastDel         (END_DEVICE* pDrvCtrl, 
  537.                                                          char* pAddress);
  538. LOCAL STATUS    gei82543EndMCastGet         (END_DEVICE* pDrvCtrl,
  539.                                                          MULTI_TABLE* pTable);
  540. LOCAL STATUS    gei82543EndPollStart        (END_DEVICE* pDrvCtrl);
  541. LOCAL STATUS    gei82543EndPollStop         (END_DEVICE* pDrvCtrl);
  542. LOCAL STATUS    gei82543EndPollSend         (END_DEVICE* pDrvCtrl, 
  543.                                                          M_BLK_ID pBuf);
  544. LOCAL STATUS    gei82543EndPollRcv          (END_DEVICE* pDrvCtrl, 
  545.                                                          M_BLK_ID pBuf);
  546. LOCAL void      gei82543AddrFilterSet       (END_DEVICE* pDrvCtrl);
  547. LOCAL STATUS    gei82543EndParse            (END_DEVICE*, char *);
  548. LOCAL STATUS    gei82543EndMemInit          (END_DEVICE*);
  549. /*
  550.  * Declare our function table.  This is LOCAL across all driver
  551.  * instances.
  552.  */
  553. LOCAL NET_FUNCS gei82543EndFuncTable =
  554.     {
  555.     (FUNCPTR) gei82543EndStart,     /* Function to start the device. */
  556.     (FUNCPTR) gei82543EndStop,      /* Function to stop the device. */
  557.     (FUNCPTR) gei82543EndUnload,    /* Unloading function for the driver. */
  558.     (FUNCPTR) gei82543EndIoctl,     /* Ioctl function for the driver. */
  559.     (FUNCPTR) gei82543EndSend,      /* Send function for the driver. */
  560.     (FUNCPTR) gei82543EndMCastAdd,  /* Multicast add function for the */
  561.                                     /* driver. */
  562.     (FUNCPTR) gei82543EndMCastDel,  /* Multicast delete function for */
  563.                                     /* the driver. */
  564.     (FUNCPTR) gei82543EndMCastGet,  /* Multicast retrieve function for */
  565.                                     /* the driver. */
  566.     (FUNCPTR) gei82543EndPollSend,  /* Polling send function */
  567.     (FUNCPTR) gei82543EndPollRcv,   /* Polling receive function */
  568.     endEtherAddressForm,            /* put address info into a NET_BUFFER */
  569.     endEtherPacketDataGet,          /* get pointer to data in NET_BUFFER */
  570.     endEtherPacketAddrGet           /* Get packet addresses. */
  571.     };
  572. /*************************************************************************
  573. *
  574. * gei82543EndLoad - initialize the driver and device
  575. *
  576. * This routine initializes the driver and the device to the operational state.
  577. * All of the device specific parameters are passed in the initString.
  578. *
  579. * The string contains the target specific parameters like this:
  580. * "unitnum:shmem_addr:shmem_size:rxDescNum:txDescNum:usrFlags:offset:mtu"
  581. *
  582. * RETURNS: an END object pointer, NULL if error, or zero 
  583. */
  584. END_OBJ* gei82543EndLoad
  585.     (
  586.     char  *initString        /* String to be parsed by the driver. */
  587.     )
  588.     {
  589.     END_DEVICE  *pDrvCtrl = NULL; /* pointer to device structure */
  590.     DRV_LOG (DRV_DEBUG_LOAD, "Loading gei82543End Driver...n", 
  591.                               1, 2, 3, 4, 5, 6);
  592.     /* sanity check */
  593.     if (initString == NULL)
  594.        return NULL;
  595.     if (initString[0] == 0)
  596.        {
  597.        bcopy ((char *) DEVICE_NAME, (void *)initString, DEVICE_NAME_LENGTH);
  598.        return 0;
  599.        }
  600.     /* allocate the device structure */
  601.     pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1);
  602.     if (pDrvCtrl == NULL)
  603.         goto errorExit;
  604.     /* clean up driver structure */
  605.     memset((void *)pDrvCtrl, 0, sizeof (END_DEVICE));
  606.     /* parse the init string, filling in the device structure */
  607.     if (gei82543EndParse (pDrvCtrl, initString) == ERROR)
  608.         goto errorExit;
  609.     /* zero adaptor structure */
  610.     memset ((void *)&pDrvCtrl->adaptor, 0, sizeof(ADAPTOR_INFO));
  611.     /* call BSP routine to get PCI information*/
  612.     if (sys82543BoardInit (pDrvCtrl->unit, &pDrvCtrl->adaptor) != OK)
  613.         {
  614.         DRV_LOG (DRV_DEBUG_LOAD, "Error in getting board infon", 
  615.                                   1, 2, 3, 4, 5, 6);
  616.         goto errorExit;
  617.         } 
  618.     /* set up the base register */
  619.     pDrvCtrl->devRegBase = (UINT32)(pDrvCtrl->adaptor.regBaseLow);
  620.     /* set up device structure based on user's flags */
  621.     if (pDrvCtrl->usrFlags & GEI_END_JUMBO_FRAME_SUPPORT)
  622.         {
  623.         if (pDrvCtrl->mtu <= 0)
  624.             pDrvCtrl->mtu = GEI_DEFAULT_JUMBO_MTU_SIZE;
  625.         
  626.         pDrvCtrl->mtu = (pDrvCtrl->mtu <= ETHERMTU)? ETHERMTU :
  627.                   ((pDrvCtrl->mtu > GEI_MAX_JUMBO_MTU_SIZE)? 
  628.                   GEI_MAX_JUMBO_MTU_SIZE : pDrvCtrl->mtu);
  629.         }
  630.     else  /* normal frame */
  631.         pDrvCtrl->mtu = ETHERMTU;
  632.     /* increase transmit storage in FIFO for jumbo frames */
  633.   
  634.     if (pDrvCtrl->mtu > ETHERMTU)
  635.         {
  636.         GEI_WRITE_REG(INTEL_82543GC_PBA, 0x20); /* 24KB for TX buffer */
  637.         }
  638.     /* perform memory allocation for descriptors */
  639.     if (gei82543EndMemInit (pDrvCtrl) == ERROR)
  640.         goto errorExit;
  641.     /* set up device structure based on user's flags */
  642.    
  643.     if (pDrvCtrl->usrFlags & GEI_END_SET_TIMER)
  644.         {
  645.         pDrvCtrl->timerId = wdCreate ();
  646.         if (pDrvCtrl->timerId == NULL)
  647.             DRV_LOG (DRV_DEBUG_LOAD, ("create timer failsn"), 
  648.                                       1, 2, 3, 4, 5, 6);
  649.         }
  650.     if (pDrvCtrl->usrFlags & GEI_END_SET_RX_PRIORITY)
  651.         pDrvCtrl->dmaPriority = DMA_RX_PRIORITY;
  652.     else
  653.         pDrvCtrl->dmaPriority = DMA_FAIR_RX_TX;
  654.     if (pDrvCtrl->usrFlags & GEI_END_FREE_RESOURCE_DELAY)
  655.         {
  656.         pDrvCtrl->txIntDelay  = TXINT_DELAY_MORE;
  657.         pDrvCtrl->txResoFreeQuick = FALSE;
  658.         }
  659.     else
  660.         {
  661.         pDrvCtrl->txIntDelay  = TXINT_DELAY_LESS;
  662.         pDrvCtrl->txResoFreeQuick = TRUE; 
  663.         }
  664. #ifdef INCLUDE_TBI_COMPATIBLE
  665.     pDrvCtrl->tbiCompatibility = FALSE;
  666. #endif /* INCLUDE_TBI_COMPATIBLE */
  667.    
  668.     /* stop/reset the chip before configuration */
  669.     gei82543Reset (pDrvCtrl);
  670.     
  671.     /* disable all chip interrupt */
  672.     gei82543DisableChipInt (pDrvCtrl);
  673.     /* turn off system interrupts */
  674.     SYS_INT_DISABLE(pDrvCtrl);
  675.     /* set the default value for device */
  676.     pDrvCtrl->rxIntDelay     = DEFAULT_RXINT_DELAY;
  677.     pDrvCtrl->maxRxNumPerInt = DEFAULT_RXRES_PROCESS_FACTOR * 
  678.                                pDrvCtrl->rxDescNum;
  679.     pDrvCtrl->timerInterval  = DEFAULT_TIMER_INTERVAL;
  680.     pDrvCtrl->flowCtrl       = DEFAULT_FLOW_CONTRL;   
  681.     pDrvCtrl->duplex         = DEFAULT_DUPLEX_MODE;
  682.      
  683.     /* Misc. setting */
  684.     pDrvCtrl->flags          = 0;
  685.     pDrvCtrl->linkStatus     = LINK_STATUS_UNKNOWN;
  686.     pDrvCtrl->linkMethod     = GEI82543_HW_AUTO;
  687.     pDrvCtrl->txConfigureWord     = (TXCW_ANE_BIT | TXCW_FD_BIT);
  688.     pDrvCtrl->multiCastFilterType = DEFAULT_MULTI_FILTER_TYPE; 
  689.     pDrvCtrl->attach         = FALSE;
  690.     pDrvCtrl->devStartFlag   = FALSE;
  691.     /* initialize the END and MIB2 parts of the structure */
  692.     /*
  693.      * The M2 element must come from m2Lib.h 
  694.      * This setting is for a DIX type ethernet device.
  695.      */
  696.     
  697.     if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, DEVICE_NAME,
  698.                       pDrvCtrl->unit, &gei82543EndFuncTable,
  699.                       "gei82543End Driver.") == ERROR || 
  700.         END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
  701.                       &pDrvCtrl->adaptor.enetAddr[0], 6, pDrvCtrl->mtu,
  702.                       END_SPEED) == ERROR )
  703.         goto errorExit;
  704.    /* disable RX/TX operations now, will be re-enable in Start function */
  705.     gei82543TxRxDisable (pDrvCtrl);
  706.     pDrvCtrl->attach = TRUE;
  707.     DRV_LOG (DRV_DEBUG_LOAD, ("loading gei82543End...OKn"),1,2,3,4,5,6);
  708.     return (&pDrvCtrl->end);
  709. errorExit:
  710.     /* free all allocated memory */
  711.     gei82543MemAllFree (pDrvCtrl);
  712.     if (pDrvCtrl != NULL)
  713.          free ((char *)pDrvCtrl);
  714.     DRV_LOG (DRV_DEBUG_LOAD, ("Loading gei82543End...Errorn"), 
  715.                                1, 2, 3, 4, 5, 6);
  716.     return NULL;
  717.     }
  718. /*************************************************************************
  719. *
  720. * gei82534EndParse - parse the init string
  721. *
  722. * Parse the input string.  Fill in values in the driver control structure.
  723. *
  724. * RETURNS: OK or ERROR for invalid arguments.
  725. */
  726. LOCAL STATUS gei82543EndParse
  727.     (
  728.     END_DEVICE *    pDrvCtrl,       /* device pointer */
  729.     char *          initString      /* information string */
  730.     )
  731.     {
  732.     char *    tok;
  733.     char *    pHolder = NULL;
  734.     DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndParse...n"), 1, 2, 3, 4, 5, 6);
  735.     /* parse the initString */
  736.     tok = strtok_r (initString, ":", &pHolder);
  737.     if (tok == NULL)
  738.     return ERROR;
  739.     pDrvCtrl->unit = atoi (tok);
  740.  
  741.     /* address of shared memory */
  742.     tok = strtok_r (NULL, ":", &pHolder);
  743.     if (tok == NULL)
  744.     return ERROR;
  745.     pDrvCtrl->pMemBase = (char *) strtoul (tok, NULL, 16);
  746.  
  747.     /* size of shared memory */
  748.     tok = strtok_r (NULL, ":", &pHolder);
  749.     if (tok == NULL)
  750.     return ERROR;
  751.     pDrvCtrl->memSize = strtoul (tok, NULL, 16);
  752.     /* number of rx descriptors */
  753.     tok = strtok_r (NULL, ":", &pHolder);
  754.     if (tok == NULL)
  755.      return ERROR;
  756.     pDrvCtrl->rxDescNum = strtoul (tok, NULL, 16);
  757.     /* number of tx descriptors */
  758.     tok = strtok_r (NULL, ":", &pHolder);
  759.     if (tok == NULL)
  760.     return ERROR;
  761.     pDrvCtrl->txDescNum = strtoul (tok, NULL, 16);
  762.    
  763.     /* get the usrFlags */
  764.     tok = strtok_r (NULL, ":", &pHolder);
  765.     if (tok == NULL)
  766.     return ERROR;
  767.     pDrvCtrl->usrFlags = strtoul (tok, NULL, 16);
  768.     /* get the offset value */
  769.     tok = strtok_r (NULL, ":", &pHolder);
  770.     if (tok != NULL)
  771.         pDrvCtrl->offset = atoi (tok);
  772.     DRV_LOG (DRV_DEBUG_LOAD,
  773.             ("gei82543EndParse: unit=%d pMemBase=0x%x memSize=0x%x
  774.               rxDescNums=%d txDescNum=%d, usrFlags=0x%xn"),
  775.               pDrvCtrl->unit, 
  776.               (int)pDrvCtrl->pMemBase,
  777.               (int) pDrvCtrl->memSize,
  778.               pDrvCtrl->rxDescNum,
  779.               pDrvCtrl->txDescNum,
  780.               pDrvCtrl->usrFlags
  781.               );
  782.     /* check Jumbo Frame support */
  783.     if (pDrvCtrl->usrFlags & GEI_END_JUMBO_FRAME_SUPPORT)
  784.         {        
  785.         /* get mtu */
  786.         tok = strtok_r (NULL, ":", &pHolder);
  787.         if (tok != NULL)
  788.             pDrvCtrl->mtu = atoi (tok);
  789.         DRV_LOG (DRV_DEBUG_LOAD, ("mtu = %dn"),pDrvCtrl->mtu, 
  790.                  2, 3, 4, 5, 6);
  791.         }
  792.     return OK;
  793.     }
  794. /*************************************************************************
  795. *
  796. * gei82543MemAllFree - free all memory allocated by driver
  797. *
  798. * This routine returns all allocated memory by this driver to OS
  799. *
  800. * RETURN: N/A
  801. */
  802. LOCAL void gei82543MemAllFree 
  803.     (
  804.     END_DEVICE * pDrvCtrl    /* device to be initialized */
  805.     )
  806.     {
  807.     if (pDrvCtrl == NULL)
  808.         return;
  809.     /* release TxDesCtl */
  810.     if (pDrvCtrl->pTxDesCtlBase != NULL)
  811.         {
  812.         free (pDrvCtrl->pTxDesCtlBase);
  813.         }
  814.     if (pDrvCtrl->pTxPollBufAdr != NULL)
  815.         {
  816.         cacheDmaFree (pDrvCtrl->pTxPollBufAdr);
  817.         }
  818.     /* release TX/RX descriptors and RX buffer */
  819.     if (pDrvCtrl->pMemBase != NULL && (pDrvCtrl->memAllocFlag == TRUE))
  820.         {
  821.         cacheDmaFree (pDrvCtrl->pMemBase);
  822.         }
  823.     /* release RX mBlk pool */
  824.     if (pDrvCtrl->pMclkArea != NULL)
  825.         {
  826.         cfree (pDrvCtrl->pMclkArea);
  827.         }      
  828.  
  829.     /* release netPool structure */
  830.     if (pDrvCtrl->end.pNetPool != NULL)
  831.         {
  832.     if (netPoolDelete(pDrvCtrl->end.pNetPool) != OK)
  833.             {
  834.             LOGMSG("netPoolDelete failsn", 0,0,0,0,0,0);
  835.             }
  836.     free ((char *)pDrvCtrl->end.pNetPool);
  837.         }
  838.     return;
  839.     }
  840. /*************************************************************************
  841. *
  842. * gei82543EndMemInit - allocate and initialize memory for driver
  843. *
  844. * This routine allocates and initializes memory for descriptors and 
  845. * corresponding buffers, and sets up the receive data pool for receiving 
  846. * packets. 
  847. *
  848. * RETURNS: OK or ERROR.
  849. */
  850. LOCAL STATUS gei82543EndMemInit
  851.     (
  852.     END_DEVICE * pDrvCtrl    /* device to be initialized */
  853.     )
  854.     {
  855.     M_CL_CONFIG geiMclBlkConfig; /* Mblk */
  856.     CL_DESC     geiClDesc;      /* Cluster descriptor */
  857.     UINT32      size;           /* required memory size */
  858.     UINT32      tmpBase;        /* temporary memory base */
  859.     UINT32      bufSz;          /* real cluster size */
  860.     int         bufNum;         /* temp variable */
  861.     DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndMemInit...n"), 1, 2, 3, 4, 5, 6);
  862.     /* set the default TX/RX descriptor Number */
  863.     if (pDrvCtrl->txDescNum == 0)
  864.         pDrvCtrl->txDescNum = DEFAULT_NUM_TXDES;
  865.     if (pDrvCtrl->rxDescNum == 0)
  866.         pDrvCtrl->rxDescNum = DEFAULT_NUM_RXDES;
  867.     /* round up to multiple of 8, hardware requirement */
  868.     pDrvCtrl->txDescNum = ROUND_UP_MULTIPLE(pDrvCtrl->txDescNum, 
  869.                                            INTEL_82543GC_MULTIPLE_DES);
  870.     pDrvCtrl->rxDescNum = ROUND_UP_MULTIPLE((UINT32)pDrvCtrl->rxDescNum, 
  871.                                          (UINT32)INTEL_82543GC_MULTIPLE_DES);
  872.     /* calculate reasonable receive buffer size */
  873.     size = pDrvCtrl->mtu + GEI_DEFAULT_ETHERHEADER + ETHER_CRC_LENGTH;
  874.     if (size > GEI_MAX_FRAME_SIZE)
  875.         return ERROR;
  876.     if (pDrvCtrl->usrFlags & GEI_END_JUMBO_FRAME_SUPPORT)
  877.         {
  878.         for (bufSz = 2048; bufSz <= 16384; bufSz = bufSz << 1)
  879.              {           
  880.              if (size <= bufSz)
  881.                  {
  882.                  pDrvCtrl->rxBufSize = bufSz;
  883.                  break;
  884.                  }
  885.              }
  886.         }
  887.     else /* normal frame */
  888.         pDrvCtrl->rxBufSize = 2048;
  889.     /* add cluster ID and offset */
  890.     bufSz = size + pDrvCtrl->offset + CL_OVERHEAD;
  891.     bufNum = bufSz / GEI_DESC_ALIGN_BYTE;
  892.     if (bufSz != (bufNum * GEI_DESC_ALIGN_BYTE))  
  893.             bufSz = (bufNum + 1) * GEI_DESC_ALIGN_BYTE;
  894.     /* get the needed memory size */
  895.     size = pDrvCtrl->txDescNum * TXDESC_SIZE +       /* for TX descriptor */
  896.            pDrvCtrl->rxDescNum * RXDESC_SIZE +       /* for RX descriptor */
  897.            pDrvCtrl->rxDescNum * bufSz *             /* for RX buffer */
  898.            (DEFAULT_LOAN_RXBUF_FACTOR + 1) +         /* for RX loan buffer */
  899.            1024;                                     /* for alignment */
  900.     if ((int)(pDrvCtrl->pMemBase) == NONE)
  901.         {
  902.         if (!CACHE_DMA_IS_WRITE_COHERENT ())
  903.             {
  904.             DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndMemInit: shared memory not 
  905.                                        cache coherentn"), 1, 2, 3, 4, 5, 6);
  906.             return ERROR;
  907.             }
  908.         
  909.         /* alloc memory in driver */
  910.         pDrvCtrl->pMemBase = cacheDmaMalloc (size);
  911.         if (pDrvCtrl->pMemBase == NULL)      /* no memory available */
  912.             {
  913.             DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndMemInit: could not obtain 
  914.                      memoryn"), 1, 2, 3, 4, 5, 6);
  915.             return (ERROR);
  916.             }
  917.         pDrvCtrl->memSize = size;
  918.         pDrvCtrl->cacheFuncs = cacheDmaFuncs;
  919.         pDrvCtrl->memAllocFlag = TRUE;
  920.         }
  921.     else
  922.         { 
  923.        /* 
  924.         * if user has provided a shared memory, we assume 
  925.         * it is a cache safe area 
  926.         */
  927.         if (pDrvCtrl->memSize < size)
  928.             {
  929.             DRV_LOG (DRV_DEBUG_LOAD, ("GEI82543EndMemInit: not enough 
  930.                                       memoryn"), 1, 2, 3, 4, 5, 6);
  931.             return ERROR;
  932.             }
  933.         pDrvCtrl->cacheFuncs = cacheNullFuncs;
  934.         pDrvCtrl->memAllocFlag = FALSE;
  935.         }
  936.     /* zero the pre-provided or allocated memory */
  937.     memset((void *)pDrvCtrl->pMemBase, 0, size);
  938.     /* set the TX descriptor base address, align to 128 byte */
  939.  
  940.     pDrvCtrl->pTxDescBase = (char *)(((UINT32)(pDrvCtrl->pMemBase) + 
  941.                                       (GEI_DESC_ALIGN_BYTE - 1)) & 
  942.                                       ~(GEI_DESC_ALIGN_BYTE - 1));
  943.     /* set the RX descriptor base Address */
  944.     pDrvCtrl->pRxDescBase = (char *)GEI_GET_TX_DESC_ADDR(pDrvCtrl->txDescNum);
  945.     tmpBase = (UINT32)GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescNum);
  946.     /* set the RX buffer base address */
  947.     pDrvCtrl->pRxBufBase = (char *)(((tmpBase + (GEI_DESC_ALIGN_BYTE)) & 
  948.                             ~(GEI_DESC_ALIGN_BYTE - 1)) - CL_OVERHEAD);
  949.     /* allocate memory for txDescriptor manager array */
  950.     size = pDrvCtrl->txDescNum * sizeof(TX_DESCTL);
  951.     pDrvCtrl->pTxDesCtlBase = (P_TX_DESCTL) malloc (size);    
  952.     if ((pDrvCtrl->pTxDesCtlBase) == NULL)
  953.         {
  954.         DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: TxDesCtl memory 
  955.                                   unavailablen",1, 2, 3, 4, 5, 6);
  956.         goto errorExit;
  957.         }
  958.     /* get a buffer for TX polling mode */
  959.     pDrvCtrl->pTxPollBufAdr = cacheDmaMalloc (bufSz);
  960.     if ((pDrvCtrl->pTxPollBufAdr) == NULL)
  961.         {
  962.         DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Tx Polling memory 
  963.                                   unavailablen",1, 2, 3, 4, 5, 6);
  964.         goto errorExit;
  965.         }
  966.     /* clean up txDesCtl memory */
  967.     memset((void *)pDrvCtrl->pTxDesCtlBase, 0, size);
  968.     /* 
  969.      * set up RX mBlk pool
  970.      * This is how we set up and END netPool using netBufLib(1).
  971.      * This code is pretty generic.
  972.      */
  973.     if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
  974.         goto errorExit;
  975.     bzero ((char *)&geiMclBlkConfig, sizeof(geiMclBlkConfig));
  976.     bzero ((char *)&geiClDesc, sizeof(geiClDesc));
  977.     geiMclBlkConfig.mBlkNum = pDrvCtrl->rxDescNum * 
  978.                                        (DEFAULT_MBLK_NUM_FACTOR + 1);
  979.     geiClDesc.clNum = pDrvCtrl->rxDescNum * 
  980.                                      (DEFAULT_LOAN_RXBUF_FACTOR + 1);
  981.     geiClDesc.clSize = bufSz - CL_OVERHEAD;
  982.         
  983.     geiMclBlkConfig.clBlkNum = geiClDesc.clNum;
  984.     /* calculate the total memory for all the M-Blks and CL-Blks. */
  985.     geiMclBlkConfig.memSize = 
  986.         ((geiMclBlkConfig.mBlkNum * (M_BLK_SZ + sizeof (long))) +
  987.          (geiMclBlkConfig.clBlkNum * CL_BLK_SZ + sizeof(long)));
  988.     if ((geiMclBlkConfig.memArea = (char *) memalign (sizeof(long), 
  989.                                             geiMclBlkConfig.memSize)) == 
  990.                                             NULL)
  991.         {
  992.         DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: MclBlkConfig memory 
  993.                                   unavailablen",1, 2, 3, 4, 5, 6);
  994.         goto errorExit;
  995.         }
  996.     pDrvCtrl->pMclkArea = geiMclBlkConfig.memArea;
  997.     geiClDesc.memSize = geiClDesc.clNum * (geiClDesc.clSize + CL_OVERHEAD);
  998.     geiClDesc.memArea = (char *)(pDrvCtrl->pRxBufBase);
  999.     geiClDesc.memArea = (char *)(((UINT32) geiClDesc.memArea + 0x3) & ~0x3);
  1000.     /* initialize the memory pool. */
  1001.     if (netPoolInit(pDrvCtrl->end.pNetPool, &geiMclBlkConfig,
  1002.                      &geiClDesc, 1,NULL) == ERROR)
  1003.         {
  1004.         DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Could not 
  1005.                                   init bufferingn", 1, 2, 3, 4, 5, 6);
  1006.         goto errorExit;
  1007.         }
  1008.     if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,
  1009.                                geiClDesc.clSize, FALSE)) == NULL)
  1010.         {
  1011.         DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Could not find specified
  1012.                                   pool IDn", 1, 2, 3, 4, 5, 6);
  1013.         goto errorExit;
  1014.         }
  1015.     CACHE_PIPE_FLUSH ();
  1016.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit...OKn", 1, 2, 3, 4, 5, 6);
  1017.     return OK;
  1018. errorExit:
  1019.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit...ERRORn", 1, 2, 3,4,5,6);
  1020.   
  1021.     return ERROR;
  1022.     }
  1023. /*************************************************************************
  1024. *
  1025. * gei82543EndStart - setup and start the device 
  1026. *
  1027. * This routine connects interrupts, initializes receiver and transmitter, 
  1028. * and enable the device for running 
  1029. *
  1030. * RETURNS: OK or ERROR
  1031. */
  1032. LOCAL STATUS gei82543EndStart
  1033.     (
  1034.     END_DEVICE * pDrvCtrl    /* device ID */
  1035.     )
  1036.     {
  1037.     STATUS result;           /* results of start device */
  1038.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...n", 1, 2, 3, 4, 5, 6);
  1039.     if (pDrvCtrl->attach != TRUE)
  1040.        return ERROR;
  1041.     /* disable all chip interrupts */
  1042.     gei82543DisableChipInt (pDrvCtrl);
  1043.     /* turn off system interrupts */
  1044.     SYS_INT_DISABLE(pDrvCtrl);
  1045.     /* initialize the hardware and set up link */
  1046.     if (gei82543HwInit (pDrvCtrl) != OK)
  1047.        {
  1048.         DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndStart: link setup failsn"), 
  1049.                                   1, 2, 3, 4, 5, 6);
  1050.         LOGMSG("link failsn", 1, 2, 3, 4, 5, 6);
  1051.        }
  1052.     /* disable TX/RX now */
  1053.     gei82543TxRxDisable (pDrvCtrl);
  1054.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: set up TX structuren", 
  1055.                               1, 2, 3, 4, 5, 6);
  1056.     /* initialize SW/HW structures for TX */
  1057.     gei82543TxSetup (pDrvCtrl);
  1058.     /* initialize SW/HW structure for RX */
  1059.     gei82543RxSetup (pDrvCtrl);  
  1060.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: configure devicen", 
  1061.                               1, 2, 3, 4, 5, 6);
  1062.     /* configure devices */
  1063.     pDrvCtrl->flags = DEFAULT_DRV_FLAGS;
  1064.     END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
  1065.     gei82543EndConfigure (pDrvCtrl);
  1066.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Connect interruptn", 
  1067.                               1, 2, 3, 4, 5, 6);
  1068.     /* connect interrupt handler */
  1069.     SYS_INT_CONNECT(pDrvCtrl, gei82543EndInt, (int)pDrvCtrl, &result);
  1070.     if (result == ERROR)
  1071.        {
  1072.        DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: connect interrupt 
  1073.                                  ERROR !n", 1, 2, 3, 4, 5, 6);    
  1074.        return ERROR;
  1075.        }
  1076.     /* clean up all statistic registers */
  1077.     gei82543HwStatusDump (pDrvCtrl);
  1078.     /* clean all pending interrupts */
  1079.     gei82543DisableChipInt (pDrvCtrl);
  1080.     /* turn on system interrupt */
  1081.     SYS_INT_ENABLE(pDrvCtrl);
  1082.     /* enable interrupt in chip level */
  1083.     gei82543EnableChipInt (pDrvCtrl);    
  1084.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Interrupt enablen",  
  1085.                               1, 2, 3, 4, 5, 6);
  1086.     /* set the END flags, make driver ready to start */
  1087.     END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | 
  1088.                     IFF_BROADCAST | IFF_MULTICAST));   
  1089.     gei82543EndConfigure (pDrvCtrl);
  1090.     /* wait for chip to settle down */
  1091.     taskDelay (sysClkRateGet () / 20);
  1092.     /* check link status again before really start */
  1093.     if (gei82543linkStatusCheck (pDrvCtrl) != OK)
  1094.         {
  1095.         LOGMSG("gei82543EndStart:Link is down n", 1, 2, 3, 4, 5, 6);
  1096.         }
  1097.     
  1098.     /* set the internal timer */
  1099.     if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)    
  1100.       {
  1101.       ADAPTOR_INFO * pBoard = &pDrvCtrl->adaptor; /* pointer to board specific struct */ 
  1102.       if (pBoard->sysGeiInitTimerSetup != NULL)
  1103.           if (pBoard->sysGeiInitTimerSetup (&pDrvCtrl->adaptor))
  1104.       {
  1105.               if (!(pBoard->devTimerUpdate.rdtrVal & 0xffff0000))
  1106.                   GEI_WRITE_REG(INTEL_82543GC_RDTR,pBoard->devTimerUpdate.rdtrVal);
  1107.               if (!(pBoard->devTimerUpdate.radvVal & 0xffff0000))
  1108.                   GEI_WRITE_REG(INTEL_82546EB_RADV,pBoard->devTimerUpdate.radvVal);
  1109.               if (!(pBoard->devTimerUpdate.itrVal & 0xffff0000))
  1110.                   GEI_WRITE_REG(INTEL_82546EB_ITR,pBoard->devTimerUpdate.itrVal);
  1111.       pDrvCtrl->timerInterval = (pBoard->devTimerUpdate.watchDogIntVal <= 0) ?
  1112.      DEFAULT_TIMER_INTERVAL : (pBoard->devTimerUpdate.watchDogIntVal);
  1113.               }
  1114.       }
  1115.     /* start the timer if configured */
  1116.     if (pDrvCtrl->usrFlags & GEI_END_SET_TIMER)
  1117.         {
  1118.         if (pDrvCtrl->timerId)
  1119.         wdStart(pDrvCtrl->timerId, pDrvCtrl->timerInterval * sysClkRateGet(), 
  1120.                   (FUNCPTR) gei82543EndTimerHandler, (int) pDrvCtrl);
  1121.         }
  1122.     /* set the device start flag */
  1123.     pDrvCtrl->devStartFlag = TRUE;
  1124.     /* enable TX and RX operation */
  1125.     gei82543TxRxEnable (pDrvCtrl);
  1126.     DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...Donen", 1, 2, 3, 4, 5, 6);
  1127.     
  1128.     return (OK);
  1129.     }
  1130. /*************************************************************************
  1131. *
  1132. * gei82543EndSend - driver send routine
  1133. *
  1134. * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
  1135. * The buffer must already have the addressing information properly installed
  1136. * in it. This is done by a higher layer.  
  1137. *
  1138. * RETURNS: OK or ERROR.
  1139. *
  1140. * ERRNO: EINVAL
  1141. */
  1142. LOCAL STATUS gei82543EndSend
  1143.     (
  1144.     END_DEVICE * pDrvCtrl,    /* device ptr */
  1145.     M_BLK_ID     pMblk        /* data to send */
  1146.     )
  1147.     {
  1148.     M_BLK_ID    pMblkDup = pMblk; /* temporary pMblk */ 
  1149.     int         mBlkNum;          /* num of mBlk of a packet */
  1150.     DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...n", 1, 2, 3, 4, 5, 6);
  1151.     if (pMblk == NULL)
  1152.         return ERROR;
  1153.     /* return if entering polling mode */
  1154.     if (pDrvCtrl->flags & FLAG_POLLING_MODE)
  1155.         {
  1156.         netMblkClChainFree (pMblk);
  1157.         errno = EINVAL;
  1158.         return (ERROR);
  1159.         }
  1160.     END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
  1161.     /* get the mBlk number in this packet */
  1162.     mBlkNum = 0;
  1163.     while (pMblkDup != NULL)
  1164.         {
  1165.         mBlkNum++;
  1166.         pMblkDup = pMblkDup->mBlkHdr.mNext;
  1167.         }
  1168.     /* 
  1169.      * release mBlks if the number of mBlks in this packet exceeds the maximum 
  1170.      * available transmit descriptors 
  1171.      */
  1172.     if (mBlkNum >= pDrvCtrl->txDescNum)
  1173.         {
  1174.         DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend:mBlks num exceeds max TX descn"),
  1175.                                 1, 2, 3, 4, 5, 6);
  1176.         netMblkClChainFree (pMblk);
  1177.         errno = EINVAL;
  1178.         END_TX_SEM_GIVE (&pDrvCtrl->end);        
  1179.         return (ERROR);
  1180.         }
  1181.     if ((mBlkNum > pDrvCtrl->txDescFreeNum) && 
  1182.          (mBlkNum > gei82543TxDesCleanGet(pDrvCtrl,FREE_ALL_AUTO)))
  1183.         {         
  1184.         /* not enough TX descriptors */
  1185.         DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend: No TX descriptor 
  1186.                                  availablen"), 1, 2, 3, 4, 5, 6);
  1187.         if (pDrvCtrl->txStall != TRUE)
  1188.             {
  1189.             pDrvCtrl->txStall = TRUE;
  1190.             pDrvCtrl->txReqDescNum = mBlkNum;
  1191.             if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
  1192.        {
  1193.                /* enable the TXD_LOW interrupt */
  1194.                GEI_WRITE_REG(INTEL_82543GC_IMS, IMS_TXDLOW_BIT);
  1195.                }
  1196.             GEI_WRITE_REG(INTEL_82543GC_TIDV, MIN_TXINT_DELAY);
  1197.             }     
  1198.       
  1199.         END_TX_SEM_GIVE (&pDrvCtrl->end);        
  1200.         return (END_ERR_BLOCK);     
  1201.         }         
  1202.     /* bump statistic counter */
  1203.     
  1204.     if (pMblk->mBlkHdr.mData[0] & (UINT8) 0x01)
  1205.         pDrvCtrl->end.mib2Tbl.ifOutNUcastPkts += 1;   
  1206.     else
  1207.         END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
  1208.     DRV_LOG (DRV_DEBUG_TX, "loan buffers of the packet and transmit...n",
  1209.                                 1, 2, 3, 4, 5, 6);
  1210.     pDrvCtrl->txActivity = TRUE;
  1211.     gei82543LoanTransmit (pDrvCtrl, pMblk);
  1212.     /* release semaphore now */
  1213.     END_TX_SEM_GIVE (&pDrvCtrl->end);
  1214.     DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend...Done"), 1, 2, 3, 4, 5, 6);
  1215.     return (OK);
  1216.     }
  1217. /**********************************************************************
  1218. *
  1219. * gei82543LoanTransmit - store the mbuf address into TX descriptor to transmit
  1220. *
  1221. * This routine stores the mbuf address into the Tx descriptors address field,
  1222. * and then directly transfer data from mbuf to chip memory without copying,
  1223. * The loaned mBlk will be freed later
  1224. *
  1225. * RETURNS: N/A.
  1226. */
  1227. LOCAL void gei82543LoanTransmit 
  1228.     (
  1229.     END_DEVICE *     pDrvCtrl,      /* END device structure */
  1230.     M_BLK_ID         pMblkFirst     /* pointer to the beginning of a mBlk */
  1231.     )
  1232.     {
  1233.     P_TX_DESCTL     pDescCtl;       /* pointer to a Tx descriptor */ 
  1234.                                     /* control structure*/
  1235.     char *          pDesc;          /* pointer to a descriptor */
  1236.     M_BLK_ID        pMblk;          /* pointer to a Mblk */
  1237.     UINT32          len;            /* temporary len for each mBlk */
  1238.     UINT32          totalLen = 0;   /* total length of this packet */
  1239.     UINT32          index = 0;      /* index to the number of mBlk */ 
  1240.     int             tmpTail;        /* temporary tail index of TX descriptor*/
  1241.     UINT32          poptSta = 0;    /* value in the option and status filed */
  1242.     UINT32          dataCtx;        /* value in the command field */
  1243.     dataCtx = ((TXD_CMD_IDE | TXD_CMD_RS) << 24); 
  1244.     pMblk = pMblkFirst;
  1245.     FOREVER
  1246.         {
  1247.         /* get the available TX descriptor and its manager */
  1248.         GEI_GET_TX_DESC_TAIL_UPDATE(tmpTail, index);
  1249.          
  1250.         pDescCtl = GEI_GET_TX_DESC_CTL_ADDR(tmpTail);
  1251.         pDesc = GEI_GET_TX_DESC_ADDR(tmpTail);  
  1252.         len = pMblk->mBlkHdr.mLen;        
  1253.         totalLen += len;     
  1254.         /* flush buffer for cache coherence */
  1255.         cacheFlush(DATA_CACHE, (void *)(pMblk->mBlkHdr.mData), len);   
  1256.         GEI_WRITE_DESC_LONG(pDesc, TXDESC_BUFADRHIGH_OFFSET, 0);
  1257.         GEI_WRITE_DESC_LONG(pDesc, TXDESC_BUFADRLOW_OFFSET,
  1258.              (UINT32)GEI_VIRT_TO_BUS((UINT32)(pMblk->mBlkHdr.mData)));
  1259.        
  1260.         /* zero the status field in the TX descriptor */
  1261.         GEI_WRITE_DESC_LONG(pDesc, TXDESC_STATUS_OFFSET, poptSta);
  1262.               
  1263.         pMblk = pMblk->mBlkHdr.mNext;
  1264.         index++;
  1265.         if (pMblk == NULL || pMblk->mBlkHdr.mLen == 0)
  1266.             {        
  1267.             /* the last mBlk for this packet */
  1268.             pDescCtl->txType = TX_DESC_TYPE_EOP; 
  1269.             pDescCtl->mBlk = pMblkFirst;              
  1270.             if (totalLen < ETHERSMALL)
  1271.                 len = max (len, len + ETHERSMALL - totalLen);
  1272.             /* set up the length/commond field */
  1273.      
  1274.             GEI_WRITE_DESC_LONG(pDesc, TXDESC_LENGTH_OFFSET, 
  1275.                                 ((UINT16)len | (dataCtx) | 
  1276.                                 ((TXD_CMD_EOP | TXD_CMD_IFCS) << 24)));
  1277.             break;
  1278.             }
  1279.         else
  1280.             {
  1281.             pDescCtl->txType = TX_DESC_TYPE_CHAIN; 
  1282.             pDescCtl->mBlk = NULL;             
  1283.             /* set up the length field */
  1284.             GEI_WRITE_DESC_LONG(pDesc, TXDESC_LENGTH_OFFSET, 
  1285.                                 ((UINT16)len | dataCtx));
  1286.             }
  1287.         } /* FOREVER */
  1288.        
  1289.     /* update the tail pointer in the driver structure */
  1290.     GEI_GET_TX_DESC_TAIL_UPDATE(pDrvCtrl->txDescTail, index);
  1291.     pDrvCtrl->txDescFreeNum -= index;
  1292.     CACHE_PIPE_FLUSH();
  1293.     /* update the tail pointer in TDT register */
  1294.     GEI_WRITE_REG(INTEL_82543GC_TDT, pDrvCtrl->txDescTail);
  1295.     return;
  1296.     }    
  1297. /*************************************************************************
  1298. *
  1299. * gei82543TxDesCleanGet - clean up TX descriptors 
  1300. *
  1301. * This routine cleans up TX descriptors and update available TX descriptor 
  1302. * for transmitting. 
  1303. *
  1304. * RETURNS: number of available TX descriptors
  1305. */
  1306. LOCAL int gei82543TxDesCleanGet
  1307.     (
  1308.     END_DEVICE * pDrvCtrl,      /* device to clean up TX descriptor */
  1309.     int          mode           /* clean up mode Force/Auto */
  1310.     )
  1311.     {
  1312.     P_TX_DESCTL pDescCtl;       /* TX descriptor control structure */
  1313.     char *      pDesc;          /* pointer to descriptor */
  1314.     int         maxTxDesFree;   /* maximum available TX descriptors to free */
  1315.     int         index;          /* index */
  1316.     /* check the maximum free TX Desc */
  1317.     maxTxDesFree = pDrvCtrl->txDescNum - 1;
  1318.     while (pDrvCtrl->txDescFreeNum != maxTxDesFree)
  1319.         {
  1320.         index = (pDrvCtrl->txDescLastCheck + 1) % (pDrvCtrl->txDescNum);
  1321.         pDesc =  GEI_GET_TX_DESC_ADDR(index);
  1322.         /* check data has been transmitted */
  1323.         if (mode != FREE_ALL_FORCE)
  1324.             if (!(GEI_READ_DESC_BYTE(pDesc, TXDESC_STATUS_OFFSET) & 
  1325.                   TXD_STAT_DD))
  1326.                 break; 
  1327.         pDescCtl = GEI_GET_TX_DESC_CTL_ADDR(index); 
  1328.        
  1329.         if (pDescCtl->txType == TX_DESC_TYPE_EOP && pDescCtl->mBlk != NULL)
  1330.             {
  1331.             /* free loaned TX buffers */
  1332.             netMblkClChainFree (pDescCtl->mBlk);      
  1333.             pDescCtl->mBlk = NULL;
  1334.             }
  1335.         /* mark descrptor clean */
  1336.         pDescCtl->txType = TX_DESC_TYPE_CLEAN;
  1337.         /* update the index of descriptor checked */
  1338.         pDrvCtrl->txDescLastCheck = index;
  1339.         /* update the available TX descriptor */
  1340.         pDrvCtrl->txDescFreeNum++;
  1341.         }       
  1342.     return (pDrvCtrl->txDescFreeNum);
  1343.     }
  1344. /*************************************************************************
  1345. *
  1346. * gei82543EndInt - handle 82543 chip interrupt event
  1347. *
  1348. * This routine is called at interrupt level in response to an interrupt from
  1349. * the controller.
  1350. *
  1351. * RETURNS: N/A.
  1352. */
  1353. LOCAL void gei82543EndInt
  1354.     (
  1355.     END_DEVICE *    pDrvCtrl    /* device to handle interrupt */
  1356.     )
  1357.     {
  1358.     UINT32 stat;                /* cause of interrupt */
  1359.     UINT32 statusRegVal;        /* status register value */
  1360.     UINT32 intTypeChk;          /* type of interrupt to be checked */
  1361.     DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt ...n", 1, 2, 3, 4, 5, 6);
  1362.     /* read the device status register */
  1363.     GEI_READ_REG(INTEL_82543GC_ICR, stat); 
  1364.     stat &= INTEL_82543GC_VALID_INT;
  1365.     /* return if not interrupt for this device */ 
  1366.     if (stat == 0) 
  1367.         {
  1368.         DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: PCI interrupt is not
  1369.                  caused by this GEI devicen", 1, 2, 3, 4, 5, 6);
  1370.         return;    
  1371.         }
  1372.     /* handle link interrupt event */
  1373.     if (stat & INT_LINK_CHECK)
  1374.         {
  1375.         DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: get a Link problemn", 
  1376.                                  1, 2, 3, 4, 5, 6);
  1377.         /* link status change, get status register */
  1378.         GEI_READ_REG(INTEL_82543GC_STATUS, statusRegVal);
  1379.         if (statusRegVal & STATUS_LU_BIT)
  1380.             {                
  1381.             /* link is up */
  1382.             if (pDrvCtrl->cableType == GEI_FIBER_MEDIA)
  1383.                 {
  1384.                 /* 
  1385.                  * restart link if partner send back a TXCW after
  1386.                  * force link
  1387.                  */
  1388.                 UINT32 rxcwRegVal;
  1389.                 UINT32 txcwRegVal;
  1390.       
  1391.                 GEI_READ_REG(INTEL_82543GC_RXCW, rxcwRegVal);
  1392.                 GEI_READ_REG(INTEL_82543GC_TXCW, txcwRegVal);
  1393.                 if ((pDrvCtrl->linkMethod == GEI82543_FORCE_LINK) &&
  1394.                     (rxcwRegVal & RXCW_C_BIT) &&          
  1395.                     (!(txcwRegVal & TXCW_ANE_BIT)))
  1396.                     {
  1397.                     DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: Hardware 
  1398.                              Auto-Negotiation restartn", 1, 2, 3, 4, 5, 6);
  1399.                     netJobAdd ((FUNCPTR)gei82543linkTBISetup, (int)pDrvCtrl, 
  1400.                                         FALSE, 0, 0, 0);             
  1401.                     return;
  1402.                     }
  1403.                 }
  1404.             else if (pDrvCtrl->cableType == GEI_COPPER_MEDIA)
  1405.                 {
  1406.                 LOGMSG("Reconfig device ... n",1,2,3,4,5,6); 
  1407.                 /* re-configure device based on GMII negotiation results */
  1408.    
  1409.                 if (pDrvCtrl->linkMethod == GEI82543_HW_AUTO)
  1410.                     {
  1411.                     netJobAdd ((FUNCPTR) gei82543GMIIphyReConfig, 
  1412.                                          (int)pDrvCtrl, 0, 0, 0, 0);             
  1413.                     return;
  1414.                     }
  1415.                 }
  1416.             }
  1417.         else  /* if link is down */
  1418.             {
  1419.             return;
  1420.             }
  1421.         }
  1422.     if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
  1423.         {   
  1424. if (stat & INT_RXTO_BIT)
  1425.     pDrvCtrl->rxIntCount++;
  1426.    if (stat & INT_RXO_BIT)
  1427.     pDrvCtrl->rxORunIntCount++;
  1428.   if (stat & (INT_TXDW_BIT | INT_TXDLOW_BIT))
  1429.     pDrvCtrl->txIntCount++;
  1430.         intTypeChk = AVAIL_RX_TX_INT | INT_TXDLOW_BIT;
  1431.         }
  1432.     else
  1433.         {
  1434.         intTypeChk = AVAIL_RX_TX_INT;
  1435.         }
  1436.                     
  1437.     /* tNetTask handles RX/TX interrupts */
  1438.     if ((stat & intTypeChk) && (pDrvCtrl->rxtxHandling != TRUE))
  1439.         {
  1440.         pDrvCtrl->rxtxHandling = TRUE;
  1441.  
  1442.         /* disable receive / transmit interrupt */        
  1443.         GEI_WRITE_REG(INTEL_82543GC_IMC, intTypeChk);
  1444.         /*
  1445.          * NOTE: Read back any chip register to flush PCI
  1446.          * bridge write buffer in case this adaptor is behind
  1447.          * a PCI bridge.
  1448.          */
  1449.      
  1450.         CACHE_PIPE_FLUSH ();
  1451.         GEI_READ_REG(INTEL_82543GC_IMS, stat);
  1452.         /* defer the handling ... */
  1453.         netJobAdd ((FUNCPTR) gei82543RxTxIntHandle, (int)pDrvCtrl, 0, 
  1454.                              0, 0, 0);
  1455.         }
  1456.     DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt...Donen", 1, 2, 3, 4, 5, 6);
  1457.     return;
  1458.     }
  1459. /*************************************************************************
  1460. *
  1461. * gei82543RxTxIntHandle - receive/transmit interrupt handle in task mode
  1462. *
  1463. * This routine gets the receive packet and pass them to upper network stack.
  1464. * It also cleans up TX descriptor if necessary. 
  1465. *
  1466. * RETURNS: N/A.
  1467. */
  1468. LOCAL void gei82543RxTxIntHandle
  1469.     (
  1470.     END_DEVICE *    pDrvCtrl     /* device to handle RX/TX */
  1471.     )
  1472.     {
  1473.     UINT32  rxCountPerInt = 0;   /* maximum RX descriptors to handle a int */
  1474.     UINT32  retry = 0;           /* retry count */
  1475.     char *  pRxDesc;             /* RX descriptor pointer */
  1476.     UINT32  stat;                /* cause of interrupt */
  1477.     UINT32  txRestartChk = TX_RESTART_NONE; /* flag chk if txRestart is scheduled */
  1478.     UINT8   rxdStat;             /* status of recv descriptor */
  1479.     DRV_LOG (DRV_DEBUG_RX, "gei82543RxTxIntHandle...n", 1, 2, 3, 4, 5, 6);
  1480.     do {
  1481.         while (rxCountPerInt++ < pDrvCtrl->maxRxNumPerInt)
  1482.             {
  1483.             /* get the current RX descriptor */
  1484.             pRxDesc = GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescTail);
  1485.             END_CACHE_INVALIDATE ((UINT32)pRxDesc, RXDESC_SIZE);     
  1486.             /* check RX descriptor status */
  1487.             rxdStat = GEI_READ_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET);
  1488.             if ((rxdStat & RXD_STAT_DD) == 0)
  1489.                break;
  1490.             /* process an incoming packet */
  1491.             if (gei82543Recv (pDrvCtrl, pRxDesc, rxdStat) != OK)
  1492.                 {
  1493.                 break;
  1494.                 }
  1495.             }
  1496.         if (retry++ == 3 || rxCountPerInt >= pDrvCtrl->maxRxNumPerInt)
  1497.               break;
  1498.         /* handle case that TX stalls */
  1499.        
  1500.         if (pDrvCtrl->txStall && txRestartChk != TX_RESTART_TRUE)
  1501.             txRestartChk = gei82543TxStallCheck (pDrvCtrl);     
  1502.         GEI_READ_REG(INTEL_82543GC_ICR, stat);
  1503.                   
  1504.         } while (stat & AVAIL_RX_INT);
  1505.     pDrvCtrl->rxtxHandling = FALSE;
  1506.     
  1507.     if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
  1508.         {
  1509. pDrvCtrl->rxtxHandlerNum++;
  1510.         pDrvCtrl->rxPacketNum += rxCountPerInt;
  1511. }
  1512.     /* free loaned mBlk if needed */
  1513.     if (pDrvCtrl->txResoFreeQuick == TRUE)
  1514.         gei82543TxMblkFree (pDrvCtrl, FREE_ALL_AUTO);
  1515.     /* enable RX/TX interrupts */
  1516.     if (pDrvCtrl->txStall && pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD) 
  1517.         {
  1518.         GEI_WRITE_REG(INTEL_82543GC_IMS, (AVAIL_RX_TX_INT | IMS_TXDLOW_BIT));
  1519.         }
  1520.     else 
  1521.         {
  1522.         GEI_WRITE_REG(INTEL_82543GC_IMS, AVAIL_RX_TX_INT);
  1523.         }
  1524.     
  1525.     /* if muxTxRestart is not in tNetTask job queue, chk TxStall */
  1526.     if (txRestartChk != TX_RESTART_TRUE)
  1527.         gei82543TxStallCheck (pDrvCtrl);   
  1528.     CACHE_PIPE_FLUSH();
  1529.     DRV_LOG (DRV_DEBUG_RX, "gei82543RxTxIntHandle...Donen", 
  1530.                             1, 2, 3, 4, 5, 6);
  1531.     return;
  1532.     }
  1533. /*************************************************************************
  1534. *
  1535. * gei82543TxStallCheck - handling TX stalling due to out of TX descriptors
  1536. *
  1537. * This routine checks the availability of TX descriptors, and restart 
  1538. * transmitting if TX descriptor available
  1539. *
  1540. * RETURN: TX_RESTART_TRUE if muxTxRestart is put into tNetTask job queue,
  1541. *         otherwise, TX_RESTART_NONE 
  1542. */ 
  1543. LOCAL UINT32 gei82543TxStallCheck
  1544.     (
  1545.     END_DEVICE *    pDrvCtrl    /* device to check TX stall */
  1546.     )
  1547.     {
  1548.     int txFreeDescNum;          /* available Tx number */
  1549.     DRV_LOG (DRV_DEBUG_TX, "handle txStall ...n", 1, 2, 3, 4, 5, 6);
  1550.     /* take a semaphore */
  1551.     END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
  1552.     if (pDrvCtrl->txStall == FALSE)
  1553.         {
  1554.         END_TX_SEM_GIVE (&pDrvCtrl->end);
  1555.         return TX_RESTART_NONE; 
  1556.         }
  1557.     txFreeDescNum = gei82543TxDesCleanGet (pDrvCtrl, FREE_ALL_AUTO);
  1558.     if (pDrvCtrl->txReqDescNum <= txFreeDescNum)
  1559.         {
  1560.         /* TX Descriptors available, restart transmit */
  1561.         DRV_LOG (DRV_DEBUG_TX, "Restart muxn", 1, 2, 3, 4, 5, 6);
  1562.         (void) netJobAdd ((FUNCPTR) muxTxRestart, (int)&pDrvCtrl->end, 
  1563.                           0, 0, 0, 0);
  1564.         if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
  1565.     {
  1566.             /* disable the TXD_LOW interrupt */
  1567.             GEI_WRITE_REG(INTEL_82543GC_IMC, IMC_TXDLOW_BIT);
  1568.             }
  1569.         GEI_WRITE_REG(INTEL_82543GC_TIDV, pDrvCtrl->txIntDelay);
  1570.         pDrvCtrl->txStall = FALSE;             
  1571.  
  1572.         END_TX_SEM_GIVE (&pDrvCtrl->end);
  1573.         return TX_RESTART_TRUE;
  1574.         }
  1575.     END_TX_SEM_GIVE (&pDrvCtrl->end);
  1576.     return TX_RESTART_NONE;
  1577.     }
  1578. /*************************************************************************
  1579. *
  1580. * gei82543Recv - process an incoming packet
  1581. *
  1582. * This routine checks the incoming packet, and passes it the upper layer.
  1583. *
  1584. * RETURNS: OK, or ERROR if receiving fails
  1585. */
  1586. LOCAL STATUS gei82543Recv
  1587.     (
  1588.     END_DEVICE *    pDrvCtrl,    /* device structure */
  1589.     char *          pRxDesc,     /* pointer to RX descriptor */
  1590.     UINT8           rxdStat      /* RX descriptor status */
  1591.     )
  1592.     {
  1593.     UINT16                len;              /* len of packet received */
  1594.     M_BLK_ID              pMblk;            /* mBlk to store this packet */
  1595.     volatile char *       pCluster = NULL;  /* cluster pointer */
  1596.     volatile char *       pNewCluster = NULL; /* new cluster pointer */
  1597.     volatile CL_BLK_ID    pClBlk = NULL;    /* cluster block pointer */
  1598.     char *                pData;            /* receve data pointer */
  1599.     UINT32                bufAddr;          /* buffer address */
  1600.     UINT8                 rxdErr;           /* RX descriptor Error field */
  1601.     DRV_LOG (DRV_DEBUG_RX, "gei82543Recv start...n",  1, 2, 3, 4, 5, 6);
  1602.     /* check packet status */
  1603.     
  1604.     if (!(rxdStat & RXD_STAT_EOP))
  1605.         {
  1606.         DRV_LOG (DRV_DEBUG_RX, "Packet EOP not setn", 1, 2, 3, 4, 5, 6);
  1607.         LOGMSG("Packet EOP not set n",1,2,3,4,5,6);
  1608.         goto receiveError;
  1609.         }
  1610.     rxdErr = GEI_READ_DESC_BYTE(pRxDesc, RXDESC_ERROR_OFFSET);
  1611. #ifdef INCLUDE_TBI_COMPATIBLE
  1612.     rxdErr &= (UINT8)(~(RXD_ERROR_IPE | RXD_ERROR_TCPE | RXD_ERROR_RSV));
  1613.     GEI_READ_DESC_WORD(pRxDesc, RXDESC_LENGTH_OFFSET, len);
  1614.     if (rxdErr)
  1615.         {
  1616.         BOOL frameAccept = FALSE;
  1617.         if (rxdErr == RXD_ERROR_CE && pDrvCtrl->tbiCompatibility)
  1618.             {
  1619.             UINT8 * bufAdr;
  1620.             UINT8 lastChar;
  1621.             /* software workaround for TBI compatibility problem */
  1622.            
  1623.             GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, (UINT32)bufAdr);
  1624.             lastChar = *(UINT8 *)((UINT32)bufAdr + len - 1);
  1625.             
  1626.             if (lastChar == CARRIER_EXTENSION_BYTE &&
  1627.                 len > (MIN_ETHER_PACKET_SIZE + RX_CRC_LEN) && 
  1628.                 len <= (pDrvCtrl->mtu + GEI_DEFAULT_ETHERHEADER + RX_CRC_LEN + 1))  
  1629.                 {
  1630.                 frameAccept = TRUE;
  1631.                 rxdErr = 0;
  1632.                 len--;
  1633.                 }
  1634.             }
  1635.         if (frameAccept != TRUE)
  1636.             {
  1637.             DRV_LOG (DRV_DEBUG_RX, "Packet Error 0x%xn", rxdErr, 
  1638.                                     2, 3, 4, 5, 6);
  1639.             LOGMSG("Packet error 0x%x n",rxdErr, 2, 3, 4, 5, 6);
  1640.             goto receiveError;
  1641.             }
  1642.         }
  1643. #else /* !INCLUDE_TBI_COMPATIBLE */
  1644.     if (rxdErr & (UINT8)(~(RXD_ERROR_IPE | RXD_ERROR_TCPE)))
  1645.         {
  1646.         DRV_LOG (DRV_DEBUG_RX, "Packet Error 0x%xn", rxdErr, 2, 3, 4, 5, 6);
  1647.         LOGMSG("Packet error 0x%x n",rxdErr, 2, 3, 4, 5, 6);
  1648.         goto receiveError;
  1649.         }
  1650.     /* get packet length */
  1651.     GEI_READ_DESC_WORD(pRxDesc, RXDESC_LENGTH_OFFSET, len);
  1652. #endif /* INCLUDE_TBI_COMPATIBLE */
  1653.     len -= RX_CRC_LEN;
  1654.     len &= ~0xc000;
  1655.     if (len > (pDrvCtrl->mtu + GEI_DEFAULT_ETHERHEADER) || 
  1656.         len < MIN_ETHER_PACKET_SIZE)
  1657.         {        
  1658.         DRV_LOG (DRV_DEBUG_RX, ("invalid packet length=0x%x!n"), len, 
  1659.                                  0, 0, 0, 0, 0);
  1660.         goto receiveError;
  1661.         }
  1662.    /*
  1663.     * we implicitly using loaning here, if copying is necessary this
  1664.     * step may be skipped, but the data must be copied before being
  1665.     * passed up to the protocols.
  1666.     */
  1667.     pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, 
  1668.                     pDrvCtrl->pClPoolId);
  1669.     if (pNewCluster == NULL)
  1670.         {
  1671.         DRV_LOG (DRV_DEBUG_RX, "Not free new Cluster!n", 1, 2, 3, 4, 5, 6);
  1672.         goto receiveError;
  1673.         }
  1674.     /* grab a cluster block to marry to the cluster we received. */
  1675.     if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
  1676.         {
  1677.         netClFree (pDrvCtrl->end.pNetPool, (unsigned char *)pNewCluster);
  1678.         DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!n", 1, 2, 3, 4, 5, 6);
  1679.         goto receiveError;
  1680.         }   
  1681.     /*
  1682.      * OK we've got a spare descriptor, let's get an M_BLK_ID and marry it 
  1683.      * to the one in the ring.
  1684.      */
  1685.     if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) 
  1686.           == NULL)
  1687.         {
  1688.         netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); 
  1689.         netClFree (pDrvCtrl->end.pNetPool, (unsigned char *)pNewCluster);
  1690.         DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!n", 1, 2, 3, 4, 5, 6);
  1691.         goto receiveError;
  1692.         }
  1693.     GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, bufAddr);
  1694.     pCluster = GEI_BUS_TO_VIRT(bufAddr);
  1695.     pData = (char *) pCluster;
  1696.     END_CACHE_INVALIDATE ((UINT32)pCluster, len);   
  1697.     pCluster -= pDrvCtrl->offset;
  1698.     netClBlkJoin (pClBlk, (char *)pCluster, len, NULL, 0, 0, 0);
  1699.     netMblkClJoin (pMblk, pClBlk);
  1700.     if ((*pData ) & (UINT8) 0x01)
  1701.         pDrvCtrl->end.mib2Tbl.ifInNUcastPkts += 1;
  1702.     else
  1703.         END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
  1704.     /* set up Mblk */
  1705.     pMblk->mBlkHdr.mLen = len;
  1706.     pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  1707.     pMblk->mBlkPktHdr.len = len;
  1708.     pMblk->mBlkHdr.mData = (char *)pData;
  1709.     /* update the new descriptor, and update the tail pointer */
  1710.     gei82543RxDesUpdate(pDrvCtrl, (char *)pNewCluster);
  1711.     /* call the upper layer's receive routine. */
  1712.     END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
  1713.     DRV_LOG (DRV_DEBUG_RX, "Receive done!n", 1, 2, 3, 4, 5, 6);
  1714.     return OK;
  1715. receiveError:
  1716.     END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
  1717.     gei82543RxDesUpdate (pDrvCtrl, NULL);
  1718.     if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
  1719.         {
  1720. pDrvCtrl->rxPacketDrvErr++;
  1721. }
  1722.     DRV_LOG (DRV_DEBUG_RX, "Receive ERROR!n", 1, 2, 3, 4, 5, 6);
  1723.  
  1724.     return ERROR;
  1725.     }
  1726. /*************************************************************************
  1727. *
  1728. * gei82543RxDesUpdate - clean up the receive descriptor
  1729. *
  1730. * This routine cleans up receive descriptors, hook up to a new cluster 
  1731. * if needed, and then update the tail pointer to make it available to the
  1732. * hardware.
  1733. *
  1734. * RETURNS: N/A
  1735. */
  1736. LOCAL void gei82543RxDesUpdate 
  1737.     (
  1738.     END_DEVICE *    pDrvCtrl,    /* device to update  */
  1739.     char *          pCluster     /* new cluster pointer */
  1740.     )
  1741.     {
  1742.     int         tempTail;        /* temporary tail index */
  1743.     char *      pRxDesc = NULL;   /* RX descriptor */
  1744.    
  1745.     DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...n", 1, 2, 3, 4, 5, 6);
  1746.     /* get the RX tail descriptor */
  1747.     pRxDesc = GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescTail);
  1748.     
  1749.     if (pCluster != NULL)
  1750.         {
  1751.         pCluster += pDrvCtrl->offset;
  1752.         GEI_WRITE_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET,
  1753.                            (UINT32)GEI_VIRT_TO_BUS(pCluster));
  1754.         }
  1755.     /* clean up status field */
  1756.     GEI_WRITE_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET, 0);
  1757.     /* save the tail pointer before update */
  1758.     tempTail = pDrvCtrl->rxDescTail;
  1759.     /* update the tail pointer */
  1760.     GEI_GET_RX_DESC_TAIL_UPDATE(pDrvCtrl->rxDescTail, 1);
  1761.     /* kick this descriptor for receiving packet */
  1762.     GEI_WRITE_REG(INTEL_82543GC_RDT, tempTail);
  1763.     CACHE_PIPE_FLUSH();
  1764.  
  1765.     DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...Donen", 
  1766.                             1, 2, 3, 4, 5, 6);
  1767.     return;
  1768.     }
  1769. /*************************************************************************
  1770. *
  1771. * gei82543TxMblkFree - free transmit mBlk(s)
  1772. *
  1773. * This routine frees transmit mBlk(s) after packets have been transmitted 
  1774. * on wire. 
  1775. *
  1776. * RETURNS: N/A.
  1777. */
  1778. LOCAL void gei82543TxMblkFree
  1779.     (
  1780.     END_DEVICE *    pDrvCtrl,    /* device to free transmit mBlk(s) */
  1781.     int             mode         /* AUTO/FORCE */
  1782.     )
  1783.     {
  1784.     int    maxFreeTxDesc;
  1785.                
  1786.     DRV_LOG (DRV_DEBUG_TX, "gei82543TxMblkFree...n", 1, 2, 3, 4, 5, 6);
  1787.     
  1788.     /* take semaphore */
  1789.     END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
  1790.     gei82543TxDesCleanGet (pDrvCtrl, mode);    
  1791.     /* sanity check */
  1792.     if (mode == FREE_ALL_FORCE)
  1793.         {
  1794.         maxFreeTxDesc = pDrvCtrl->txDescNum - 1;
  1795.         if (pDrvCtrl->txDescFreeNum != maxFreeTxDesc)
  1796.             {
  1797.             LOGMSG("Panic: TX Descriptors are not cleaned upn", 1,2,3,4,5,6);
  1798.             }
  1799.         }
  1800.     END_TX_SEM_GIVE (&pDrvCtrl->end);
  1801.     DRV_LOG (DRV_DEBUG_TX, "gei82543TxMblkFree...Donen", 1, 2, 3, 4, 5, 6);    
  1802.     
  1803.     return;
  1804.     }
  1805. /*****************************************************************************
  1806. *
  1807. * gei82543TxResoFree - free loaned TX mBlks constantly
  1808. *
  1809. * This routine frees loaned TX mBlks constantly, and updates device statistics,
  1810. * it may also execute a callback function defined in sysGei82543End.c
  1811. *
  1812. * RETURNS: N/A
  1813. */
  1814. LOCAL void gei82543TxResoFree 
  1815.     (
  1816.     END_DEVICE * pDrvCtrl   /* END device */
  1817.     )
  1818.     {
  1819.     ADAPTOR_INFO * pBoard;   /* pointer to device specific struct */
  1820.     DEVDRV_STAT  * pStat;    /* pointer to device/driver statistics */
  1821.     DEV_TIMER    * pTimer;   /* pointer to driver specific timer info */
  1822.     int ti;                  /* timer interval */
  1823.     DRV_LOG (DRV_DEBUG_TIMER, "gei82543TxResoFree...startn", 
  1824.                                        1, 2, 3, 4, 5, 6);
  1825.     gei82543TxMblkFree (pDrvCtrl, FREE_ALL_AUTO);
  1826.     /* set the internal timer */
  1827.     if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)    
  1828.       {
  1829.       pBoard = &pDrvCtrl->adaptor;
  1830.       if (pBoard->sysGeiDynaTimerSetup != NULL)
  1831.   {
  1832.           pStat = &pBoard->devDrvStat;
  1833.           ti = pDrvCtrl->timerInterval;
  1834.     pStat->rxtxHandlerNum = pDrvCtrl->rxtxHandlerNum / ti;
  1835.           pStat->rxIntCount     = pDrvCtrl->rxIntCount / ti;
  1836.   pStat->txIntCount     = pDrvCtrl->txIntCount / ti;
  1837.   pStat->rxORunIntCount = pDrvCtrl->rxORunIntCount / ti;
  1838.   pStat->rxPacketNum    = pDrvCtrl->rxPacketNum / ti;
  1839.   pStat->rxPacketDrvErr = pDrvCtrl->rxPacketDrvErr / ti;
  1840.           GEI_READ_REG(INTEL_82543GC_TPT, pDrvCtrl->staRegs.tpt);
  1841.           pStat->txPacketNum    = pDrvCtrl->staRegs.tpt / ti;
  1842.           if (pBoard->sysGeiDynaTimerSetup (pBoard))
  1843.       {
  1844.               pTimer = &pBoard->devTimerUpdate;
  1845.               if (!(pTimer->rdtrVal & 0xffff0000))
  1846.                   GEI_WRITE_REG(INTEL_82543GC_RDTR,pTimer->rdtrVal);
  1847.               if (!(pTimer->radvVal & 0xffff0000))
  1848.                   GEI_WRITE_REG(INTEL_82546EB_RADV,pTimer->radvVal);
  1849.               if (!(pTimer->itrVal & 0xffff0000))
  1850.                   GEI_WRITE_REG(INTEL_82546EB_ITR,pTimer->itrVal);
  1851.       pDrvCtrl->timerInterval = (pTimer->watchDogIntVal <= 0) ?
  1852.      DEFAULT_TIMER_INTERVAL : (pTimer->watchDogIntVal);
  1853.               }
  1854.           
  1855.           /* clean up */
  1856.   pDrvCtrl->rxtxHandlerNum  = 0;
  1857.           pDrvCtrl->rxIntCount      = 0;
  1858.   pDrvCtrl->txIntCount      = 0;
  1859.   pDrvCtrl->rxORunIntCount  = 0;
  1860.   pDrvCtrl->rxPacketNum     = 0;
  1861.   pDrvCtrl->rxPacketDrvErr  = 0;
  1862.           }
  1863.       }
  1864.     /* restart timer */
  1865.     
  1866.     wdStart (pDrvCtrl->timerId, pDrvCtrl->timerInterval * sysClkRateGet(), 
  1867.              (FUNCPTR) gei82543EndTimerHandler, (int) pDrvCtrl);        
  1868.     DRV_LOG (DRV_DEBUG_TIMER, "gei82543TxResoFree...Donen", 
  1869.                                        1, 2, 3, 4, 5, 6);    
  1870.     }
  1871. /*****************************************************************************
  1872. *
  1873. * gei82543EndTimerHandler - timer interrupt handler routine
  1874. *
  1875. * This routine handle timer interrupts to free TX resources
  1876. *
  1877. * RETURNS: N/A
  1878. */
  1879. LOCAL void gei82543EndTimerHandler
  1880.     (
  1881.     END_DEVICE *    pDrvCtrl  /* END device structure */
  1882.     )
  1883.     {
  1884.     DRV_LOG (DRV_DEBUG_TIMER, ("gei82543EndTimerHandler...n"), 
  1885.                                1, 2, 3, 4, 5, 6);
  1886.     if (pDrvCtrl->txDescFreeNum != (pDrvCtrl->txDescNum - 1) || 
  1887.          ((pDrvCtrl->adaptor.sysGeiDynaTimerSetup != NULL) && 
  1888.           (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)))    
  1889.       {
  1890.        netJobAdd ((FUNCPTR)gei82543TxResoFree, (int)pDrvCtrl,0,0,0,0);
  1891.       }
  1892.     else
  1893.        wdStart (pDrvCtrl->timerId, pDrvCtrl->timerInterval * sysClkRateGet(), 
  1894.              (FUNCPTR) gei82543EndTimerHandler, (int) pDrvCtrl);        
  1895.        
  1896.     DRV_LOG (DRV_DEBUG_TIMER, ("gei82543EndTimerHandler...DONEn"), 
  1897.                                1, 2, 3, 4, 5, 6);
  1898.     return;
  1899.     }
  1900. /*************************************************************************
  1901. *
  1902. * gei82543EndIoctl - the driver I/O control routine
  1903. *
  1904. * Process an ioctl request.
  1905. *
  1906. * RETURNS: A command specific response, usually OK or ERROR.
  1907. */
  1908. LOCAL int gei82543EndIoctl
  1909.     (
  1910.     END_DEVICE *    pDrvCtrl,    /* device receiving command */
  1911.     int             cmd,         /* ioctl command code */
  1912.     caddr_t         data         /* command argument */
  1913.     )
  1914.     {
  1915.     int     error = 0;
  1916.     long    value;
  1917.     DRV_LOG (DRV_DEBUG_IOCTL, ("IOCTL command beginn"), 0,0,0,0,0,0);
  1918.     switch ((UINT)cmd)
  1919.         {
  1920.         case EIOCSADDR:
  1921.             if (data == NULL)
  1922.                 return (EINVAL);
  1923.             bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
  1924.                       END_HADDR_LEN(&pDrvCtrl->end));
  1925.             break;
  1926.         case EIOCGADDR:
  1927.             if (data == NULL)
  1928.                 return (EINVAL);
  1929.             bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
  1930.                                            END_HADDR_LEN(&pDrvCtrl->end));
  1931.             break;
  1932.         case EIOCSFLAGS:
  1933.             value = (long)data;
  1934.             if (value < 0)
  1935.                 {
  1936.                 value = -value;
  1937.                 value--;
  1938.                 END_FLAGS_CLR (&pDrvCtrl->end, value);
  1939.                 }
  1940.             else
  1941.                 END_FLAGS_SET (&pDrvCtrl->end, value);
  1942.             DRV_LOG (DRV_DEBUG_IOCTL, ("endFlag=0x%xn"), 
  1943.                                 END_FLAGS_GET(&pDrvCtrl->end), 0,0,0,0,0);
  1944.             END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
  1945.             gei82543EndConfigure(pDrvCtrl);
  1946.             END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
  1947.             break;
  1948.         case EIOCGFLAGS:
  1949.             *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
  1950.             break;
  1951.         case EIOCPOLLSTART:    /* Begin polled operation */
  1952.             gei82543EndPollStart (pDrvCtrl);
  1953.             break;
  1954.         case EIOCPOLLSTOP:    /* End polled operation */
  1955.             gei82543EndPollStop (pDrvCtrl);
  1956.             break;
  1957.            
  1958.         case EIOCGMIB2:        /* return MIB information */
  1959.             if (data == NULL)
  1960.                 return (EINVAL);
  1961.             bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data,
  1962.                   sizeof(pDrvCtrl->end.mib2Tbl));
  1963.             break;
  1964.         case EIOCMULTIADD:
  1965.             error = gei82543EndMCastAdd (pDrvCtrl, (char *) data);
  1966.             break;
  1967.         case EIOCMULTIDEL:
  1968.             error = gei82543EndMCastDel (pDrvCtrl, (char *) data);
  1969.             break;
  1970.         case EIOCMULTIGET:
  1971.             error = gei82543EndMCastGet (pDrvCtrl, (MULTI_TABLE *) data);
  1972.             break;
  1973.         default:
  1974.             DRV_LOG (DRV_DEBUG_IOCTL, ("invalid IOCTL command n"), 
  1975.                                         0,0,0,0,0,0);
  1976.             error = EINVAL;
  1977.         }
  1978.     DRV_LOG (DRV_DEBUG_IOCTL, ("IOCTL command Donen"), 0,0,0,0,0,0);
  1979.     return (error);
  1980.     }
  1981. /*************************************************************************
  1982. *
  1983. * gei82543EndConfigure - re-configure chip interface 
  1984. *
  1985. * This routine re-configures the interface such as promisc, multicast
  1986. * and broadcast modes
  1987. *
  1988. * RETURNS: N/A.
  1989. */
  1990. LOCAL void gei82543EndConfigure
  1991.     (
  1992.     END_DEVICE *    pDrvCtrl        /* device to configure */
  1993.     )
  1994.     {
  1995.     int    oldVal = 0;
  1996.     int    newVal = 0;
  1997.     DRV_LOG (DRV_DEBUG_IOCTL, ("gei82543EndConfig...n"), 1,2,3,4,5,6);
  1998.     (void)taskLock ();
  1999.      
  2000.     /* save flags for later use */
  2001.     oldVal = pDrvCtrl->flags;
  2002.     newVal = END_FLAGS_GET(&pDrvCtrl->end);
  2003.     /* set the driver flag based on END_FLAGS */ 
  2004.     if (newVal & IFF_PROMISC)
  2005.         pDrvCtrl->flags |= FLAG_PROMISC_MODE;            
  2006.     else
  2007.         pDrvCtrl->flags &= ~FLAG_PROMISC_MODE;
  2008.     if (newVal & IFF_ALLMULTI)
  2009.         pDrvCtrl->flags |= FLAG_ALLMULTI_MODE;
  2010.     else
  2011.         pDrvCtrl->flags &= ~FLAG_ALLMULTI_MODE;
  2012.     if (newVal & IFF_MULTICAST)
  2013.         pDrvCtrl->flags |= FLAG_MULTICAST_MODE;
  2014.     else
  2015.         pDrvCtrl->flags &= ~FLAG_MULTICAST_MODE;
  2016.     if (newVal & IFF_BROADCAST)
  2017.         pDrvCtrl->flags |= FLAG_BROADCAST_MODE;
  2018.     else
  2019.         pDrvCtrl->flags &= ~FLAG_BROADCAST_MODE;
  2020.     if (oldVal == pDrvCtrl->flags)
  2021.         {
  2022.         (void)taskUnlock ();
  2023.         return;
  2024.         }
  2025.     /* read RX control register */
  2026.     GEI_READ_REG(INTEL_82543GC_RCTL, oldVal);
  2027.     newVal = oldVal;
  2028.     /* prepare new value for RX control register */
  2029.     if (pDrvCtrl->flags & FLAG_PROMISC_MODE)
  2030.         newVal |= (RCTL_UPE_BIT | RCTL_MPE_BIT | RCTL_BAM_BIT);
  2031.     else
  2032.         newVal &= ~(RCTL_UPE_BIT | RCTL_MPE_BIT);
  2033.     if (pDrvCtrl->flags & FLAG_ALLMULTI_MODE)
  2034.         newVal |= RCTL_MPE_BIT;
  2035.     else if (!(pDrvCtrl->flags & FLAG_PROMISC_MODE))
  2036.         newVal &= ~RCTL_MPE_BIT;
  2037.     if (pDrvCtrl->flags & FLAG_BROADCAST_MODE)
  2038.         newVal |= RCTL_BAM_BIT;
  2039.     else if (!(pDrvCtrl->flags & FLAG_PROMISC_MODE))
  2040.         newVal &= ~RCTL_BAM_BIT;
  2041.     /* set up RX control register if needed */
  2042.     if (newVal != oldVal)
  2043.         GEI_WRITE_REG(INTEL_82543GC_RCTL, newVal);
  2044.     /* set up Multicasting address */
  2045.     if (pDrvCtrl->flags & FLAG_MULTICAST_MODE)
  2046.         gei82543AddrFilterSet (pDrvCtrl);
  2047.     else 
  2048.         gei82543McastAdrClean(pDrvCtrl);
  2049.   
  2050.     (void)taskUnlock ();
  2051.     DRV_LOG (DRV_DEBUG_IOCTL, ("gei82543EndConfig...Donen"), 
  2052.                                 0, 0, 0, 0, 0, 0);
  2053.     return;
  2054.     }
  2055. /*************************************************************************
  2056. *
  2057. * gei82543AddrFilterSet - set the address filter for multicast addresses
  2058. *
  2059. * This routine goes through all of the multicast addresses on the list
  2060. * of addresses (added with the endAddrAdd() routine) and sets the
  2061. * device's filter correctly.
  2062. *
  2063. * RETURNS: N/A.
  2064. */
  2065. LOCAL void gei82543AddrFilterSet
  2066.     (
  2067.     END_DEVICE *pDrvCtrl    /* device to be updated */
  2068.     )
  2069.     {
  2070.     ETHER_MULTI* pCurr;                      /* multi table address */
  2071.     int          count;                      /* number of multi address */
  2072.     int          i;                          /* index */
  2073.     int          col;                        /* column in MTA */
  2074.     int          row;                        /* row in MTA */
  2075.     int          tmp;                        /* temporary */
  2076.     UINT8        tmpBuf[ETHER_ADDRESS_SIZE]; /* array to save ETH addr */
  2077.     UINT16       hashVal;                    /* hash value for MTA */
  2078.     UINT32       lowAdr;                     /* adr low in RTA */
  2079.     UINT32       highAdr;                    /* adr high in RTA */
  2080.     DRV_LOG (DRV_DEBUG_IOCTL, ("gei82543AddrFilterSet...n"), 0,0,0,0,0,0);
  2081.     /* clean up all multicasting address in RTA and MTA */
  2082.     gei82543McastAdrClean(pDrvCtrl);
  2083.     /* get the number of multicasting address */
  2084.     if ((count = END_MULTI_LST_CNT(&pDrvCtrl->end)) == 0)
  2085.            return;
  2086.        
  2087.     if (count > MAX_NUM_MULTI)
  2088.         {
  2089.         LOGMSG("only accept %d multicast addressn",MAX_NUM_MULTI,2,3,4,5,6);
  2090.         count =  MAX_NUM_MULTI;
  2091.         }
  2092.     /* 
  2093.      * The first 15 multicast will stored in the RAT (RAL/RAH)
  2094.      * the rest are stored in MAT 
  2095.      */
  2096.     pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);    
  2097.     /* the first entry (i=0) in RAT is not for multicast addr */
  2098.     for (i = 1; i< NUM_RAR && count; i++, count--)
  2099.         {
  2100.         memcpy (tmpBuf, (char *)&pCurr->addr, ETHER_ADDRESS_SIZE);
  2101.             
  2102.         lowAdr = tmpBuf[0] | (tmpBuf[1] << 8) | (tmpBuf[2] << 16) |
  2103.                    (tmpBuf[3] << 24);
  2104.  
  2105.         highAdr = tmpBuf[4] | (tmpBuf[5] << 8);
  2106.         GEI_WRITE_REG((INTEL_82543GC_RAL + 8 * i), lowAdr);
  2107.         GEI_WRITE_REG((INTEL_82543GC_RAH +8 * i), (highAdr | RAH_AV_BIT));
  2108.        
  2109.         pCurr = END_MULTI_LST_NEXT(pCurr);
  2110.         }
  2111.     /* configure MTA table if more multicast address remaining */
  2112.     while (count--)
  2113.         {
  2114.         memcpy (tmpBuf, (char *)&pCurr->addr, ETHER_ADDRESS_SIZE);
  2115.         /* 
  2116.          * compose hash value based on filter type :
  2117.          * MULTI_FILTER_TYPE_47_36: 47 - 36 bits for dest multicast addr match
  2118.          * MULTI_FILTER_TYPE_46_35: 46 - 35 bits for dest multicast addr match
  2119.          * MULTI_FILTER_TYPE_45_34: 45 - 34 bits for dest multicast addr match
  2120.          * MULTI_FILTER_TYPE_43_32: 43 - 32 bits for dest multicast addr match
  2121.          */
  2122.         
  2123.         if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_47_36)
  2124.             hashVal = (tmpBuf[4] >> 4) | ((UINT16)(tmpBuf[5]) << 4); 
  2125.         else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_46_35)
  2126.             hashVal = (tmpBuf[4] >> 3) | ((UINT16)(tmpBuf[5]) << 5); 
  2127.         else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_45_34)
  2128.             hashVal = (tmpBuf[4] >> 2) | ((UINT16)(tmpBuf[5]) << 6 ); 
  2129.         else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_43_32)
  2130.             hashVal = tmpBuf[4] | ((UINT16)(tmpBuf[5]) << 8 ); 
  2131.            
  2132.         else
  2133.             {
  2134.             LOGMSG("Error in compose multicast hash valuen",1,2,3,4,5,6);
  2135.             return;
  2136.             }  
  2137.         /* the first 5 bits is the bit location (32 maximum) in a register */
  2138.        
  2139.         col = hashVal & 0x1f;
  2140.         /* the remaining 7 bits is for the register offset (128 maximum) */
  2141.         row = (hashVal >> 5) & 0x7f;
  2142.        
  2143.         GEI_READ_REG((INTEL_82543GC_MTA + row * 32), tmp);
  2144.         /* find the right bit location */
  2145.         tmp |= (1 << col);       
  2146.         GEI_WRITE_REG((INTEL_82543GC_MTA + row * 32), tmp);
  2147.         pCurr = END_MULTI_LST_NEXT(pCurr);
  2148.         }
  2149.     taskDelay (sysClkRateGet() / 20);
  2150.     DRV_LOG (DRV_DEBUG_IOCTL,("gei82543AddrFilterSet...Donen"), 0,0,0,0,0,0);
  2151.     return;
  2152.     }
  2153. /*************************************************************************
  2154. *
  2155. * gei82543EndMCastAdd - add a multicast address for the device
  2156. *
  2157. * This routine adds a multicast address to whatever the driver
  2158. * is already listening for.  It then resets the address filter.
  2159. *
  2160. * RETURNS: OK or ERROR.
  2161. */
  2162. LOCAL STATUS gei82543EndMCastAdd
  2163.     (
  2164.     END_DEVICE *    pDrvCtrl,        /* device pointer */
  2165.     char *          pAddress         /* new address to add */
  2166.     )
  2167.     {
  2168.     int error;
  2169.     if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == 
  2170.           ENETRESET)
  2171.         {
  2172.         pDrvCtrl->end.nMulti++;
  2173.         if (pDrvCtrl->end.nMulti  > MAX_NUM_MULTI)
  2174.             {
  2175.             pDrvCtrl->end.nMulti--;
  2176.             etherMultiDel (&pDrvCtrl->end.multiList,pAddress);
  2177.             return ERROR;
  2178.             }
  2179.         else
  2180.             gei82543AddrFilterSet(pDrvCtrl);
  2181.         }
  2182.     return (OK);
  2183.     }
  2184. /*************************************************************************
  2185. *
  2186. * gei82543EndMCastDel - delete a multicast address for the device
  2187. *
  2188. * This routine removes a multicast address from whatever the driver
  2189. * is listening for.  It then resets the address filter.
  2190. *
  2191. * RETURNS: OK or ERROR.
  2192. */
  2193. LOCAL STATUS gei82543EndMCastDel
  2194.     (
  2195.     END_DEVICE *     pDrvCtrl,        /* device pointer */
  2196.     char *           pAddress         /* address to be deleted */
  2197.     )
  2198.     {
  2199.     int error;
  2200.     if ((error = etherMultiDel (&pDrvCtrl->end.multiList,(char *)pAddress)) 
  2201.         == ENETRESET)
  2202.         {
  2203.         gei82543AddrFilterSet(pDrvCtrl);         
  2204.         pDrvCtrl->end.nMulti--;
  2205.         }
  2206.     return (OK);
  2207.     }
  2208. /*****************************************************************************
  2209. *
  2210. * gei82543EndMCastGet - get the multicast address list for the device
  2211. *
  2212. * This routine gets the multicast list of whatever the driver
  2213. * is already listening for.
  2214. *
  2215. * RETURNS: OK or ERROR.
  2216. */
  2217. LOCAL STATUS gei82543EndMCastGet
  2218.     (
  2219.     END_DEVICE *    pDrvCtrl,        /* device pointer */
  2220.     MULTI_TABLE *   pTable            /* address table to be filled in */
  2221.     )
  2222.     {
  2223.     return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));
  2224.     }
  2225. /*************************************************************************
  2226. *
  2227. * gei82453EndPollRcv - routine to receive a packet in polling mode.
  2228. *
  2229. * This routine receive a packet in polling mode
  2230. *
  2231. * RETURNS: OK or ERROR.
  2232. */
  2233. LOCAL STATUS gei82543EndPollRcv
  2234.     (
  2235.     END_DEVICE * pDrvCtrl,    /* device to be polled */
  2236.     M_BLK_ID     pMblk        /* mBlk to receive */
  2237.     )
  2238.     {
  2239.     char*    pCluster;        /* receiving packet addr */
  2240.     char*    pRxDesc;         /* RX descriptor addr */
  2241.     int      len;             /* packet length */
  2242.     STATUS   retVal = OK;     /* return value */
  2243.     UINT32   bufAddr;         /* buffer address */
  2244.     DRV_LOG (DRV_DEBUG_POLL_RX, "gei82543EndPollRcv...n", 
  2245.                                  1, 2, 3, 4, 5, 6);
  2246.     if (!(pMblk->mBlkHdr.mFlags & M_EXT))
  2247.         {
  2248.         DRV_LOG (DRV_DEBUG_POLL_RX, "poll receive: bad mblkn", 
  2249.                                      1, 2, 3, 4, 5, 6);
  2250.         return (EAGAIN);
  2251.         }
  2252.     pRxDesc = GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescTail);
  2253.     END_CACHE_INVALIDATE ((UINT32)pRxDesc, RXDESC_SIZE);     
  2254.     /* check RX descriptor status */ 
  2255.     if (!(GEI_READ_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET) & RXD_STAT_DD))   
  2256.         return (EAGAIN);
  2257.     if (!(GEI_READ_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET) & RXD_STAT_EOP) 
  2258.         || (GEI_READ_DESC_BYTE(pRxDesc, RXDESC_ERROR_OFFSET)) )
  2259.         {
  2260.         DRV_LOG (DRV_DEBUG_POLL_RX, "packet Error or EOP not setn", 1, 2, 
  2261.                                      3, 4, 5, 6);
  2262.         retVal = EAGAIN;
  2263.         goto errorExit;
  2264.         }
  2265.     /* get the packet length */
  2266.     GEI_READ_DESC_WORD(pRxDesc, RXDESC_LENGTH_OFFSET, len);
  2267. #ifdef INCLUDE_TBI_COMPATIBLE
  2268.     {
  2269.     UINT8 rxdErr;
  2270.     rxdErr = GEI_READ_DESC_BYTE(pRxDesc, RXDESC_ERROR_OFFSET);
  2271.     rxdErr &= (UINT8)(~(RXD_ERROR_IPE | RXD_ERROR_TCPE | RXD_ERROR_RSV));
  2272.     if (rxdErr)
  2273.         {
  2274.         BOOL frameAccept = FALSE;
  2275.         if (rxdErr == RXD_ERROR_CE && pDrvCtrl->tbiCompatibility)
  2276.             {
  2277.             UINT8 * bufAdr;
  2278.             UINT8 lastChar;
  2279.             /* software workaround for TBI compatibility problem */
  2280.            
  2281.             GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, (UINT32)bufAdr);
  2282.             lastChar = *(UINT8 *)((UINT32)bufAdr + len - 1);
  2283.             
  2284.             if (lastChar == CARRIER_EXTENSION_BYTE &&
  2285.                 len > (MIN_ETHER_PACKET_SIZE +  RX_CRC_LEN) && 
  2286.                 len <= (pDrvCtrl->mtu + GEI_DEFAULT_ETHERHEADER + RX_CRC_LEN + 1))  
  2287.                 {
  2288.                 frameAccept = TRUE;
  2289.                 rxdErr = 0;
  2290.                 len--;
  2291.                 }