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

VxWorks

开发平台:

C/C++

  1. /* bcm1250MacEnd.c - END style BCM1250 MAC Ethernet driver */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright 2000,2001
  6.  * Broadcom Corporation. All rights reserved.
  7.  *
  8.  * This software is furnished under license to Wind River Systems, Inc.
  9.  * and may be used only in accordance with the terms and conditions of
  10.  * this license.  No title or ownership is transferred hereby.
  11.  */
  12. /*
  13.  * This file has been developed or significantly modified by the
  14.  * MIPS Center of Excellence Dedicated Engineering Staff.
  15.  * This notice is as per the MIPS Center of Excellence Master Partner
  16.  * Agreement, do not remove this notice without checking first with
  17.  * WR/Platforms MIPS Center of Excellence engineering management.
  18.  */
  19. /*
  20. modification history
  21. --------------------
  22. 01h,26jun02,pgh  Fix SPR 79037, polled mode.
  23. 01g,21jun02,agf  change comment block to match coding standard
  24. 01f,19mar02,pgh  Apply code review fixes.
  25. 01e,14mar02,pgh  Made the code compliant with the coding standard.
  26.                  Eliminated unused code.
  27.                  Added comments.
  28.                  Restructured areas of the code.
  29. 01d,06mar02,pgh  Fixes SPR 73552 and SPR 74000.
  30. 01c,05mar02,pgh  Fixes SPR73549, SPR73550, and SPR73644.
  31. 01b,07dec01,agf  apply coding standard fix-ups
  32. 01a,15nov01,agf  written.
  33. */
  34. /*
  35. DESCRIPTION
  36. This module implements the Broadcom BCM1250 on-chip ethernet MACs.
  37. The BCM1250 ethernet DMA has two channels, but this module only 
  38. supports channel 0.  The dual DMA channel feature is intended for 
  39. packet classification and quality of service applications.
  40. EXTERNAL INTERFACE
  41. The only external interface is the bcm1250MacEndLoad() routine, which has the
  42. <initString> as its only parameter.  The initString parameter must be a colon-
  43. delimited string in the following format:
  44. <unit>:<hwunit>:<vecnum>:<flags>:<numRds0>:<numTds0>
  45. TARGET-SPECIFIC PARAMETERS
  46. .IP <unit>
  47. This parameter defines which ethernet interface is being loaded.
  48. .IP <hwunit>
  49. This parameter is no longer used, but must be present so the string can be 
  50. parsed properly.  Its value should be zero.
  51. .IP <vecnum>
  52. This parameter specifies the interrupt vector number.  This driver configures 
  53. the MAC device to generate hardware interrupts for various events within the 
  54. device; thus it contains an interrupt handler routine.  The driver calls 
  55. bcm1250IntConnect() to connect its interrupt handler to this interrupt vector.
  56. .IP <flags>
  57. Device specific flags, for future use.  Its value should be zero.
  58. .IP <numRds0>
  59. This parameter specifies the number of receive DMA buffer descriptors for DMA
  60. channel 0.
  61. .IP <numTds0>
  62. This parameter specifies the number of transmit DMA buffer descriptors for DMA
  63. channel 0.
  64. SYSTEM RESOURCE USAGE
  65. When implemented, this driver requires the following system resources:
  66.     - one mutual exclusion semaphore
  67.     - one interrupt vector
  68.     - 68 bytes in the initialized data section (data)
  69.     - 0 bytes in the uninitialized data section (BSS)
  70.     The driver allocates clusters of size 1520 bytes for receive frames and
  71.     and transmit frames.
  72. INCLUDES:
  73. endLib.h etherMultiLib.h bcm1250MacEnd.h
  74. SEE ALSO: muxLib, endLib, netBufLib
  75. .I "Writing and Enhanced Network Driver"
  76. */
  77. #include "vxWorks.h"
  78. #include "stdio.h"
  79. #include "stdlib.h"
  80. #include "logLib.h"
  81. #include "semLib.h"
  82. #include "intLib.h"
  83. #include "netLib.h"
  84. #include "netBufLib.h"
  85. #include "memLib.h"
  86. #include "etherLib.h"
  87. #include "etherMultiLib.h"
  88. #include "endLib.h"
  89. #include "lstLib.h"
  90. #include "drv/multi/bcm1250Lib.h"
  91. #include "drv/end/bcm1250MacEnd.h"
  92. #define DRV_DEBUG
  93. #ifdef  DRV_DEBUG
  94. #define DRV_DEBUG_OFF           0x0000
  95. #define DRV_DEBUG_RX            0x0001
  96. #define DRV_DEBUG_TX            0x0002
  97. #define DRV_DEBUG_INT           0x0004
  98. #define DRV_DEBUG_POLL          (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)
  99. #define DRV_DEBUG_POLL_RX       0x0008
  100. #define DRV_DEBUG_POLL_TX       0x0010
  101. #define DRV_DEBUG_LOAD          0x0020
  102. #define DRV_DEBUG_IOCTL         0x0040
  103. #define DRV_DEBUG_RXD           0x0100
  104. #define DRV_DEBUG_TXD           0x0200
  105. #define DRV_DEBUG_POLL_REDIR   0x10000
  106. #define DRV_DEBUG_LOG_NVRAM    0x20000
  107. #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)                        
  108.         if (bcm1250MacDebug & FLG)                                             
  109.             (void)logMsg (X0, X1, X2, X3, X4, X5, X6);
  110. #else /*DRV_DEBUG*/
  111. #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
  112. #endif /*DRV_DEBUG*/
  113. /* DRV_CTRL flags access macros */
  114. #define DRV_FLAGS_SET(setBits) 
  115.         (pDrvCtrl->flags |= (setBits))
  116. #define DRV_FLAGS_ISSET(setBits) 
  117.         (pDrvCtrl->flags & (setBits))
  118. #define DRV_FLAGS_CLR(clrBits) 
  119.         (pDrvCtrl->flags &= ~(clrBits))
  120. #define DRV_FLAGS_GET() 
  121.         (pDrvCtrl->flags)
  122. #define END_FLAGS_ISSET(pEnd, setBits) 
  123.         ((pEnd)->flags & (setBits))
  124. #define END_HADDR(pEnd) 
  125.         ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
  126. #define END_HADDR_LEN(pEnd) 
  127.         ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
  128. #define KVTOPHYS(x) ((UINT32)(x) & 0x7FFFFFFF)
  129. #define PHYSTOV(x)  ((UINT32)(x) | 0x80000000)
  130. #ifndef ETH_MAC_REG_READ
  131. #define ETH_MAC_REG_READ(reg)  
  132.     MIPS3_LD (pDrvCtrl->regMacBase + reg)
  133. #endif /* ETH_MAC_REG_READ */
  134. #ifndef ETH_MAC_REG_WRITE
  135. #define ETH_MAC_REG_WRITE(reg, val)  
  136.     MIPS3_SD ((pDrvCtrl->regMacBase + reg), (val))
  137. #endif /* ETH_MAC_REG_WRITE */
  138. #ifndef ETH_DMA_REG_READ
  139. #define ETH_DMA_REG_READ(reg)   MIPS3_LD (reg)
  140. #endif /* ETH_DMA_REG_READ */
  141. #ifndef ETH_DMA_REG_WRITE
  142. #define ETH_DMA_REG_WRITE(reg, val)     MIPS3_SD ((reg), (val))
  143. #endif /* ETH_DMA_REG_WRITE */
  144. #define NET_BUF_ALLOC() 
  145.     netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->clPoolId)
  146. #define NET_BUF_FREE(pBuf) 
  147.     netClFree (pDrvCtrl->endObj.pNetPool, (unsigned char *)(pBuf))
  148. #define NET_MBLK_ALLOC() 
  149.     mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)
  150. #define NET_MBLK_FREE(pMblk) 
  151.     netMblkFree (pDrvCtrl->endObj.pNetPool, (M_BLK_ID)pMblk)
  152. #define NET_CL_BLK_ALLOC() 
  153.     clBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)
  154. #define NET_CL_BLK_FREE(pClblk) 
  155.     clBlkFree (pDrvCtrl->endObj.pNetPool, (CL_BLK_ID)pClBlk)
  156. #define NET_MBLK_BUF_FREE(pMblk) 
  157.     (void)netMblkClFree ((M_BLK_ID)pMblk)
  158. #define NET_MBLK_CL_JOIN(pMblk, pClBlk) 
  159.     (void)netMblkClJoin ((pMblk), (pClBlk))
  160. #define NET_CL_BLK_JOIN(pClBlk, pBuf, len) 
  161.     (void)netClBlkJoin ((pClBlk), (pBuf), (len), (FUNCPTR)NULL, 0, 0, 0)
  162. /* PHY/MII */
  163. #define MII_COMMAND_START       0x01
  164. #define MII_COMMAND_READ        0x02
  165. #define MII_COMMAND_WRITE       0x01
  166. #define MII_COMMAND_ACK         0x02
  167. /* Basic Mode Control Register bit definitions */
  168. #define BMCR_RESET     0x8000
  169. #define BMCR_LOOPBACK  0x4000
  170. #define BMCR_SPEED0    0x2000
  171. #define BMCR_ANENABLE  0x1000
  172. #define BMCR_POWERDOWN 0x0800
  173. #define BMCR_ISOLATE   0x0400
  174. #define BMCR_RESTARTAN 0x0200
  175. #define BMCR_DUPLEX    0x0100
  176. #define BMCR_COLTEST   0x0080
  177. #define BMCR_SPEED1    0x0040
  178. #define BMCR_SPEED1000 (BMCR_SPEED1 | BMCR_SPEED0)
  179. #define BMCR_SPEED100  (BMCR_SPEED0)
  180. #define BMCR_SPEED10    0
  181. /* Basic Mode Status Register bit definitions */
  182. #define BMSR_100BT4     0x8000
  183. #define BMSR_100BT_FDX  0x4000
  184. #define BMSR_100BT_HDX  0x2000
  185. #define BMSR_10BT_FDX   0x1000
  186. #define BMSR_10BT_HDX   0x0800
  187. #define BMSR_100BT2_FDX 0x0400
  188. #define BMSR_100BT2_HDX 0x0200
  189. #define BMSR_1000BT_XSR 0x0100
  190. #define BMSR_PRESUP     0x0040
  191. #define BMSR_ANCOMPLT   0x0020
  192. #define BMSR_REMFAULT   0x0010
  193. #define BMSR_AUTONEG    0x0008
  194. #define BMSR_LINKSTAT   0x0004
  195. #define BMSR_JABDETECT  0x0002
  196. #define BMSR_EXTCAPAB   0x0001
  197. /* 1K Status Register bit definitions */
  198. #define K1STSR_MSMCFLT  0x8000
  199. #define K1STSR_MSCFGRES 0x4000
  200. #define K1STSR_LRSTAT   0x2000
  201. #define K1STSR_RRSTAT   0x1000
  202. #define K1STSR_LP1KFD   0x0800
  203. #define K1STSR_LP1KHD   0x0400
  204. #define K1STSR_LPASMDIR 0x0200
  205. /* AutoNegotiation Link Partner Abilities Register bit definitions */
  206. #define ANLPAR_NP       0x8000
  207. #define ANLPAR_ACK      0x4000
  208. #define ANLPAR_RF       0x2000
  209. #define ANLPAR_ASYPAUSE 0x0800
  210. #define ANLPAR_PAUSE    0x0400
  211. #define ANLPAR_T4       0x0200
  212. #define ANLPAR_TXFD     0x0100
  213. #define ANLPAR_TXHD     0x0080
  214. #define ANLPAR_10FD     0x0040
  215. #define ANLPAR_10HD     0x0020
  216. #define ANLPAR_PSB      0x0001  /* 802.3 */
  217. #define PHYIDR1         0x2000
  218. #define PHYIDR2         0x5C60
  219. /* Physical interface chip register index definitions */
  220. #define MII_BMCR    0x00    /* Basic mode control register (rw) */
  221. #define MII_BMSR    0x01    /* Basic mode status register (ro) */
  222. #define MII_K1STSR  0x0A    /* 1K Status Register (ro) */
  223. #define MII_ANLPAR  0x05    /* AutoNegotiation Link Partner Abilities (rw) */
  224. #define M_MAC_MDIO_DIR_OUTPUT   0               /* for clarity */
  225. /* externs */
  226. IMPORT void sysBcm1250MacEnetAddrGet (int, char *);
  227. IMPORT STATUS bcm1250IntConnect (int, int, VOIDFUNCPTR, int);
  228. IMPORT STATUS bcm1250IntDisconnect (int);
  229. IMPORT STATUS bcm1250IntEnable (int);
  230. IMPORT STATUS bcm1250IntDisable (int);
  231. /* locals */
  232. #ifdef  DRV_DEBUG
  233. /*
  234. LOCAL int bcm1250MacDebug = DRV_DEBUG_LOAD | DRV_DEBUG_INT | DRV_DEBUG_TX |
  235.                             DRV_DEBUG_RX | DRV_DEBUG_POLL;
  236. */
  237. LOCAL int bcm1250MacDebug = DRV_DEBUG_OFF;
  238. #endif /*DRV_DEBUG*/
  239. char *  pTxPollBuf;     /* Points to polled mode transmit cluster */
  240. /* forward declarations */
  241. void bcm1250MacRxDmaShow (int);    /* for debug */
  242. void bcm1250MacTxDmaShow (int);    /* for debug */
  243. void bcm1250MacShow (int);         /* for debug */
  244. void bcm1250MacPhyShow (int);      /* for debug */
  245. LOCAL UINT64 bcm1250MacAddr2Reg (unsigned char *);
  246. LOCAL STATUS bcm1250MacMemInit (DRV_CTRL *);
  247. LOCAL STATUS bcm1250MacDmaInit (ETH_MAC_DMA *, MAC_REG, int);
  248. LOCAL STATUS bcm1250MacPktCopyTransmit (DRV_CTRL *, M_BLK *);
  249. LOCAL STATUS bcm1250MacPktTransmit (DRV_CTRL *, M_BLK *, int);
  250. LOCAL void bcm1250MacTxHandle (DRV_CTRL *);
  251. LOCAL void bcm1250MacRxHandle (DRV_CTRL *);
  252. LOCAL STATUS bcm1250MacInitParse (DRV_CTRL *, char *);
  253. LOCAL void bcm1250MacInt (DRV_CTRL *);
  254. LOCAL void bcm1250MacRxFilterSet (DRV_CTRL *);
  255. LOCAL void  bcm1250MacMblkWalk (M_BLK *, int *, BOOL *);
  256. LOCAL unsigned bcm1250MacEthHash (unsigned char *);
  257. LOCAL void bcm1250MacEthMiiPoll (DRV_CTRL *);
  258. LOCAL void bcm1250MacEthMiiFindPhy (DRV_CTRL *);
  259. LOCAL void bcm1250MacEthMiiSync (DRV_CTRL *);
  260. LOCAL void bcm1250MacEthMiiSendData (DRV_CTRL *, unsigned int, int);
  261. LOCAL int bcm1250MacEthMiiRead (DRV_CTRL *, int, int);
  262. LOCAL STATUS bcm1250MacHashRegAdd (DRV_CTRL *, char *);
  263. LOCAL STATUS bcm1250MacHashRegSet (DRV_CTRL *);
  264. LOCAL STATUS bcm1250MacSetConfig (DRV_CTRL *, MAC_SPEED, MAC_DUPLEX, MAC_FC);
  265. /* This is the only externally visible interface. */
  266. END_OBJ * bcm1250MacEndLoad (char * initString);
  267. /* END Specific interfaces. */
  268. LOCAL STATUS bcm1250MacStart (DRV_CTRL *);
  269. LOCAL STATUS bcm1250MacStop (DRV_CTRL *);
  270. LOCAL STATUS bcm1250MacUnload (DRV_CTRL *);
  271. LOCAL int bcm1250MacIoctl (DRV_CTRL *, int, caddr_t);
  272. LOCAL STATUS bcm1250MacSend (DRV_CTRL *, M_BLK_ID);
  273. LOCAL STATUS bcm1250MacMCastAdd (DRV_CTRL *, char *);
  274. LOCAL STATUS bcm1250MacMCastDel (DRV_CTRL *, char *);
  275. LOCAL STATUS bcm1250MacMCastGet (DRV_CTRL *, MULTI_TABLE *);
  276. LOCAL STATUS bcm1250MacPollSend (DRV_CTRL *, M_BLK_ID);
  277. LOCAL STATUS bcm1250MacPollRcv (DRV_CTRL *, M_BLK_ID);
  278. LOCAL void bcm1250MacPollStart (DRV_CTRL *);
  279. LOCAL void bcm1250MacPollStop (DRV_CTRL *);
  280. /*
  281.  * Define the device function table.  This is static across all driver
  282.  * instances.
  283.  */
  284. LOCAL NET_FUNCS bcm1250MacFuncTable =
  285.     {
  286.     (FUNCPTR)bcm1250MacStart,       /* Function to start the device. */
  287.     (FUNCPTR)bcm1250MacStop,        /* Function to stop the device. */
  288.     (FUNCPTR)bcm1250MacUnload,      /* Unloading function for the driver. */
  289.     (FUNCPTR)bcm1250MacIoctl,       /* Ioctl function for the driver. */
  290.     (FUNCPTR)bcm1250MacSend,        /* Send function for the driver. */
  291.     (FUNCPTR)bcm1250MacMCastAdd,    /* Multicast add function for the */
  292.     (FUNCPTR)bcm1250MacMCastDel,    /* Multicast delete function for */
  293.     (FUNCPTR)bcm1250MacMCastGet,    /* Multicast retrieve function for */
  294.     (FUNCPTR)bcm1250MacPollSend,    /* Polling send function */
  295.     (FUNCPTR)bcm1250MacPollRcv,     /* Polling receive function */
  296.     endEtherAddressForm,            /* put address info into a NET_BUFFER */
  297.     (FUNCPTR)endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
  298.     (FUNCPTR)endEtherPacketAddrGet  /* Get packet addresses. */
  299.     };
  300. /*******************************************************************************
  301. *
  302. * bcm1250MacEndLoad - initialize the driver and device
  303. *
  304. * This routine initializes the driver and the device to the operational state.
  305. * All of the device specific parameters are passed in <initString>, which
  306. * expects a string of the following format:
  307. *
  308. * The initialization string format is:
  309. * "<unit>:<hwunit>:<vecnum>:<flags>:<numRds0>:<numTds0>:<numRds1>:<numTds1>"
  310. *
  311. * The hwunit field is not used, but must be present to parse properly.
  312. *
  313. * This routine can be called in two modes.  If it is called with an empty but
  314. * allocated string, it places the name of this device (that is, "sbe0", "sbe1",
  315. * or "sbe2") into the <initString> and returns NULL.
  316. *
  317. * If the string is allocated and not empty, the routine attempts to load
  318. * the driver using the values specified in the string.
  319. *
  320. * RETURNS: An END object pointer or NULL on error.
  321. */
  322. END_OBJ * bcm1250MacEndLoad
  323.     (
  324.     char *  initString            /* String to be parsed by the driver. */
  325.     )
  326.     {
  327.     STATUS      rtv;
  328.     DRV_CTRL *  pDrvCtrl;   /* driver control structure */
  329.     char        enetAddr[6];
  330.     DRV_LOG (DRV_DEBUG_LOAD, "Loading bcm1250MacEnd...n", 1, 2, 3, 4, 5, 6);
  331.     /* Check for an allocated string. */
  332.     if (initString == (char *)NULL)
  333.         {
  334.         DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacEndLoad: NULL initStrn",
  335.                  1, 2, 3, 4, 5, 6);
  336.         return ((END_OBJ *)NULL);
  337.         }
  338.     /* If a null string, then copy the device's name to the string. */
  339.     if (initString[0] == '')
  340.         {
  341.         bcopy ((char *)SB_DEV_NAME, initString, SB_DEV_NAME_LEN);
  342.         DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacEndLoad: initString[0]==NULn",
  343.                  1, 2, 3, 4, 5, 6);
  344.         return ((END_OBJ *)NULL);
  345.         }
  346.     /* Allocate the device structure */
  347.     pDrvCtrl = (DRV_CTRL *)calloc (sizeof (DRV_CTRL), 1);
  348.     if (pDrvCtrl == (DRV_CTRL *)NULL)
  349.         {
  350.         DRV_LOG (DRV_DEBUG_LOAD,
  351.                  "bcm1250MacEndLoad: alloc for pDrvCtrl failed.n",
  352.                  1, 2, 3, 4, 5, 6);
  353.         return ((END_OBJ *)NULL);
  354.         }
  355.     /* Parse the init string, filling in the device structure */
  356.     if (bcm1250MacInitParse (pDrvCtrl, initString) == ERROR)
  357.         {
  358.         DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacEndLoad: init parse failedn",
  359.                  1, 2, 3, 4, 5, 6);
  360.         goto errorExit;
  361.         }
  362.     /* Initialize register addresses. */
  363.     pDrvCtrl->regMacEnable = R_MAC_ENABLE;
  364.     pDrvCtrl->regMacCfg    = R_MAC_CFG;
  365.     pDrvCtrl->regFifoCfg   = R_MAC_THRSH_CFG;
  366.     pDrvCtrl->regFrameCfg  = R_MAC_FRAMECFG;
  367.     pDrvCtrl->regRxFilter  = R_MAC_ADFILTER_CFG;
  368.     pDrvCtrl->regIsr       = R_MAC_STATUS;
  369.     pDrvCtrl->regImr       = R_MAC_INT_MASK;
  370.     pDrvCtrl->regMdio      = R_MAC_MDIO;
  371.     /* Ask the BSP to provide the ethernet address. */
  372.     sysBcm1250MacEnetAddrGet (pDrvCtrl->unit, &enetAddr[0]);
  373.     DRV_LOG (DRV_DEBUG_LOAD,
  374.              "Loading bcm1250MacEnd: mac addr = %x:%x:%x:%x:%x:%xn",
  375.              enetAddr[0], enetAddr[1], enetAddr[2], enetAddr[3], enetAddr[4],
  376.              enetAddr[5]);
  377.     /* initialize the END_OBJ. */
  378.     rtv = END_OBJ_INIT (&pDrvCtrl->endObj, 
  379.                         (DEV_OBJ *)pDrvCtrl, 
  380.                         SB_DEV_NAME,
  381.                         pDrvCtrl->unit, 
  382.                         &bcm1250MacFuncTable, 
  383.                         "BCM1250 END Driver.");
  384.     if (rtv == ERROR)
  385.         goto errorExit;
  386.     /* Reset the ethernet MAC. */
  387.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, M_MAC_PORT_RESET);
  388.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, 0);
  389.     /* Perform memory allocation/initialization for ethernet DMA receive structure. */
  390.     DRV_LOG (DRV_DEBUG_LOAD, "rxDMA ch#0 initn", 1, 2, 3, 4, 5, 6);
  391.     rtv = bcm1250MacDmaInit (&pDrvCtrl->rxDma, pDrvCtrl->regDmaBase, 0);
  392.     if (rtv == ERROR)
  393.         goto errorExit;
  394.     /* Perform memory allocation/initialization for ethernet DMA transmit structure. */
  395.     DRV_LOG (DRV_DEBUG_LOAD, "txDMA ch#0 initn", 1, 2, 3, 4, 5, 6);
  396.     rtv = bcm1250MacDmaInit (&pDrvCtrl->txDma, pDrvCtrl->regDmaBase, 1);
  397.     if (rtv == ERROR)
  398.         goto errorExit;
  399.     /* 
  400.      * Perform memory allocation/initialization for the netBufLib-managed 
  401.      * memory pool.
  402.      */ 
  403.     if (bcm1250MacMemInit (pDrvCtrl) == ERROR)
  404.         goto errorExit;
  405.     /* Allocate a cluster buffer for polled mode transmit. */
  406.     pTxPollBuf = NET_BUF_ALLOC ();
  407.     /* Find the address of the physical interface chip. */
  408.     bcm1250MacEthMiiFindPhy (pDrvCtrl);
  409.     /* Determine the speed and configuration of the physical interface. */
  410.     bcm1250MacEthMiiPoll (pDrvCtrl);
  411.     /* Initialize the MIB-II structure */
  412.     rtv = END_MIB_INIT (&pDrvCtrl->endObj, 
  413.                         M2_ifType_ethernet_csmacd,
  414.                         (UINT8 *)&enetAddr[0], 
  415.                         6, 
  416.                         ETHERMTU,
  417.                         BCM1250_MAC_SPEED_DEF);
  418.     if (rtv == ERROR)
  419.         {
  420.         DRV_LOG (DRV_DEBUG_LOAD,
  421.                  "bcm1250MacEndLoad: MIB init failedn",
  422.                  1, 2, 3, 4, 5, 6);
  423.         goto errorExit;
  424.         }
  425.     /* set the flags to indicate readiness */
  426.     END_OBJ_READY (&pDrvCtrl->endObj,
  427.                    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | 
  428.                    IFF_BROADCAST | IFF_MULTICAST);
  429.     DRV_LOG (DRV_DEBUG_LOAD, "Done loading ...", 1, 2, 3, 4, 5, 6);
  430.     return (&pDrvCtrl->endObj);
  431. errorExit:
  432.     free ((char *)pDrvCtrl);
  433.     return ((END_OBJ *)NULL);
  434.     }
  435. /*******************************************************************************
  436. *
  437. * bcm1250MacInitParse - Parse the initialization string
  438. *
  439. * Parse the input string.  This routine is called from bcm1250MacEndLoad()
  440. * which initializes some values in the driver control structure with the
  441. * values passed in the intialization string.
  442. *
  443. * The initialization string format is:
  444. * "<unit>:<hwunit>:<vecnum>:<flags>:<numRds0>:<numTds0>"
  445. *
  446. * .IP <unit>
  447. * Device unit number, 0 - 2.
  448. * .IP <hwunit>
  449. * Not used, but must be present to parse properly.
  450. * .IP <vecnum>
  451. * Interrupt vector number.
  452. * .IP <flags>
  453. * Device specific flags, for future use.
  454. * .IP <numRds0>
  455. * Number of receive DMA buffer descriptors for channel 0.
  456. * .IP <numTds0>
  457. * Number of transmit DMA buffer descriptors for channel 0.
  458. *
  459. * RETURNS: OK, or ERROR if any arguments are invalid.
  460. */
  461. LOCAL STATUS bcm1250MacInitParse
  462.     (
  463.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  464.     char *      initString
  465.     )
  466.     {
  467.     char *          tok;    /* an initString token */
  468.     char *          holder = (char *)NULL;  /* points beyond tok */
  469.     ETH_MAC_DMA *   pRxDma0 = &pDrvCtrl->rxDma;
  470.     ETH_MAC_DMA *   pTxDma0 = &pDrvCtrl->txDma;
  471.     DRV_LOG (DRV_DEBUG_LOAD, "InitParse: Initstr=%sn",
  472.              (int)initString, 2, 3, 4, 5, 6);
  473.     /* Process the device unit number. */
  474.     tok = strtok_r (initString, ":", &holder);
  475.     if (tok == (char *)NULL)
  476.         return ERROR;
  477.     pDrvCtrl->unit = atoi (tok);
  478.     /* Validate the device unit number, and set the interrupt source. */
  479.     switch (pDrvCtrl->unit)
  480.         {
  481.         case 0:
  482.             pDrvCtrl->intSource = K_INT_MAC_0;
  483.             break;
  484.         case 1:
  485.             pDrvCtrl->intSource = K_INT_MAC_1;
  486.             break;
  487.         case 2:
  488.             pDrvCtrl->intSource = K_INT_MAC_2;
  489.             break;
  490.         default:
  491.             return ERROR;
  492.         }
  493.     /* Discard the hwunit, which is not used. */
  494.     tok = strtok_r ((char *)NULL, ":", &holder);
  495.     if (tok == (char *)NULL)
  496.         return ERROR;
  497.     /* Set the base address for the ethernet registers for this device. */
  498.     pDrvCtrl->regMacBase = PHYS_TO_K1 (A_MAC_CHANNEL_BASE (pDrvCtrl->unit));
  499.     pDrvCtrl->regDmaBase = pDrvCtrl->regMacBase;
  500.     /* Process the interrupt vector number. */
  501.     tok = strtok_r ((char *)NULL, ":", &holder);
  502.     if (tok == (char *)NULL)
  503.         return ERROR;
  504.     pDrvCtrl->iVecNum = strtoul (tok, (char **)NULL, 10);
  505.     /* Process the Device specific flags. */
  506.     tok = strtok_r ((char *)NULL, ":", &holder);
  507.     if (tok == (char *)NULL)
  508.         return (ERROR);
  509.     pDrvCtrl->flags = strtoul (tok, (char **)NULL, 16);
  510.     /* Process the number of receive DMA buffer descriptors for channel 0. */
  511.     tok = strtok_r ((char *)NULL, ":", &holder);
  512.     if (tok == (char *)NULL)
  513.         return ERROR;
  514.     if (atoi (tok) < 0)
  515.         pRxDma0->maxDescr = NUM_RDS_DEF;
  516.     else
  517.         pRxDma0->maxDescr = atoi (tok);
  518.     /* Process the number of transmit DMA buffer descriptors for channel 0. */
  519.     tok = strtok_r ((char *)NULL, ":", &holder);
  520.     if (tok == (char *)NULL)
  521.         return ERROR;
  522.     if (atoi (tok) < 0)
  523.         pTxDma0->maxDescr = NUM_TDS_DEF;
  524.     else
  525.         pTxDma0->maxDescr = atoi (tok);
  526.     DRV_LOG (DRV_DEBUG_LOAD,
  527.              "EndLoad: flags=0x%x dmaBase=0x%x macBase=0x%x iVecNum=0x%x intSource=0x%x ",
  528.              pDrvCtrl->flags, pDrvCtrl->regDmaBase, pDrvCtrl->regMacBase,
  529.              pDrvCtrl->iVecNum, pDrvCtrl->intSource, 6);
  530.     DRV_LOG (DRV_DEBUG_LOAD,
  531.              "EndLoad: numRd0 %d numTd0 %d unit %dn",
  532.              pRxDma0->maxDescr, pTxDma0->maxDescr, pDrvCtrl->unit, 4, 5, 6);
  533.     return OK;
  534.     }
  535. /*******************************************************************************
  536. *
  537. * bcm1250MacMemInit - initialize memory.
  538. *
  539. * Allocates and initializes the mBlk/clBlk/cluster memory pool.
  540. *
  541. * RETURNS: OK or ERROR.
  542. */
  543. LOCAL STATUS bcm1250MacMemInit
  544.     (
  545.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  546.     )
  547.     {
  548.     STATUS          rtv;            /* function return value */
  549.     M_CL_CONFIG     mClBlkConfig;   /* mBlk/clBlk configuration table */
  550.     CL_DESC         clDesc;         /* cluster descriptor table */
  551.     DRV_LOG (DRV_DEBUG_LOAD, "sbe%d - bcm1250MacMemInit() start.n",
  552.              pDrvCtrl->unit, 2, 3, 4, 5, 6);
  553.     /*
  554.      * Clear the mBlk/clBlk configuration table, 
  555.      * and the cluster descriptor table.
  556.      */
  557.     bzero ((char *)&mClBlkConfig, sizeof (mClBlkConfig));
  558.     bzero ((char *)&clDesc, sizeof (clDesc));
  559.     /* Calculate the number of clusters. */
  560.     clDesc.clNum = pDrvCtrl->rxDma.maxDescr +
  561.                    pDrvCtrl->txDma.maxDescr +
  562.                    (RXDSCR_LOAN_NUM * 2) + 2;
  563.     /* Set the size of the clusters. */
  564.     clDesc.clSize = ROUND_UP ((MAX_FRAME_SIZE + CACHELINESIZE),
  565.                               CACHELINESIZE);
  566.     /* Calculate the memory size for the clusters. */
  567.     clDesc.memSize = (clDesc.clNum * (clDesc.clSize + sizeof (long))) +
  568.                      CACHELINESIZE;
  569.     /* Allocate memory for the clusters from cache safe memory. */
  570.     pDrvCtrl->bufBase = (char *)memalign (CACHELINESIZE, clDesc.memSize);
  571.     if (pDrvCtrl->bufBase == (char *)NULL)
  572.         {
  573.         DRV_LOG (DRV_DEBUG_LOAD,
  574.                  "sbe%d - pDrvCtrl->bufBase alloc failed for size 0x%8xn",
  575.                  pDrvCtrl->unit, clDesc.memSize, 3, 4, 5, 6);
  576.         return (ERROR);
  577.         }
  578.     /* Set the base address of the cluster memory. */
  579.     clDesc.memArea = (char *)pDrvCtrl->bufBase;
  580.     /* 
  581.      * Purposely misalign the base address of the cluster memory by 
  582.      * (CACHELINESIZE - sizeof (long)), and adjust the size of the 
  583.      * clusters, so that the guts of the buffers are cache aligned.
  584.      */
  585.     clDesc.memArea += (CACHELINESIZE - sizeof (long));
  586.     clDesc.clSize -= sizeof (long);
  587.     DRV_LOG (DRV_DEBUG_LOAD,
  588.              "sbe%d - InitMem NetBufLib Cluster memArea 0x%08xn",
  589.              pDrvCtrl->unit, (UINT32)clDesc.memArea, 3, 4, 5, 6);
  590.     /* Set twice as many mBlk's as clusters. */
  591.     mClBlkConfig.mBlkNum = clDesc.clNum * 2;
  592.     /* Set the number of clusters. */
  593.     mClBlkConfig.clBlkNum = clDesc.clNum;
  594.     /* Calculate the memory size needed. */
  595.     mClBlkConfig.memSize = (mClBlkConfig.mBlkNum * (M_BLK_SZ + sizeof (long))) +
  596.                            (mClBlkConfig.clBlkNum * CL_BLK_SZ);
  597.     /* Allocated the required memory */
  598.     mClBlkConfig.memArea = (char *)memalign (sizeof (long),
  599.                                              mClBlkConfig.memSize);
  600.     if (mClBlkConfig.memArea == (char *)NULL)
  601.         {
  602.         DRV_LOG (DRV_DEBUG_LOAD,
  603.                  "sbe%d - mClBlkConfig.memArea alloc failed for size 0x%8xn",
  604.                  pDrvCtrl->unit, mClBlkConfig.memSize, 3, 4, 5, 6);
  605.         return (ERROR);
  606.         }
  607.     pDrvCtrl->mClBlkBase = mClBlkConfig.memArea;
  608.     /* Allocate the network pool. */
  609.     pDrvCtrl->endObj.pNetPool = (NET_POOL_ID)malloc (sizeof (NET_POOL));
  610.     if (pDrvCtrl->endObj.pNetPool == (NET_POOL_ID)NULL)
  611.         {
  612.         DRV_LOG (DRV_DEBUG_LOAD,
  613.                  "sbe%d - pNetPool alloc failed for size 0x%8xn",
  614.                  pDrvCtrl->unit, sizeof (NET_POOL), 3, 4, 5, 6);
  615.         return (ERROR);
  616.         }
  617.     /* Initialize the netBufLib-managed memory pool */
  618.     rtv = netPoolInit (pDrvCtrl->endObj.pNetPool, &mClBlkConfig, &clDesc, 1,
  619.                        (POOL_FUNC *)NULL);
  620.     if (rtv == ERROR)
  621.         {
  622.         DRV_LOG (DRV_DEBUG_LOAD, "netPoolInit() failed.n",
  623.                 1, 2, 3, 4, 5, 6);
  624.         return (ERROR);
  625.         }
  626.     /* Get the cluster pool ID for the clusters. */
  627.     pDrvCtrl->clPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
  628.                                          MAX_FRAME_SIZE, FALSE);
  629.     if (pDrvCtrl->clPoolId == (CL_POOL_ID)NULL)
  630.         {
  631.         DRV_LOG (DRV_DEBUG_LOAD, "netClPoolIdGet() returned NULL pool ID.n",
  632.                 1, 2, 3, 4, 5, 6);
  633.         return (ERROR);
  634.         }
  635.     DRV_LOG (DRV_DEBUG_LOAD, "sbe%d - bcm1250MacMemInit() completen",
  636.              pDrvCtrl->unit, 2, 3, 4, 5, 6);
  637.     return OK;
  638.     }
  639. /*******************************************************************************
  640. *
  641. * bcm1250MacDmaInit - Initialize DMA data structure and hardware registers
  642. *
  643. * This routine initializes the DMA data structure.  It allocates and
  644. * initializes memory for the DMA buffer descriptors, the buffer pointer
  645. * table, and the buffer type table.  The buffer type table is only used
  646. * in the transmit direction.  The variables used to manage the ring of
  647. * buffers and descriptors are also initialized in this routine.  Finally,
  648. * the address of the DMA registers are initialized, and the config and buffer
  649. * descriptor base registers are initialized.
  650. *
  651. * RETURNS: OK, or ERROR
  652. */
  653. LOCAL STATUS bcm1250MacDmaInit
  654.     (
  655.     ETH_MAC_DMA *   pDma,       /* ethernet DMA struct to be initialized */
  656.     MAC_REG         dmaBaseAdr, /* base address of DMA registers */
  657.     int             xmit        /* 1 if transmit direction, 0 for receive */
  658.     )
  659.     {
  660.     int     dscr;       /* DMA buffer descriptor index */
  661.     DRV_LOG (DRV_DEBUG_LOAD, "DMA init startn", 1, 2, 3, 4, 5, 6);
  662.     /* allocate memory for DMA buffer descriptor rings */
  663.     pDma->pDscrTable = (ETH_DMA_DSCR *)memalign (CACHELINESIZE,
  664.                                                  pDma->maxDescr *
  665.                                                      sizeof (ETH_DMA_DSCR));
  666.     if (pDma->pDscrTable == (ETH_DMA_DSCR *)NULL)
  667.         {
  668.         DRV_LOG (DRV_DEBUG_LOAD, "pDscrTable alloc failedn", 1, 2, 3, 4, 5, 6);
  669.         return (ERROR);
  670.         }
  671.     bzero ((char *)pDma->pDscrTable, (pDma->maxDescr * sizeof (ETH_DMA_DSCR)));
  672.     /* 
  673.      * For transmit only, allocate and initialize a table of pointers to buffers 
  674.      * and a table of buffers types. 
  675.      */
  676.     if (xmit == 1)
  677.         {
  678.         pDma->bufTable = (TX_BUF_TABLE *)malloc (pDma->maxDescr * 
  679.                                                  sizeof (TX_BUF_TABLE));
  680.         if (pDma->bufTable == (TX_BUF_TABLE *)NULL)
  681.             {
  682.             DRV_LOG (DRV_DEBUG_LOAD, 
  683.                      "bufTable alloc failed.n", 1, 2, 3, 4, 5, 6);
  684.             return (ERROR);
  685.             }
  686.         for (dscr = 0; dscr < pDma->maxDescr; dscr++)
  687.             {
  688.             pDma->bufTable[dscr].pBuf = (char *)NULL;
  689.             pDma->bufTable[dscr].type = BUF_TYPE_NONE;
  690.             }
  691.         }
  692.     /* Initialize ring management variables */
  693.     pDma->tailIndex = 0;
  694.     pDma->headIndex = 0;
  695.     pDma->ringCount = 0;
  696.     /* Transmitter is not blocked */
  697.     pDma->txBlocked = FALSE;
  698.     /* Initialize register addresses */
  699.     pDma->regConfig0 = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CONFIG0) + 
  700.                        dmaBaseAdr;
  701.     pDma->regConfig1 = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CONFIG1) + 
  702.                        dmaBaseAdr;
  703.     pDma->regDscrBase = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_DSCR_BASE) + 
  704.                         dmaBaseAdr;
  705.     pDma->regDscrCnt = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_DSCR_CNT) + 
  706.                        dmaBaseAdr;
  707.     pDma->regCurDscr = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CUR_DSCRADDR) +
  708.                        dmaBaseAdr;
  709.     DRV_LOG (DRV_DEBUG_LOAD, "set regs, dscrbase and config0/maxdscrn",
  710.              1, 2, 3, 4, 5, 6);
  711.     /* Initialize config registers and buffer descriptor base register */
  712.     ETH_DMA_REG_WRITE (pDma->regConfig1, 0);
  713.     ETH_DMA_REG_WRITE (pDma->regDscrBase, 
  714.                        (UINT32)(KVTOPHYS (pDma->pDscrTable)));
  715.     ETH_DMA_REG_WRITE (pDma->regConfig0, V_DMA_RINGSZ (pDma->maxDescr));
  716.     DRV_LOG (DRV_DEBUG_LOAD, "DMA init completen", 1, 2, 3, 4, 5, 6);
  717.     return (OK);
  718.     }
  719. /*******************************************************************************
  720. *
  721. * bcm1250MacUnload - unload a driver from the system
  722. *
  723. * This routine first brings down the device, and then frees any memory
  724. * allocated by the driver in the load function. The controller structure
  725. * should be freed by the calling function.
  726. *
  727. * RETURNS: OK, always.
  728. */
  729. LOCAL STATUS bcm1250MacUnload
  730.     (
  731.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  732.     )
  733.     {
  734.     ETH_MAC_DMA *   pDma;   /* ethernet DMA structure */
  735.     DRV_LOG (DRV_DEBUG_LOAD, "EndUnload ...n", 1, 2, 3, 4, 5, 6);
  736.     /* deallocate lists */
  737.     END_OBJ_UNLOAD (&pDrvCtrl->endObj);
  738.     pDma = &pDrvCtrl->rxDma;
  739.     /* Free the RX DMA buffer descriptors. */
  740.     if (pDma->pDscrTable)
  741.         free (pDma->pDscrTable);
  742.     pDma = &pDrvCtrl->txDma;
  743.     /* Free the TX buffer table. */
  744.     if (pDma->bufTable)
  745.         free (pDma->bufTable);
  746.     /* Free the TX DMA buffer descriptors. */
  747.     if (pDma->pDscrTable)
  748.         free (pDma->pDscrTable);
  749.     /* Free the mBlk/clBlk memory. */
  750.     
  751.     if (pDrvCtrl->mClBlkBase)
  752.         free (pDrvCtrl->mClBlkBase);
  753.     /* Free the cluster buffer memory. */
  754.     if (pDrvCtrl->bufBase)
  755.         free (pDrvCtrl->bufBase);
  756.     /* Free the memory allocated for driver pool structure */
  757.     if (pDrvCtrl->endObj.pNetPool != (NET_POOL *)NULL)
  758.         free (pDrvCtrl->endObj.pNetPool);
  759.     return (OK);
  760.     }
  761. /*******************************************************************************
  762. *
  763. * bcm1250MacStart - start the device
  764. *
  765. * This function calls BSP functions to connect interrupts and start the
  766. * device running in interrupt mode.
  767. *
  768. * RETURNS: OK or ERROR
  769. */
  770. LOCAL STATUS bcm1250MacStart
  771.     (
  772.     DRV_CTRL *  pDrvCtrl /* driver control structure */
  773.     )
  774.     {
  775.     UINT64          macAddr;        /* 64 bit ethernet MAC address */
  776.     STATUS          rtv;            /* function return value */
  777.     int             idx;
  778.     MAC_REG         port;
  779.     char            enetAddr[6];    /* 6 byte ethernet MAC address */
  780.     ETH_MAC_DMA *   pDma;           /* ethernet DMA structure */
  781.     int             ix;
  782.     char *          pBuf = (char *)NULL;
  783.     ETH_DMA_DSCR *  pDscr;          /* DMA buffer descriptor */
  784.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart enter ......n", 
  785.              1, 2, 3, 4, 5, 6);
  786.     /* reset */
  787.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, 0);
  788.     /* get mac addr */
  789.     sysBcm1250MacEnetAddrGet (pDrvCtrl->unit, &enetAddr[0]);
  790.     macAddr =  bcm1250MacAddr2Reg ((unsigned char *)enetAddr);
  791.     DRV_LOG (DRV_DEBUG_IOCTL, "macAddr=0x%08x%08xn", 
  792.              (int)(macAddr >> 32), macAddr, 3, 4, 5, 6);
  793.     /* set its own hw addr */
  794.     ETH_MAC_REG_WRITE (R_MAC_ETHERNET_ADDR, 0);
  795.     /* clear hash table */
  796.     port = R_MAC_HASH_BASE;
  797.     for (idx = 0; idx < MAC_HASH_COUNT; idx++)
  798.         {
  799.         ETH_MAC_REG_WRITE (port, 0);
  800.         port += sizeof (UINT64);
  801.         }
  802.     /* clear exact match addr table */
  803.     port = R_MAC_ADDR_BASE;
  804.     for (idx = 0; idx < MAC_ADDR_COUNT; idx++)
  805.         {
  806.         ETH_MAC_REG_WRITE (port, 0);
  807.         port += sizeof (UINT64);
  808.         }
  809.     /* always interested in packets addressed to self */
  810.     ETH_MAC_REG_WRITE (R_MAC_ADDR_BASE, macAddr);
  811.     /* reset channel map register to only use channel 0!!! */
  812.     port = R_MAC_CHUP0_BASE;
  813.     for (idx = 0; idx < MAC_CHMAP_COUNT; idx++)
  814.         {
  815.         ETH_MAC_REG_WRITE (port, 0);
  816.         port += sizeof (UINT64);
  817.         }
  818.     port = R_MAC_CHLO0_BASE;
  819.     for (idx = 0; idx < MAC_CHMAP_COUNT; idx++)
  820.         {
  821.         ETH_MAC_REG_WRITE (port, 0);
  822.         port += sizeof (UINT64);
  823.         }
  824.     /* clear rx filter */
  825.     ETH_MAC_REG_WRITE (pDrvCtrl->regRxFilter, 0);
  826.     /* no interrupt yet */
  827.     ETH_MAC_REG_WRITE (pDrvCtrl->regImr, 0);
  828.     /* setup frame cfg */
  829.     ETH_MAC_REG_WRITE (pDrvCtrl->regFrameCfg,
  830.                        V_MAC_MIN_FRAMESZ_DEFAULT |
  831.                        V_MAC_MAX_FRAMESZ_DEFAULT |
  832.                        V_MAC_BACKOFF_SEL (1) );
  833.     /* setup fifo cfg */
  834.     ETH_MAC_REG_WRITE (pDrvCtrl->regFifoCfg,
  835.                        V_MAC_TX_WR_THRSH (4) |       /* Must be '4' or '8' */
  836.                        V_MAC_TX_RD_THRSH (4) |
  837.                        V_MAC_TX_RL_THRSH (4) |
  838.                        V_MAC_RX_PL_THRSH (4) |
  839.                        V_MAC_RX_RD_THRSH (4) |       /* Must be '4' */
  840.                        V_MAC_RX_PL_THRSH (4) |
  841.                        V_MAC_RX_RL_THRSH (8));
  842.     /* setup the main config reg */
  843.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacCfg,
  844.                        M_MAC_RETRY_EN |
  845.                        M_MAC_TX_HOLD_SOP_EN |
  846.                        V_MAC_TX_PAUSE_CNT_16K |
  847.                        V_MAC_SPEED_SEL_100MBPS |
  848.                        M_MAC_AP_STAT_EN |
  849.                        M_MAC_FAST_SYNC |
  850.                        M_MAC_SS_EN |
  851.                        V_MAC_IPHDR_OFFSET (14));
  852.     /* Set interface's speed, duplex, and flow control */
  853.     (void)bcm1250MacSetConfig (pDrvCtrl, pDrvCtrl->macSpeed, 
  854.                                pDrvCtrl->macDuplex, pDrvCtrl->macFc);
  855.     /* init rx dma's descrs */
  856.     DRV_LOG (DRV_DEBUG_LOAD, "rxDMA ch#0 initn", 1, 2, 3, 4, 5, 6);
  857.     pDma = &(pDrvCtrl->rxDma);
  858.     /* Initialize all receive DMA buffer descriptors. */
  859.     for (ix = 0; ix < pDma->maxDescr; ix++)
  860.         {
  861.         /* Allocate a cluster */
  862.         pBuf = (char *)NET_BUF_ALLOC ();
  863.         if (pBuf == (char *)NULL)
  864.             {
  865.             DRV_LOG (DRV_DEBUG_LOAD, "bcm1250Mac - netClusterGet failedn",
  866.                          1, 2, 3, 4, 5, 6);
  867.             return (ERROR);
  868.             }
  869.         /* point to next buffer descriptor. */
  870.         pDscr = &pDma->pDscrTable[pDma->tailIndex];
  871.         /* initialize descriptor to receive into the cluster */
  872.         pDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) |
  873.                         V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) |
  874.                         M_DMA_DSCRA_INTERRUPT | VXW_RCV_BUF_OFFSET;
  875.         pDscr->dscr_b = 0;
  876.         /* give desc to the hw */
  877.         ETH_DMA_REG_WRITE (pDma->regDscrCnt, 1);
  878.         /* Advance ring management variables */
  879.         pDma->tailIndex = (pDma->tailIndex + 1) % pDma->maxDescr;
  880.         pDma->ringCount++;
  881.         DRV_LOG (DRV_DEBUG_LOAD, "set reg, dscrcntn", 1, 2, 3, 4, 5, 6);
  882.         DRV_LOG (DRV_DEBUG_LOAD, "descA manual read 0x%08x%08xn",
  883.                  (pDscr->dscr_a) >> 32, pDscr->dscr_a, 3, 4, 5, 6);
  884.         DRV_LOG (DRV_DEBUG_LOAD, "descB manual read 0x%08x%08xn",
  885.                  (pDscr->dscr_b) >> 32, pDscr->dscr_b, 3, 4, 5, 6);
  886.         }
  887.     /* enable transmit and receive interrupts for channel 0 */
  888.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable,
  889.                        M_MAC_RXDMA_EN0 |
  890.                        M_MAC_TXDMA_EN0 |
  891.                        M_MAC_RX_ENABLE |
  892.                        M_MAC_TX_ENABLE);
  893.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart: enabledn", 1, 2, 3, 4, 5, 6);
  894.     /* connect interrupt handler */
  895.     rtv = bcm1250IntConnect (pDrvCtrl->intSource, pDrvCtrl->iVecNum,
  896.                              bcm1250MacInt, (int) pDrvCtrl);
  897.     if (rtv == ERROR)
  898.         return (ERROR);
  899.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart connect intn",
  900.              1, 2, 3, 4, 5, 6);
  901.     /* unmask the mac interrupt */
  902.     ETH_MAC_REG_WRITE (pDrvCtrl->regImr,
  903.                        (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
  904.                        (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
  905.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart, set intr maskn",
  906.              1, 2, 3, 4, 5, 6);
  907.     /* set rxfilter */
  908.     ETH_MAC_REG_WRITE (pDrvCtrl->regRxFilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN);
  909.     /* set flags to indicate interface is up */
  910.     END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
  911.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart, interface upn",
  912.              1, 2, 3, 4, 5, 6);
  913.     /* enable interrupts */
  914.     (void)bcm1250IntEnable (pDrvCtrl->intSource);
  915.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart: enable interruptn",
  916.              1, 2, 3, 4, 5, 6);
  917.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart donen", 1, 2, 3, 4, 5, 6);
  918.     return OK;
  919.     }
  920. /*******************************************************************************
  921. *
  922. * bcm1250MacStop - stop the device
  923. *
  924. * This function calls BSP functions to disconnect interrupts and stop
  925. * the device from operating in interrupt mode.
  926. *
  927. * RETURNS: OK.
  928. */
  929. LOCAL STATUS bcm1250MacStop
  930.     (
  931.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  932.     )
  933.     {
  934.     DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacStop enter ......n", 1, 2, 3, 4, 5, 6);
  935.     /* mark the interface as down */
  936.     END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
  937.     /* disable mac interrupts */
  938.     ETH_MAC_REG_WRITE (pDrvCtrl->regImr, 0);
  939.     /* disable mac hw */
  940.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, 0);
  941.     /* diasble VxW interrupt */
  942.     (void)bcm1250IntDisable (pDrvCtrl->intSource);
  943.     /* disconnect interrupt handler */
  944.     (void)bcm1250IntDisconnect (pDrvCtrl->intSource);
  945.     DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacStop done.n", 1, 2, 3, 4, 5, 6);
  946.     return (OK);
  947.     }
  948. /*******************************************************************************
  949. *
  950. * bcm1250MacSend - send an Ethernet packet
  951. *
  952. * This routine() takes a M_BLK_ID and sends off the data in the M_BLK_ID.
  953. * The buffer must already have the addressing information properly installed
  954. * in it. This is done by a higher layer.
  955. *
  956. * muxSend() calls this routine each time it wants to send a packet.
  957. *
  958. * RETURNS: OK, or END_ERR_BLOCK, if no resources are available, or ERROR, if
  959. * the device is currently working in polling mode, or is passed a bad M_BLK
  960. * pointer.
  961. */
  962. LOCAL STATUS bcm1250MacSend
  963.     (
  964.     DRV_CTRL *  pDrvCtrl,       /* driver control structure */
  965.     M_BLK *     pMblk           /* pointer to the mBlk/cluster pair */
  966.     )
  967.     {
  968.     STATUS  rtv = OK;       /* function return value */
  969.     int     fragNum = 0;    /* number of fragments in this mBlk */
  970.     BOOL    zeroCopyReady;  /* able to transmit without buffer copy */
  971.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend...n", 1, 2, 3, 4, 5, 6);
  972.     /*
  973.      * Obtain exclusive access to transmitter.  This is necessary because
  974.      * we might have more than one stack transmitting at once.
  975.      */
  976.     END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);
  977.     /* check device mode */
  978.     if (DRV_FLAGS_ISSET (BCM1250_MAC_POLLING))
  979.         {
  980.         netMblkClChainFree (pMblk);
  981.         rtv = ERROR;
  982.         errno = EINVAL;
  983.         goto bcm1250MacSendError;
  984.         }
  985.     /* check for valid M_BLK */
  986.     if (pMblk == (M_BLK *)NULL)
  987.         {
  988.         DRV_LOG (DRV_DEBUG_TX, "Invalid pMblkn", 1, 2, 3, 4, 5, 6);
  989.         rtv = ERROR;
  990.         errno = EINVAL;
  991.         goto bcm1250MacSendError;
  992.         }
  993.     /* walk the mBlk */
  994.     bcm1250MacMblkWalk (pMblk, &fragNum, &zeroCopyReady);
  995.     /* check we have enough resources */
  996.     if (zeroCopyReady &&
  997.         ((pDrvCtrl->txDma.maxDescr - pDrvCtrl->txDma.ringCount) >= fragNum))
  998.         {
  999.         DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend fragNum = %dn", fragNum,
  1000.                  2, 3, 4, 5, 6);
  1001.         /* transmit the packet in zero-copy mode */
  1002.         rtv = bcm1250MacPktTransmit (pDrvCtrl, pMblk, fragNum);
  1003.         }
  1004.     else
  1005.         {
  1006.         /* transmit the packet in copy mode */
  1007.         rtv = bcm1250MacPktCopyTransmit (pDrvCtrl, pMblk);
  1008.         }
  1009. bcm1250MacSendError:
  1010.     END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1011.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend...Donen", 1, 2, 3, 4, 5, 6);
  1012.     return (rtv);
  1013.     }
  1014. /*******************************************************************************
  1015. *
  1016. * bcm1250MacPktCopyTransmit - copy and transmit a packet
  1017. *
  1018. * This routine transmits the packet described by the given parameters
  1019. * over the network, after copying the mBlk to the driver's buffer.
  1020. * It also updates statistics.
  1021. *
  1022. * RETURNS: OK, or ERROR if no resources were available.
  1023. */
  1024. LOCAL STATUS bcm1250MacPktCopyTransmit
  1025.     (
  1026.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1027.     M_BLK *     pMblk       /* pointer to the mBlk */
  1028.     )
  1029.     {
  1030.     int             len = 0;                /* length of data to be sent */
  1031.     char *          pBuf = (char *)NULL;    /* pointer to data to be sent */
  1032.     ETH_DMA_DSCR *  pTxDscr;                /* DMA buffer descriptor */
  1033.     ETH_MAC_DMA *   pTxDma;                 /* ethernet DMA structure */
  1034.     UINT64          dscrCnt;                /* buffer descriptor count */
  1035.     DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac CopyTx ...n", 1, 2, 3, 4, 5, 6);
  1036.     pTxDma = &pDrvCtrl->txDma;
  1037.     /* get a cluster buffer from the pool */
  1038.     pBuf = NET_BUF_ALLOC ();
  1039.     if (pBuf == (char *)NULL)
  1040.         {
  1041.         /* set to stall condition */
  1042.         pDrvCtrl->txDma.txBlocked = TRUE;
  1043.         return (END_ERR_BLOCK);
  1044.         }
  1045.     /* Check for all DMA buffer descriptors in use. */
  1046.     if (pTxDma->ringCount >= pTxDma->maxDescr)
  1047.         {
  1048.         DRV_LOG (DRV_DEBUG_TX, "No available TxBufsn", 1, 2, 3, 4, 5, 6);
  1049.         END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, 1);
  1050.         NET_BUF_FREE (pBuf);
  1051.         pDrvCtrl->txDma.txBlocked = TRUE;
  1052.         return (END_ERR_BLOCK); /* just return without freeing mBlk chain */
  1053.         }
  1054.     len = netMblkToBufCopy (pMblk, (char *)pBuf, (FUNCPTR)NULL);
  1055.     netMblkClChainFree (pMblk);
  1056.     len = max (ETHERSMALL, len);
  1057.     DRV_LOG (DRV_DEBUG_TXD,
  1058.              "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1059.              pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5]);
  1060.     DRV_LOG (DRV_DEBUG_TXD,
  1061.              "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1062.              pBuf[6], pBuf[7], pBuf[8], pBuf[9], pBuf[10], pBuf[11]);
  1063.     DRV_LOG (DRV_DEBUG_TXD,
  1064.              "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1065.              pBuf[12], pBuf[13], pBuf[14], pBuf[15], pBuf[16], pBuf[17]);
  1066.     /* point to next buffer descriptor */
  1067.     pTxDscr = &pTxDma->pDscrTable[pTxDma->tailIndex];
  1068.     DRV_LOG (DRV_DEBUG_TXD, "pTxd->desc_a = 0x%08xn",
  1069.              (UINT32)&pTxDscr->dscr_a, 2, 3, 4, 5, 6);
  1070.     DRV_LOG (DRV_DEBUG_TXD, "pTxd->desc_b = 0x%08xn",
  1071.              (UINT32)&pTxDscr->dscr_b, 2, 3, 4, 5, 6);
  1072.     /* set buffer ptr, size in cache line, enable intr, mark as 1st pkt */
  1073.     pTxDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) |
  1074.                       V_DMA_DSCRA_A_SIZE (NUMCACHEBLKS (len)) |
  1075.                       M_DMA_DSCRA_INTERRUPT |
  1076.                       M_DMA_ETHTX_SOP;
  1077.     /* set pkt len and  option */
  1078.     pTxDscr->dscr_b = V_DMA_DSCRB_OPTIONS (K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
  1079.                       V_DMA_DSCRB_PKT_SIZE (len);
  1080.     DRV_LOG (DRV_DEBUG_TXD, "dscr_a = 0x%08x%08xn", (pTxDscr->dscr_a) >> 32,
  1081.              pTxDscr->dscr_a, 3, 4, 5, 6);
  1082.     DRV_LOG (DRV_DEBUG_TXD, "dscr_b = 0x%08x%08xn", (pTxDscr->dscr_b) >> 32,
  1083.              pTxDscr->dscr_b, 3, 4, 5, 6);
  1084.     /* save pointer to buffer and the buffer type. */
  1085.     pTxDma->bufTable[pTxDma->tailIndex].pBuf = pBuf;
  1086.     pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_CL;
  1087.     /* advance ring management variables */
  1088.     pTxDma->tailIndex = (pTxDma->tailIndex + 1) % pTxDma->maxDescr;
  1089.     pTxDma->ringCount++;
  1090.     /* tell hw one more dscr to go */
  1091.     ETH_DMA_REG_WRITE (pTxDma->regDscrCnt, 1);
  1092.     /* debug purpose */
  1093.     dscrCnt = ETH_DMA_REG_READ (pTxDma->regDscrCnt);
  1094.     DRV_LOG (DRV_DEBUG_TX, "tx0 DMA dscrcnt=0x%08x%08xn", (dscrCnt >> 32), 
  1095.              dscrCnt, 3, 4, 5, 6);
  1096.     DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac CopyTx Done.n", 1, 2, 3, 4, 5, 6);
  1097.     return (OK);
  1098.     }
  1099. /*******************************************************************************
  1100. *
  1101. * bcm1250MacMblkWalk - walk the mBlk
  1102. *
  1103. * This routine walks the mBlk whose address is in <pMblk>, computes
  1104. * the number of fragments it is made of, and returns it in the parameter
  1105. * <pFragNum>. In addition, it finds out whether the specified packet
  1106. * is unicast or multicast.
  1107. *
  1108. * RETURNS: OK, or ERROR in case of invalid mBlk.
  1109. */
  1110. LOCAL void bcm1250MacMblkWalk
  1111.     (
  1112.     M_BLK * pMblk,          /* pointer to the mBlk */
  1113.     int *   pFragNum,       /* number of fragments in this mBlk */
  1114.     BOOL *  pZeroCopyReady  /* no buffer copy flag */
  1115.     )
  1116.     {
  1117.     M_BLK * pCurr = pMblk;  /* the current mBlk */
  1118.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacMblkWalk: startn", 1, 2, 3, 4, 5, 6);
  1119.     *pZeroCopyReady = TRUE; /* assume no buffer copy is required */
  1120.     /* walk this mBlk */
  1121.     do
  1122.         {
  1123.         /* if not first buffer in a packet, must start at cache line boundary */
  1124.         if (pCurr != pMblk)
  1125.             {
  1126.             if (((UINT32)pCurr->mBlkHdr.mData & (CACHELINESIZE - 1)) != 0)
  1127.                 {
  1128.                 DRV_LOG (DRV_DEBUG_TX,
  1129.                          "bcm1250MacMblkWalk: beginning align failn",
  1130.                          1, 2, 3, 4, 5, 6);
  1131.                 *pZeroCopyReady = FALSE;    /* buffer copy required */
  1132.                 }
  1133.             }
  1134.         /* if not last buffer in a pacet, must end at cache line boundary */
  1135.         if (pCurr->mBlkHdr.mNext != (M_BLK *)NULL)
  1136.             {
  1137.             if ((((UINT32)pCurr->mBlkHdr.mData + pCurr->mBlkHdr.mLen) &
  1138.                  (CACHELINESIZE - 1)) != 0)
  1139.                 {
  1140.                 DRV_LOG (DRV_DEBUG_TX,
  1141.                          "bcm1250MacMblkWalk: ending align failn",
  1142.                          1, 2, 3, 4, 5, 6);
  1143.                 *pZeroCopyReady = FALSE;    /* buffer copy required */
  1144.                 }
  1145.             }
  1146.         /* keep track of the number of fragments in this mBlk */
  1147.         (*pFragNum)++;
  1148.         pCurr = ((M_BLK *)pCurr->mBlkHdr.mNext);
  1149.         DRV_LOG (DRV_DEBUG_TX, "bcm1250MacMblkWalk: nextn", 1, 2, 3, 4, 5, 6);
  1150.         }
  1151.     while (pCurr != (M_BLK *)NULL);
  1152.     }
  1153. /*******************************************************************************
  1154. *
  1155. * bcm1250MacPktTransmit - zero copy packet transmit
  1156. *
  1157. * This routine transmits the packet described by the given parameters
  1158. * over the network, zero mbuf copying
  1159. *
  1160. * RETURNS: OK, or ERROR if no resources were available or condition
  1161. * does not meet.
  1162. */
  1163. LOCAL STATUS bcm1250MacPktTransmit
  1164.     (
  1165.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1166.     M_BLK *     pMblk,      /* pointer to the mBlk */
  1167.     int         fragNum     /* number of fragments in this mBlk */
  1168.     )
  1169.     {
  1170.     int             len = 0;                /* length of data to be sent */
  1171.     UINT32          offset;                 /* offset to cache line */
  1172.     char *          pBuf = (char *)NULL;    /* pointer to data to be sent */
  1173.     ETH_DMA_DSCR *  pTxDscr;                /* DMA buffer descriptor */
  1174.     ETH_MAC_DMA *   pTxDma;                 /* ethernet DMA structure */
  1175.     M_BLK *         pCurrentMblk;           /* current mBlk pointer */
  1176.     DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac Zero-Copy Tx ...n", 1, 2, 3, 4, 5, 6);
  1177.     pTxDma = &pDrvCtrl->txDma;
  1178.     pCurrentMblk = pMblk;
  1179.     while (pCurrentMblk != (M_BLK *)NULL)
  1180.         {
  1181.         /* point to next buffer descriptor */
  1182.         pTxDscr = &pTxDma->pDscrTable[pTxDma->tailIndex];
  1183.         pBuf = pCurrentMblk->mBlkHdr.mData;
  1184.         len = pCurrentMblk->mBlkHdr.mLen;
  1185.         offset = (UINT32)(pCurrentMblk->mBlkHdr.mData) & (CACHELINESIZE - 1);
  1186.         /* set buffer ptr, size in cache line */
  1187.         pTxDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) |
  1188.                           V_DMA_DSCRA_A_SIZE (NUMCACHEBLKS (offset + len));
  1189.         pTxDscr->dscr_b = V_DMA_DSCRB_OPTIONS (K_DMA_ETHTX_APPENDCRC_APPENDPAD);
  1190.         if (pCurrentMblk == pMblk)
  1191.             {
  1192.             /* set pkt len and  option */
  1193.             pTxDscr->dscr_a |= M_DMA_ETHTX_SOP;
  1194.             pTxDscr->dscr_b |= V_DMA_DSCRB_PKT_SIZE(
  1195.                                     pCurrentMblk->mBlkPktHdr.len);
  1196.             }
  1197.         DRV_LOG (DRV_DEBUG_TXD, "dscr_a = 0x%08x%08xn",
  1198.                  (pTxDscr->dscr_a) >> 32, pTxDscr->dscr_a, 3, 4, 5, 6);
  1199.         DRV_LOG (DRV_DEBUG_TXD, "dscr_b = 0x%08x%08xn",
  1200.                  (pTxDscr->dscr_b) >> 32, pTxDscr->dscr_b, 3, 4, 5, 6);
  1201.         /* Is this the last one? */
  1202.         if (pCurrentMblk->mBlkHdr.mNext == (M_BLK *)NULL)
  1203.             {
  1204.             pTxDscr->dscr_a |= M_DMA_DSCRA_INTERRUPT;
  1205.             /* save pointer to buffer and the buffer type. */
  1206.             pTxDma->bufTable[pTxDma->tailIndex].pBuf = (char *)pMblk;
  1207.             pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_MBLK;
  1208.             }
  1209.         else
  1210.             {
  1211.             /*
  1212.              * Save pointer to buffer and the buffer type for 
  1213.              * the last descriptor.
  1214.              */
  1215.             pTxDma->bufTable[pTxDma->tailIndex].pBuf = (char *)NULL;
  1216.             pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_NONE;
  1217.             }
  1218.         /* advance ring management variables */
  1219.         pTxDma->tailIndex = (pTxDma->tailIndex + 1) %  pTxDma->maxDescr;
  1220.         pTxDma->ringCount++;
  1221.         pCurrentMblk = pCurrentMblk->mBlkHdr.mNext;
  1222.         }
  1223.     /* tell hw one more dscr to go */
  1224.     ETH_DMA_REG_WRITE (pTxDma->regDscrCnt, fragNum);
  1225.     DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac Zero-Copy Tx Done.n",
  1226.              1, 2, 3, 4, 5, 6);
  1227.     return (OK);
  1228.     }
  1229. /*******************************************************************************
  1230. *
  1231. * bcm1250MacInt - entry point for handling interrupts
  1232. *
  1233. * The interrupting events are acknowledged to the device, so that the device
  1234. * will de-assert its interrupt signal.  The amount of work done here is kept
  1235. * to a minimum; the bulk of the work is deferred to the netTask.
  1236. *
  1237. * RETURNS: N/A
  1238. */
  1239. LOCAL void bcm1250MacInt
  1240.     (
  1241.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  1242.     )
  1243.     {
  1244.     UINT64  status; /* Interrupt status */
  1245.     /* Get the interrupt status register value. */
  1246.     while ((status = ETH_MAC_REG_READ (pDrvCtrl->regIsr)) != 0)
  1247.         {
  1248.         DRV_LOG (DRV_DEBUG_INT, "status = 0x%xn", status, 2, 3, 4, 5, 6);
  1249.         /* Check for receive channel 0 interrupt */
  1250.         if ((!pDrvCtrl->rxDma.hndlAct) &&
  1251.             (status & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)))
  1252.             {
  1253.             pDrvCtrl->rxDma.hndlAct = TRUE;
  1254.             (void)netJobAdd ((FUNCPTR)bcm1250MacRxHandle, (int)pDrvCtrl, 0,
  1255.                               0, 0, 0);
  1256.             }
  1257.         /* Check for transmit channel 0 interrupt */
  1258.         if ((!pDrvCtrl->txDma.hndlAct) &&
  1259.             (status & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)))
  1260.             {
  1261.             pDrvCtrl->txDma.hndlAct = TRUE;
  1262.             (void)netJobAdd ((FUNCPTR)bcm1250MacTxHandle, (int)pDrvCtrl, 0,
  1263.                               0, 0, 0);
  1264.             }
  1265.         }
  1266.     }
  1267. /*******************************************************************************
  1268. *
  1269. * bcm1250MacRxHandle - task-level routine to service receive frame interrupts
  1270. *
  1271. * This routine processes received frame interrupts, and runs at task level
  1272. * context in the netTask task.  Ethernet frames are received at the headIndex,
  1273. * and ethernet DMA hardware is given DMA buffer descriptors to receive into
  1274. * with the tailIndex.
  1275. *
  1276. * RETURNS: N/A
  1277. */
  1278. LOCAL void bcm1250MacRxHandle
  1279.     (
  1280.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  1281.     )
  1282.     {
  1283.     ETH_MAC_DMA *   pRxDma;     /* ethernet DMA structure */
  1284.     ETH_DMA_DSCR *  pRxDscr;    /* DMA buffer descriptor */
  1285.     ETH_DMA_DSCR *  pCurrDscr;  /* points to current buffer descriptor */
  1286.     M_BLK_ID        pMblk;      /* mBlk pointer */
  1287.     CL_BLK_ID       pClBlk;     /* cBlk pointer */
  1288.     char *          pBuf;       /* cluster pointer */
  1289.     char *          pData;      /* received frame data pointer */
  1290.     int             len;        /* frame length */
  1291.     DRV_LOG (DRV_DEBUG_RX, "bcm1250MacRxHandle ......n", 1, 2, 3, 4, 5, 6);
  1292.     pRxDma = &pDrvCtrl->rxDma;
  1293.     while (TRUE)
  1294.         {
  1295.         /* Point to next descriptor to be filled by the receiver. */
  1296.         pCurrDscr = (ETH_DMA_DSCR *)((UINT32)(ETH_DMA_REG_READ(
  1297.                                                  pRxDma->regCurDscr) &
  1298.                                               M_DMA_CURDSCR_ADDR));
  1299.         /* Point to next descriptor to be processed by this routine. */
  1300.         pRxDscr = &pRxDma->pDscrTable[pRxDma->headIndex];
  1301.         /* 
  1302.          * If all the full descriptors been processed, 
  1303.          * then break out of the loop and exit. 
  1304.          */
  1305.         if ((UINT32)pCurrDscr == KVTOPHYS (pRxDscr))
  1306.             {
  1307.             DRV_LOG (DRV_DEBUG_RX, "pRxDscr:0x%x catch pCurrPtr:0x%xn",
  1308.                      (int)pRxDscr, (int)pCurrDscr, 3, 4, 5, 6);
  1309.             break;
  1310.             }
  1311.         /* Get pointer to received frame */
  1312.         pData = (char *)PHYSTOV ((UINT32)(pRxDscr->dscr_a));
  1313.         /* Check this received frame for an error. */
  1314.         if (pRxDscr->dscr_a & M_DMA_ETHRX_BAD)
  1315.             {
  1316.             DRV_LOG (DRV_DEBUG_RX, "bad framen", 1, 2, 3, 4, 5, 6);
  1317.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, 1);
  1318.             /* Point to next descriptor to be given to the hardware */
  1319.             pRxDscr = &pRxDma->pDscrTable[pRxDma->tailIndex];
  1320.             pRxDscr->dscr_a = KVTOPHYS ((UINT32)pData) |
  1321.                               V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) |
  1322.                               M_DMA_DSCRA_INTERRUPT;
  1323.             pRxDscr->dscr_b = 0;
  1324.             /* mark the descriptor ready to receive */
  1325.             ETH_DMA_REG_WRITE (pRxDma->regDscrCnt, 1);
  1326.             /* advance ring management variables */
  1327.             pRxDma->tailIndex = (pRxDma->tailIndex + 1) % pRxDma->maxDescr;
  1328.             pRxDma->headIndex = (pRxDma->headIndex + 1) % pRxDma->maxDescr;
  1329.             continue;   /* back to top of while loop */
  1330.             }
  1331.         /* Process good frame received. */
  1332.         DRV_LOG (DRV_DEBUG_RX, "good framen", 1, 2, 3, 4, 5, 6);
  1333.         /* Update MIB-II variables */
  1334.         END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, 1);
  1335.         len = (int)G_DMA_DSCRB_PKT_SIZE (pRxDscr->dscr_b) - 4;
  1336.         pBuf = pData;
  1337.         DRV_LOG (DRV_DEBUG_RXD, "rx - pData= 0x%08x, len=%dn", (int)pBuf,
  1338.                  len, 3, 4, 5, 6);
  1339.         DRV_LOG (DRV_DEBUG_RXD,
  1340.                  "rx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1341.                  pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5]);
  1342.         DRV_LOG (DRV_DEBUG_RXD,
  1343.                  "rx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1344.                  pBuf[6], pBuf[7], pBuf[8], pBuf[9], pBuf[10], pBuf[11]);
  1345.         DRV_LOG (DRV_DEBUG_RXD,
  1346.                  "rx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1347.                  pBuf[12], pBuf[13], pBuf[14], pBuf[15], pBuf[16], pBuf[17]);
  1348.         /* Allocate mBlk/clBlk/Cluster */
  1349.         pMblk = NET_MBLK_ALLOC ();
  1350.         pClBlk = NET_CL_BLK_ALLOC ();
  1351.         pBuf = NET_BUF_ALLOC ();
  1352.         /* If an allocation failed, discard the frame. */
  1353.         if ((pMblk == (M_BLK *)NULL) ||
  1354.             (pBuf == (char *)NULL) ||
  1355.             (pClBlk == (CL_BLK *)NULL))
  1356.             {
  1357.             DRV_LOG (DRV_DEBUG_RX, "not available RxBufsn",
  1358.                      1, 2, 3, 4, 5, 6);
  1359.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, 1);
  1360.             pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
  1361.             muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError);
  1362.             /* Free any allocations that succeeded. */
  1363.             if (pMblk != (M_BLK *)NULL)
  1364.                 NET_MBLK_FREE (pMblk);
  1365.             if (pBuf != (char *)NULL)
  1366.                 NET_BUF_FREE (pBuf);
  1367.             if (pClBlk != (CL_BLK *)NULL)
  1368.                 NET_CL_BLK_FREE (pClBlk);
  1369.             /* Point to next descriptor to be given to the hardware */
  1370.             pRxDscr = &pRxDma->pDscrTable[pRxDma->tailIndex];
  1371.             /* Re-arm this descriptor with the same buffer. */
  1372.             pRxDscr->dscr_a = KVTOPHYS ((UINT32)pData) |
  1373.                               V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) |
  1374.                               M_DMA_DSCRA_INTERRUPT;
  1375.             pRxDscr->dscr_b = 0;
  1376.             /* mark the descriptor ready to receive */
  1377.             ETH_DMA_REG_WRITE (pRxDma->regDscrCnt, 1);
  1378.             /* advance ring management variables */
  1379.             pRxDma->tailIndex = (pRxDma->tailIndex + 1) % pRxDma->maxDescr;
  1380.             pRxDma->headIndex = (pRxDma->headIndex + 1) % pRxDma->maxDescr;
  1381.             continue;   /* back to top of while loop */
  1382.             }
  1383.         /* Point to next descriptor to be given to the hardware */
  1384.         pRxDscr = &pRxDma->pDscrTable[pRxDma->tailIndex];
  1385.         /* Re-arm this descriptor with the new buffer. */
  1386.         pRxDscr->dscr_a = KVTOPHYS ((UINT32)pBuf) |
  1387.                           V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) |
  1388.                           M_DMA_DSCRA_INTERRUPT | VXW_RCV_BUF_OFFSET;
  1389.         pRxDscr->dscr_b = 0;
  1390.         /* mark the descriptor ready to receive */
  1391.         ETH_DMA_REG_WRITE (pRxDma->regDscrCnt, 1);
  1392.         /* send the frame to the upper layer */
  1393.         NET_CL_BLK_JOIN (pClBlk, pData - VXW_RCV_BUF_OFFSET,
  1394.                          MAX_FRAME_SIZE);
  1395.         NET_MBLK_CL_JOIN (pMblk, pClBlk);
  1396.         pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  1397.         pMblk->mBlkHdr.mData = pData;
  1398.         pMblk->mBlkHdr.mLen = len;
  1399.         pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen;
  1400.         END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);
  1401.         DRV_LOG (DRV_DEBUG_RXD,
  1402.                  "rx - pMblk=0x%08x pClBlk=0x%08x pBuf=0x%08xn",
  1403.                  (int)pMblk, (int)pClBlk, (int)pBuf, 4, 5, 6);
  1404.         /* advance ring management variables */
  1405.         pRxDma->tailIndex = (pRxDma->tailIndex + 1) % pRxDma->maxDescr;
  1406.         pRxDma->headIndex = (pRxDma->headIndex + 1) % pRxDma->maxDescr;
  1407.         }
  1408.     DRV_LOG (DRV_DEBUG_RX, "bcm1250MacRxHandle Done.n", 1, 2, 3, 4, 5, 6);
  1409.     pRxDma->hndlAct = FALSE;
  1410.     }
  1411. /*******************************************************************************
  1412. *
  1413. * bcm1250MacTxHandle - task-level routine to service transmit frame interrupts
  1414. *
  1415. * This routine is processes transmit frame interrupts, and runs at task level
  1416. * context in the netTask task.
  1417. *
  1418. * RETURNS: N/A
  1419. */
  1420. LOCAL void bcm1250MacTxHandle
  1421.     (
  1422.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  1423.     )
  1424.     {
  1425.     ETH_MAC_DMA *   pTxDma;             /* ethernet DMA structure */
  1426.     ETH_DMA_DSCR *  pTxDscr;            /* DMA buffer descriptor */
  1427.     ETH_DMA_DSCR *  pCurrDscr;          /* points to current descriptor */
  1428.     TX_BUF_TABLE *  pBufTbl;            /* points to current buffer table */
  1429.     BOOL            restart = FALSE;    /* mux restart flag */
  1430.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacTxHandle ......n", 1, 2, 3, 4, 5, 6);
  1431.     pTxDma = &(pDrvCtrl->txDma);
  1432.     while (TRUE)
  1433.         {
  1434.         /* Point to next descriptor to be transmitted by the hardware. */
  1435.         pCurrDscr = (ETH_DMA_DSCR *)((UINT32)(ETH_DMA_REG_READ (
  1436.                                                  pTxDma->regCurDscr) &
  1437.                                               M_DMA_CURDSCR_ADDR));
  1438.         /* Point to next descriptor to be processed by this routine. */
  1439.         pTxDscr = &pTxDma->pDscrTable[pTxDma->headIndex];
  1440.         /* Have all the transmit complete descriptors been processed? */
  1441.         if ((UINT32)pCurrDscr == KVTOPHYS (pTxDscr))
  1442.              break;
  1443.         DRV_LOG (DRV_DEBUG_TX, "tx_remindex=0x%x, curdscr=0x%x, remdscr=0x%xn",
  1444.                  pTxDma->headIndex, (int)pCurrDscr, (int)pTxDscr, 4, 5, 6);
  1445.         /* point to current descriptors buffer table entry. */
  1446.         pBufTbl = &pTxDma->bufTable[pTxDma->headIndex];
  1447.         /* free this descriptors buffer */
  1448.         if (pBufTbl->pBuf != (char *)NULL)
  1449.             {
  1450.             if (pBufTbl->type == BUF_TYPE_CL)
  1451.                 {
  1452.                 NET_BUF_FREE (pBufTbl->pBuf);
  1453.                 }
  1454.             else if (pBufTbl->type == BUF_TYPE_MBLK)
  1455.                 {
  1456.                 netMblkClChainFree ((M_BLK *)pBufTbl->pBuf);
  1457.                 }
  1458.             else
  1459.                 {
  1460.                 DRV_LOG (DRV_DEBUG_TX,
  1461.                          "unknown buffer type when try to release tx bufn",
  1462.                          1, 2, 3, 4, 5, 6);
  1463.                 }
  1464.             pBufTbl->pBuf = (char *)NULL;
  1465.             pBufTbl->type = BUF_TYPE_NONE;
  1466.             }
  1467.         /* Update descriptor index and count variables */
  1468.         END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);
  1469.         pTxDma->headIndex = (pTxDma->headIndex + 1) % pTxDma->maxDescr;
  1470.         pTxDma->ringCount--;
  1471.         END_TX_SEM_GIVE (&pDrvCtrl->endObj);
  1472.         /* Indicate that we need to check for the restart condition. */
  1473.         restart = TRUE;
  1474.         }
  1475.     /*
  1476.      * Does the Mux need to be restarted, and do we have plenty of DMA buffer
  1477.      * descriptors?
  1478.      */
  1479.     if ((restart) && (pTxDma->txBlocked) && (pTxDma->ringCount < 5))
  1480.         {
  1481.             pTxDma->txBlocked = FALSE;
  1482.             muxTxRestart ((void *)&pDrvCtrl->endObj);
  1483.         }
  1484.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacTxHandle Done.n", 1, 2, 3, 4, 5, 6);
  1485.     /* Indicate that all transmit descriptors have been processed. */
  1486.     pTxDma->hndlAct = FALSE;
  1487.     }
  1488. /*******************************************************************************
  1489. * bcm1250MacPollSend - routine to send a packet in polled mode.
  1490. *
  1491. * This routine is called by a user to try and send a packet on the
  1492. * device.
  1493. *
  1494. * RETURNS: OK upon success.  EAGAIN if device is busy.
  1495. */
  1496. LOCAL STATUS bcm1250MacPollSend
  1497.     (
  1498.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1499.     M_BLK *     pMblk       /* mBlk to transmit */
  1500.     )
  1501.     {
  1502.     ETH_MAC_DMA *   pTxDma;     /* ethernet DMA structure */
  1503.     ETH_DMA_DSCR *  pTxDscr;    /* DMA buffer descriptor */
  1504.     ETH_DMA_DSCR *  pCurrDscr;  /* current descriptor */
  1505.     TX_BUF_TABLE *  pBufTbl;            /* points to current buffer table */
  1506.     int             len;        /* length of frame */
  1507.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacPollSend enter ......n",
  1508.               1, 2, 3, 4, 5, 6);
  1509.     pTxDma = &pDrvCtrl->txDma;
  1510.     /* DMA buffer descriptors available? */
  1511.     if (pTxDma->ringCount >= pTxDma->maxDescr)
  1512.         {
  1513.         DRV_LOG (DRV_DEBUG_TX, "No available TxBufsn", 1, 2, 3, 4, 5, 6);
  1514.         END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, 1);
  1515.         return (EAGAIN); /* just return without freeing mBlk chain */
  1516.         }
  1517.     len = netMblkToBufCopy (pMblk, pTxPollBuf, (FUNCPTR)NULL);
  1518.     len = max (ETHERSMALL, len);
  1519.     DRV_LOG (DRV_DEBUG_TXD,
  1520.              "tx - *pTxPollBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1521.              pTxPollBuf[0], pTxPollBuf[1], pTxPollBuf[2], pTxPollBuf[3], pTxPollBuf[4], pTxPollBuf[5]);
  1522.     DRV_LOG (DRV_DEBUG_TXD,
  1523.              "tx - *pTxPollBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1524.              pTxPollBuf[6], pTxPollBuf[7], pTxPollBuf[8], pTxPollBuf[9], pTxPollBuf[10], pTxPollBuf[11]);
  1525.     DRV_LOG (DRV_DEBUG_TXD,
  1526.              "tx - *pTxPollBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1527.              pTxPollBuf[12], pTxPollBuf[13], pTxPollBuf[14], pTxPollBuf[15], pTxPollBuf[16], pTxPollBuf[17]);
  1528.     pTxDscr = &pTxDma->pDscrTable[pTxDma->tailIndex];
  1529.     /* set txbuf ptr, cache line size, ...  */
  1530.     pTxDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pTxPollBuf)) |
  1531.                       V_DMA_DSCRA_A_SIZE (NUMCACHEBLKS (len)) |
  1532.                       M_DMA_ETHTX_SOP;
  1533.     /* set pkt len and option */
  1534.     pTxDscr->dscr_b = V_DMA_DSCRB_OPTIONS (K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
  1535.                       V_DMA_DSCRB_PKT_SIZE (len);
  1536.     /* save the buf info */
  1537.     pTxDma->bufTable[pTxDma->tailIndex].pBuf = pTxPollBuf;
  1538.     pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_CL;
  1539.     /* Advance ring management variables */
  1540.     pTxDma->tailIndex = (pTxDma->tailIndex + 1) % pTxDma->maxDescr;
  1541.     pTxDma->ringCount++;
  1542.     ETH_DMA_REG_WRITE (pTxDma->regDscrCnt, 1);
  1543.     while (TRUE)
  1544.         {
  1545.         /* Point to next descriptor to be transmitted by the hardware. */
  1546.         pCurrDscr = (ETH_DMA_DSCR *)((UINT32)(ETH_DMA_REG_READ (
  1547.                                                  pTxDma->regCurDscr) &
  1548.                                               M_DMA_CURDSCR_ADDR));
  1549.         /* Point to next descriptor to be processed by this routine. */
  1550.         
  1551.         pTxDscr = &pTxDma->pDscrTable[pTxDma->headIndex];
  1552.         /* Have all the transmit complete descriptors been processed? */
  1553.         if ((UINT32)pCurrDscr == KVTOPHYS (pTxDscr))
  1554.             break;
  1555.         DRV_LOG (DRV_DEBUG_TX, 
  1556.                  "TX headIndex:0x%x, pCurrDscr=0x%x, pTxDscr=0x%xn",
  1557.                  pTxDma->headIndex, (int)pCurrDscr, (int)pTxDscr, 4, 5, 6);
  1558.         /* point to current descriptors buffer table entry. */
  1559.         pBufTbl = &pTxDma->bufTable[pTxDma->headIndex];
  1560.         /* free this descriptors buffer */
  1561.  
  1562.         if (pBufTbl->pBuf != (char *)NULL)
  1563.             {
  1564.             pBufTbl->pBuf = (char *)NULL;
  1565.             pBufTbl->type = BUF_TYPE_NONE;
  1566.             }
  1567.         /* Update ring management variables */
  1568.         pTxDma->headIndex = (pTxDma->headIndex + 1) % pTxDma->maxDescr;
  1569.         pTxDma->ringCount--;
  1570.         }
  1571.     DRV_LOG (DRV_DEBUG_TX, "bcm1250MacPollSend Donen", 1, 2, 3, 4, 5, 6);
  1572.     return (OK);
  1573.     }
  1574. /*******************************************************************************
  1575. * bcm1250MacPollRcv - routine to receive a packet in polled mode.
  1576. *
  1577. * This routine is called by a user to try and get a packet from the
  1578. * device.
  1579. *
  1580. * RETURNS: OK upon success.  EAGAIN is returned when no packet is available.
  1581. */
  1582. LOCAL STATUS bcm1250MacPollRcv
  1583.     (
  1584.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1585.     M_BLK *     pMblk       /* mBlk to receive into */
  1586.     )
  1587.     {
  1588.     ETH_MAC_DMA *   pRxDma;     /* ethernet DMA structure */
  1589.     ETH_DMA_DSCR *  pRxDscr;    /* DMA buffer descriptor */
  1590.     ETH_DMA_DSCR *  pCurrDscr;  /* current descriptor */
  1591.     char *          pData;      /* frame data pointer */
  1592.     int             len;        /* frame data length */
  1593.     DRV_LOG (DRV_DEBUG_RX, "bcm1250MacPollRcv enter ......n",
  1594.              1, 2, 3, 4, 5, 6);
  1595.     pRxDma = &pDrvCtrl->rxDma;
  1596.     /* Point to next descriptor to be filled by the receiver. */
  1597.     pCurrDscr = (ETH_DMA_DSCR *)((UINT32)(ETH_DMA_REG_READ (
  1598.                                              pRxDma->regCurDscr) &
  1599.                                           M_DMA_CURDSCR_ADDR));
  1600.     /* Point to next descriptor to be processed by this routine. */
  1601.     pRxDscr = &pRxDma->pDscrTable[pRxDma->headIndex];
  1602.     DRV_LOG (DRV_DEBUG_RX, "RX headIndex=%d, pRxDscr=0x%x pCurrDscr=0x%xn",
  1603.                             pRxDma->headIndex, (int)pRxDscr,
  1604.                             (int)pCurrDscr, 4, 5, 6);
  1605.     /* 
  1606.      * If all the full descriptors been processed, 
  1607.      * then break out of the loop. 
  1608.      */
  1609.     if ((UINT32)pCurrDscr == KVTOPHYS (pRxDscr))
  1610.         {
  1611.         DRV_LOG (DRV_DEBUG_RX, "bcm1250MacPollRcv donen", 1, 2, 3, 4, 5, 6);
  1612.         return (EAGAIN);
  1613.         }
  1614.     DRV_LOG (DRV_DEBUG_RX, "RX headIndex=%d, pRxDscr=0x%x pCurrDscr=0x%xn",
  1615.                             pRxDma->headIndex, (int)pRxDscr,
  1616.                             (int)pCurrDscr, 4, 5, 6);
  1617.     /* Check this received frame for an error. */
  1618.     if (pRxDscr->dscr_a & M_DMA_ETHRX_BAD)
  1619.         {
  1620.         DRV_LOG (DRV_DEBUG_RX, "Bad Framen", 1, 2, 3, 4, 5, 6);
  1621.         END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, 1);
  1622.         pData = (char *)PHYSTOV ((UINT32)(pRxDscr->dscr_a));
  1623.         pRxDscr = &pRxDma->pDscrTable[pRxDma->tailIndex];
  1624.         pRxDscr->dscr_a = KVTOPHYS ((UINT32)pData) |
  1625.                           V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS);
  1626.         pRxDscr->dscr_b = 0;
  1627.         /* mark the descriptor ready to receive  again */
  1628.         ETH_DMA_REG_WRITE (pRxDma->regDscrCnt, 1);
  1629.         /* advance ring management variables */
  1630.         pRxDma->tailIndex = (pRxDma->tailIndex + 1) % pRxDma->maxDescr;
  1631.         pRxDma->headIndex = (pRxDma->headIndex + 1) % pRxDma->maxDescr;
  1632.         DRV_LOG (DRV_DEBUG_RX, "bcm1250MacPollRcv donen", 1, 2, 3, 4, 5, 6);
  1633.         return (EAGAIN);
  1634.         }
  1635.     DRV_LOG (DRV_DEBUG_RX, "Good Framen", 1, 2, 3, 4, 5, 6);
  1636.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, 1);
  1637.     len = (int)G_DMA_DSCRB_PKT_SIZE (pRxDscr->dscr_b) - ETH_CRC_LEN;
  1638.     pData = (char *)PHYSTOV ((UINT32)(pRxDscr->dscr_a));
  1639.     DRV_LOG (DRV_DEBUG_RXD, "rx - pData= 0x%08x, len=%dn",
  1640.              (int)pData, len, 3, 4, 5, 6);
  1641.     DRV_LOG (DRV_DEBUG_RXD,
  1642.              "rx - *pData= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1643.              pData[0], pData[1], pData[2], pData[3], pData[4], pData[5]);
  1644.     DRV_LOG (DRV_DEBUG_RXD,
  1645.              "rx - *pData= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1646.              pData[6], pData[7], pData[8], pData[9], pData[10], pData[11]);
  1647.     DRV_LOG (DRV_DEBUG_RXD,
  1648.              "rx - *pData= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02xn",
  1649.              pData[12], pData[13], pData[14], pData[15], pData[16],
  1650.              pData[17]);
  1651.     pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  1652.     pMblk->mBlkHdr.mLen = len;
  1653.     pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen;
  1654.     pMblk->mBlkHdr.mData += VXW_RCV_BUF_OFFSET;
  1655.     bcopy (pData, (char *)pMblk->mBlkHdr.mData, len);
  1656.     pRxDscr = &pRxDma->pDscrTable[pRxDma->tailIndex];
  1657.     pRxDscr->dscr_a = KVTOPHYS ((UINT32)pData) |
  1658.                       V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) | 2;
  1659.     pRxDscr->dscr_b = 0;
  1660.     /* mark the descriptor ready to receive again */
  1661.     ETH_DMA_REG_WRITE (pRxDma->regDscrCnt, 1);
  1662.     /* advance ring management variables */
  1663.     pRxDma->tailIndex = (pRxDma->tailIndex + 1) % pRxDma->maxDescr;
  1664.     pRxDma->headIndex = (pRxDma->headIndex + 1) % pRxDma->maxDescr;
  1665.     return OK;
  1666.     }
  1667. /*******************************************************************************
  1668. *
  1669. * bsm1250MacPollStart - start polled mode operations
  1670. *
  1671. * RETURNS: N/A
  1672. */
  1673. LOCAL void bcm1250MacPollStart
  1674.     (
  1675.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  1676.     )
  1677.     {
  1678.     int         oldLevel;   /* saved interrupt level */
  1679.     DRV_LOG (DRV_DEBUG_POLL, "PollStart enter ......n", 1, 2, 3, 4, 5, 6);
  1680.     oldLevel = intLock ();
  1681.     DRV_FLAGS_SET (BCM1250_MAC_POLLING);
  1682.     /* diasble VxW interrupt */
  1683.     (void)bcm1250IntDisable (pDrvCtrl->intSource);
  1684.     intUnlock (oldLevel);
  1685.     DRV_LOG (DRV_DEBUG_POLL, "PollStart donen", 1, 2, 3, 4, 5, 6);
  1686.     }
  1687. /*******************************************************************************
  1688. *
  1689. * bcm1250MacPollStop - stop polled mode operations
  1690. *
  1691. * This function terminates polled mode operation.  The device returns to
  1692. * interrupt mode.
  1693. *
  1694. * The device interrupts are enabled, the current mode flag is switched
  1695. * to indicate interrupt mode and the device is then reconfigured for
  1696. * interrupt operation.
  1697. *
  1698. * RETURNS: N/A
  1699. */
  1700. LOCAL void bcm1250MacPollStop
  1701.     (
  1702.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  1703.     )
  1704.     {
  1705.     int         oldLevel;   /* saved interrupt level */
  1706.     DRV_LOG (DRV_DEBUG_POLL, "PollStop enter ......n", 1, 2, 3, 4, 5, 6);
  1707.     oldLevel = intLock ();
  1708.     (void)bcm1250IntEnable (pDrvCtrl->intSource);
  1709.     DRV_FLAGS_CLR (BCM1250_MAC_POLLING);
  1710.     intUnlock (oldLevel);
  1711.     DRV_LOG (DRV_DEBUG_POLL, "PollStop donen", 1, 2, 3, 4, 5, 6);
  1712.     }
  1713. /*******************************************************************************
  1714. *
  1715. * bcm1250MacIoctl - the driver I/O control routine
  1716. *
  1717. * Process an ioctl request.
  1718. *
  1719. * RETURNS: A command specific response, usually OK or ERROR.
  1720. */
  1721. LOCAL int bcm1250MacIoctl
  1722.     (
  1723.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1724.     int         cmd,        /* command to be executed */
  1725.     caddr_t     data        /* data associated with command */
  1726.     )
  1727.     {
  1728.     int         error = OK; /* command error flag */
  1729.     long        endFlags;   /* END_OBJ flags */
  1730.     int         drvFlags;   /* driver flags */
  1731.     UINT64      reg;        /* value to read/write to register */
  1732.     END_OBJ *   pEndObj = &pDrvCtrl->endObj;
  1733.     DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%xn",
  1734.              pDrvCtrl->unit, cmd, (int)data, 4, 5, 6);
  1735.     switch (cmd)
  1736.         {
  1737.         case EIOCSADDR:
  1738.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCSADDRn", 1, 2, 3, 4, 5, 6);
  1739.             if (data == (caddr_t)NULL)
  1740.                 error = EINVAL;
  1741.             else
  1742.                 {
  1743.                 /* Copy and install the new address */
  1744.                 bcopy ((char *)data, (char *)END_HADDR (pEndObj),
  1745.                        END_HADDR_LEN (pEndObj));
  1746.                 reg =  bcm1250MacAddr2Reg ((unsigned char *)data);
  1747.                 DRV_LOG (DRV_DEBUG_IOCTL, "mac addr = 0x%08x%08xn",
  1748.                          (int)(reg >> 32), reg, 3, 4, 5, 6);
  1749.                 /* need pass 1 bug workaround */
  1750.                 ETH_MAC_REG_WRITE (R_MAC_ADDR_BASE, reg);
  1751.                 ETH_MAC_REG_WRITE (R_MAC_ETHERNET_ADDR, reg);
  1752.                 }
  1753.             break;
  1754.         case EIOCGADDR:
  1755.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGADDRn", 1, 2, 3, 4, 5, 6);
  1756.             if (data == (caddr_t)NULL)
  1757.                 error = EINVAL;
  1758.             else
  1759.                 bcopy ((char *)END_HADDR (pEndObj), (char *)data,
  1760.                        END_HADDR_LEN (pEndObj));
  1761.             break;
  1762.         case EIOCSFLAGS:
  1763.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCSAFLGSn", 1, 2, 3, 4, 5, 6);
  1764.             endFlags = (long)data;
  1765.             if (endFlags < 0)
  1766.                 {
  1767.                 endFlags = -endFlags;
  1768.                 endFlags--;
  1769.                 END_FLAGS_CLR (pEndObj, endFlags);
  1770.                 }
  1771.             else
  1772.                 {
  1773.                 END_FLAGS_SET (pEndObj, endFlags);
  1774.                 }
  1775.             /* handle IFF_PROMISC */
  1776.             drvFlags = DRV_FLAGS_GET ();
  1777.             if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC))
  1778.                 DRV_FLAGS_SET (BCM1250_MAC_PROMISC);
  1779.             else
  1780.                 DRV_FLAGS_CLR (BCM1250_MAC_PROMISC);
  1781.             if (END_FLAGS_GET (pEndObj) & (IFF_MULTICAST | IFF_ALLMULTI))
  1782.                 DRV_FLAGS_SET (BCM1250_MAC_MCAST);
  1783.             else
  1784.                 DRV_FLAGS_CLR (BCM1250_MAC_MCAST);
  1785.             DRV_LOG (DRV_DEBUG_IOCTL,
  1786.                      "endFlags=0x%x drvFlags=0x%x newFlags=0x%xn",
  1787.                      END_FLAGS_GET (pEndObj), drvFlags, DRV_FLAGS_GET (),
  1788.                      4, 5, 6);
  1789.             if ((DRV_FLAGS_GET () != drvFlags) &&
  1790.                 (END_FLAGS_GET (pEndObj) & IFF_UP))
  1791.                 bcm1250MacRxFilterSet (pDrvCtrl);
  1792.             break;
  1793.         case EIOCGFLAGS:
  1794.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS: 0x%x: 0x%xn",
  1795.                     pEndObj->flags, *(long *)data, 3, 4, 5, 6);
  1796.             if (data == (caddr_t)NULL)
  1797.                 error = EINVAL;
  1798.             else
  1799.                 *(long *)data = END_FLAGS_GET (pEndObj);
  1800.             break;
  1801.         case EIOCMULTIADD:
  1802.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCMULTIADDn", 1, 2, 3, 4, 5, 6);
  1803.             error = bcm1250MacMCastAdd (pDrvCtrl, (char *)data);
  1804.             break;
  1805.         case EIOCMULTIDEL:
  1806.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCMULTIDELn", 1, 2, 3, 4, 5, 6);
  1807.             error = bcm1250MacMCastDel (pDrvCtrl, (char *)data);
  1808.             break;
  1809.         case EIOCMULTIGET:
  1810.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCMULITGETn", 1, 2, 3, 4, 5, 6);
  1811.             error = bcm1250MacMCastGet (pDrvCtrl, (MULTI_TABLE *)data);
  1812.             break;
  1813.         case EIOCPOLLSTART:
  1814.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCPOLLSTARTn", 1, 2, 3, 4, 5, 6);
  1815.             bcm1250MacPollStart (pDrvCtrl);
  1816.             break;
  1817.         case EIOCPOLLSTOP:
  1818.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCPOLLSTOPn", 1, 2, 3, 4, 5, 6);
  1819.             bcm1250MacPollStop (pDrvCtrl);
  1820.             break;
  1821.         case EIOCGMIB2:                      /* move to mux */
  1822.             DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGMIBS2n", 1, 2, 3, 4, 5, 6);
  1823.             if (data == (caddr_t)NULL)
  1824.                 error = EINVAL;
  1825.             else
  1826.                 bcopy ((char *)&pEndObj->mib2Tbl, (char *)data,
  1827.                        sizeof (pEndObj->mib2Tbl));
  1828.             break;
  1829.         default:
  1830.             DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL Invalid Commandn",
  1831.                                         1, 2, 3, 4, 5, 6);
  1832.             error = EINVAL;
  1833.             break;
  1834.         }
  1835.     return (error);
  1836.     }
  1837. /*******************************************************************************
  1838. *
  1839. * bcm1250MacMCastAddrAdd - add a multicast address for the device
  1840. *
  1841. * This routine adds a multicast address to whatever the driver
  1842. * is already listening for.
  1843. *
  1844. * SEE ALSO: bcm1250MacMCastAddrDel() bcm1250MacMCastAddrGet()
  1845. *
  1846. * RETURNS: OK or ERROR.
  1847. */
  1848. LOCAL STATUS bcm1250MacMCastAdd
  1849.     (
  1850.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1851.     char *      pAddr       /* multicast address */
  1852.     )
  1853.     {
  1854.     int     rtv;    /* function return value */
  1855.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacMCastAddn", 1, 2, 3, 4, 5, 6);
  1856.     rtv = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);
  1857.     if (rtv == ENETRESET)
  1858.         {
  1859.         pDrvCtrl->endObj.nMulti++;
  1860.         return (bcm1250MacHashRegAdd (pDrvCtrl, pAddr));
  1861.         }
  1862.     return ((rtv == OK) ? OK : ERROR);
  1863.     }
  1864. /*******************************************************************************
  1865. *
  1866. * bcm1250MacMCastAddrDel - delete a multicast address for the device
  1867. *
  1868. * This routine deletes a multicast address from the current list of
  1869. * multicast addresses.
  1870. *
  1871. * SEE ALSO: bcm1250MacMCastAddrAdd() bcm1250MacMCastAddrGet()
  1872. *
  1873. * RETURNS: OK or ERROR.
  1874. */
  1875. LOCAL STATUS bcm1250MacMCastDel
  1876.     (
  1877.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1878.     char *      pAddr       /* multicast address */
  1879.     )
  1880.     {
  1881.     int     rtv;    /* function return value */
  1882.     DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacMCastDeln", 1, 2, 3, 4, 5, 6);
  1883.     rtv = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);
  1884.     if (rtv == ENETRESET)
  1885.         {
  1886.         pDrvCtrl->endObj.nMulti--;
  1887.         return (bcm1250MacHashRegSet (pDrvCtrl));
  1888.         }
  1889.     return ((rtv == OK) ? OK : ERROR);
  1890.     }
  1891. /*******************************************************************************
  1892. *
  1893. * bcm1250MacMCastAddrGet - get the current multicast address list
  1894. *
  1895. * This routine returns the current multicast address list in <pTable>
  1896. *
  1897. * SEE ALSO: bcm1250MacMCastAddrAdd() bcm1250MacMCastAddrDel()
  1898. *
  1899. * RETURNS: OK or ERROR.
  1900. */
  1901. LOCAL STATUS bcm1250MacMCastGet
  1902.     (
  1903.     DRV_CTRL *      pDrvCtrl,   /* driver control structure */
  1904.     MULTI_TABLE *   pTable      /* multicast address table */
  1905.     )
  1906.     {
  1907.     DRV_LOG (DRV_DEBUG_IOCTL, "sbMCastGetn", 1, 2, 3, 4, 5, 6);
  1908.     return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));
  1909.     }
  1910. /*******************************************************************************
  1911. *
  1912. * bcm1250MacHashRegAdd
  1913. *
  1914. * Set Receiver Hash table registers
  1915. *
  1916. * RETURNS: OK
  1917. */
  1918. LOCAL STATUS bcm1250MacHashRegAdd
  1919.     (
  1920.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  1921.     char     *  pAddr       /* multicast address */
  1922.     )
  1923.     {
  1924.     int     dwOffset;
  1925.     int     hashVal;
  1926.     UINT64  reg;
  1927.     UINT64  oldReg;
  1928.     DRV_LOG (DRV_DEBUG_IOCTL, "MacHashRegAdd enter ......n",
  1929.              1, 2, 3, 4, 5, 6);
  1930.     hashVal = bcm1250MacEthHash ((unsigned char *)pAddr);
  1931.     dwOffset = hashVal >> 6;
  1932.     reg = 1 << ((hashVal & 0x3F) - 1);
  1933.     oldReg = ETH_MAC_REG_READ (R_MAC_HASH_BASE + (dwOffset * 8));
  1934.     ETH_MAC_REG_WRITE (R_MAC_HASH_BASE + (dwOffset * 8), (reg | oldReg));
  1935.     DRV_LOG (DRV_DEBUG_IOCTL, "MacHashRegAdd donen", 1, 2, 3, 4, 5, 6);
  1936.     return (OK);
  1937.     }
  1938. /*******************************************************************************
  1939. *
  1940. * bcm1250MacHashRegSet
  1941. *
  1942. * Set Receiver Hash table registers
  1943. *
  1944. * RETURNS: OK
  1945. */
  1946. LOCAL STATUS bcm1250MacHashRegSet
  1947.     (
  1948.     DRV_CTRL *  pDrvCtrl       /* driver control structure */
  1949.     )
  1950.     {
  1951.     int             dwOffset;
  1952.     int             hashVal;
  1953.     int             idx;
  1954.     UINT64          reg;
  1955.     UINT64          oldReg;
  1956.     MAC_REG         port;
  1957.     ETHER_MULTI *   mCastNode = (ETHER_MULTI *)NULL;
  1958.     DRV_LOG (DRV_DEBUG_IOCTL, "MacHashRegSet enter ......n",
  1959.              1, 2, 3, 4, 5, 6);
  1960.     /* clear hash table */
  1961.     port = R_MAC_HASH_BASE;
  1962.     for (idx = 0; idx < MAC_HASH_COUNT; idx++)
  1963.         {
  1964.         ETH_MAC_REG_WRITE (port, 0);
  1965.         port += sizeof (UINT64);
  1966.         }
  1967.     port = R_MAC_HASH_BASE;
  1968.     for (mCastNode = (ETHER_MULTI *)lstFirst (&pDrvCtrl->endObj.multiList);
  1969.              mCastNode != (ETHER_MULTI *)NULL;
  1970.                  mCastNode = (ETHER_MULTI *)lstNext (&mCastNode->node))
  1971.         {
  1972.         hashVal = bcm1250MacEthHash ((unsigned char *)mCastNode->addr);
  1973.         dwOffset = hashVal >> 6;
  1974.         reg = 1 << ((hashVal & 0x3F) - 1);
  1975.         oldReg = ETH_MAC_REG_READ (port + (dwOffset * 8));
  1976.         ETH_MAC_REG_WRITE (port + (dwOffset * 8), (reg | oldReg));
  1977.         }
  1978.     DRV_LOG (DRV_DEBUG_IOCTL, "MacHashRegSet donen", 1, 2, 3, 4, 5, 6);
  1979.     return (OK);
  1980.     }
  1981. /*******************************************************************************
  1982. * bcm1250MacEthHash - Calculate destination address hash value.
  1983. *
  1984. * Function to calculate dest addr hash value.
  1985. * See bcm1250 manual page 9-190
  1986. *
  1987. * RETURNS: Destination address hash value.
  1988. */
  1989. LOCAL unsigned bcm1250MacEthHash
  1990.     (
  1991.     unsigned char * pAddr   /* destination address */
  1992.     )
  1993.     {
  1994.     int             idx;
  1995.     unsigned int    crc = 0xFFFFFFFFUL;
  1996.     static unsigned int crcTab[] =
  1997.                         {
  1998.                         0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC,
  1999.                         0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C,
  2000.                         0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
  2001.                         0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
  2002.                         };
  2003.     for (idx = 0; idx < ETH_ADDR_LEN; idx++)
  2004.         {
  2005.         crc ^= *pAddr++;
  2006.         crc = (crc >> 4) ^ crcTab[crc & 0xF];
  2007.         crc = (crc >> 4) ^ crcTab[crc & 0xF];
  2008.         }
  2009.     return ((crc >> 1) & 0x1FF);
  2010. }
  2011. /*******************************************************************************
  2012. *
  2013. * bcm1250MacRxFilterSet
  2014. *
  2015. * Set rx filter register according to DRV FLAGS
  2016. *
  2017. * RETURNS: N/A
  2018. */
  2019. LOCAL void bcm1250MacRxFilterSet
  2020.     (
  2021.     DRV_CTRL    *pDrvCtrl   /* driver control structure */
  2022.     )
  2023.     {
  2024.     UINT64  rxFilterCfg;    /* RX filter register value */
  2025.     DRV_LOG (DRV_DEBUG_IOCTL, "RxFiltern", 1, 2, 3, 4, 5, 6);
  2026.     /* read the current rx filter reg */
  2027.     rxFilterCfg = ETH_MAC_REG_READ (pDrvCtrl->regRxFilter);
  2028.     if (DRV_FLAGS_ISSET (BCM1250_MAC_MCAST))
  2029.         rxFilterCfg |= M_MAC_MCAST_EN;
  2030.     if (DRV_FLAGS_ISSET (BCM1250_MAC_PROMISC))
  2031.         rxFilterCfg |= M_MAC_ALLPKT_EN;
  2032.     ETH_MAC_REG_WRITE (pDrvCtrl->regRxFilter, rxFilterCfg);
  2033.     }
  2034. /*******************************************************************************
  2035. *
  2036. * bcm1250MacSetConfig(pDrvCtrl, speed)
  2037. *
  2038. * Configure LAN speed, Ethernet duplex and flow control options for this MAC.
  2039. *
  2040. * RETURNS: OK if successful, ERROR if invalid parameters
  2041. */
  2042. LOCAL STATUS bcm1250MacSetConfig
  2043.     (
  2044.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  2045.     MAC_SPEED   speed,      /* speed to set MAC to */
  2046.     MAC_DUPLEX  duplex,     /* duplex setting */
  2047.     MAC_FC      fc          /* flow control setting */
  2048.     )
  2049.     {
  2050.     UINT64  macCfg;     /* MAC config register value */
  2051.     UINT64  frameCfg;   /* frame config register value */
  2052.     /* Read current register values */
  2053.     macCfg = ETH_MAC_REG_READ (pDrvCtrl->regMacCfg);
  2054.     frameCfg = ETH_MAC_REG_READ (pDrvCtrl->regFrameCfg);
  2055.     /* Mask out the stuff we want to change */
  2056.     macCfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL | M_MAC_FC_SEL | 
  2057.                 M_MAC_FC_CMD   | M_MAC_HDX_EN);
  2058.     frameCfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
  2059.                   M_MAC_SLOT_SIZE);
  2060.      /* Now add in the new bits */
  2061.     switch (speed)
  2062.         {
  2063.         case MAC_SPEED_10:
  2064.             frameCfg |= V_MAC_IFG_RX_10 |
  2065.                         V_MAC_IFG_TX_10 |
  2066.                         K_MAC_IFG_THRSH_10 |
  2067.                         V_MAC_SLOT_SIZE_10;
  2068.             macCfg |= V_MAC_SPEED_SEL_10MBPS;
  2069.             break;
  2070.         case MAC_SPEED_100:
  2071.             frameCfg |= V_MAC_IFG_RX_100 |
  2072.                         V_MAC_IFG_TX_100 |
  2073.                         V_MAC_IFG_THRSH_100 |
  2074.                         V_MAC_SLOT_SIZE_100;
  2075.             macCfg |= V_MAC_SPEED_SEL_100MBPS ;
  2076.             break;
  2077.         case MAC_SPEED_1000:
  2078.             frameCfg |= V_MAC_IFG_RX_1000 |
  2079.                         V_MAC_IFG_TX_1000 |
  2080.                         V_MAC_IFG_THRSH_1000 |
  2081.                         V_MAC_SLOT_SIZE_1000;
  2082.             macCfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
  2083.             break;
  2084.         default:
  2085.             return ERROR;
  2086.         }
  2087.     /* Send the bits back to the hardware */
  2088.     ETH_MAC_REG_WRITE (pDrvCtrl->regFrameCfg, frameCfg);
  2089.     switch (duplex)
  2090.         {
  2091.         case MAC_DUPLEX_HALF:
  2092.             switch (fc)
  2093.                 {
  2094.                 case MAC_FC_DISABLED:
  2095.                     macCfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
  2096.                     break;
  2097.                 case MAC_FC_COLLISION:
  2098.                     macCfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
  2099.                     break;
  2100.                 case MAC_FC_CARRIER:
  2101.                     macCfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
  2102.                     break;
  2103.                 case MAC_FC_FRAME:            /* not valid in half duplex */
  2104.                 default:                        /* invalid selection */
  2105.                     return ERROR;
  2106.                 }
  2107.             macCfg &= ~(M_MAC_BURST_EN);
  2108.             break;
  2109.         case MAC_DUPLEX_FULL:
  2110.             switch (fc)
  2111.                 {
  2112.                 case MAC_FC_DISABLED:
  2113.                     macCfg |= V_MAC_FC_CMD_DISABLED;
  2114.                     break;
  2115.                 case MAC_FC_FRAME:
  2116.                     macCfg |= V_MAC_FC_CMD_ENABLED;
  2117.                     break;
  2118.                 case MAC_FC_COLLISION:        /* not valid in full duplex */
  2119.                 case MAC_FC_CARRIER:          /* not valid in full duplex */
  2120.                     /* fall through */
  2121.                 default:
  2122.                     return ERROR;
  2123.                 }
  2124.             break;
  2125.         }
  2126.     /* Send the bits back to the hardware */
  2127.     ETH_MAC_REG_WRITE (pDrvCtrl->regMacCfg, macCfg);
  2128.     return OK;
  2129.     }
  2130. /*******************************************************************************
  2131. *
  2132. * bcm1250MacAddr2Reg - Convert 6 byte MAC address into 64 bit value.
  2133. *
  2134. * This routine converts the hardware ethernet MAC address from an array of
  2135. * six byte vaules into a 64 bit register value.
  2136. *
  2137. * RETURNS: 64 bit hardware ethernet MAC address
  2138. */
  2139. LOCAL UINT64 bcm1250MacAddr2Reg
  2140.     (
  2141.     unsigned char * ptr /* points to 6 byte MAC address */
  2142.     )
  2143.     {
  2144.     UINT64 reg = 0; /* 64 bit ethernet MAC address */
  2145.     ptr += 6;
  2146.     reg |= (UINT64) *(--ptr);
  2147.     reg <<= 8;
  2148.     reg |= (UINT64) *(--ptr);
  2149.     reg <<= 8;
  2150.     reg |= (UINT64) *(--ptr);
  2151.     reg <<= 8;
  2152.     reg |= (UINT64) *(--ptr);
  2153.     reg <<= 8;
  2154.     reg |= (UINT64) *(--ptr);
  2155.     reg <<= 8;
  2156.     reg |= (UINT64) *(--ptr);
  2157.     return reg;
  2158.     }
  2159. /*******************************************************************************
  2160. *
  2161. * bcm1250MacEthMiiSync - send sync bits to physical interface chip.
  2162. *
  2163. * RETURNS: N/A
  2164. */
  2165. LOCAL void bcm1250MacEthMiiSync
  2166.     (
  2167.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  2168.     )
  2169.     {
  2170.     int     cnt;    /* loop count */
  2171.     UINT64  bits;   /* holds sync bits */
  2172.     bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
  2173.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits);
  2174.     for (cnt = 0; cnt < 32; cnt++)
  2175.         {
  2176.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits | M_MAC_MDC);
  2177.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits);
  2178.         }
  2179.     }
  2180. /*******************************************************************************
  2181. *
  2182. * bcm1250MacEthMiiSendData - send number of bits to physical interface chip.
  2183. *
  2184. * RETURNS: N/A
  2185. */
  2186. LOCAL void bcm1250MacEthMiiSendData
  2187.     (
  2188.     DRV_CTRL *      pDrvCtrl,   /* driver control structure */
  2189.     unsigned int    data,       /* data bits to send */
  2190.     int             bitCnt      /* number of bits to send */
  2191.     )
  2192.     {
  2193.     int             i;          /* loop count */
  2194.     UINT64          bits;       /* bits to send */
  2195.     unsigned int    curMask;    /* bit mask */
  2196.     bits = M_MAC_MDIO_DIR_OUTPUT;
  2197.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits);
  2198.     curMask = 1 << (bitCnt - 1);
  2199.     for (i = 0; i < bitCnt; i++)
  2200.         {
  2201.         if (data & curMask)
  2202.             bits |= M_MAC_MDIO_OUT;
  2203.         else
  2204.             bits &= ~M_MAC_MDIO_OUT;
  2205.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits);
  2206.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits | M_MAC_MDC);
  2207.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, bits);
  2208.         curMask >>= 1;
  2209.         }
  2210.     }
  2211. /*******************************************************************************
  2212. *
  2213. * bcm1250MacEthMiiRead - read from physical interface chip.
  2214. *
  2215. * First send sync bits, then START and READ command, followed by physical
  2216. * interface chip address and register index.  Next switch to input mode and
  2217. * clock in physical interface chip data.
  2218. *
  2219. * RETURNS: Value read from physical interface chip.
  2220. */
  2221. LOCAL int bcm1250MacEthMiiRead
  2222.     (
  2223.     DRV_CTRL *  pDrvCtrl,   /* driver control structure */
  2224.     int         phyAddr,    /* physical interface chip address */
  2225.     int         regIdx      /* physical interface chip register index */
  2226.     )
  2227.     {
  2228.     int     idx;    /* loop index */
  2229.     int     error;  /* error flag */
  2230.     int     regVal; /* register value */
  2231.     /*
  2232.      * Synchronize ourselves so that the PHY knows the next
  2233.      * thing coming down is a command
  2234.      */
  2235.     bcm1250MacEthMiiSync (pDrvCtrl);
  2236.     /*
  2237.      * Send the data to the PHY.  The sequence is
  2238.      * a "start" command (2 bits)
  2239.      * a "read" command (2 bits)
  2240.      * the PHY addr (5 bits)
  2241.      * the register index (5 bits)
  2242.      */
  2243.     bcm1250MacEthMiiSendData (pDrvCtrl, MII_COMMAND_START, 2);
  2244.     bcm1250MacEthMiiSendData (pDrvCtrl, MII_COMMAND_READ, 2);
  2245.     bcm1250MacEthMiiSendData (pDrvCtrl, phyAddr, 5);
  2246.     bcm1250MacEthMiiSendData (pDrvCtrl, regIdx, 5);
  2247.     /*
  2248.      * Switch the port around without a clock transition.
  2249.      */
  2250.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT);
  2251.     /*
  2252.      * Send out a clock pulse to signal we want the status
  2253.      */
  2254.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
  2255.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT);
  2256.     /*
  2257.      * If an error occured, the PHY will signal '1' back
  2258.      */
  2259.     error = ETH_MAC_REG_READ (pDrvCtrl->regMdio) & M_MAC_MDIO_IN;
  2260.     /*
  2261.      * Issue an 'idle' clock pulse, but keep the direction
  2262.      * the same.
  2263.      */
  2264.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
  2265.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT);
  2266.     regVal = 0;
  2267.     for (idx = 0; idx < 16; idx++)
  2268.         {
  2269.         regVal <<= 1;
  2270.         if (error == 0)
  2271.             {
  2272.             if (ETH_MAC_REG_READ (pDrvCtrl->regMdio) & M_MAC_MDIO_IN)
  2273.                 regVal |= 1;
  2274.             }
  2275.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio,
  2276.                            M_MAC_MDIO_DIR_INPUT | M_MAC_MDC);
  2277.         ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_INPUT);
  2278.         }
  2279.     if (error != 0)
  2280.         regVal = 0;
  2281.     /* Switch back to output */
  2282.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_OUTPUT);
  2283.     return regVal;
  2284.     }
  2285. /*******************************************************************************
  2286. *
  2287. * bcm1250MacEthMiiWrite - write to phy register
  2288. *
  2289. * It first sends START and WRITE command, followed by address of physical
  2290. * interface chip, then register index. It then sends ACK and register value
  2291. * to be written.
  2292. *
  2293. * RETURNS: N/A
  2294. */
  2295. #ifdef FUTURE_USE
  2296. LOCAL void bcm1250MacEthMiiWrite
  2297.     (
  2298.     DRV_CTRL *      pDrvCtrl,   /* driver control structure */
  2299.     int             phyAddr,    /* physical interface chip address */
  2300.     int             regIdx,     /* register in physical interface chip */
  2301.     unsigned int    regVal      /* value to write to regIdx */
  2302.     )
  2303.     {
  2304.     bcm1250MacEthMiiSync (pDrvCtrl);
  2305.     bcm1250MacEthMiiSendData (pDrvCtrl, MII_COMMAND_START, 2);
  2306.     bcm1250MacEthMiiSendData (pDrvCtrl, MII_COMMAND_WRITE, 2);
  2307.     bcm1250MacEthMiiSendData (pDrvCtrl, phyAddr, 5);
  2308.     bcm1250MacEthMiiSendData (pDrvCtrl, regIdx, 5);
  2309.     bcm1250MacEthMiiSendData (pDrvCtrl, MII_COMMAND_ACK, 2);
  2310.     bcm1250MacEthMiiSendData (pDrvCtrl, regVal, 16);
  2311.     ETH_MAC_REG_WRITE (pDrvCtrl->regMdio, M_MAC_MDIO_DIR_OUTPUT);
  2312.     }
  2313. #endif /* FUTURE_USE */
  2314. /*******************************************************************************
  2315. *
  2316. * bcm1250MacEthMiiFindPhy - Search for a physical interface chip.
  2317. *
  2318. * This routine reads from all the possible physical interface chip addresses
  2319. * checking for a valid interface chip.  If one is found, its address is saved
  2320. * in the driver control structure.
  2321. *
  2322. * RETURNS: N/A
  2323. */
  2324. LOCAL void bcm1250MacEthMiiFindPhy
  2325.     (
  2326.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  2327.     )
  2328.     {
  2329.     int     phy;    /* physical interface chip address */
  2330.     int     bmsr;   /* value of Basic Mode Status Register */
  2331.     for (phy = 0; phy < 31; phy++)
  2332.         {
  2333.         bmsr = bcm1250MacEthMiiRead (pDrvCtrl, phy, MII_BMSR);
  2334.         if (bmsr != 0)
  2335.             {
  2336.             pDrvCtrl->phyAddr = phy;
  2337.             return;
  2338.             }
  2339.         }
  2340.     (void)printf ("Found no PHYn");
  2341.     pDrvCtrl->phyAddr = 1;
  2342.     }
  2343. /*******************************************************************************
  2344. *
  2345. *  bcm1250MacEthMiiPoll
  2346. *
  2347. *  Ask the PHY what is going on, and configure speed appropriately.
  2348. *  For the moment, we only support automatic configuration.
  2349. *
  2350. *  Input parameters:
  2351. *      s - sbeth structure
  2352. *
  2353. * RETURNS: N/A
  2354. */
  2355. LOCAL void bcm1250MacEthMiiPoll
  2356.     (
  2357.     DRV_CTRL *  pDrvCtrl    /* driver control structure */
  2358.     )
  2359.     {
  2360.     int     bmsr;   /* value of Basic Mode Status Register */
  2361.     int     bmcr;   /* value of Basic Mode Control Register */
  2362.     int     k1stsr; /* value of 1K Status Register */
  2363.     int     anlpar; /* value of Autonegotiation lnk partner abilities */
  2364.     /* Read the mode status and mode control registers. */
  2365.     bmsr = bcm1250MacEthMiiRead (pDrvCtrl, pDrvCtrl->phyAddr, MII_BMSR);
  2366.     bmcr = bcm1250MacEthMiiRead (pDrvCtrl, pDrvCtrl->phyAddr, MII_BMCR);
  2367.     /* get the link partner status */
  2368.     anlpar = bcm1250MacEthMiiRead (pDrvCtrl, pDrvCtrl->phyAddr, MII_ANLPAR);
  2369.     /* if supported, read the 1000baseT register */
  2370.     if (bmsr & BMSR_1000BT_XSR)
  2371.         {
  2372.         k1stsr = bcm1250MacEthMiiRead (pDrvCtrl, pDrvCtrl->phyAddr, MII_K1STSR);
  2373.         }
  2374.     else
  2375.         {
  2376.         k1stsr = 0;
  2377.         }
  2378.     (void)printf ("Link speed: ");
  2379.     if (k1stsr & K1STSR_LP1KFD)
  2380.         {
  2381.         pDrvCtrl->macSpeed = MAC_SPEED_1000;
  2382.         pDrvCtrl->macDuplex = MAC_DUPLEX_FULL;
  2383.         pDrvCtrl->macFc = MAC_FC_FRAME;
  2384.         (void)printf ("1000BaseT FDXn");
  2385.         }
  2386.     else if (k1stsr & K1STSR_LP1KHD)
  2387.         {
  2388.         pDrvCtrl->macSpeed = MAC_SPEED_1000;
  2389.         pDrvCtrl->macDuplex = MAC_DUPLEX_HALF;
  2390.         pDrvCtrl->macFc = MAC_FC_DISABLED;
  2391.         (void)printf ("1000BaseT HDXn");
  2392.         }
  2393.     else if (anlpar & ANLPAR_TXFD)
  2394.         {
  2395.         pDrvCtrl->macSpeed = MAC_SPEED_100;
  2396.         pDrvCtrl->macDuplex = MAC_DUPLEX_FULL;
  2397.         pDrvCtrl->macFc = (anlpar & ANLPAR_PAUSE) ?
  2398.                            MAC_FC_FRAME : MAC_FC_DISABLED;
  2399.         (void)printf ("100BaseT FDXn");
  2400.         }
  2401.     else if (anlpar & ANLPAR_TXHD)
  2402.         {
  2403.         pDrvCtrl->macSpeed = MAC_SPEED_100;
  2404.         pDrvCtrl->macDuplex = MAC_DUPLEX_HALF;
  2405.         pDrvCtrl->macFc = MAC_FC_DISABLED;
  2406.         (void)printf ("100BaseT HDXn");
  2407.         }
  2408.     else if (anlpar & ANLPAR_10FD)
  2409.         {
  2410.         pDrvCtrl->macSpeed = MAC_SPEED_10;
  2411.         pDrvCtrl->macDuplex = MAC_DUPLEX_FULL;
  2412.         pDrvCtrl->macFc = MAC_FC_FRAME;
  2413.         (void)printf ("10BaseT FDXn");
  2414.         }
  2415.     else if (anlpar & ANLPAR_10HD)
  2416.         {
  2417.         pDrvCtrl->macSpeed = MAC_SPEED_10;
  2418.         pDrvCtrl->macDuplex = MAC_DUPLEX_HALF;
  2419.         pDrvCtrl->macFc = MAC_FC_COLLISION;
  2420.         (void)printf ("10BaseT HDXn");
  2421.         }
  2422.     else
  2423.         {
  2424.         (void)printf ("Unknownn");
  2425.         }
  2426.     (void)printf ("BMSR=%04X, BMCR=%04X, 1KSTSR=%04X, ANLPAR=%04Xn",
  2427.                   bmsr, bmcr, k1stsr, anlpar);
  2428.     }
  2429. /*******************************************************************************
  2430. *
  2431. * bcm1250MacRxDmaShow - display RX DMA register values
  2432. *
  2433. * This routine prints the enet RX DMA registers to stdout
  2434. *
  2435. * RETURNS: N/A
  2436. */
  2437. void bcm1250MacRxDmaShow
  2438.     (
  2439.     int     inst   /* driver instance */
  2440.     )
  2441.     {
  2442.     DRV_CTRL *      pDrvCtrl;   /* driver control structure */
  2443.     ETH_MAC_DMA *   pDma;       /* ethernet DMA structure */
  2444.     UINT64          reg;        /* register value */
  2445.     UINT32          regLo;      /* 32 LSB of register */
  2446.     UINT32          regHi;      /* 32 MSB of register */
  2447.     pDrvCtrl = (DRV_CTRL *)endFindByName ("sbe", inst);
  2448.     if (pDrvCtrl == (DRV_CTRL *)NULL)
  2449.         {
  2450.         (void)printf ("can't find sbe%dn", inst);
  2451.         return;
  2452.         }
  2453.     pDma = &pDrvCtrl->rxDma;
  2454.     reg = ETH_DMA_REG_READ (pDma->regConfig0);
  2455.     regHi = (UINT32)(reg >> 32);
  2456.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2457.     (void)printf ("RX0 config0 = 0x%08x%08xn", regHi, regLo);
  2458.     reg = ETH_DMA_REG_READ (pDma->regConfig1);
  2459.     regHi = (UINT32)(reg >> 32);
  2460.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2461.     (void)printf ("RX0 config1 = 0x%08x%08xn", regHi, regLo);
  2462.     reg = ETH_DMA_REG_READ (pDma->regDscrCnt);
  2463.     regHi = (UINT32)(reg >> 32);
  2464.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2465.     (void)printf ("RX0 dscrcnt = 0x%08x%08xn", regHi, regLo);
  2466.     reg = ETH_DMA_REG_READ (pDma->regDscrBase);
  2467.     regHi = (UINT32)(reg >> 32);
  2468.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2469.     (void)printf ("RX0 dscrbase = 0x%08x%08xn", regHi, regLo);
  2470.     reg = ETH_DMA_REG_READ (pDma->regCurDscr);
  2471.     regHi = (UINT32)(reg >> 32);
  2472.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2473.     (void)printf ("RX0 curdscr = 0x%08x%08xn", regHi, regLo);
  2474.     (void)printf ("RX0 headIndex = %dn", pDma->headIndex);
  2475.     (void)printf ("RX0 tailIndex = %dn", pDma->tailIndex);
  2476.     (void)printf ("RX0 ringCount = %dn", pDma->ringCount);
  2477.     (void)printf ("RX0 maxDescr = %dn", pDma->maxDescr);
  2478.     }
  2479. /*******************************************************************************
  2480. *
  2481. * bcm1250MacTxDmaShow - display TX DMA register values
  2482. *
  2483. * This routine prints the enet TX DMA registers to stdout
  2484. *
  2485. * RETURNS: N/A
  2486. */
  2487. void bcm1250MacTxDmaShow
  2488.     (
  2489.     int     inst    /* driver instance */
  2490.     )
  2491.     {
  2492.     DRV_CTRL *      pDrvCtrl;   /* driver control structure */
  2493.     ETH_MAC_DMA *   pDma;       /* ethernet DMA structure */
  2494.     UINT64          reg;        /* register value */
  2495.     UINT32          regLo;      /* 32 LSB of register */
  2496.     UINT32          regHi;      /* 32 MSB of register */
  2497.     pDrvCtrl = (DRV_CTRL *)endFindByName ("sbe", inst);
  2498.     if (pDrvCtrl == (DRV_CTRL *)NULL)
  2499.         {
  2500.         (void)printf ("can't find sbe%dn", inst);
  2501.         return;
  2502.         }
  2503.     pDma = &pDrvCtrl->txDma;
  2504.     reg = ETH_DMA_REG_READ (pDma->regConfig0);
  2505.     regHi = (UINT32)(reg >> 32);
  2506.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2507.     (void)printf ("TX0 config0 = 0x%08x%08xn", regHi, regLo);
  2508.     reg = ETH_DMA_REG_READ (pDma->regConfig1);
  2509.     regHi = (UINT32)(reg >> 32);
  2510.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2511.     (void)printf ("TX0 config1 = 0x%08x%08xn", regHi, regLo);
  2512.     reg = ETH_DMA_REG_READ (pDma->regDscrCnt);
  2513.     regHi = (UINT32)(reg >> 32);
  2514.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2515.     (void)printf ("TX0 dscrcnt = 0x%08x%08xn", regHi, regLo);
  2516.     reg = ETH_DMA_REG_READ (pDma->regDscrBase);
  2517.     regHi = (UINT32)(reg >> 32);
  2518.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2519.     (void)printf ("TX0 dscrbase = 0x%08x%08xn", regHi, regLo);
  2520.     reg = ETH_DMA_REG_READ (pDma->regCurDscr);
  2521.     regHi = (UINT32)(reg >> 32);
  2522.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2523.     (void)printf ("TX0 curdscr = 0x%08x%08xn", regHi, regLo);
  2524.     (void)printf ("TX0 headIndex = %dn", pDma->headIndex);
  2525.     (void)printf ("TX0 tailIndex = %dn", pDma->tailIndex);
  2526.     (void)printf ("TX0 ringCount = %dn", pDma->ringCount);
  2527.     (void)printf ("TX0 maxDescr = %dn", pDma->maxDescr);
  2528.     }
  2529. /*******************************************************************************
  2530. *
  2531. * bcm1250MacShow - display mac register values
  2532. *
  2533. * This routine prints the enet MAC registers to stdout
  2534. *
  2535. * RETURNS: N/A
  2536. */
  2537. void bcm1250MacShow
  2538.     (
  2539.     int     inst    /* driver instance */
  2540.     )
  2541.     {
  2542.     DRV_CTRL *  pDrvCtrl;   /* driver control structure */
  2543.     UINT64      reg;        /* register value */
  2544.     UINT32      regLo;      /* 32 LSB of register */
  2545.     UINT32      regHi;      /* 32 MSB of register */
  2546.     pDrvCtrl = (DRV_CTRL *)endFindByName ("sbe", inst);
  2547.     if (pDrvCtrl == (DRV_CTRL *)NULL)
  2548.         {
  2549.         (void)printf ("can't find sbe%dn", inst);
  2550.         return;
  2551.         }
  2552.     reg = ETH_MAC_REG_READ (pDrvCtrl->regMacEnable);
  2553.     regHi = (UINT32)(reg >> 32);
  2554.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2555.     (void)printf ("mac macenable = 0x%08x%08xn", regHi, regLo);
  2556.     reg = ETH_MAC_REG_READ (pDrvCtrl->regMacCfg);
  2557.     regHi = (UINT32)(reg >> 32);
  2558.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2559.     (void)printf ("mac maccfg = 0x%08x%08xn",  regHi, regLo);
  2560.     reg = ETH_MAC_REG_READ (pDrvCtrl->regFifoCfg);
  2561.     regHi = (UINT32)(reg >> 32);
  2562.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2563.     (void)printf ("mac fifocfg = 0x%08x%08xn", regHi, regLo);
  2564.     reg = ETH_MAC_REG_READ (pDrvCtrl->regFrameCfg);
  2565.     regHi = (UINT32)(reg >> 32);
  2566.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2567.     (void)printf ("mac framecfg = 0x%08x%08xn", regHi, regLo);
  2568.     reg = ETH_MAC_REG_READ (pDrvCtrl->regRxFilter);
  2569.     regHi = (UINT32)(reg >> 32);
  2570.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2571.     (void)printf ("mac rxfilter = 0x%08x%08xn", regHi, regLo);
  2572.     reg = ETH_MAC_REG_READ (pDrvCtrl->regImr);
  2573.     regHi = (UINT32)(reg >> 32);
  2574.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2575.     (void)printf ("mac imr = 0x%08x%08xn", regHi, regLo);
  2576.     reg = ETH_MAC_REG_READ (pDrvCtrl->regIsr);
  2577.     regHi = (UINT32)(reg >> 32);
  2578.     regLo = (UINT32)(reg & 0xFFFFFFFF);
  2579.     (void)printf ("mac isr = 0x%08x%08xn", regHi, regLo);
  2580.     }
  2581. /*******************************************************************************
  2582. *
  2583. * bcm1250MacPhyShow - display phy register values
  2584. *
  2585. * This routine prints the enet PHY registers to stdout
  2586. *
  2587. * RETURNS: N/A
  2588. */
  2589. void bcm1250MacPhyShow
  2590.     (
  2591.     int     inst    /* driver instance */
  2592.     )
  2593.     {
  2594.     DRV_CTRL *  pDrvCtrl;   /* driver control structure */
  2595.     pDrvCtrl = (DRV_CTRL *)endFindByName ("sbe", inst);
  2596.     if (pDrvCtrl == (DRV_CTRL *)NULL)
  2597.         {
  2598.         (void)printf ("can't find sbe%dn", inst);
  2599.         return;
  2600.         }
  2601.     (void)printf ("PhyReg %02X val %04Xn", 0,
  2602.            bcm1250MacEthMiiRead (pDrvCtrl, 1/*pDrvCtrl->phyAddr*/, 0));
  2603.     (void)printf ("PhyReg %02X val %04Xn", 0,
  2604.            bcm1250MacEthMiiRead (pDrvCtrl, 1/*pDrvCtrl->phyAddr*/, 1));
  2605.     }