sh7615End.c
资源名称:ixp425BSP.rar [点击查看]
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:74k
源码类别:
VxWorks
开发平台:
C/C++
- /* sh7615End.c - sh7615End END network interface driver */
- /* Copyright 1984-2001 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- modification history
- --------------------
- 01l,28mar02,h_k added muxError() at failing of netClusterGet() and
- netClBlkGet(). moved E-DMAC Receive Request enable to
- sh7615EndRcvIntHandle() from sh7615EndInt(). added setting
- depth of FIFO. changed clNum and mBlkNum. (SPR #74021)
- 01k,02nov01,zl corrected NULL usage.
- 01j,19oct01,zl documentation fixes. Removed sh7615EndIASetup().
- 01i,09may01,zl detect link status change, add restart routine.
- 01h,05may01,zl made interrupt handling more efficient and robust.
- 01g,30apr01,zl detect and set full duplex mode.
- 01f,09nov00,rsh missing #ifdef
- 01e,02nov00,frf Read and Write functions to a PHY registers:
- dp83843RegRead, dp83843RegWrite, dp83843RegPrint.
- 01d,10oct00,zl got polled mode working. Code Cleanup.
- 01c,27sep00,rsh add cache support.
- 01b,26sep00,rsh remove bsp option to provide shared memory since this chip.
- doesn't provide special memory.
- 01a,16aug00,rsh written based on dec21x40End.c
- */
- /*
- DESCRIPTION
- This module implements an network interface driver for the Hitachi SH7615
- on-chip Ethernet controller (EtherC) and EtherNet COntroller Direct Memory
- Access Controller (E-DMAC). The EtherC is fully compliant with the IEEE 802.3
- 10Base-T and 100Base-T specifications. Hardware support of the Media
- Independent Interface (MII) is off-chip.
- The Ethernet controller is connected to dedicated transmit and receive
- Ethernet DMACs (E-DMACs) in the SH7615, and carries out high-speed data
- transfer to and from memory. The operation of the E-DMAC is controlled with
- the transmit and receive descriptor rings. The start address of the
- descriptors is set in the RDLAR and TDLAR registers, so they can reside
- anywhwere. The descriptors must reside on boundaries that are multiple
- of their size (16, 32, or 64 bytes).
- EXTERNAL INTERFACE
- The driver provides the standard external interface, sh7615EndLoad(), which
- takes a string of colon-separated parameters. The parameters should be
- specified in hexadecimal, optionally preceeded by "0x" or a minus sign "-".
- The parameter string is parsed using strtok_r() and each parameter is
- converted from a string representation to binary by a call to
- strtoul(parameter, NULL, 16).
- The format of the parameter string is:
- "<ivec>:<ilevel>:<numRds>:<numTds>:<phyDefMode>:<userFlags>"
- TARGET-SPECIFIC PARAMETERS
- .IP <ivec>
- This is the interrupt vector number of the hardware interrupt generated by
- this Ethernet device. The driver uses intConnect() to attach an interrupt
- handler for this interrupt.
- .IP <ilevel>
- This parameter defines the level of the hardware interrupt.
- .IP <numRds>
- The number of receive descriptors to use. This controls how much data
- the device can absorb under load. If this is specified as NONE (-1),
- the default of 32 is used.
- .IP <numTds>
- The number of transmit descriptors to use. This controls how much data
- the device can absorb under load. If this is specified as NONE (-1) then
- the default of 64 is used.
- .IP <phyDefMode>
- This parameter specifies the operating mode that will be set up
- by the default physical layer initialization routine in case all
- the attempts made to establish a valid link failed. If that happens,
- the first PHY that matches the specified abilities will be chosen to
- work in that mode, and the physical link will not be tested.
- .IP <userFlags>
- This field enables the user to give some degree of customization to the
- driver.
- Bit [0-3] reserved for receive FIFO depth and bit [4-7] reserved for transmit
- FIFO depth. The actual FIFO size is 256 times + 256 the set value for each
- FIFO. The max FIFO depth is 512 bytes for SH7615 (i.e. 0x1 for receive FIFO,
- 0x10 for transmit FIFO) and 2048 bytes for SH7616 (i.e. 0x7 for receive FIFO,
- 0x70 for transmit FIFO).
- The macros SYS_INT_CONNECT, SYS_INT_DISCONNECT, and SYS_INT_ENABLE allow
- the driver to be customized for BSPs that use special versions of these
- routines.
- The macro SYS_INT_CONNECT is used to connect the interrupt handler to
- the appropriate vector. By default it is the routine intConnect().
- The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler prior
- to unloading the module. By default this is a dummy routine that
- returns OK.
- The macro SYS_INT_ENABLE is used to enable the interrupt level for the
- end device. It is called once during initialization. By default this is
- the routine sysLanIntEnable(), defined in the module sysLib.o.
- The macro SYS_ENET_ADDR_GET is used to get the ethernet address (MAC)
- for the device. The single argument to this routine is the SH7615END_DRV_CTRL
- pointer. By default this routine copies the ethernet address stored in
- the global variable sysTemplateEnetAddr into the SH7615END_DRV_CTRL structure.
- SEE ALSO: muxLib, endLib
- .I "Writing and Enhanced Network Driver"
- .I "SH7615 Hardware Manual"
- */
- /* includes */
- #include "vxWorks.h"
- #include "stdlib.h"
- #include "cacheLib.h"
- #include "intLib.h"
- #include "end.h" /* Common END structures. */
- #include "endLib.h"
- #include "lstLib.h" /* Needed to maintain protocol list. */
- #include "wdLib.h"
- #include "iv.h"
- #include "semLib.h"
- #include "etherLib.h"
- #include "logLib.h"
- #include "netLib.h"
- #include "stdio.h"
- #include "sysLib.h"
- #include "errno.h"
- #include "errnoLib.h"
- #include "memLib.h"
- #include "iosLib.h"
- #undef ETHER_MAP_IP_MULTICAST
- #include "etherMultiLib.h" /* multicast stuff. */
- #include "net/mbuf.h"
- #include "net/unixLib.h"
- #include "net/protosw.h"
- #include "net/systm.h"
- #include "net/if_subr.h"
- #include "net/route.h"
- #include "sys/socket.h"
- #include "sys/ioctl.h"
- #include "sys/times.h"
- #include "drv/end/sh7615End.h"
- /* defines */
- #define INCLUDE_PHY
- #define DRV_CTRL SH7615END_DRV_CTRL
- #define SH7615END_DEV_NAME "shend"
- #define SH7615END_DEV_NAME_LEN 6
- #define SH7615END_BUFSIZ (ETHERMTU + ENET_HDR_REAL_SIZ + 6 +
- SH7615END_BD_ALIGN)
- #define SH7615END_SPEED 10000000 /* 10Mbs */
- /* DRV_CTRL flags */
- #define SH7615END_INV_TBD_NUM 0x02 /* invalid numTds provided */
- #define SH7615END_INV_RBD_NUM 0x04 /* invalid numRds provided */
- #define SH7615END_POLLING 0x08 /* Poll mode, io mode */
- #define SH7615END_PROMISC 0x20 /* Promiscuous, rx mode */
- #define SH7615END_MCAST 0x40 /* Multicast, rx mode */
- #define SH7615END_FD 0x80 /* full duplex mode */
- /*
- * Default macro definitions for BSP interface.
- * These macros can be redefined in a wrapper file, to generate
- * a new module with an optimized interface.
- */
- #ifndef SYS_INT_CONNECT
- #define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult)
- {
- *pResult = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),
- rtn, (int)arg);
- }
- #endif /* SYS_INT_CONNECT */
- #ifndef SYS_INT_DISCONNECT
- #define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult)
- {
- *pResult = OK;
- }
- #endif /* SYS_INT_DISCONNECT */
- #ifndef SYS_INT_ENABLE
- #define SYS_INT_ENABLE(pDrvCtrl)
- {
- IMPORT void sysLanIntEnable();
- sysLanIntEnable (pDrvCtrl->ilevel);
- }
- #endif /* SYS_INT_ENABLE */
- #ifndef SYS_INT_DISABLE
- #define SYS_INT_DISABLE(pDrvCtrl)
- {
- IMPORT STATUS sysLanIntDisable();
- sysLanIntDisable(pDrvCtrl->ilevel);
- }
- #endif /*SYS_INT_DISABLE*/
- #define NET_BUF_ALLOC()
- netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId)
- #define NET_TO_SH7615END_BUF(netBuf)
- (((UINT32) (netBuf) + SH7615END_BD_ALIGN - 1)
- & ~(SH7615END_BD_ALIGN - 1))
- #define NET_BUF_FREE(pBuf)
- netClFree (pDrvCtrl->end.pNetPool, pBuf)
- #define NET_MBLK_ALLOC()
- mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)
- #define NET_MBLK_FREE(pMblk)
- netMblkFree (pDrvCtrl->end.pNetPool, (M_BLK_ID)pMblk)
- #define NET_CL_BLK_ALLOC()
- clBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)
- #define NET_CL_BLK_FREE(pClblk)
- clBlkFree (pDrvCtrl->end.pNetPool, (CL_BLK_ID)pClBlk)
- #define NET_MBLK_BUF_FREE(pMblk)
- netMblkClFree ((M_BLK_ID)pMblk)
- #define NET_MBLK_CL_JOIN(pMblk, pClBlk)
- netMblkClJoin ((pMblk), (pClBlk))
- #define NET_CL_BLK_JOIN(pClBlk, pBuf, len)
- netClBlkJoin ((pClBlk), (pBuf), (len), NULL, 0, 0, 0)
- #ifndef SYS_ENET_ADDR_GET
- #define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress)
- {
- IMPORT STATUS sysEnetAddrGet (int, char*);
- sysEnetAddrGet (pDrvCtrl->unit, pAddress);
- }
- #endif /* SYS_ENET_ADDR_GET */
- #define SH7615END_REG_READ(regAddr, value)
- ((value) = (* (volatile UINT32 *) (regAddr)))
- #define SH7615END_REG_WRITE(regAddr, value)
- ((* (volatile UINT32 *) (regAddr)) = ((UINT32) value))
- #define SH7615END_BIT_SET(reg, val)
- {
- UINT32 temp = 0;
- SH7615END_REG_READ(reg, temp);
- SH7615END_REG_WRITE((reg), temp | (val));
- }
- #define SH7615END_BIT_CLR(reg, val)
- {
- UINT32 temp = 0;
- SH7615END_REG_READ(reg, temp);
- SH7615END_REG_WRITE((reg), temp & ~(val));
- }
- /* DRV_CTRL flags access macros */
- #define DRV_FLAGS_SET(setBits)
- (pDrvCtrl->flags |= (setBits))
- #define DRV_FLAGS_ISSET(setBits)
- (pDrvCtrl->flags & (setBits))
- #define DRV_FLAGS_CLR(clrBits)
- (pDrvCtrl->flags &= ~(clrBits))
- #define DRV_FLAGS_GET()
- (pDrvCtrl->flags)
- #define END_FLAGS_ISSET(pEnd, setBits)
- ((pEnd)->flags & (setBits))
- /* A shortcut for getting the hardware address from the MIB II stuff. */
- #define END_HADDR(pEnd)
- ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
- #define END_HADDR_LEN(pEnd)
- ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
- /* Cache related macros */
- #define SH7615END_CACHE_FLUSH(address, len)
- cacheFlush(DATA_CACHE, (address), (len))
- #define SH7615END_CACHE_INVALIDATE(address, len)
- cacheInvalidate (DATA_CACHE, (address), (len))
- /* DEBUG MACROS */
- #ifdef DRV_DEBUG
- #undef LOCAL
- #define LOCAL
- #define DRV_DEBUG_OFF 0x0000
- #define DRV_DEBUG_RX 0x0001
- #define DRV_DEBUG_TX 0x0002
- #define DRV_DEBUG_INT 0x0004
- #define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)
- #define DRV_DEBUG_POLL_RX 0x0008
- #define DRV_DEBUG_POLL_TX 0x0010
- #define DRV_DEBUG_LOAD 0x0020
- #define DRV_DEBUG_IOCTL 0x0040
- #define DRV_DEBUG_POLL_REDIR 0x10000
- #define DRV_DEBUG_LOG_NVRAM 0x20000
- #define DRV_DEBUG_PHY 0x40000
- int sh7615EndDebug = 0x40000;
- int sh7615EndRfcof = 0;
- int sh7615EndEci = 0;
- int sh7615EndTc = 0;
- int sh7615EndTde = 0;
- int sh7615EndTfuf = 0;
- int sh7615EndFr = 0;
- int sh7615EndRde = 0;
- int sh7615EndRfof = 0;
- int sh7615EndItf = 0;
- int sh7615EndCnd = 0;
- int sh7615EndDlc = 0;
- int sh7615EndCd = 0;
- int sh7615EndTro = 0;
- int sh7615EndRmaf = 0;
- int sh7615EndRrf = 0;
- int sh7615EndRtlf = 0;
- int sh7615EndRtsf = 0;
- int sh7615EndPre = 0;
- int sh7615EndCerf = 0;
- int sh7615EndTfe = 0;
- /* globals for easy access */
- CL_POOL_ID sh7615ClPool;
- NET_POOL_ID sh7615NetPoolId;
- DRV_CTRL * pShEnd;
- #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)
- if (sh7615EndDebug & FLG)
- logMsg(X0, X1, X2, X3, X4, X5, X6);
- #define DRV_PRINT(FLG,X)
- if (sh7615EndDebug & FLG) printf X;
- #else /*DRV_DEBUG*/
- #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
- #define DRV_PRINT(DBG_SW,X)
- #endif /*DRV_DEBUG*/
- /* LOCALS */
- /* forward static functions */
- LOCAL void sh7615EndReset (DRV_CTRL *pDrvCtrl);
- LOCAL void sh7615EndInt (DRV_CTRL *pDrvCtrl);
- LOCAL void sh7615EndRcvIntHandle (DRV_CTRL *pDrvCtrl);
- LOCAL STATUS sh7615EndRecv (DRV_CTRL *pDrvCtrl, SH7615_RD * pRxD );
- LOCAL void sh7615EndConfig (DRV_CTRL *pDrvCtrl);
- LOCAL void sh7615EndModeSet (DRV_CTRL *pDrvCtrl);
- LOCAL STATUS sh7615EndParse (DRV_CTRL * pDrvCtrl, char * initString);
- LOCAL STATUS sh7615EndMemInit (DRV_CTRL * pDrvCtrl);
- LOCAL void sh7615EnetAddrGet (DRV_CTRL* pDrvCtrl, char* addr);
- LOCAL SH7615_RD * sh7615EndRxDGet (DRV_CTRL *pDrvCtrl);
- LOCAL SH7615_TD * sh7615EndTxDGet (DRV_CTRL *pDrvCtrl);
- LOCAL void sh7615EndTxRingClean (DRV_CTRL *pDrvCtrl);
- LOCAL void sh7615EndRestart (DRV_CTRL *pDrvCtrl);
- #ifdef INCLUDE_PHY
- LOCAL void dp83843SingleBitWrite (int bitVal);
- #if 0 /* currently not used */
- LOCAL void dp83843RegWrite (UINT16 regAddr, UINT16 regData);
- #endif
- LOCAL UINT16 dp83843RegRead (UINT16 regAddr);
- #endif
- /* END Specific interfaces. */
- END_OBJ* sh7615EndLoad (char* initString);
- LOCAL STATUS sh7615EndUnload (DRV_CTRL* pDrvCtrl);
- LOCAL STATUS sh7615EndStart (DRV_CTRL* pDrvCtrl);
- LOCAL STATUS sh7615EndStop (DRV_CTRL* pDrvCtrl);
- LOCAL STATUS sh7615EndIoctl (DRV_CTRL* pDrvCtrl, int cmd, caddr_t data);
- LOCAL STATUS sh7615EndSend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
- LOCAL STATUS sh7615EndMCastAddrAdd (DRV_CTRL *pDrvCtrl, char* pAddress);
- LOCAL STATUS sh7615EndMCastAddrDel (DRV_CTRL *pDrvCtrl, char* pAddress);
- LOCAL STATUS sh7615EndMCastAddrGet (DRV_CTRL *pDrvCtrl,
- MULTI_TABLE *pTable);
- LOCAL STATUS sh7615EndPollSend (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
- LOCAL STATUS sh7615EndPollReceive (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);
- LOCAL STATUS sh7615EndPollStart (DRV_CTRL *pDrvCtrl);
- LOCAL STATUS sh7615EndPollStop (DRV_CTRL *pDrvCtrl);
- /*
- * Declare our function table. This is static across all driver
- * instances.
- */
- LOCAL NET_FUNCS sh7615EndFuncTable =
- {
- (FUNCPTR) sh7615EndStart, /* Function to start the device. */
- (FUNCPTR) sh7615EndStop, /* Function to stop the device. */
- (FUNCPTR) sh7615EndUnload, /* Unloading function for the driver. */
- (FUNCPTR) sh7615EndIoctl, /* Ioctl function for the driver. */
- (FUNCPTR) sh7615EndSend, /* send func. */
- (FUNCPTR) sh7615EndMCastAddrAdd, /* multicast add func. */
- (FUNCPTR) sh7615EndMCastAddrDel, /* multicast delete func. */
- (FUNCPTR) sh7615EndMCastAddrGet, /* multicast get fun. */
- (FUNCPTR) sh7615EndPollSend, /* polling send func. */
- (FUNCPTR) sh7615EndPollReceive, /* polling receive func. */
- endEtherAddressForm, /* put address info into a NET_BUFFER */
- (FUNCPTR) endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
- (FUNCPTR) endEtherPacketAddrGet /* Get packet addresses. */
- };
- /*******************************************************************************
- *
- * sh7615EndLoad - initialize the driver and device
- *
- * This routine initializes the driver and the device to the operational state.
- * All of the device specific parameters are passed in the initString.
- *
- * The string contains the target specific parameters like this:
- * "ivec:ilevel:numRds:numTds:phyDefMode:userFlags"
- *
- * RETURNS: An END object pointer or NULL on error.
- */
- END_OBJ* sh7615EndLoad
- (
- char * initString /* String to be parsed by the driver. */
- )
- {
- DRV_CTRL * pDrvCtrl;
- DRV_LOG (DRV_DEBUG_LOAD, "Loading sh7615End...n", 1, 2, 3, 4, 5, 6);
- if (initString == NULL)
- return (NULL);
- if (initString[0] == EOS)
- {
- bcopy((char *)SH7615END_DEV_NAME, initString, SH7615END_DEV_NAME_LEN);
- return (0);
- }
- /* Allocate a control structure for this device */
- pDrvCtrl = (DRV_CTRL *)calloc (sizeof (DRV_CTRL), 1);
- if (pDrvCtrl == NULL)
- {
- printf ("%s - Failed to allocate control structuren",
- SH7615END_DEV_NAME );
- return (NULL);
- }
- /* parse the init string, filling in the device structure */
- if (sh7615EndParse (pDrvCtrl, initString) == ERROR)
- goto errorExit;
- /* Ask the BSP to provide the ethernet address. */
- sh7615EnetAddrGet (pDrvCtrl, (char*) &(pDrvCtrl->enetAddr));
- DRV_LOG (DRV_DEBUG_LOAD, "ENET Addr: %x:%x:%x:%x:%x:%x n",
- pDrvCtrl->enetAddr[0], pDrvCtrl->enetAddr[1],
- pDrvCtrl->enetAddr[2], pDrvCtrl->enetAddr[3],
- pDrvCtrl->enetAddr[4], pDrvCtrl->enetAddr[5]);
- /* initialize some flags */
- pDrvCtrl->loaded = TRUE;
- /* initialize the END and MIB2 parts of the structure */
- /*
- * The M2 element must come from m2Lib.h
- * This sh7615End is set up for a DIX type ethernet device.
- */
- if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, SH7615END_DEV_NAME,
- pDrvCtrl->unit, &sh7615EndFuncTable,
- "Hitachi SH7615 Enhanced Network Driver.") == ERROR
- || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
- &pDrvCtrl->enetAddr[0], 6, ETHERMTU, SH7615END_SPEED)
- == ERROR)
- goto errorExit;
- pDrvCtrl->flags = 0;
- /* Perform memory allocation/distribution */
- if (sh7615EndMemInit (pDrvCtrl) == ERROR)
- goto errorExit;
- /* set the End flags to indicate readiness */
- END_OBJ_READY (&pDrvCtrl->end,
- (IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST));
- DRV_LOG (DRV_DEBUG_LOAD, "Done loading sh7615end...", 1, 2, 3, 4, 5, 6);
- #ifdef DRV_DEBUG
- pShEnd = pDrvCtrl;
- #endif
- return (&pDrvCtrl->end);
- errorExit:
- sh7615EndUnload (pDrvCtrl);
- free ((char *)pDrvCtrl);
- return NULL;
- }
- /******************************************************************************
- *
- * sh7615EndUnload - unload a driver from the system
- *
- * This function first brings down the device, and then frees any
- * stuff that was allocated by the driver in the load function.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS sh7615EndUnload
- (
- DRV_CTRL* pDrvCtrl /* device to be unloaded */
- )
- {
- DRV_LOG (DRV_DEBUG_LOAD, "EndUnloadn", 0, 0, 0, 0, 0, 0);
- if (pDrvCtrl == NULL)
- return (ERROR);
- pDrvCtrl->loaded = FALSE;
- END_OBJECT_UNLOAD (&pDrvCtrl->end);
- /* free allocated shared memory */
- if (pDrvCtrl->memBase != NULL)
- cacheDmaFree (pDrvCtrl->memBase);
- /* free allocated memory if necessary */
- if ((pDrvCtrl->pMBlkArea) != NULL)
- free (pDrvCtrl->pMBlkArea);
- /* REVISIT - what about clusters? */
- cfree ((char *) pDrvCtrl);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndParse - parse the init string
- *
- * Parse the input string. Fill in values in the driver control structure.
- *
- * The muxLib.o module automatically prepends the unit number to the user's
- * initialization string from the BSP (configNet.h).
- *
- *
- * RETURNS: OK or ERROR for invalid arguments.
- */
- LOCAL STATUS sh7615EndParse
- (
- DRV_CTRL * pDrvCtrl, /* device pointer */
- char * initString /* information string */
- )
- {
- char* tok;
- char* pHolder = NULL;
- /* Parse the initString */
- /* Unit number. (from muxLib.o) */
- tok = strtok_r (initString, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->unit = atoi (tok);
- /* Get various driver configuration values */
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->ivec = atoi (tok);
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->ilevel = atoi (tok);
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->numTds = strtoul (tok, NULL, 16);
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->numRds = strtoul (tok, NULL, 16);
- /* PHY options (phyDefMode) currently not used */
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- tok = strtok_r (NULL, ":", &pHolder);
- if (tok == NULL)
- return ERROR;
- pDrvCtrl->userFlags = strtoul (tok, NULL, 16);
- /* Use default values for invalid settings */
- if (!pDrvCtrl->numTds || pDrvCtrl->numTds <= 2)
- {
- DRV_FLAGS_SET (SH7615END_INV_TBD_NUM);
- pDrvCtrl->numTds = SH7615END_TBD_DEF_NUM;
- }
- if (!pDrvCtrl->numRds || pDrvCtrl->numRds <= 2)
- {
- DRV_FLAGS_SET (SH7615END_INV_RBD_NUM);
- pDrvCtrl->numRds = SH7615END_RBD_DEF_NUM;
- }
- DRV_LOG (DRV_DEBUG_LOAD, "Processed all arugmentsn", 1, 2, 3, 4, 5, 6);
- return OK;
- }
- /*******************************************************************************
- *
- * sh7615EndMemInit - initialize memory for the chip
- *
- * This routine sets up memory required by the driver. It is highly specific
- * to the device.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS sh7615EndMemInit
- (
- DRV_CTRL * pDrvCtrl /* device to be initialized */
- )
- {
- SH7615_RD * pRxD;
- SH7615_TD * pTxD;
- char * pBuf;
- int ix;
- int sz;
- M_CL_CONFIG mclBlkConfig = {0, 0, NULL, 0};
- /* cluster blocks configuration */
- CL_DESC clDesc = {SH7615END_BUFSIZ, 0, NULL, 0};
- /* cluster blocks config table */
- /* Establish size of shared memory region we require */
- DRV_LOG (DRV_DEBUG_LOAD, "MemInit n", 0, 0, 0, 0, 0, 0);
- /* Establish a region of shared memory - allow for 16 byte align */
- sz = (((pDrvCtrl->numRds + 1) * SH7615END_RBD_SZ) +
- ((pDrvCtrl->numTds + 1) * SH7615END_TBD_SZ));
- /* this driver can't handle write incoherent caches */
- if (!CACHE_DMA_IS_WRITE_COHERENT ())
- {
- DRV_LOG (DRV_DEBUG_LOAD, "sh7615EndMemInit: shared
- memory not cache coherentn",
- 1, 2, 3, 4, 5, 6);
- return (ERROR);
- }
- /* cacheDmaMalloc returns CACHE_ALIGN_SIZE aligned and rounded
- * non-cacheable buffer. So, there is no need to flush and invalidate
- * descriptor buffers in this driver.
- */
- pDrvCtrl->memBase = (char *) cacheDmaMalloc (sz);
- if (pDrvCtrl->memBase == NULL)
- {
- DRV_LOG (DRV_DEBUG_LOAD, "%s%d - system memory unavailablen",
- (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);
- return (ERROR);
- }
- pDrvCtrl->memSize = sz;
- /* zero the shared memory */
- bzero (pDrvCtrl->memBase, (int) pDrvCtrl->memSize);
- /* ensure 16 byte alignment - device requirement */
- pDrvCtrl->rxRing = (SH7615_RD *) NET_TO_SH7615END_BUF (pDrvCtrl->memBase);
- /* carve Tx memory structure */
- pDrvCtrl->txRing = (SH7615_TD *) (pDrvCtrl->rxRing + pDrvCtrl->numRds);
- /* Initialize net buffer pool for tx/rx buffers */
- clDesc.clNum = pDrvCtrl->numRds + pDrvCtrl->numTds + NUM_LOAN;
- mclBlkConfig.mBlkNum = pDrvCtrl->numRds * 4;
- mclBlkConfig.clBlkNum = clDesc.clNum;
- mclBlkConfig.memSize = mclBlkConfig.mBlkNum * (MSIZE + sizeof (long)) +
- mclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long));
- mclBlkConfig.memArea = (char *) memalign (MBLK_ALIGNMENT,
- mclBlkConfig.memSize);
- if (mclBlkConfig.memArea == NULL)
- return (ERROR);
- /* store the pointer to the mBlock area */
- pDrvCtrl->pMBlkArea = mclBlkConfig.memArea;
- pDrvCtrl->mBlkSize = mclBlkConfig.memSize;
- /* Calculate the memory size of all the clusters. */
- clDesc.clSize = SH7615END_BUFSIZ;
- clDesc.memSize = clDesc.clNum * (clDesc.clSize + sizeof(int));
- clDesc.memArea = (char *) memalign (CL_ALIGNMENT, clDesc.memSize);
- if (clDesc.memArea == NULL)
- {
- DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailablen",
- 1, 2, 3, 4, 5, 6);
- return (ERROR);
- }
- /* store the pointer to the clBlock area - for show purposes */
- pDrvCtrl->pClBlkArea = clDesc.memArea;
- pDrvCtrl->clBlkSize = clDesc.memSize;
- /* Allocate and initialize the memory pool. */
- if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
- return (ERROR);
- if (netPoolInit(pDrvCtrl->end.pNetPool, &mclBlkConfig,
- &clDesc, 1, NULL) == ERROR)
- {
- DRV_LOG (DRV_DEBUG_LOAD, "Could not initialize net poolsn",
- 1, 2, 3, 4, 5, 6);
- return (ERROR);
- }
- /* Save the cluster pool id */
- pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,
- SH7615END_BUFSIZ, FALSE);
- if (pDrvCtrl->pClPoolId == NULL)
- return (ERROR);
- #ifdef DRV_DEBUG
- sh7615NetPoolId = pDrvCtrl->end.pNetPool;
- sh7615ClPool = pDrvCtrl->pClPoolId;
- #endif
- /* Clear all indices */
- pDrvCtrl->rxIndex=0;
- pDrvCtrl->txIndex=0;
- pDrvCtrl->txDiIndex=0;
- pDrvCtrl->txCleaning = FALSE;
- pDrvCtrl->rxHandling = FALSE;
- pDrvCtrl->txBlocked = FALSE;
- /* Setup the receive ring */
- pRxD = pDrvCtrl->rxRing;
- for (ix = 0; ix < pDrvCtrl->numRds; ix++, pRxD++)
- {
- pBuf = NET_BUF_ALLOC();
- if (pBuf == NULL)
- {
- pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
- muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);
- DRV_LOG (DRV_DEBUG_LOAD, "Could not get a buffern",
- 1, 2, 3, 4, 5, 6);
- return (ERROR);
- }
- pRxD->rDesc0 = RD0_OWN; /* chip owns the buffer */
- pRxD->rDesc1 = SH7615END_BUFSIZ << 16; /* max frame size */
- pRxD->rDesc2 = NET_TO_SH7615END_BUF (pBuf); /* buffer address */
- pRxD->rDesc3 = (UINT32) pBuf; /* The real cluster address */
- if (ix == (pDrvCtrl->numRds - 1)) /* if its is last one */
- pRxD->rDesc0 |= RD0_RDL; /* end of receive ring */
- }
- /* Setup the transmit ring */
- pTxD = pDrvCtrl->txRing;
- for (ix = 0; ix < pDrvCtrl->numTds; ix++, pTxD++)
- {
- /* empty -- no buffers at this time -- owner is host */
- pTxD->tDesc0 = 0;
- pTxD->tDesc1 = 0;
- pTxD->tDesc2 = 0;
- pTxD->tDesc3 = 0;
- if (ix == (pDrvCtrl->numTds - 1)) /* if its is last one */
- pTxD->tDesc0 |= TD0_TDL; /* end of transmit ring */
- }
- DRV_LOG (DRV_DEBUG_LOAD, "Memory setup completen", 1, 2, 3, 4, 5, 6);
- return OK;
- }
- /***************************************************************************
- *
- * sh7615EndRestart - restart the device
- *
- * Restarts the device after cleaning up the transmit and receive queues. This
- * routine should be called only after sh7615EndStop().
- *
- * RETURNS: OK or ERROR
- */
- LOCAL void sh7615EndRestart
- (
- DRV_CTRL *pDrvCtrl
- )
- {
- SH7615_TD *pTxD = pDrvCtrl->txRing;
- FREE_BUF *pFreeBuf = pDrvCtrl->freeBuf;
- SH7615_RD *pRxD;
- int count;
- DRV_LOG (DRV_DEBUG_LOAD, "%s%d - restarting device.n",
- (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
- /* cleanup the tx and rx queues */
- sh7615EndTxRingClean (pDrvCtrl);
- while ((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL)
- sh7615EndRecv (pDrvCtrl, pRxD);
- /* drop rest of the queued tx packets */
- for (count=pDrvCtrl->numTds; count > 0; count--, pTxD++, pFreeBuf++)
- {
- /* Free buffers */
- if (pFreeBuf->pClBuf != NULL)
- {
- NET_BUF_FREE(pFreeBuf->pClBuf);
- pFreeBuf->pClBuf = NULL;
- }
- /* These never had the chance to be sent */
- if (pTxD->tDesc0 & TD0_OWN)
- {
- END_OBJ *pEndObj = &pDrvCtrl->end;
- END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1);
- END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1);
- }
- /* Mark descriptors free */
- #if 0
- pTxD->tDesc0 &= TD0_CLEAR_ERRORS_N_STATS;
- #else
- /* Mark descriptors free */
- pTxD->tDesc0 = 0;
- pTxD->tDesc1 = 0;
- pTxD->tDesc2 = 0;
- pTxD->tDesc3 = 0;
- if (count == 1) /* if it is last one */
- pTxD->tDesc0 |= TD0_TDL; /* end of transmit ring */
- #endif
- }
- /* Start the device */
- sh7615EndStart (pDrvCtrl);
- }
- /*******************************************************************************
- *
- * sh7615EndStart - start the device
- *
- * This function calls BSP functions to connect interrupts and start the
- * device running in interrupt mode. The driver must have already been loaded
- * with the sh7615EndLoad() routine.
- *
- * RETURNS: OK or ERROR
- *
- */
- LOCAL STATUS sh7615EndStart
- (
- DRV_CTRL * pDrvCtrl /* device ID */
- )
- {
- STATUS result;
- DRV_LOG (DRV_DEBUG_LOAD, "Starting shend n", 0, 0, 0, 0, 0, 0);
- /* must have been loaded */
- if (!pDrvCtrl->loaded)
- return (ERROR);
- /* Reset the device */
- sh7615EndReset (pDrvCtrl);
- /* Clear all indices */
- pDrvCtrl->rxIndex = 0;
- pDrvCtrl->txIndex = 0;
- pDrvCtrl->txDiIndex = 0;
- pDrvCtrl->txCleaning = FALSE;
- pDrvCtrl->rxHandling = FALSE;
- pDrvCtrl->txBlocked = FALSE;
- /* Configure and start the device */
- sh7615EndConfig (pDrvCtrl);
- /* Connect the interrupt handler */
- SYS_INT_CONNECT (pDrvCtrl, sh7615EndInt, (int)pDrvCtrl, &result);
- if (result == ERROR)
- return ERROR;
- /* mark the interface -- up */
- END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));
- /* Enable LAN interrupts */
- SYS_INT_ENABLE (pDrvCtrl);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndStop - stop the device
- *
- * This function calls BSP functions to disconnect interrupts and stop
- * the device from operating in interrupt mode.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS sh7615EndStop
- (
- DRV_CTRL * pDrvCtrl /* device to be stopped */
- )
- {
- STATUS result = OK;
- /* mark the interface -- down */
- END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
- /* stop transmit and receive */
- SH7615END_BIT_CLR(ETHERC_ECMR, ECMR_TE);
- SH7615END_BIT_CLR(ETHERC_ECMR, ECMR_RE);
- /* Disable LAN interrupts */
- SYS_INT_DISABLE (pDrvCtrl);
- SYS_INT_DISCONNECT (pDrvCtrl, sh7615EndInt, (int)pDrvCtrl, &result);
- return (result);
- }
- /*******************************************************************************
- *
- * sh7615EndInt - handle controller interrupt
- *
- * This routine is called at interrupt level in response to an interrupt from
- * the controller.
- *
- * RETURNS: N/A.
- */
- LOCAL void sh7615EndInt
- (
- DRV_CTRL * pDrvCtrl /* interrupting device */
- )
- {
- UINT32 status;
- /* Read the device status register */
- SH7615END_REG_READ (E_DMAC_EESR, status);
- /* if not one of our interrupts, exit */
- if ((status & pDrvCtrl->intrMask) == 0)
- {
- return;
- }
- /*
- * read is not destructive, so, lets clear the sources by writing
- * the status back. This is safe to do since writing a 0 value does
- * not clear the bit. New sources may have come in, but they'll be
- * latched into the interrupt controller and caught when we exit here.
- */
- SH7615END_REG_WRITE (E_DMAC_EESR, status);
- /* Handle link status change */
- if ((status & EESR_ECI) != 0)
- {
- UINT32 ecsr;
- SH7615END_REG_READ (ETHERC_ECSR, ecsr);
- SH7615END_REG_WRITE (ETHERC_ECSR, ecsr);
- if ((ecsr & ECSR_LCHNG) != 0)
- {
- DRV_LOG (DRV_DEBUG_INT, "%s%d - link status changen",
- (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
- sh7615EndStop (pDrvCtrl);
- netJobAdd ((FUNCPTR)sh7615EndRestart, (int)pDrvCtrl, 0, 0, 0, 0);
- return;
- }
- }
- /* Handle received packets */
- if ((status & EESR_FR) && (!pDrvCtrl->rxHandling))
- {
- /* DRV_LOG (DRV_DEBUG_INT, "Recieve Int!! n", 0, 0, 0, 0, 0, 0); */
- if (netJobAdd ((FUNCPTR)sh7615EndRcvIntHandle,
- (int)pDrvCtrl, 0, 0, 0, 0) == OK)
- {
- /*
- * prevent additional scheduling of task level recv handling due
- * to new recv ints that may have been latched since we entered
- * here.
- */
- pDrvCtrl->rxHandling = TRUE;
- /*
- * disable Rx ints - we've already got a handler scheduled so
- * no need to come in here again. Note, that we may already have
- * latched a recv int since we entered here and cleared the status
- * bits above. the rxHandling will ensure that guy schedules no
- * no more jobs.
- */
- SH7615END_BIT_CLR (E_DMAC_EESIPR, EESIPR_FRIP);
- }
- }
- #ifdef DRV_DEBUG
- if (status & EESR_RFCOF)
- sh7615EndRfcof++;
- if (status & EESR_ECI)
- sh7615EndEci++;
- if (status & EESR_TC)
- sh7615EndTc++;
- if (status & EESR_TDE)
- sh7615EndTde++;
- if (status & EESR_TFUF)
- sh7615EndTfuf++;
- if (status & EESR_FR)
- sh7615EndFr++;
- if (status & EESR_RDE)
- sh7615EndRde++;
- if (status & EESR_RFOF)
- sh7615EndRfof++;
- if (status & EESR_ITF)
- sh7615EndItf++;
- if (status & EESR_CND)
- sh7615EndCnd++;
- if (status & EESR_DLC)
- sh7615EndDlc++;
- if (status & EESR_CD)
- sh7615EndCd++;
- if (status & EESR_TRO)
- sh7615EndTro++;
- if (status & EESR_RMAF)
- sh7615EndRmaf++;
- if (status & EESR_RRF)
- sh7615EndRrf++;
- if (status & EESR_RTLF)
- sh7615EndRtlf++;
- if (status & EESR_RTSF)
- sh7615EndRtsf++;
- if (status & EESR_PRE)
- sh7615EndPre++;
- if (status & EESR_CERF)
- sh7615EndCerf++;
- #endif
- /* Cleanup TxRing */
- if ((status & EESR_TC) && (!pDrvCtrl->txCleaning))
- {
- DRV_LOG (DRV_DEBUG_INT, "Cleanup TxRing from Int() n", 0, 0, 0, 0, 0, 0);
- pDrvCtrl->txCleaning = TRUE;
- netJobAdd ((FUNCPTR)sh7615EndTxRingClean, (int)pDrvCtrl, 0, 0, 0, 0);
- }
- if (pDrvCtrl->txBlocked)
- {
- pDrvCtrl->txBlocked = FALSE;
- netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->end, 0, 0, 0, 0);
- }
- }
- /*******************************************************************************
- *
- * sh7615EndRxDGet - get next receive descriptor
- *
- * Get next receive descriptor. Returns NULL if none are ready.
- *
- * RETURNS: ptr to next packet, or NULL if none ready.
- */
- LOCAL SH7615_RD * sh7615EndRxDGet
- (
- DRV_CTRL * pDrvCtrl /* device structure */
- )
- {
- SH7615_RD * pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;
- /* check if the descriptor is owned by the chip. The chip will clear
- * this bit once it has completed writing to the buffer.
- */
- if (pRxD->rDesc0 & RD0_OWN)
- return NULL;
- return pRxD;
- }
- /*******************************************************************************
- *
- * sh7615EndTxDGet - get an available transmit descriptor
- *
- * Get next transmit descriptor. Returns NULL if none are ready.
- *
- * RETURNS: an available transmit descriptor, otherwise NULL.
- */
- LOCAL SH7615_TD * sh7615EndTxDGet
- (
- DRV_CTRL * pDrvCtrl
- )
- {
- SH7615_TD * pTxD = pDrvCtrl->txRing + pDrvCtrl->txIndex;
- /* check if this descriptor is owned by the chip or is out of bounds */
- if ((pTxD->tDesc0 & TD0_OWN) ||
- (((pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds) == pDrvCtrl->txDiIndex))
- return (NULL);
- return pTxD;
- }
- /*******************************************************************************
- *
- * sh7615EndTxRingClean - clean up processed tx descriptors
- *
- * This routine processes the transmit queue, freeing all transmitted
- * descriptors.
- *
- * RETURNS: None
- */
- LOCAL void sh7615EndTxRingClean
- (
- DRV_CTRL * pDrvCtrl
- )
- {
- SH7615_TD * pTxD;
- pDrvCtrl->txCleaning = TRUE;
- while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)
- {
- pTxD = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;
- /* All handled, break from the loop */
- if (pTxD->tDesc0 & TD0_OWN)
- break;
- /* free the buffer */
- if (pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf != NULL)
- {
- NET_BUF_FREE(pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf);
- pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf = NULL;
- }
- pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->numTds;
- /* count collisions */
- #if 0
- if (! (pTxD->tDesc0 & TD0_CD))
- END_ERR_ADD (pEndObj, MIB2_COLLISIONS,
- SH7615END_REG_READ (ETHERC_CDCR));
- #endif
- if (pTxD->tDesc0 & TD0_TFE)
- {
- END_OBJ *pEndObj = &pDrvCtrl->end;
- END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1);
- END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1);
- #ifdef DRV_DEBUG
- /* check for no carrier */
- if (pTxD->tDesc0 & (TD0_CND | TD0_DLC))
- {
- logMsg ("%s%d - no carriern",
- (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
- }
- sh7615EndTfe++;
- #endif /* DRV_DEBUG */
- }
- /* clear errors and stats but don't touch TDL bit */
- pTxD->tDesc0 &= TD0_CLEAR_ERRORS_N_STATS;
- }
- pDrvCtrl->txCleaning = FALSE;
- return;
- }
- /*******************************************************************************
- *
- * sh7615EndRecv - process the next incoming packet
- *
- * Handle one incoming packet. The packet is checked for errors.
- *
- * RETURNS: N/A.
- */
- LOCAL STATUS sh7615EndRecv
- (
- DRV_CTRL * pDrvCtrl, /* device structure */
- SH7615_RD * pRxD /* packet to process */
- )
- {
- END_OBJ * pEndObj = &pDrvCtrl->end;
- M_BLK_ID pMblk;
- CL_BLK_ID pClBlk;
- char* pNewCluster;
- int len;
- /* check for errors */
- if (pRxD->rDesc0 & RD0_RFE)
- {
- DRV_LOG (DRV_DEBUG_RX, "Receive with error RD0 = 0x%08x n",
- pRxD->rDesc0, 2, 3, 4, 5, 6);
- END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);
- goto cleanRxD;
- }
- DRV_LOG (DRV_DEBUG_RX, "Receive start n", 1, 2, 3, 4, 5, 6);
- /*
- * We implicitly are loaning here, if copying is necessary this
- * step may be skipped, but the data must be copied before being
- * passed up to the protocols.
- */
- pNewCluster = NET_BUF_ALLOC ();
- if (pNewCluster == NULL)
- {
- pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
- muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);
- DRV_LOG (DRV_DEBUG_RX, "Cannot loan!n", 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
- goto cleanRxD;
- }
- /* Grab a cluster block to marry to the cluster we received. */
- if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
- {
- pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
- muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);
- NET_BUF_FREE (pNewCluster);
- DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!n", 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
- goto cleanRxD;
- }
- /*
- * OK we've got a spare, let's get an M_BLK_ID and marry it to the
- * one in the ring.
- */
- if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
- {
- netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
- NET_BUF_FREE (pNewCluster);
- DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!n", 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
- goto cleanRxD;
- }
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
- len = SH7615END_FRAME_LEN_GET (pRxD->rDesc1);
- /*
- * Invalidate cache and copy to ensure 4 byte alignment of IP header.
- * This is required by the IP network stack.
- */
- SH7615END_CACHE_INVALIDATE ((char *) (pRxD->rDesc2), len);
- len = (len + 1) & 0xfffffffe;
- bcopy((char*)pRxD->rDesc2,(char*)pRxD->rDesc2+2,len);
- /* Join the cluster to the MBlock */
- netClBlkJoin (pClBlk, (char *) (pRxD->rDesc3), SH7615END_BUFSIZ, NULL,
- 0, 0, 0);
- netMblkClJoin (pMblk, pClBlk);
- pMblk->mBlkHdr.mFlags |= M_PKTHDR;
- pMblk->mBlkHdr.mLen = len;
- pMblk->mBlkHdr.mData = (char *) (pRxD->rDesc2 + 2);
- pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen;
- /* save the new True data buffer address for freeing later */
- pRxD->rDesc3 = (UINT32) pNewCluster;
- /* Install new data buffer - force 16 byte alignment */
- pRxD->rDesc2 = NET_TO_SH7615END_BUF (pNewCluster);
- /* mark the descriptor ready to receive, preserve the RDL bit */
- pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN;
- /* advance management index */
- pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
- /* Call the upper layer's receive routine. */
- DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!n", 1, 2, 3, 4, 5, 6);
- END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
- return (OK);
- cleanRxD:
- /* mark the descriptor ready to receive - make sure to preserve the RDL bit */
- pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN;
- /* advance management index */
- pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndRcvIntHandle - task level interrupt service for input packets
- *
- * This routine is called at task level indirectly by the interrupt
- * service routine to do any message received processing.
- *
- * RETURNS: N/A.
- */
- LOCAL void sh7615EndRcvIntHandle
- (
- DRV_CTRL *pDrvCtrl /* interrupting device */
- )
- {
- SH7615_RD *pRxD;
- pDrvCtrl->rxHandling = TRUE; /* interlock with sh7615EndInt() */
- while ((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL)
- sh7615EndRecv (pDrvCtrl, pRxD);
- pDrvCtrl->rxHandling = FALSE; /* interlock with sh7615EndInt() */
- /* Make sure the Receive Request is still ON */
- SH7615END_REG_WRITE(E_DMAC_EDRRR, EDRRR_RR);
- /* enable receive interrupt */
- SH7615END_BIT_SET (E_DMAC_EESIPR, EESIPR_FRIP);
- }
- /*******************************************************************************
- *
- * sh7615EndSend - transmit an ethernet packet
- *
- * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
- * The buffer must already have the addressing information properly installed
- * in it. This is done by a higher layer. The last arguments are a free
- * routine to be called when the device is done with the buffer and a pointer
- * to the argument to pass to the free routine.
- *
- * RETURNS: OK on success; and ERROR otherwise.
- */
- LOCAL STATUS sh7615EndSend
- (
- DRV_CTRL * pDrvCtrl,
- M_BLK * pMblk
- )
- {
- SH7615_TD * pTxD;
- char * pBuf;
- int len;
- DRV_LOG (DRV_DEBUG_TX, "EndSendn", 1, 2, 3, 4, 5, 6);
- /* Gain exclusive access to transmit */
- END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
- /* Get the next TXD */
- pTxD = sh7615EndTxDGet (pDrvCtrl);
- if (pTxD == NULL)
- {
- DRV_LOG (DRV_DEBUG_TX, "No available TxD-s n", 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);
- END_TX_SEM_GIVE (&pDrvCtrl->end);
- if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)
- sh7615EndTxRingClean (pDrvCtrl);
- pDrvCtrl->txBlocked = TRUE; /* transmitter not ready */
- return (END_ERR_BLOCK); /* just return without freeing mBlk chain */
- }
- pBuf = NET_BUF_ALLOC();
- if (pBuf == NULL)
- {
- pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
- muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);
- DRV_LOG (DRV_DEBUG_TX, "No available TxBufs n", 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);
- END_TX_SEM_GIVE (&pDrvCtrl->end);
- if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)
- sh7615EndTxRingClean (pDrvCtrl);
- pDrvCtrl->txBlocked = TRUE; /* transmitter not ready */
- return (END_ERR_BLOCK); /* just return without freeing mBlk chain */
- }
- /*
- * Store the buf info. Do this before adjusting alignment below
- * so that the netBufFree will work correctly later.
- */
- pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf = pBuf;
- /* force 16 byte alignment of send buffer */
- (UINT32) pBuf = NET_TO_SH7615END_BUF (pBuf);
- /* Now copy data to 16 byte aligned location in pBuf and free Mblk */
- len = netMblkToBufCopy (pMblk, pBuf, NULL);
- len = max (ETHERSMALL, len);
- netMblkClChainFree (pMblk);
- /* flush the cache, if necessary */
- SH7615END_CACHE_FLUSH (pBuf, len);
- /* initialize the transmit descriptor -- preserve TD0_TDL bit */
- pTxD->tDesc0 = ((pTxD->tDesc0 & TD0_TDL) | (TD0_OWN | TD0_TFP));
- pTxD->tDesc1 = SH7615END_TBS_PUT(len);
- pTxD->tDesc2 = (UINT32) pBuf;
- pTxD->tDesc3 = 0;
- /* Advance our management index */
- pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
- SH7615END_REG_WRITE(E_DMAC_EDTRR, EDTRR_TR); /* Transmit request */
- END_TX_SEM_GIVE (&pDrvCtrl->end);
- /* update statistics */
- END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndPollStart - starting polling mode
- *
- * This routine starts polling mode by disabling ethernet interrupts and
- * setting the polling flag in the END_CTRL stucture.
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS sh7615EndPollStart
- (
- DRV_CTRL * pDrvCtrl
- )
- {
- int intLevel;
- DRV_LOG (DRV_DEBUG_POLL, "PollStartn", 1, 2, 3, 4, 5, 6);
- intLevel = intLock();
- /* Disable system interrupts */
- SYS_INT_DISABLE (pDrvCtrl);
- /* mask interrupts */
- SH7615END_BIT_CLR(E_DMAC_EESIPR, pDrvCtrl->intrMask);
- DRV_FLAGS_SET (SH7615END_POLLING);
- intUnlock (intLevel);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndPollStop - stop polling mode
- *
- * This function terminates polled mode operation. The device returns to
- * interrupt mode.
- *
- * The device interrupts are enabled, the current mode flag is switched
- * to indicate interrupt mode and the device is then reconfigured for
- * interrupt operation.
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS sh7615EndPollStop
- (
- DRV_CTRL * pDrvCtrl
- )
- {
- int intLevel;
- DRV_LOG (DRV_DEBUG_POLL, "PollStopn", 1, 2, 3, 4, 5, 6);
- intLevel = intLock();
- DRV_FLAGS_CLR (SH7615END_POLLING);
- /* Enable chip interrupts */
- SH7615END_REG_WRITE(E_DMAC_EESIPR, pDrvCtrl->intrMask);
- /* Enable system interrupts */
- SYS_INT_ENABLE (pDrvCtrl);
- intUnlock (intLevel);
- DRV_LOG (DRV_DEBUG_POLL, "sn", 1, 2, 3, 4, 5, 6);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndPollSend - send a packet in polled mode
- *
- * This routine is called by a user to try and send a packet on the
- * device.
- *
- * RETURNS: OK on success, EAGAIN on failure
- */
- LOCAL STATUS sh7615EndPollSend
- (
- DRV_CTRL * pDrvCtrl,
- M_BLK * pMblk
- )
- {
- SH7615_TD * pTxD;
- char * pBuf;
- char * pBufAligned;
- int len;
- DRV_LOG (DRV_DEBUG_POLL, "PollSendn", 1, 2, 3, 4, 5, 6);
- pTxD = sh7615EndTxDGet (pDrvCtrl);
- pBuf = NET_BUF_ALLOC ();
- if ((pTxD == NULL) || (pBuf == NULL))
- {
- pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
- muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);
- sh7615EndTxRingClean (pDrvCtrl);
- if (pBuf) NET_BUF_FREE (pBuf);
- return (EAGAIN);
- }
- /* force 16 byte alignment of send buffer */
- (UINT32) pBufAligned = NET_TO_SH7615END_BUF (pBuf);
- /* copy the MBLK */
- len = netMblkToBufCopy (pMblk, pBufAligned, NULL);
- len = max (ETHERSMALL, len);
- /* flush the cache, if necessary */
- SH7615END_CACHE_FLUSH (pBufAligned, len);
- pTxD->tDesc0 = ((pTxD->tDesc0 & TD0_TDL) | (TD0_OWN | TD0_TFP));
- pTxD->tDesc1 = SH7615END_TBS_PUT(len);
- pTxD->tDesc2 = (UINT32) pBufAligned;
- pTxD->tDesc3 = 0;
- /* Advance our management index */
- pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
- /* Transmit request */
- SH7615END_REG_WRITE(E_DMAC_EDTRR, EDTRR_TR);
- /* The buffer does not belong to us; Spin until it can be freed */
- while (pTxD->tDesc0 & TD0_OWN)
- ;
- NET_BUF_FREE (pBuf);
- /* Try again on transmit errors */
- if (pTxD->tDesc0 & TD0_TFE)
- return (EAGAIN);
- return (EAGAIN);
- }
- /*******************************************************************************
- *
- * sh7615EndPollReceive - get a packet in polled mode
- *
- * This routine is called by a user to try and get a packet from the
- * device.
- *
- * RETURNS: OK on success, EAGAIN on failure.
- */
- LOCAL STATUS sh7615EndPollReceive
- (
- DRV_CTRL *pDrvCtrl,
- M_BLK *pMblk
- )
- {
- SH7615_RD *pRxD;
- char *pRxBuf;
- int len;
- BOOL gotOne=FALSE;
- DRV_LOG (DRV_DEBUG_POLL, "PollReceiven", 1, 2, 3, 4, 5, 6);
- if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)
- return (EAGAIN);
- while (((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL) && !gotOne)
- {
- /* Check if the packet was received OK */
- if (pRxD->rDesc0 & RD0_RFE)
- {
- /* Update the error statistics and discard the packet */
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
- }
- else
- {
- len = SH7615END_FRAME_LEN_GET (pRxD->rDesc1);
- if ((len <= pMblk->mBlkHdr.mLen) && (len >= ETHERSMALL))
- {
- gotOne = TRUE;
- END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
- pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
- pMblk->mBlkHdr.mLen = len; /* set the data len */
- pMblk->mBlkPktHdr.len = len; /* set the total len */
- /* cache invalidate to prepare for the copy */
- pRxBuf = (char *) pRxD->rDesc2;
- SH7615END_CACHE_INVALIDATE (pRxBuf, len);
- /* bump the buffer mData by 2 to ensure alignment */
- pMblk->mBlkHdr.mData +=2;
- bcopy (pRxBuf, (char *)pMblk->mBlkHdr.mData, len);
- }
- }
- /* mark the descriptor ready to receive - preserve the RDL bit */
- pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN;
- pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
- }
- return (gotOne ? OK : EAGAIN);
- }
- /*******************************************************************************
- *
- * sh7615EndIoctl - the driver I/O control routine
- *
- * Process an ioctl request.
- *
- * This routine implements the network interface control functions.
- * It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,
- * EIOCMULTIDEL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.
- *
- * RETURNS: A command specific response, usually OK or ERROR.
- */
- LOCAL STATUS sh7615EndIoctl
- (
- DRV_CTRL * pDrvCtrl, /* device receiving command */
- int cmd, /* ioctl command code */
- caddr_t data /* command argument */
- )
- {
- int error = 0;
- long value;
- int savedFlags;
- END_OBJ * pEndObj=&pDrvCtrl->end;
- DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%xn",
- pDrvCtrl->unit, cmd, (int)data, 4, 5, 6);
- switch (cmd)
- {
- case EIOCSADDR:
- if (data == NULL)
- return (EINVAL);
- bcopy ((char *)data, (char *)END_HADDR(pEndObj),
- END_HADDR_LEN(pEndObj));
- break;
- case EIOCGADDR:
- if (data == NULL)
- return (EINVAL);
- bcopy ((char *)END_HADDR(pEndObj), (char *)data,
- END_HADDR_LEN(pEndObj));
- break;
- case EIOCSFLAGS:
- value = (long)data;
- if (value < 0)
- {
- value = -value;
- value--;
- END_FLAGS_CLR (pEndObj, value);
- }
- else
- {
- END_FLAGS_SET (pEndObj, value);
- }
- /* handle IIF_PROMISC and IFF_ALLMULTI */
- savedFlags = DRV_FLAGS_GET();
- if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC))
- DRV_FLAGS_SET (SH7615END_PROMISC);
- else
- DRV_FLAGS_CLR (SH7615END_PROMISC);
- if (END_FLAGS_GET(pEndObj) & (IFF_MULTICAST | IFF_ALLMULTI))
- DRV_FLAGS_SET (SH7615END_MCAST);
- else
- DRV_FLAGS_CLR (SH7615END_MCAST);
- DRV_LOG (DRV_DEBUG_IOCTL,
- "EIOCSFLAGS!! endFlags=0x%x savedFlags=0x%x newFlags=0x%xn",
- END_FLAGS_GET(pEndObj), savedFlags, DRV_FLAGS_GET(), 4, 5, 6);
- if ((DRV_FLAGS_GET() != savedFlags) &&
- (END_FLAGS_GET(pEndObj) & IFF_UP))
- sh7615EndModeSet (pDrvCtrl);
- break;
- case EIOCGFLAGS:
- DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS IOCTL: 0x%x: 0x%xn",
- pEndObj->flags, *(long *)data, 0, 0, 0, 0);
- if (data == NULL)
- error = EINVAL;
- else
- *(long *)data = END_FLAGS_GET(pEndObj);
- break;
- case EIOCMULTIADD:
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIADDn", 1, 2, 3, 4, 5, 6);
- error = sh7615EndMCastAddrAdd (pDrvCtrl, (char *)data);
- break;
- case EIOCMULTIDEL:
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIDELn", 1, 2, 3, 4, 5, 6);
- error = sh7615EndMCastAddrDel (pDrvCtrl, (char *)data);
- break;
- case EIOCMULTIGET:
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIGETn", 1, 2, 3, 4, 5, 6);
- error = sh7615EndMCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data);
- break;
- case EIOCPOLLSTART:
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCPOLLSTARTn", 1, 2, 3, 4, 5, 6);
- sh7615EndPollStart (pDrvCtrl);
- break;
- case EIOCPOLLSTOP:
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCPOLLSTOPn", 1, 2, 3, 4, 5, 6);
- sh7615EndPollStop (pDrvCtrl);
- break;
- case EIOCGMIB2:
- if (data == NULL)
- error=EINVAL;
- else
- bcopy((char *)&pEndObj->mib2Tbl, (char *)data,
- sizeof(pEndObj->mib2Tbl));
- DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCGMIB2n", 1, 2, 3, 4, 5, 6);
- break;
- default:
- error = EINVAL;
- }
- return (error);
- }
- /*******************************************************************************
- *
- * sh7615EndModeSet - promiscuous & multicast operation
- *
- * This routine enables promiscuous and duplex mode if corresponding flags
- * are set.
- *
- * RETURNS: N/A
- */
- LOCAL void sh7615EndModeSet
- (
- DRV_CTRL *pDrvCtrl
- )
- {
- /* NOTE - manual says mode should not be changed while
- Rx/Tx is enabled. To modify mode settings, first issue
- software reset */
- /* Set promiscuous mode if necessary */
- if (DRV_FLAGS_ISSET (SH7615END_PROMISC))
- SH7615END_BIT_SET (ETHERC_ECMR, ECMR_PRM);
- /* Set duplex mode if necessary */
- if (DRV_FLAGS_ISSET (SH7615END_FD))
- SH7615END_BIT_SET(ETHERC_ECMR, ECMR_DM);
- }
- /******************************************************************************
- *
- * sh7615EndConfig - reconfigure the interface under us.
- *
- * Reconfigure the interface setting promiscuous mode, and changing the
- * multicast interface list.
- *
- * RETURNS: N/A.
- */
- LOCAL void sh7615EndConfig
- (
- DRV_CTRL *pDrvCtrl /* device to be re-configured */
- )
- {
- UCHAR* pEnetAddr = pDrvCtrl->enetAddr;
- UINT32 MACAddr = 0;
- DRV_LOG (DRV_DEBUG_LOAD, "Configuring shendn", 0, 0, 0, 0, 0, 0);
- /* initialize the dp83843 Physical interface device */
- #ifdef INCLUDE_PHY
- /* Check full duplex mode */
- DRV_FLAGS_CLR (SH7615END_FD);
- if (dp83843RegRead(PHYSTS) & 0x0004)
- {
- DRV_FLAGS_SET (SH7615END_FD);
- }
- #define PFC_PACR ((volatile UINT16 *)0xfffffc80)
- *PFC_PACR = *PFC_PACR | (UINT16) 0x0004; /* LINKSTA pin */
- #endif
- /* set depth of FIFO */
- SH7615END_REG_WRITE(E_DMAC_FDR, ((pDrvCtrl->userFlags & 0x70) << 4) |
- (pDrvCtrl->userFlags & 0x7));
- /* Write start of receive and transmit rings */
- SH7615END_REG_WRITE(E_DMAC_RDLAR, (UINT32)pDrvCtrl->rxRing);
- SH7615END_REG_WRITE(E_DMAC_TDLAR, (UINT32)pDrvCtrl->txRing);
- /* set MAC Address */
- MACAddr = (UINT32)pEnetAddr[0] << 24;
- MACAddr |= (UINT32)pEnetAddr[1] << 16;
- MACAddr |= (UINT32)pEnetAddr[2] << 8;
- MACAddr |= (UINT32)pEnetAddr[3];
- SH7615END_REG_WRITE(ETHERC_MAHR, MACAddr);
- MACAddr = (UINT32)pEnetAddr[4] << 8;
- MACAddr |= (UINT32)pEnetAddr[5];
- SH7615END_REG_WRITE(ETHERC_MALR, MACAddr);
- /* set receive frame length register - specifies max receiveable length */
- SH7615END_REG_WRITE(ETHERC_RFLR, 0x5F0); /* 1520 bytes */
- /* clear any pending interrupts */
- SH7615END_REG_WRITE(ETHERC_ECSR, ECSR_CLEAR);
- SH7615END_REG_WRITE(E_DMAC_EESR, EESR_CLEAR);
- /* set operating mode and start the receiver */
- sh7615EndModeSet (pDrvCtrl);
- /* start the transmitter, receiver */
- SH7615END_REG_WRITE(E_DMAC_RCR, RCR_RNC); /* continuous mode */
- SH7615END_REG_WRITE(E_DMAC_EDRRR, EDRRR_RR); /* Receive request */
- SH7615END_BIT_SET(ETHERC_ECMR, ECMR_TE);
- SH7615END_BIT_SET(ETHERC_ECMR, ECMR_RE);
- /* set up the interrupt mask */
- pDrvCtrl->intrMask = EESIPR_FRIP | EESIPR_TCIP | EESIPR_ECIIP;
- /* enable interrupts at the device */
- SH7615END_REG_WRITE(E_DMAC_EESIPR, pDrvCtrl->intrMask);
- SH7615END_REG_WRITE(ETHERC_ECSIPR, ECSIPR_LCHNGIP);
- return;
- }
- /*******************************************************************************
- *
- * sh7615EndMCastAddrAdd - add a multicast address
- *
- * This routine adds a multicast address to whatever the driver
- * is already listening for.
- *
- * RETURNS: OK on success, ERROR otherwise.
- */
- LOCAL STATUS sh7615EndMCastAddrAdd
- (
- DRV_CTRL * pDrvCtrl,
- char * pAddr
- )
- {
- int retVal;
- DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAddn", 0, 0, 0, 0, 0, 0);
- retVal = etherMultiAdd (&pDrvCtrl->end.multiList, pAddr);
- if (retVal == ENETRESET)
- sh7615EndConfig (pDrvCtrl);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndMCastAddrDel - remove a multicast address
- *
- * This routine deletes a multicast address from the current list of
- * multicast addresses.
- *
- * RETURNS: OK on success, ERROR otherwise.
- */
- LOCAL STATUS sh7615EndMCastAddrDel
- (
- DRV_CTRL * pDrvCtrl,
- char * pAddr
- )
- {
- int retVal;
- DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDeln", 0, 0, 0, 0, 0, 0);
- retVal = etherMultiDel (&pDrvCtrl->end.multiList, pAddr);
- if (retVal == ENETRESET)
- sh7615EndConfig (pDrvCtrl);
- return (OK);
- }
- /*******************************************************************************
- *
- * sh7615EndMCastAddrGet - retreive current multicast address list
- *
- * This routine returns the current multicast address list in <pTable>
- *
- * RETURNS: OK on success; otherwise ERROR.
- */
- LOCAL STATUS sh7615EndMCastAddrGet
- (
- DRV_CTRL * pDrvCtrl,
- MULTI_TABLE *pTable
- )
- {
- DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrGetn", 0, 0, 0, 0, 0, 0);
- return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));
- }
- /*******************************************************************************
- *
- * sh7615EnetAddrGet - get the Ethernet address.
- *
- * This routine gets the ethernet address by calling the appropriate
- * BSP routine.
- *
- * RETURNS: N/A.
- */
- LOCAL void sh7615EnetAddrGet
- (
- DRV_CTRL * pDrvCtrl,
- char * addr
- )
- {
- int i;
- char bytes[6];
- SYS_ENET_ADDR_GET (pDrvCtrl, bytes);
- /* For big endian we need to swap byte order */
- for (i=0; i<6; i++)
- *addr++ = bytes[5-i];
- }
- /*******************************************************************************
- *
- * sh7615EndReset - reset device
- *
- * This routines issues a software reset of the SH7615 on-chip EDMAC.
- *
- * RETURNS: N/A.
- */
- LOCAL void sh7615EndReset
- (
- DRV_CTRL *pDrvCtrl
- )
- {
- /*
- * Note - this also sets Tx/Rx descriptor length to 16 bytes, which is
- * what we want.
- *
- * This should reset all internal registers to the initial values.
- * Both the etherC AND the E-DMAC regs are reset.
- * Consequently, all interrupts should be masked.
- */
- SH7615END_REG_WRITE (E_DMAC_EDMR, EDMR_SWR);
- }
- #ifdef DRV_DEBUG
- /*******************************************************************************
- *
- * sh7615EndRegDump - reads all ETHERC and EDMAC registers and print the value
- *
- * This routine reads all the registers of the SH7615 on-chip ETHERC and EDMAC.
- * Only for debug purpose.
- *
- * RETURNS: N/A.
- *
- * NOMANUAL
- */
- void sh7615EndRegDump()
- {
- UINT32 value;
- SH7615END_REG_READ(E_DMAC_EDMR, value);
- logMsg ("E_DMAC_EDMR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_EDTRR, value);
- logMsg ("E_DMAC_EDTRR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_EDRRR, value);
- logMsg ("E_DMAC_EDRRR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_TDLAR, value);
- logMsg ("E_DMAC_TDLAR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_RDLAR, value);
- logMsg ("E_DMAC_RDLAR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_EESR, value);
- logMsg ("E_DMAC_EESR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_EESIPR, value);
- logMsg ("E_DMAC_EESIPR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_TRSCER, value);
- logMsg ("E_DMAC_TRSCER: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_RMFCR, value);
- logMsg ("E_DMAC_RMFCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_TFTR, value);
- logMsg ("E_DMAC_TFTR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_FDR, value);
- logMsg ("E_DMAC_FDR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_RCR, value);
- logMsg ("E_DMAC_RCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(E_DMAC_EDOCR, value);
- logMsg ("E_DMAC_EDOCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_ECMR, value);
- logMsg ("ETHERC_ECMR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_ECSR, value);
- logMsg ("ETHERC_ECSR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_ECSIPR, value);
- logMsg ("ETHERC_ECSIPR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_PIR, value);
- logMsg ("ETHERC_PIR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_MAHR, value);
- logMsg ("ETHERC_MAHR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_MALR, value);
- logMsg ("ETHERC_MALR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_RFLR, value);
- logMsg ("ETHERC_RFLR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_PSR, value);
- logMsg ("ETHERC_PSR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_TROCR, value);
- logMsg ("ETHERC_TROCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_CDCR, value);
- logMsg ("ETHERC_CDCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_LCCR, value);
- logMsg ("ETHERC_LCCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_CNDCR, value);
- logMsg ("ETHERC_CNDCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_IFLCR, value);
- logMsg ("ETHERC_IFLCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_CEFCR, value);
- logMsg ("ETHERC_CEFCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_FRECR, value);
- logMsg ("ETHERC_FRECR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_TSFRCR, value);
- logMsg ("ETHERC_TSFRCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_TLFRCR, value);
- logMsg ("ETHERC_TLFRCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_RFCR, value);
- logMsg ("ETHERC_RFCR: 0x%xn", value, 0, 0, 0, 0, 0);
- SH7615END_REG_READ(ETHERC_MAFCR, value);
- logMsg ("ETHERC_MAFCR: 0x%xn", value, 0, 0, 0, 0, 0);
- }
- #endif /* DRV_DEBUG */
- #ifdef INCLUDE_PHY
- /*******************************************************************************
- *
- * dp83843SingleBitRead - reads a single bit value from the dp83843
- *
- * This routine reads a single bit value from the dp83843 via the etherc's PHY
- * Interface Register (PIR).
- *
- * RETURNS: N/A.
- */
- LOCAL UINT16 dp83843SingleBitRead (void)
- {
- UINT32 data;
- /* lead clock and data direction is read */
- SH7615END_REG_WRITE (ETHERC_PIR, ~PIR_MMD & PIR_MDC);
- /* read data */
- SH7615END_REG_READ (ETHERC_PIR, data);
- /*
- * NOTE - I assume this should be a write for the trailing clock,
- * but the doc is confusing, saying "MII control register read"
- */
- SH7615END_REG_WRITE (ETHERC_PIR, 0x0);
- /* shift data */
- if (data & PIR_MDI)
- return 1;
- else
- return 0;
- }
- /*******************************************************************************
- *
- * dp83843SingleBitWrite - writes a single bit value to the dp83843
- *
- * This routine writes a single bit value to the dp83843 via the etherc's PHY
- * Interface Register (PIR). The dp83843 is programmed one bit at a time.
- *
- * RETURNS: N/A.
- */
- LOCAL void dp83843SingleBitWrite
- (
- int bitVal
- )
- {
- UINT32 data;
- UINT32 leadClock;
- UINT32 trailClock;
- if (bitVal)
- data = PIR_MDO | PIR_MMD;
- else
- data = PIR_MMD;
- leadClock = data | PIR_MDC;
- trailClock = data;
- /* Set data and write direction */
- SH7615END_REG_WRITE (ETHERC_PIR, (PIR_MMD & ~PIR_MDC) | (bitVal << 2) );
- /* Provide the clock leading and trailing pulses to latch on */
- SH7615END_REG_WRITE (ETHERC_PIR, PIR_MMD | PIR_MDC | (bitVal << 2) );
- SH7615END_REG_WRITE (ETHERC_PIR, (PIR_MMD & ~PIR_MDC) | (bitVal << 2));
- }
- /*******************************************************************************
- *
- * dp83843GetPackt - compose a frame format for the PHY
- *
- * This routine composes a frame format for the PHY chip according to
- * the following scheme:
- *
- * <idle><ST><OP><AAAAA><RRRRR><TA>
- *
- * where:
- * ST: start command (01)
- * OP: operation code (01: write, 10: read)
- * AAAAA: address of the PHY chip.
- * RRRRR: register of the PHY chip.
- * TA: turnaround (10: write, Z0: read)
- *
- * Example write sequence to ANAR (address offset == 0x4)
- *
- * 5 0 9 2 this routine returns: 0x5092
- * _____ _____ _____ _____
- * | | | | | | | |
- * 0 1 0 1 0 0 0 0 1 0 0 1 0 0 1 0
- * | | | | | | | | | |
- * - - ------- ------- -
- * s o phy reg T
- * t p addr addr A
- * a 1 0x4
- * r w
- * t r
- *
- * This routine returns a 16-bit pattern. Note: the <idle> at the
- * beginning is not included. For reading, the TA field is irrelevant.
- *
- * RETURNS: the frame packet.
- */
- LOCAL UINT16 dp83843GetPackt
- (
- UCHAR phyAddr, /* Address of the PHY in the transaction */
- UCHAR phyReg, /* Register interested in the transaction */
- BOOL writePck /* frame for writing if true */
- )
- {
- UINT16 value = 0;
- /* start command */
- value |= ((0x0001 & 0x0003) << 14);
- /* Operation command */
- if( writePck )
- value |= ((0x0001 & 0x0003) << 12); /* write command */
- else
- value |= ((0x0002 & 0x0003) << 12); /* read command */
- /* Address of the PHY chip */
- value |= ((phyAddr & 0x001f) << 7);
- /* Register */
- value |= ((phyReg & 0x001f) << 2);
- /* turnaround */
- if( writePck )
- value |= 0x0002; /* write operation only */
- else
- value |= 0x0000;
- return value;
- }
- #if 0 /* Not used currently */
- /*******************************************************************************
- *
- * dp83843RegWrite - writes a dp83843 register
- *
- * This routine writes a UINT16 value to a dp83843 register via the etherc's PHY
- * Interface Register (PIR). dp83843 registers are all 16bit.
- *
- * RETURNS: N/A.
- *
- * NOMANUAL
- */
- LOCAL void dp83843RegWrite
- (
- UINT16 regAddr,
- UINT16 regData
- )
- {
- int i;
- UINT16 pckFrame;
- pckFrame = dp83843GetPackt(PHY_ADDR, regAddr, TRUE);
- /* this preamble step may not be necessary - BMSR's bit 6 has default
- value of 1 which means the device is supposed to be able to operate
- without the preamble. However, it does still need 32 bits after a
- reset.
- */
- for(i=0; i<32; i++)
- dp83843SingleBitWrite(1); /* preamble is 32 1's */
- for(i=0; i<16; i++) /* start, opcode, devAddrr, regAddr and turn */
- {
- if((pckFrame & 0x8000)==0x8000)
- dp83843SingleBitWrite(1);
- else
- dp83843SingleBitWrite(0);
- pckFrame = pckFrame << 1;
- }
- for(i=0; i<16; i++) /* regdata */
- {
- if((regData & 0x8000)==0x8000)
- {
- dp83843SingleBitWrite(1);
- }
- else
- {
- dp83843SingleBitWrite(0);
- }
- regData = regData << 1;
- }
- /* independent bus release */
- SH7615END_REG_WRITE (ETHERC_PIR, ~PIR_MDC & ~PIR_MMD );
- }
- #endif
- /*******************************************************************************
- *
- * dp83843RegRead - reads a dp83843 register
- *
- * This routine reads a UINT16 register from a dp83843 via the etherc's PHY
- * Interface Register (PIR). dp83843 registers are all 16bit.
- *
- * RETURNS: value read.
- */
- LOCAL UINT16 dp83843RegRead
- (
- UINT16 regAddr /* register to be read */
- )
- {
- int i;
- UINT16 value = 0;
- UINT16 data;
- UINT16 pckFrame;
- pckFrame = dp83843GetPackt(PHY_ADDR, regAddr, FALSE);
- /*
- * NOTE: this preamble step may not be necessary - BMSR's bit 6 has
- * default value of 1 which means the device is supposed to be able to
- * operate without the preamble. However, it does still need 32 bits
- * after a reset.
- */
- for(i = 0; i < 32; i++)
- {
- dp83843SingleBitWrite(1); /* preamble is 32 1's */
- }
- /*
- * NOTE - ought to hard code in the start, opcode and devAddr here and
- * only pass in the regAddr offset as defined in the doc. This would
- * make the macro defs in sh7615End.h more understandable. Then, they
- * would just be the simple offsets as opposed to containing the start
- * opcode and devAddr also.
- */
- /* write the start, opcode, devAddr and regAddr. Note - this is only 14 bits */
- for(i = 0; i < 14; i++)
- {
- if( (pckFrame & 0x8000) == 0x8000 )
- {
- dp83843SingleBitWrite(1);
- }
- else
- {
- dp83843SingleBitWrite(0);
- }
- pckFrame = pckFrame << 1;
- }
- /* release the bus */
- SH7615END_REG_WRITE (ETHERC_PIR, 0);
- SH7615END_REG_WRITE (ETHERC_PIR, PIR_MDC);
- SH7615END_REG_WRITE (ETHERC_PIR, 0);
- /* read bit 0 of TA */
- if( dp83843SingleBitRead() == 1 )
- DRV_LOG(DRV_DEBUG_PHY,"dp83843RegRead: Last bit of TA fild is Set!n",
- 1,2,3,4,5,6);
- /* read data */
- for(i = 15; i >= 0; i--)
- {
- data = dp83843SingleBitRead();
- value |= (data << i);
- }
- return value;
- }
- #ifdef DRV_DEBUG
- /*******************************************************************************
- *
- * dp83843RegDump - reads all the dp83843 registers and print the value
- *
- * This routine reads all the registers of a dp83843 via the etherc's PHY
- * Interface Register (PIR) and prints the values. Only for debug purpose.
- *
- * RETURNS: N/A.
- *
- * NOMANUAL
- */
- void dp83843RegDump (void)
- {
- DRV_LOG(DRV_DEBUG_PHY,"nn PHY CHIP Registers:nn",1,2,3,4,5,6)
- DRV_LOG(DRV_DEBUG_PHY,"BMCR:tt%04xn",
- dp83843RegRead(BMCR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"BMSR:tt%04xn",
- dp83843RegRead(BMSR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"PHYIDR1:tt%04xn",
- dp83843RegRead(PHYIDR1),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"PHYIDR2:tt%04xn",
- dp83843RegRead(PHYIDR2),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"ANAR:tt%04xn",
- dp83843RegRead(ANAR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"ANLPAR:tt%04xn",
- dp83843RegRead(ANLPAR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"ANER:tt%04xn",
- dp83843RegRead(ANER),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"ANNPTR:tt%04xn",
- dp83843RegRead(ANNPTR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"PHYSTS:tt%04xn",
- dp83843RegRead(PHYSTS),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"MIPSCR:tt%04xn",
- dp83843RegRead(MIPSCR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"MIPGSR:tt%04xn",
- dp83843RegRead(MIPGSR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"DCR:tt%04xn",
- dp83843RegRead(DCR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"FCSCR:tt%04xn",
- dp83843RegRead(FCSCR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"RECR:tt%04xn",
- dp83843RegRead(RECR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"PCSR:tt%04xn",
- dp83843RegRead(PCSR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"LBR:tt%04xn",
- dp83843RegRead(LBR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"BTSCR:tt%04xn",
- dp83843RegRead(BTSCR),2,3,4,5,6);
- DRV_LOG(DRV_DEBUG_PHY,"PHYCTL:tt%04xn",
- dp83843RegRead(PHYCTRL),2,3,4,5,6);
- }
- #endif /* DRV_DEBUG */
- #endif /* INCLUDE_PHY */