motFecEnd.c
资源名称:ixp425BSP.rar [点击查看]
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:168k
源码类别:
VxWorks
开发平台:
C/C++
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: bad rbdn"),
- 1, 2, 3, 4, 5, 6);
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
- #ifdef MOT_FEC_DBG
- if ((rbdStatus & MOT_FEC_RBD_LG) == MOT_FEC_RBD_LG)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: len violationn"),
- 1, 2, 3, 4, 5, 6);
- MOT_FEC_RX_LG_ADD;
- }
- if ((rbdStatus & MOT_FEC_RBD_NO) == MOT_FEC_RBD_NO)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: not alignedn"),
- 1, 2, 3, 4, 5, 6);
- MOT_FEC_RX_NO_ADD;
- }
- if ((rbdStatus & MOT_FEC_RBD_CRC) == MOT_FEC_RBD_CRC)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: CRC errorn"),
- 1, 2, 3, 4, 5, 6);
- MOT_FEC_RX_CRC_ADD;
- }
- if ((rbdStatus & MOT_FEC_RBD_OV) == MOT_FEC_RBD_OV)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: rx overrunn"),
- 1, 2, 3, 4, 5, 6);
- MOT_FEC_RX_OV_ADD;
- }
- if ((rbdStatus & MOT_FEC_RBD_TR) == MOT_FEC_RBD_TR)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive: trunc frame n"),
- 1, 2, 3, 4, 5, 6);
- MOT_FEC_RX_TR_ADD;
- }
- #endif /* MOT_FEC_DBG */
- /* put the errored RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- return;
- }
- /* get the actual amount of received data */
- MOT_FEC_BD_WORD_RD (pUsedRbd, MOT_FEC_BD_LEN_OFF,
- rbdLen);
- if (rbdLen < ETHERSMALL)
- {
- MOT_FEC_RX_LS_ADD;
- /* put the errored RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- return;
- }
- /* Allocate an MBLK, and a replacement buffer */
- pMblk = NET_MBLK_ALLOC();
- pBuf = NET_BUF_ALLOC ();
- pClBlk = NET_CL_BLK_ALLOC();
- if ((pMblk == NULL) || (pBuf == NULL) ||
- (pClBlk == NULL))
- {
- MOT_FEC_RX_MEM_ADD;
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive mem problemn"),
- 0, 0, 0, 0, 0, 0);
- goto motFecRecvError;
- }
- MOT_FEC_BD_LONG_RD (pUsedRbd, MOT_FEC_BD_ADDR_OFF, pData);
- NET_CL_BLK_JOIN (pClBlk, (char *) (pDrvCtrl->rxBuf [pDrvCtrl->rbdIndex]),
- MOT_FEC_MAX_CL_LEN, retVal);
- if (retVal == NULL)
- {
- goto motFecRecvError;
- }
- NET_MBLK_CL_JOIN(pMblk, pClBlk, retVal);
- if (retVal == NULL)
- {
- goto motFecRecvError;
- }
- /* set up the mBlk properly */
- pMblk->mBlkHdr.mFlags |= M_PKTHDR;
- pMblk->mBlkHdr.mData = pData;
- pMblk->mBlkHdr.mLen = (rbdLen - ETHER_CRC_LEN) & ~0xc000;
- pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen;
- /* Make cache consistent with memory */
- MOT_FEC_CACHE_INVAL ((char *) pData, pMblk->mBlkHdr.mLen);
- /* up-date statistics */
- if ((*pData ) & (UINT8) 0x01)
- {
- pDrvCtrl->endObj.mib2Tbl.ifInNUcastPkts += 1;
- }
- else
- {
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
- }
- /* put the new RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecReceive... Done, n"),
- 0, 0, 0, 0, 0, 0);
- return;
- motFecRecvError:
- /* free buffers/clusters, clean the RBD */
- if (pMblk != NULL)
- NET_MBLK_FREE (pMblk);
- if (pClBlk != NULL)
- NET_CL_BLK_FREE (pClBlk);
- if (pBuf != NULL)
- NET_BUF_FREE ((UCHAR *) pBuf);
- /* put the errored RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- }
- /**************************************************************************
- *
- * motFecRbdClean - clean a receive buffer descriptor
- *
- * This routine cleans a receive buffer descriptor and initializes it
- * with the data pointer <pBuf>.
- *
- * RETURNS: N/A
- *
- */
- LOCAL void motFecRbdClean
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- char * pBuf /* pointer to a new data buffer */
- )
- {
- MOT_FEC_RBD_ID pUsedRbd; /* pointer to a RBD */
- char * pData = NULL; /* a rx data pointer */
- /* get the first used RBD */
- MOT_FEC_NEXT_RBD (pDrvCtrl, pUsedRbd);
- /* up-date the data pointer with the one provided by the pool */
- if (pBuf != NULL)
- {
- pDrvCtrl->rxBuf [(pDrvCtrl->rbdIndex)] = (UCHAR *) pBuf;
- pData = (char *) NET_TO_MOT_FEC_BUF (pBuf);
- MOT_FEC_BD_LONG_WR (pUsedRbd, MOT_FEC_BD_ADDR_OFF, (UINT32) pData);
- }
- MOT_FEC_BD_WORD_WR (pUsedRbd, MOT_FEC_BD_LEN_OFF, 0);
- /* up-date the status word: treat the last RBD in the ring differently */
- if ((pDrvCtrl->rbdIndex) == (pDrvCtrl->rbdNum - 1))
- {
- MOT_FEC_BD_WORD_WR (pUsedRbd, MOT_FEC_BD_STAT_OFF,
- (MOT_FEC_RBD_WRAP | MOT_FEC_RBD_EMPTY));
- }
- else
- {
- MOT_FEC_BD_WORD_WR (pUsedRbd, MOT_FEC_BD_STAT_OFF,
- MOT_FEC_RBD_EMPTY);
- }
- /* let's move on to the next used RBD */
- pDrvCtrl->rbdIndex = (pDrvCtrl->rbdIndex + 1) % (pDrvCtrl->rbdNum);
- MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecRbdClean... Done, n"),
- 0, 0, 0, 0, 0, 0);
- }
- /**************************************************************************
- *
- * motFecRbdInit - initialize the receive buffer ring
- *
- * This routine initializes the receive buffer descriptors ring.
- *
- * SEE ALSO: motFecTbdInit()
- *
- * RETURNS: OK, or ERROR if not enough clusters were available.
- */
- LOCAL STATUS motFecRbdInit
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- char * pData = NULL; /* a rx data pointer */
- char * pBuf = NULL; /* a rx data pointer */
- MOT_FEC_RBD_ID pRbd = NULL; /* generic rbd pointer */
- UINT16 ix; /* a counter */
- /* the receive ring is located right after the transmit one */
- pDrvCtrl->rbdBase = pRbd = (MOT_FEC_RBD_ID) (pDrvCtrl->pBufBase
- + MOT_FEC_TBD_MEM (pDrvCtrl));
- for (ix = 0; ix < pDrvCtrl->rbdNum; ix++)
- {
- /* get a cluster buffer from the pool */
- if ((pBuf = NET_BUF_ALLOC()) == NULL)
- return (ERROR);
- /*
- * fill each buffer with en entire frame and make it available
- * for the receiver. Do not activate the receiver yet.
- */
- MOT_FEC_BD_WORD_WR (pRbd, MOT_FEC_BD_STAT_OFF,
- MOT_FEC_RBD_EMPTY);
- MOT_FEC_BD_WORD_WR (pRbd, MOT_FEC_BD_LEN_OFF, 0);
- /*
- * what we need to do here is to save the cluster pointer
- * for use by the net pool later. We won't be using that
- * cluster as is, because the FEC requires receive buffers
- * being aligned by 16. So we move that cluster pointer to
- * the next 16-byte aligned boundary, and program the chip
- * with that value. When we receive the packet, we'll have
- * to join the saved cluster pointer to the mBlk.
- */
- pDrvCtrl->rxBuf [ix] = (UCHAR *) pBuf;
- pData = (char *) NET_TO_MOT_FEC_BUF (pBuf);
- MOT_FEC_BD_LONG_WR (pRbd, MOT_FEC_BD_ADDR_OFF, (UINT32) pData);
- /* move on to the next RBD */
- pRbd += MOT_FEC_RBD_SZ;
- }
- /* have the last RBD to close the ring */
- pRbd -= MOT_FEC_RBD_SZ;
- MOT_FEC_BD_WORD_WR (pRbd, MOT_FEC_BD_STAT_OFF,
- (MOT_FEC_RBD_WRAP | MOT_FEC_RBD_EMPTY));
- return (OK);
- }
- /**************************************************************************
- *
- * motFecBdFree - free the receive buffers
- *
- * This routine frees the netpool clusters associated with the receive
- * buffer descriptors ring. It is called by motFecStop(), in order to
- * properly release the driver's resources when the device is stopped.
- *
- * SEE ALSO: motFecStop()
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecBdFree
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- MOT_FEC_RBD_ID pRbd = NULL; /* generic rbd pointer */
- UINT16 ix; /* a counter */
- pRbd = (MOT_FEC_RBD_ID) (pDrvCtrl->rbdBase);
- for (ix = 0; ix < pDrvCtrl->rbdNum; ix++)
- {
- /* return the cluster buffer to the pool */
- if ((pDrvCtrl->rxBuf [ix]) != NULL)
- NET_BUF_FREE ((pDrvCtrl->rxBuf [ix]));
- pRbd += MOT_FEC_RBD_SZ;
- }
- /* free the transmit poll buffer */
- if ((pDrvCtrl->pTxPollBuf) != NULL)
- NET_BUF_FREE ((UCHAR *) (pDrvCtrl->pTxPollBuf));
- return (OK);
- }
- /**************************************************************************
- *
- * motFecPrePhyConfig - configure the chip before the PHY is initialized
- *
- * This routine programs all the CSRs that are not concerned with the
- * PHY configuration. It follows closely but not entirely the
- * initialization sequence recommended in the FEC User's Manual.
- *
- * SEE ALSO: motFecPostPhyConfig()
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecPrePhyConfig
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- UINT32 csrVal = 0; /* holder for the CSR value */
- UINT32 csr0Val = 0; /* holder for the CSR0 value */
- UINT32 csr1Val = 0; /* holder for the CSR1 value */
- static BOOL first = TRUE; /* first initialization */
- UINT32 miiSpeed; /* calculated value for MII_SPEED */
- /*
- * we enable the following event interrupts:
- * heartbeat check fail, only if the user requested it;
- * tx and rx babbling errors;
- * tx and rx frame completion;
- * graceful transmit command;
- * mii management interface frame completion;
- * U-bus access error.
- */
- if (MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_HBC))
- {
- csrVal |= MOT_FEC_EVENT_HB;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecPrePhyConfig: heartbeat control n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- csrVal &= ~MOT_FEC_EVENT_HB;
- csrVal |= (MOT_FEC_EVENT_GRA | MOT_FEC_EVENT_MII | MOT_FEC_EVENT_TXF |
- MOT_FEC_EVENT_RXF | MOT_FEC_EVENT_BABR | MOT_FEC_EVENT_BABT |
- MOT_FEC_EVENT_BERR);
- MOT_FEC_CSR_WR (MOT_FEC_MASK_OFF, csrVal);
- /* save the interrupt mask register */
- pDrvCtrl->intMask = csrVal;
- /* clear all interrupts */
- MOT_FEC_CSR_WR (MOT_FEC_EVENT_OFF, MOT_FEC_EVENT_MSK);
- /* set the interrupt level */
- MOT_FEC_CSR_WR (MOT_FEC_VEC_OFF, (pDrvCtrl->ilevel << MOT_FEC_LVL_SHIFT));
- if (pDrvCtrl->fifoTxBase != NONE)
- MOT_FEC_CSR_WR (MOT_FEC_TX_FIFO_OFF, pDrvCtrl->fifoTxBase);
- if (pDrvCtrl->fifoRxBase != NONE)
- MOT_FEC_CSR_WR (MOT_FEC_RX_FIFO_OFF, pDrvCtrl->fifoRxBase);
- /* program the individual enet address */
- if (motFecAddrRegValGet (pDrvCtrl, &csr0Val, &csr1Val) != OK)
- return (ERROR);
- MOT_FEC_CSR_WR (MOT_FEC_ADDR_L_OFF, csr0Val);
- MOT_FEC_CSR_WR (MOT_FEC_ADDR_H_OFF, csr1Val);
- /* reset the hash table */
- /* question: does muxDevStop/Start re-init the multi table? */
- if (first)
- {
- first = FALSE;
- MOT_FEC_CSR_WR (MOT_FEC_HASH_L_OFF, 0);
- MOT_FEC_CSR_WR (MOT_FEC_HASH_H_OFF, 0);
- }
- /*
- * if no clock speed is defined, assume a clock speed of 50 MHz.
- * Otherwise, derive the MII clock speed according to the formula
- * MII_SPEED = ceil(pDrvCtrl->clockSpeed / (2 * MII_CLOCK_MAX))
- */
- if (pDrvCtrl->clockSpeed == 0)
- miiSpeed = MOT_FEC_MII_SPEED_50;
- else
- miiSpeed = (pDrvCtrl->clockSpeed + (2 * MOT_FEC_MII_CLOCK_MAX) - 1) /
- (2 * MOT_FEC_MII_CLOCK_MAX);
- /* MII_SPEED is left-shifted in the MII_SPEED register */
- MOT_FEC_CSR_WR (MOT_FEC_MII_SPEED_OFF, miiSpeed << MOT_FEC_MII_SPEED_SHIFT);
- /* program the max receive buffer length */
- MOT_FEC_CSR_WR (MOT_FEC_RX_BUF_OFF, MOT_FEC_MAX_RX_BUF);
- /* program the receive and transmit rings registers */
- MOT_FEC_CSR_WR (MOT_FEC_RX_START_OFF, (UINT32) (pDrvCtrl->rbdBase));
- MOT_FEC_CSR_WR (MOT_FEC_TX_START_OFF, (UINT32) (pDrvCtrl->tbdBase));
- MOT_FEC_CSR_WR (MOT_FEC_SDMA_OFF, MOT_FEC_SDMA_DATA_BE |
- MOT_FEC_SDMA_BD_BE |
- MOT_FEC_SDMA_FUNC_0);
- MOT_FEC_CSR_WR (MOT_FEC_RX_FR_OFF, MOT_FEC_BUF_V_LEN);
- return (OK);
- }
- /**************************************************************************
- *
- * motFecPostPhyConfig - configure the chip after the PHY is initialized
- *
- * This routine programs all the CSRs that are concerned with the
- * PHY configuration.
- *
- * SEE ALSO: motFecPrePhyConfig()
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecPostPhyConfig
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- UINT32 rxCtrlVal; /* holder for the rx CSR value */
- UINT32 txCtrlVal; /* holder for the tx CSR value */
- /* get the proper value for the rx CSR and program it accordingly */
- if (motFecRxCtrlRegValGet (pDrvCtrl, &rxCtrlVal) == ERROR)
- return (ERROR);
- MOT_FEC_CSR_WR (MOT_FEC_RX_CTRL_OFF, rxCtrlVal);
- /*
- * get the proper value for the tx CSR and program it accordingly.
- * At this point we do not have to check whether the FEC is
- * active, as we already know.
- */
- if (motFecTxCtrlRegValGet (pDrvCtrl, &txCtrlVal) == ERROR)
- return (ERROR);
- MOT_FEC_CSR_WR (MOT_FEC_TX_CTRL_OFF, txCtrlVal);
- /*
- * disable the MII management interface, as we do not
- * need to change the MII setting at any time.
- */
- MOT_FEC_CSR_WR (MOT_FEC_MII_SPEED_OFF, MOT_FEC_MII_MAN_DIS);
- return (OK);
- }
- /**************************************************************************
- *
- * motFecRxCtrlRegValGet - get the proper value for the receive CSR
- *
- * This routine finds out the proper value to be programmed in the
- * receive CSR by looking at some of the user/driver flags. It deals
- * with options like promiscous mode, full duplex, loopback and
- * the physical serial interface.
- *
- * This routine does not program the receive CSR.
- *
- * SEE ALSO: motFecTxCtrlRegValGet(), motFecPostPhyConfig()
- *
- * RETURNS: OK or ERROR if rxCtrlVal is NULL pointer.
- */
- LOCAL STATUS motFecRxCtrlRegValGet
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT32 * rxCtrlVal /* holder for the rx CSR value */
- )
- {
- /* Initialize holder for the rx CSR value */
- if (rxCtrlVal == NULL)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecRxCtrlRegValGet: rxCtrlVal is NULL n"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- else
- *rxCtrlVal = 0;
- /* deal with promiscous mode */
- if (MOT_FEC_FLAG_ISSET (MOT_FEC_PROM))
- {
- *rxCtrlVal |= MOT_FEC_RX_CTRL_PROM;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecRxCtrlRegValGet: promiscous mode n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *rxCtrlVal &= ~MOT_FEC_RX_CTRL_PROM;
- /*
- * enable full duplex mode if the PHY was configured
- * to work in full duplex mode.
- */
- if (MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_FD))
- {
- *rxCtrlVal &= ~MOT_FEC_RX_CTRL_DRT;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecRxCtrlRegValGet: full duplex n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *rxCtrlVal |= MOT_FEC_RX_CTRL_DRT;
- /*
- * enable the 7-wire serial interface if the
- * related user flag was set.
- */
- if (MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_SER))
- {
- *rxCtrlVal &= ~MOT_FEC_RX_CTRL_MII;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecRxCtrlRegValGet: serial interface n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *rxCtrlVal |= MOT_FEC_RX_CTRL_MII;
- /*
- * if the user wishes to go in loopback mode,
- * enable it. Also enable receiver and transmitter
- * to work independently from each other.
- */
- if (MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_LOOP))
- {
- *rxCtrlVal |= MOT_FEC_RX_CTRL_LOOP;
- *rxCtrlVal &= ~MOT_FEC_RX_CTRL_DRT;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecRxCtrlRegValGet: loopback mode n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *rxCtrlVal &= ~MOT_FEC_RX_CTRL_LOOP;
- return (OK);
- }
- /**************************************************************************
- *
- * motFecTxCtrlRegValGet - get the proper value for the transmit CSR
- *
- * This routine finds out the proper value to be programmed in the
- * transmit CSR by looking at some of the user/driver flags. It deals
- * with options like full duplex mode and the heartbeat control.
- *
- * This routine does not program the transmit CSR.
- *
- * RETURNS: OK or ERROR if txCtrlVal is NULL pointer.
- *
- * SEE ALSO: motFecRxCtrlRegValGet(), motFecPostPhyConfig()
- *
- */
- LOCAL STATUS motFecTxCtrlRegValGet
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT32 * txCtrlVal /* holder for the tx CSR value */
- )
- {
- /* Initialize holder for the tx CSR value */
- if (txCtrlVal == NULL)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecTxCtrlRegValGet: txCtrlVal is NULL n"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- else
- *txCtrlVal = 0;
- /* deal with the heartbeat control */
- if (MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_HBC))
- {
- *txCtrlVal |= MOT_FEC_TX_CTRL_HBC;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecTxCtrlRegValGet: heartbeat control n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *txCtrlVal &= ~MOT_FEC_TX_CTRL_HBC;
- /*
- * enable full duplex mode if the PHY was configured
- * to work in full duplex mode.
- */
- if (MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_FD))
- {
- *txCtrlVal |= MOT_FEC_TX_CTRL_FD;
- MOT_FEC_LOG (MOT_FEC_DBG_START,
- ("motFecTxCtrlRegValGet: full duplex n"),
- 0, 0, 0, 0, 0, 0);
- }
- else
- *txCtrlVal &= ~MOT_FEC_TX_CTRL_FD;
- return (OK);
- }
- /**************************************************************************
- *
- * motFecAddrRegValGet - get the values to program in CSR0 and CSR1
- *
- * This routine finds out the proper values to be programmed in the
- * two 32-bit perfect match address registers (CSR0 and CSR1).
- *
- * This routine does not program neither CSR0 nor CSR1.
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecAddrRegValGet
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT32 * csr0Val, /* holder for the CSR0 value */
- UINT32 * csr1Val /* holder for the CSR1 value */
- )
- {
- char * enetAddr = NULL; /* holder for the enet address */
- /*
- * programming the enet address is done by writing
- * its low-order 4 bytes to CSR0 and its high-order
- * 2 bytes to the MSW of CSR1.
- */
- enetAddr = (char *) MOT_FEC_ADDR_GET (&pDrvCtrl->endObj);
- *csr0Val = * (UINT32 *) enetAddr;
- /*
- * this way we'll zero-out the low-order 16 bits in the
- * CSR, as recommended in the documentation.
- */
- *csr1Val = ((UINT32) (* (UINT16 *) (enetAddr + 4)) << 16);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecIoctl - interface ioctl procedure
- *
- * Process an interface ioctl request.
- *
- * RETURNS: OK, or ERROR.
- */
- LOCAL int motFecIoctl
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- int cmd, /* command to process */
- caddr_t data /* pointer to data */
- )
- {
- int error = OK;
- INT8 savedFlags;
- long value;
- END_OBJ * pEndObj=&pDrvCtrl->endObj;
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL,
- ("Ioctl unit=0x%x cmd=%d data=0x%xn"),
- pDrvCtrl->unit, cmd, (int)data, 0, 0, 0);
- switch (cmd)
- {
- case EIOCSADDR:
- if (data == NULL)
- error = EINVAL;
- else
- {
- UINT32 csr0Val; /* holder for the CSR0 value */
- UINT32 csr1Val; /* holder for the CSR1 value */
- /* Copy and install the new address */
- bcopy ((char *) data,
- (char *) MOT_FEC_ADDR_GET (&pDrvCtrl->endObj),
- MOT_FEC_ADDR_LEN_GET (&pDrvCtrl->endObj));
- /* stop the FEC */
- if (motFecStop (pDrvCtrl) != OK)
- return (ERROR);
- /* program the individual enet address */
- if (motFecAddrRegValGet (pDrvCtrl, &csr0Val, &csr1Val) != OK)
- return (ERROR);
- MOT_FEC_CSR_WR (MOT_FEC_ADDR_L_OFF, csr0Val);
- MOT_FEC_CSR_WR (MOT_FEC_ADDR_H_OFF, csr1Val);
- /* restart the FEC */
- if (motFecStart (pDrvCtrl) != OK)
- return (ERROR);
- }
- break;
- case EIOCGADDR:
- if (data == NULL)
- error = EINVAL;
- else
- bcopy ((char *) MOT_FEC_ADDR_GET (&pDrvCtrl->endObj),
- (char *) data,
- MOT_FEC_ADDR_LEN_GET (&pDrvCtrl->endObj));
- break;
- case EIOCSFLAGS:
- value = (long) data;
- if (value < 0)
- {
- value = -value;
- value--;
- END_FLAGS_CLR (pEndObj, value);
- }
- else
- END_FLAGS_SET (pEndObj, value);
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("endFlags=0x%x n"),
- END_FLAGS_GET(pEndObj),
- 0, 0, 0, 0, 0);
- /* handle IFF_PROMISC */
- savedFlags = MOT_FEC_FLAG_GET();
- if (END_FLAGS_ISSET (IFF_PROMISC))
- {
- MOT_FEC_FLAG_SET (MOT_FEC_PROM);
- if ((MOT_FEC_FLAG_GET () != savedFlags) &&
- (END_FLAGS_GET (pEndObj) & IFF_UP))
- {
- UINT32 rxCtrlVal;
- /* config down */
- END_FLAGS_CLR (pEndObj, IFF_UP | IFF_RUNNING);
- /* program the rx CSR to promiscous mode */
- if (motFecRxCtrlRegValGet (pDrvCtrl, &rxCtrlVal) == ERROR)
- return (ERROR);
- MOT_FEC_CSR_WR (MOT_FEC_RX_CTRL_OFF, rxCtrlVal);
- /* config up */
- END_FLAGS_SET (pEndObj, IFF_UP | IFF_RUNNING);
- }
- }
- else
- MOT_FEC_FLAG_CLEAR (MOT_FEC_PROM);
- /* handle IFF_MULTICAST */
- if (END_FLAGS_GET(pEndObj) & (IFF_MULTICAST))
- MOT_FEC_FLAG_SET (MOT_FEC_MCAST);
- else
- MOT_FEC_FLAG_CLEAR (MOT_FEC_MCAST);
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("EIOCSFLAGS: 0x%x: 0x%xn"),
- pEndObj->flags, savedFlags,
- 0, 0, 0, 0);
- break;
- case EIOCGFLAGS:
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("EIOCGFLAGS: 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:
- error = motFecMCastAddrAdd (pDrvCtrl, (char *) data);
- break;
- case EIOCMULTIDEL:
- error = motFecMCastAddrDel (pDrvCtrl, (char *) data);
- break;
- case EIOCMULTIGET:
- error = motFecMCastAddrGet (pDrvCtrl, (MULTI_TABLE *) data);
- break;
- case EIOCPOLLSTART:
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("IOCTL call motFecPollStartn"),
- 0, 0, 0, 0, 0, 0);
- motFecPollStart (pDrvCtrl);
- break;
- case EIOCPOLLSTOP:
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("IOCTL call motFecPollStopn"),
- 0, 0, 0, 0, 0, 0);
- motFecPollStop (pDrvCtrl);
- break;
- case EIOCGMIB2:
- if (data == NULL)
- error=EINVAL;
- else
- bcopy ((char *) &pEndObj->mib2Tbl, (char *) data,
- sizeof (pEndObj->mib2Tbl));
- break;
- default:
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("INVALID IO COMMAND!! n"),
- 0, 0, 0, 0, 0, 0);
- error = EINVAL;
- }
- return (error);
- }
- /**************************************************************************
- *
- * motFecPhyInit - initialize and configure the PHY devices
- *
- * This routine scans, initializes and configures PHY devices.
- *
- * This routine is called from the driver's Start routine to
- * perform media inialization and configuration. To access the PHY
- * device, it uses the routines: motFecPhyRead(), motFecPhyWrite(),
- * which exploit the support to the MII interface built-in in the
- * FEC.
- *
- * Before it attempts to bring the link up, this routine checks the
- * phyInfo structure in the driver control structure for a device that
- * needs to be electrically isolated by the MII interface; if a valid
- * device is found it is isolated.
- *
- * The routine then scans for all possible PHY addresses in the range 0-31,
- * checking for an MII-compliant PHY, and attempts to establish a
- * valid link for it. If none is found, ERROR is returned.
- * Typically PHYs are scanned from address 0, but if the user specifies
- * an alternative start PHY address via the parameter phyAddr in the
- * driver's load string, all (32) PHYs are scanned in order starting
- * with the specified PHY address.
- *
- * This routine offers two strategies to select a PHY and establish a
- * valid link. The default strategy is to use the standard 802.3 style
- * auto-negotiation, where both link partners negotiate all their
- * technology abilities at the same time, and the highest common
- * denominator ability is chosen. Before the auto-negotiation
- * is started, the next-page exchange mechanism is disabled.
- *
- * The user can prevent the PHY from negotiating certain abilities via
- * userFlags -- <MOT_FEC_USR_PHY_NO_FD>, <MOT_FEC_USR_PHY_NO_100>,
- * <MOT_FEC_USR_PHY_NO_HD>, and <MOT_FEC_USR_PHY_NO_10>. When
- * <MOT_FEC_USR_PHY_NO_FD> is specified, full duplex will not be
- * negotiated; when <MOT_FEC_USR_PHY_NO_HD> is specified half duplex
- * will not be negotiated, when <MOT_FEC_USR_PHY_NO_100> is specified,
- * 100Mbps ability will not negotiated; when <MOT_FEC_USR_PHY_NO_10>
- * 10Mbps ability will not be negotiated.
- *
- * When <MOT_FEC_USR_PHY_TBL> is set in the user flags, the BSP specific
- * table <motFecPhyAnOrderTbl> is used to obtain the list, and the order
- * of technology abilities to be negotiated.
- * The entries in this table are ordered such that entry 0 is the
- * highest priority, entry 1 in next and so on. Entries in this table
- * may be repeated, and multiple technology abilities can
- * be OR'd to create a single entry. If a PHY cannot support a
- * ability in an entry, that entry is ignored. Currently, only one
- * table per driver is supported.
- *
- * If no PHY provides a valid link, the PHYs are scanned again in the
- * same order, and the first PHY that supports the default abilities
- * defined in the <phyDefMode> of the Load string will be selected,
- * regardless of the link status.
- *
- * RETURNS: OK or ERROR if the PHY could not be initialised.
- *
- */
- LOCAL STATUS motFecPhyInit
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- UINT8 phyAddr; /* address of a PHY */
- UINT8 isoPhyAddr; /* address of a PHY to be isolated */
- UINT8 ix; /* an index */
- int retVal; /* convenient holder for return value */
- BOOL found = FALSE; /* no PHY has been found */
- /* isolate the PHY in the phyInfo structure */
- isoPhyAddr = pDrvCtrl->phyInfo->isoPhyAddr;
- if (isoPhyAddr != MOT_FEC_PHY_NULL)
- {
- /* check the PHY is there */
- retVal = motFecMiiProbe (pDrvCtrl, isoPhyAddr);
- if (retVal == ERROR)
- return (ERROR);
- if (retVal == OK)
- if (motFecMiiIsolate (pDrvCtrl, isoPhyAddr) == ERROR)
- return (ERROR);
- }
- /*
- * there may be several PHYs, with distinct logical addresses
- * and these can be as high as 31. Start with the one the
- * user suggested and, in case of failure, scan the whole range.
- */
- for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)
- {
- phyAddr = (ix + pDrvCtrl->phyInfo->phyAddr) % MII_MAX_PHY_NUM;
- /* check this is not the isolated PHY */
- if (phyAddr == isoPhyAddr)
- continue;
- /* check the PHY is there */
- retVal = motFecMiiProbe (pDrvCtrl, phyAddr);
- if (retVal == ERROR)
- return (ERROR);
- if (retVal == MOT_FEC_PHY_NULL)
- continue;
- found = TRUE;
- /* run some diagnostics */
- if (motFecMiiDiag (pDrvCtrl, phyAddr) != OK)
- return (ERROR);
- /*
- * start the auto-negotiation process,
- * unless the user dictated the contrary.
- */
- if (pDrvCtrl->phyInfo->phyFlags & MOT_FEC_PHY_AUTO)
- if (motFecMiiAnRun (pDrvCtrl, phyAddr) == OK)
- return (OK);
- /*
- * the auto-negotiation process did not succeed
- * in establishing a valid link: try to do it
- * manually, enabling as high priority abilities
- * as you can.
- */
- if (motFecMiiModeForce (pDrvCtrl, phyAddr) == OK)
- return (OK);
- /*
- * Trying to force a specific operating mode was
- * unsuccessful, too. Force default parameters:
- * field phyDefMode in the PHY info structure.
- */
- if (motFecMiiDefForce (pDrvCtrl, phyAddr) == OK)
- return (OK);
- }
- if (!(found))
- return (ERROR);
- /* if we're here, none of the PHYs could be initialized */
- logMsg ("motFecPhyInit check cable connection n",
- 0, 0, 0, 0, 0, 0);
- /* try to establish a default operating mode, do not check the link! */
- for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)
- {
- phyAddr = (ix + pDrvCtrl->phyInfo->phyAddr) % MII_MAX_PHY_NUM;
- /* check this is not the isolated PHY */
- if (phyAddr == isoPhyAddr)
- continue;
- /* check the PHY is there */
- retVal = motFecMiiProbe (pDrvCtrl, phyAddr);
- if (retVal == ERROR)
- return (ERROR);
- if (retVal == MOT_FEC_PHY_NULL)
- continue;
- /* return OK even if the link is not up */
- retVal = motFecMiiDefForce (pDrvCtrl, phyAddr);
- if (retVal == ERROR)
- return (ERROR);
- /* if the PHY does not have the default abilities... */
- if (retVal == MOT_FEC_PHY_NO_ABLE)
- continue;
- return (OK);
- }
- return (ERROR);
- }
- /**************************************************************************
- *
- * motFecMiiProbe - probe the PHY device
- *
- * This routine probes the PHY device by reading its control register.
- *
- * RETURNS: OK, ERROR in case of fatal errors, or MOT_FEC_PHY_NULL, if
- * the device was not found.
- */
- LOCAL STATUS motFecMiiProbe
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* the PHY being read */
- )
- {
- UINT8 regAddr; /* the PHY's register being read */
- UINT16 data; /* data to be written to the control reg */
- regAddr = MII_CTRL_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &data) != OK)
- return (ERROR);
- if (data == 0xffff)
- return (MOT_FEC_PHY_NULL);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiProbe... endsn"),
- 0, 0, 0, 0, 0, 0);
- return (OK);
- }
- /**************************************************************************
- *
- * motFecPhyPreInit - initialize some fields in the phy info structure
- *
- * This routine initializes some fields in the phy info structure,
- * for use of the motFecPhyInit() routine.
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecPhyPreInit
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- /* set some default values */
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_10MBS;
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_HD;
- pDrvCtrl->phyInfo->phyFlags = 0;
- /* handle some user-to-physical flags */
- if (!(MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_NO_AN)))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_AUTO);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_AUTO);
- if (MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_TBL))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_TBL);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_TBL);
- if (!(MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_NO_100)))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_100);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_100);
- if (!(MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_NO_FD)))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_FD);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_FD);
- if (!(MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_NO_10)))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_10);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_10);
- if (!(MOT_FEC_USR_FLAG_ISSET (MOT_FEC_USR_PHY_NO_HD)))
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_HD);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_HD);
- /* mark it as pre-initilized */
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_PRE_INIT);
- return (OK);
- }
- /**************************************************************************
- *
- * motFecMiiRead - read the MII register
- *
- * This routine reads the register specified by <phyReg> in the PHY device
- * whose address is <phyAddr>. The value read is returned in the location
- * pointed to by <retVal>.
- *
- * SEE ALSO: motFecMiiWrite()
- *
- * RETURNS: OK, always.
- *
- */
- LOCAL STATUS motFecMiiRead
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr, /* the PHY being read */
- UINT8 regAddr, /* the PHY's register being read */
- UINT16 *retVal /* the value read */
- )
- {
- UINT32 reg; /* convenient holder for the PHY register */
- UINT32 phy; /* convenient holder for the PHY */
- UINT32 miiVal; /* value written/read to/from the FEC's MII register */
- /*
- * reading from any PHY's register is done by properly
- * programming the FEC's MII data register.
- */
- reg = regAddr << MOT_FEC_MII_RA_SHIFT;
- phy = phyAddr << MOT_FEC_MII_PA_SHIFT;
- miiVal = (MOT_FEC_MII_ST | MOT_FEC_MII_OP_RD | MOT_FEC_MII_TA |
- phy | reg);
- MOT_FEC_CSR_WR (MOT_FEC_MII_DATA_OFF, miiVal);
- /* wait for the related interrupt */
- MOT_FEC_MII_SEM_TAKE;
- /* it's now safe to read the PHY's register */
- MOT_FEC_CSR_RD (MOT_FEC_MII_DATA_OFF, miiVal);
- *retVal = (UINT16) miiVal;
- return (OK);
- }
- /**************************************************************************
- *
- * motFecMiiWrite - write to the MII register
- *
- * This routine writes the register specified by <phyReg> in the PHY device,
- * whose address is <phyAddr>, with the 16-bit value included in <data>.
- *
- * SEE ALSO: motFecMiiRead()
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecMiiWrite
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr, /* the PHY being written */
- UINT8 regAddr, /* the PHY's register being written */
- UINT16 data /* the value written to the PHY register */
- )
- {
- UINT32 reg; /* convenient holder for the PHY register */
- UINT32 phy; /* convenient holder for the PHY */
- UINT32 miiVal; /* value written to the mii reg */
- reg = regAddr << MOT_FEC_MII_RA_SHIFT;
- phy = phyAddr << MOT_FEC_MII_PA_SHIFT;
- miiVal = (MOT_FEC_MII_ST | MOT_FEC_MII_OP_WR | MOT_FEC_MII_TA |
- phy | reg | data);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiWrite reg=%d n
- PHY=%d data=0x%xn"),
- regAddr, phyAddr, miiVal, 0, 0, 0);
- MOT_FEC_CSR_WR (MOT_FEC_MII_DATA_OFF, miiVal);
- /* wait for the related interrupt */
- MOT_FEC_MII_SEM_TAKE;
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiDiag - run some diagnostics
- *
- * This routine runs some diagnostics on the PHY whose address is
- * specified in the parameter <phyAddr>.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiDiag
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT16 data; /* data to be written to the control reg */
- UINT8 regAddr; /* PHY register */
- UINT16 ix = 0; /* a counter */
- /* reset the PHY */
- regAddr = MII_CTRL_REG;
- data = MII_CR_RESET;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, data) != OK)
- return (ERROR);
- while (ix++ < MOT_FEC_PHY_MAX_WAIT)
- {
- taskDelay (1);
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &data) != OK)
- return (ERROR);
- if (!(data & MII_CR_RESET))
- break;
- }
- if (ix >= MOT_FEC_PHY_MAX_WAIT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiDiag reset failn"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- /* isolate the PHY */
- if (motFecMiiIsolate (pDrvCtrl, phyAddr) == ERROR)
- return (ERROR);
- /* re-enable the chip */
- data = MII_CR_NORM_EN;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, data) != OK)
- return (ERROR);
- /* check isolate bit is deasserted */
- ix = 0;
- while (ix++ < MOT_FEC_PHY_MAX_WAIT)
- {
- taskDelay (1);
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &data) != OK)
- return (ERROR);
- if (!(data & MII_CR_ISOLATE))
- break;
- }
- if (ix >= MOT_FEC_PHY_MAX_WAIT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiDiag de-isolate failn"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiDiag... endsn"),
- 0, 0, 0, 0, 0, 0);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiIsolate - isolate the PHY device
- *
- * This routine isolates the PHY device whose address is specified in
- * the parameter <isoPhyAddr>.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiIsolate
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 isoPhyAddr /* address of a PHY to be isolated */
- )
- {
- UINT8 regAddr; /* PHY register */
- UINT16 ix = 0; /* a counter */
- UINT16 data; /* data to be written to the control reg */
- if (isoPhyAddr == MOT_FEC_PHY_NULL)
- return (OK);
- data = MII_CR_ISOLATE;
- regAddr = MII_CTRL_REG;
- if (motFecMiiWrite (pDrvCtrl, isoPhyAddr, regAddr, data) != OK)
- return (ERROR);
- /* check isolate bit is asserted */
- ix = 0;
- while (ix++ < MOT_FEC_PHY_MAX_WAIT)
- {
- taskDelay (1);
- if (motFecMiiRead (pDrvCtrl, isoPhyAddr, regAddr, &data) != OK)
- return (ERROR);
- if ((data & MII_CR_ISOLATE))
- break;
- }
- if (ix >= MOT_FEC_PHY_MAX_WAIT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiIsolate failn"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiIsolate... endsn"),
- 0, 0, 0, 0, 0, 0);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiAnRun - run the auto-negotiation process
- *
- * This routine runs the auto-negotiation process for the PHY whose
- * address is specified in the parameter <phyAddr>, without enabling the
- * next page function. It also calls motFecMiiAnCheck() to ensure
- * a valid link has been established.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiAnRun
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT8 regAddr; /* PHY register */
- UINT16 phyAds; /* holder for the PHY ads register value */
- UINT16 status; /* PHY auto-negotiation status */
- UINT16 ix; /* a counter */
- int retVal; /* holder for return value */
- regAddr = MII_AN_ADS_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyAds) != OK)
- return (ERROR);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnRun phyAds=0x%xn"),
- phyAds, 0, 0, 0, 0, 0);
- /* disable the next page function */
- phyAds &= (~MII_NP_NP);
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, phyAds)
- != OK)
- return (ERROR);
- /* Read ANER to clear status from previous operations */
- regAddr = MII_AN_EXP_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &status) != OK)
- return (ERROR);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnRun expStat=0x%xn"),
- status, 0, 0, 0, 0, 0);
- /* Read ANAR */
- regAddr = MII_AN_ADS_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyAds) != OK)
- return (ERROR);
- /* store the current registers values */
- pDrvCtrl->phyInfo->miiRegs.phyAds = phyAds;
- /*
- * start the auto-negotiation process, possibly
- * following the order the user dictated.
- */
- for (ix = 0; ; ix++)
- {
- if (MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_TBL))
- {
- /* check we're not at the end of the user table */
- if ((motFecPhyAnOrderTbl [ix]) == -1)
- return (ERROR);
- /* just negotiate one ability at a time */
- phyAds &= ~MII_TECH_MASK;
- /* translate user settings */
- phyAds |= miiAnLookupTbl [(motFecPhyAnOrderTbl [ix])];
- /* check the PHY has the desidered ability */
- if (!(phyAds & pDrvCtrl->phyInfo->miiRegs.phyAds))
- continue;
- /* set the ANAR accordingly */
- regAddr = MII_AN_ADS_REG;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, phyAds)
- != OK)
- return (ERROR);
- }
- else
- {
- /* check the PHY flags and possibly mask some abilities off */
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_FD)))
- phyAds &= ~(MII_TECH_10BASE_FD | MII_TECH_100BASE_TX_FD
- | MII_TECH_100BASE_T4);
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_HD)))
- phyAds &= ~(MII_TECH_10BASE_T | MII_TECH_100BASE_TX);
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_100)))
- phyAds &= ~(MII_TECH_100BASE_TX | MII_TECH_100BASE_TX_FD
- | MII_TECH_100BASE_T4);
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_10)))
- phyAds &= ~(MII_TECH_10BASE_T | MII_TECH_10BASE_FD);
- /* Write ANAR */
- regAddr = MII_AN_ADS_REG;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, phyAds) != OK)
- return (ERROR);
- /* store the current registers values */
- pDrvCtrl->phyInfo->miiRegs.phyAds = phyAds;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnRun phyAds=0x%xn"),
- phyAds, 0, 0, 0, 0, 0);
- }
- /*
- * start the auto-negotiation process: return
- * only in case of fatal error.
- */
- retVal = motFecMiiAnStart (pDrvCtrl, phyAddr);
- if (retVal == ERROR)
- return (ERROR);
- /*
- * in case of failure, we return only if we're using
- * the standard auto-negotiation process.
- */
- if (retVal == MII_AN_FAIL)
- {
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_TBL)))
- return (retVal);
- else
- continue;
- }
- /* check the negotiation was successful */
- if (motFecMiiAnCheck (pDrvCtrl, phyAddr) == OK)
- return (OK);
- /*
- * we are here if the negotiation went wong:
- * if the user did not force any priority order,
- * we return ERROR, as all the PHY abilities
- * were negotiated at once.
- */
- if (!(MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_TBL)))
- return (ERROR);
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiAnStart - start the auto-negotiation process
- *
- * This routine starts the auto-negotiation process for the PHY whose
- * address is specified in the parameter <phyAddr>.
- *
- * RETURNS: OK, ERROR in case of fatal errors or MII_AN_FAIL, if the
- * auto-negotiation did not complete within a reasonable amount of time.
- */
- LOCAL STATUS motFecMiiAnStart
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT16 data; /* data to be written to the control reg */
- UINT8 regAddr; /* PHY register */
- UINT16 phyStatus; /* holder for the PHY status */
- UINT16 ix = 0; /* a counter */
- regAddr = MII_STAT_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- /* check the PHY has this ability */
- if ((phyStatus & MII_SR_AUTO_SEL) != MII_SR_AUTO_SEL)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnStart phy not n
- auto neg capablen"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- /* restart the auto-negotiation process */
- regAddr = MII_CTRL_REG;
- data = (MII_CR_RESTART | MII_CR_AUTO_EN);
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, data) != OK)
- return (ERROR);
- /* save status info */
- pDrvCtrl->phyInfo->miiRegs.phyCtrl = data;
- /* let's check the PHY status */
- regAddr = MII_STAT_REG;
- /* spin until it is done */
- do
- {
- taskDelay (1);
- if (ix++ == MOT_FEC_PHY_MAX_WAIT)
- break;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus)
- != OK)
- return (ERROR);
- } while ((phyStatus & MII_SR_AUTO_NEG) != MII_SR_AUTO_NEG);
- if (ix >= MOT_FEC_PHY_MAX_WAIT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII,
- ("motFecMiiAnStart auto neg failn"),
- 0, 0, 0, 0, 0, 0);
- return (MII_AN_FAIL);
- }
- else
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII,
- ("motFecMiiAnStart auto neg done phyStat=0x%xn"),
- phyStatus, 0, 0, 0, 0, 0);
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiBasicCheck - run a basic check on the PHY status register
- *
- * This routine runs a basic check on the PHY status register to
- * ensure a valid link has been established and no faults have been
- * detected.
- *
- * RETURNS: OK, MII_STAT_FAIL, if an error was reported in the PHY's
- * status register, or ERROR, in case of unrecoverable errors.
- */
- LOCAL STATUS motFecMiiBasicCheck
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT8 regAddr; /* PHY register */
- UINT16 phyStatus; /* holder for the PHY status */
- /* let's check the PHY status */
- regAddr = MII_STAT_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- if ((phyStatus & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS)
- {
- /* wait for a while */
- taskDelay (10);
- /* we need to read it twice, as this's a latched function */
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- if ((phyStatus & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiBasicCheck n
- phy stat=0x%xn"),
- phyStatus, 0, 0, 0, 0, 0);
- return (MII_STAT_FAIL);
- }
- }
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiBasicCheckn
- Link up! status=0x%xn"),
- phyStatus, 0, 0, 0, 0, 0);
- /* check for remote fault condition */
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- if ((phyStatus & MII_SR_REMOTE_FAULT) == MII_SR_REMOTE_FAULT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiBasicCheck remote faultn"),
- 0, 0, 0, 0, 0, 0);
- return (MII_STAT_FAIL);
- }
- /* store the current registers values */
- pDrvCtrl->phyInfo->miiRegs.phyStatus = phyStatus;
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiAnCheck - check the auto-negotiation process result
- *
- * This routine checks the auto-negotiation process has completed
- * successfully and no faults have been detected by any of the PHYs
- * engaged in the process.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiAnCheck
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT8 regAddr; /* PHY register */
- UINT16 phyAds; /* PHY advertisement register value */
- UINT16 phyPrtn; /* PHY partner ability register value */
- UINT16 phyExp; /* PHY expansion register value */
- UINT16 negAbility; /* abilities after negotiation */
- int retVal; /* convenient holder for return value */
- /* run a check on the status bits of basic registers only */
- retVal = motFecMiiBasicCheck (pDrvCtrl, phyAddr);
- if (retVal != OK)
- return (retVal);
- /* we know the auto-negotiation process has terminated */
- regAddr = MII_AN_EXP_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyExp) != OK)
- return (ERROR);
- /* check for faults detected by the parallel function */
- if ((phyExp & MII_EXP_FAULT) == MII_EXP_FAULT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck:n
- fault expStat=0x%xn"),
- phyExp, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- /* check for remote faults */
- regAddr = MII_AN_PRTN_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyPrtn) != OK)
- return (ERROR);
- if ((phyPrtn & MII_BP_FAULT) == MII_BP_FAULT)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck partner stat=0x%xn"),
- phyPrtn, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- regAddr = MII_AN_ADS_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyAds) != OK)
- return (ERROR);
- /* store the current registers values */
- pDrvCtrl->phyInfo->miiRegs.phyAds = phyAds;
- pDrvCtrl->phyInfo->miiRegs.phyPrtn = phyPrtn;
- pDrvCtrl->phyInfo->miiRegs.phyExp = phyExp;
- /* find out the max common abilities */
- negAbility = phyPrtn & phyAds & MII_TECH_MASK;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck phyAds=0x%xn
- phyPrtn=0x%x common=0x%x phyExp=0x%xn"),
- phyAds,
- phyPrtn,
- negAbility,
- phyExp, 0, 0);
- if (negAbility & MII_TECH_100BASE_TX_FD)
- {
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_100MBS;
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_FD;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck speed=%d mode=%sn"),
- pDrvCtrl->phyInfo->phySpeed,
- (int) "full duplex", 0, 0, 0, 0);
- }
- else if ((negAbility & MII_TECH_100BASE_T4) ||
- (negAbility & MII_TECH_100BASE_TX))
- {
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_100MBS;
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_HD;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck speed=%d mode=%sn"),
- pDrvCtrl->phyInfo->phySpeed,
- (int) "half duplex", 0, 0, 0, 0);
- }
- else if (negAbility & MII_TECH_10BASE_FD)
- {
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_10MBS;
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_FD;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck speed=%d mode=%sn"),
- pDrvCtrl->phyInfo->phySpeed,
- (int) "full duplex", 0, 0, 0, 0);
- }
- else if (negAbility & MII_TECH_10BASE_T)
- {
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_10MBS;
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_HD;
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck speed=%d mode=%sn"),
- pDrvCtrl->phyInfo->phySpeed,
- (int) "half duplex", 0, 0, 0, 0);
- }
- else
- {
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck fail!n"),
- 0, 0, 0, 0, 0, 0);
- return (ERROR);
- }
- /* handle some flags */
- if (pDrvCtrl->phyInfo->phySpeed == MOT_FEC_100MBS)
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_100);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_100);
- if (pDrvCtrl->phyInfo->phyMode == MOT_FEC_PHY_FD)
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_FD);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_FD);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiAnCheck OKn"),
- 0, 0, 0, 0, 0, 0);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiModeForce - force an operating mode for the PHY
- *
- * This routine forces an operating mode for the PHY whose address is
- * specified in the parameter <phyAddr>. It also calls motFecMiiBasicCheck()
- * to ensure a valid link has been established.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiModeForce
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT16 data; /* data to be written to the control reg */
- UINT8 regAddr; /* PHY register */
- UINT16 phyStatus; /* holder for the PHY status */
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiModeForce n"),
- 0, 0, 0, 0, 0, 0);
- /* find out what abilities the PHY features */
- regAddr = MII_STAT_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- /*
- * force as a high priority as possible operating
- * mode, not overlooking what the user dictated.
- */
- data = MII_CR_NORM_EN;
- if ((phyStatus & (MII_SR_TX_FULL_DPX | MII_SR_TX_HALF_DPX))
- && (MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_100)))
- {
- data |= MII_CR_100;
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_100MBS;
- }
- if ((phyStatus & (MII_SR_TX_FULL_DPX | MII_SR_10T_FULL_DPX | MII_SR_T4))
- && (MOT_FEC_PHY_FLAGS_ISSET (MOT_FEC_PHY_FD)))
- {
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_FD;
- data |= MII_CR_FDX;
- }
- pDrvCtrl->phyInfo->miiRegs.phyCtrl = data;
- regAddr = MII_CTRL_REG;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, data) != OK)
- return (ERROR);
- /* run a check on the status bits of basic registers only */
- if (motFecMiiBasicCheck (pDrvCtrl, phyAddr) != OK)
- return (ERROR);
- /* handle some flags */
- if (pDrvCtrl->phyInfo->phySpeed == MOT_FEC_100MBS)
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_100);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_100);
- if (pDrvCtrl->phyInfo->phyMode == MOT_FEC_PHY_FD)
- MOT_FEC_PHY_FLAGS_SET (MOT_FEC_PHY_FD);
- else
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_FD);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiModeForce speed=%d mode=%dn"),
- pDrvCtrl->phyInfo->phySpeed,
- pDrvCtrl->phyInfo->phyMode,
- 0, 0, 0, 0);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecMiiDefForce - force a default operating mode for the PHY
- *
- * This routine forces a default operating mode for the PHY whose address is
- * specified in the parameter <phyAddr>. It also calls motFecMiiBasicCheck()
- * to ensure a valid link has been established.
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMiiDefForce
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT8 phyAddr /* address of a PHY */
- )
- {
- UINT16 data; /* data to be written to the control reg */
- UINT8 regAddr; /* PHY register */
- int retVal; /* convenient holder for return value */
- UINT16 phyStatus; /* holder for the PHY status */
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiDefForce n"),
- 0, 0, 0, 0, 0, 0);
- /* translate user settings */
- data = miiCrLookupTbl [(pDrvCtrl->phyInfo->phyDefMode)];
- /* find out what abilities the PHY features */
- regAddr = MII_STAT_REG;
- if (motFecMiiRead (pDrvCtrl, phyAddr, regAddr, &phyStatus) != OK)
- return (ERROR);
- if (data & MII_CR_100)
- {
- if (!(phyStatus & (MII_SR_TX_HALF_DPX
- | MII_SR_TX_FULL_DPX
- | MII_SR_T4)))
- return (MOT_FEC_PHY_NO_ABLE);
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_100MBS;
- }
- else
- {
- if (!(phyStatus & (MII_SR_10T_HALF_DPX
- | MII_SR_10T_FULL_DPX)))
- return (MOT_FEC_PHY_NO_ABLE);
- /* handle phy flags */
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_100);
- pDrvCtrl->phyInfo->phySpeed = MOT_FEC_10MBS;
- }
- if (data & MII_CR_FDX)
- {
- if (!(phyStatus & (MII_SR_10T_FULL_DPX
- | MII_SR_TX_FULL_DPX
- | MII_SR_T4)))
- return (MOT_FEC_PHY_NO_ABLE);
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_FD;
- }
- else
- {
- if (!(phyStatus & (MII_SR_10T_HALF_DPX
- | MII_SR_TX_HALF_DPX)))
- return (MOT_FEC_PHY_NO_ABLE);
- /* handle phy flags */
- MOT_FEC_PHY_FLAGS_CLEAR (MOT_FEC_PHY_FD);
- pDrvCtrl->phyInfo->phyMode = MOT_FEC_PHY_HD;
- }
- pDrvCtrl->phyInfo->miiRegs.phyCtrl = data;
- regAddr = MII_CTRL_REG;
- if (motFecMiiWrite (pDrvCtrl, phyAddr, regAddr, data) != OK)
- return (ERROR);
- /* run a check on the status bits of basic registers only */
- retVal = motFecMiiBasicCheck (pDrvCtrl, phyAddr);
- MOT_FEC_LOG (MOT_FEC_DBG_MII, ("motFecMiiDefForce speed=%d mode=%dn"),
- pDrvCtrl->phyInfo->phySpeed,
- pDrvCtrl->phyInfo->phyMode,
- 0, 0, 0, 0);
- return (retVal);
- }
- /*******************************************************************************
- *
- * motFecMCastAddrAdd - add a multicast address for the device
- *
- * This routine adds a multicast address to whatever the driver
- * is already listening for.
- *
- * SEE ALSO: motFecMCastAddrDel() motFecMCastAddrGet()
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMCastAddrAdd
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- char * pAddr /* address to be added */
- )
- {
- int retVal; /* convenient holder for return value */
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("motFecMCastAddrAdd addr = 0x%x 0x%xn
- 0x%x 0x%x 0x%x 0x%xn"),
- (int) (*pAddr + 0), (int) (*pAddr + 1),
- (int) (*pAddr + 2), (int) (*pAddr + 3),
- (int) (*pAddr + 4), (int) (*pAddr + 5));
- retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);
- if (retVal == ENETRESET)
- {
- pDrvCtrl->endObj.nMulti++;
- return (motFecHashTblAdd (pDrvCtrl, pAddr));
- }
- return ((retVal == OK) ? OK : ERROR);
- }
- /*****************************************************************************
- *
- * motFecMCastAddrDel - delete a multicast address for the device
- *
- * This routine deletes a multicast address from the current list of
- * multicast addresses.
- *
- * SEE ALSO: motFecMCastAddrAdd() motFecMCastAddrGet()
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMCastAddrDel
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- char * pAddr /* address to be deleted */
- )
- {
- int retVal; /* convenient holder for return value */
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("motFecMCastAddrDel addr = 0x%x 0x%xn
- 0x%x 0x%x 0x%x 0x%xn"),
- (int) (*pAddr + 0), (int) (*pAddr + 1),
- (int) (*pAddr + 2), (int) (*pAddr + 3),
- (int) (*pAddr + 4), (int) (*pAddr + 5));
- retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);
- if (retVal == ENETRESET)
- {
- pDrvCtrl->endObj.nMulti--;
- /* stop the FEC */
- if (motFecStop (pDrvCtrl) != OK)
- return (ERROR);
- /* populate the hash table */
- retVal = motFecHashTblPopulate (pDrvCtrl);
- /* restart the FEC */
- if (motFecStart (pDrvCtrl) != OK)
- return (ERROR);
- }
- return ((retVal == OK) ? OK : ERROR);
- }
- /*******************************************************************************
- *
- * motFecMCastAddrGet - get the current multicast address list
- *
- * This routine returns the current multicast address list in <pTable>
- *
- * SEE ALSO: motFecMCastAddrAdd() motFecMCastAddrDel()
- *
- * RETURNS: OK or ERROR.
- */
- LOCAL STATUS motFecMCastAddrGet
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- MULTI_TABLE *pTable /* table into which to copy addresses */
- )
- {
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("motFecMCastAddrGetn"),
- 0, 0, 0, 0, 0, 0);
- return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));
- }
- /*******************************************************************************
- *
- * motFecHashTblAdd - add an entry to the hash table
- *
- * This routine adds an entry to the hash table for the address pointed to
- * by <pAddr>.
- *
- * RETURNS: OK, or ERROR.
- */
- LOCAL STATUS motFecHashTblAdd
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- char * pAddr /* address to be added */
- )
- {
- UINT32 crcVal; /* convenient holder for the CRC value */
- UINT32 csrOldVal; /* current value in the hash register */
- UINT16 offset; /* offset into the Internal RAM */
- UINT32 csrVal; /* value to be written to the hash register */
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("motFecHashTblAdd addr = 0x%x 0x%xn
- 0x%x 0x%x 0x%x 0x%xn"),
- (int) (*pAddr + 0), (int) (*pAddr + 1),
- (int) (*pAddr + 2), (int) (*pAddr + 3),
- (int) (*pAddr + 4), (int) (*pAddr + 5));
- /* get the CRC for the given address */
- crcVal = motFecCrcGet (pAddr);
- /* get the value to be written to the proper hash register */
- if (motFecHashRegValGet (pDrvCtrl, crcVal, &csrVal, &offset) != OK)
- return (ERROR);
- MOT_FEC_LOG (MOT_FEC_DBG_IOCTL, ("motFecHashTblAdd hashReg=0x%xn"),
- (int) csrVal,
- 0, 0, 0, 0, 0);
- /*
- * write to the proper hash register: be careful not
- * to override the current value.
- */
- MOT_FEC_CSR_RD (offset, csrOldVal);
- MOT_FEC_CSR_WR (offset, (csrOldVal | csrVal));
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecHashTblPopulate - populate the hash table
- *
- * This routine populates the hash table with the entries found in the
- * multicast table. We have to reset the hash registers first, and
- * populate them again, as more than one address may be mapped to
- * the same bit.
- *
- * RETURNS: OK, or ERROR.
- */
- LOCAL STATUS motFecHashTblPopulate
- (
- DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- UINT32 crcVal; /* convenient holder for the CRC value */
- UINT16 offset; /* offset into the Internal RAM */
- UINT32 csrVal; /* value to be written to the hash register */
- UINT32 csrOldVal; /* current value in the hash register */
- ETHER_MULTI * mCastNode = NULL;
- /* reset the hash table registers first */
- MOT_FEC_CSR_WR (MOT_FEC_HASH_H_OFF, 0);
- MOT_FEC_CSR_WR (MOT_FEC_HASH_L_OFF, 0);
- /* scan the multicast address list */
- for (mCastNode = (ETHER_MULTI *) lstFirst (&pDrvCtrl->endObj.multiList);
- mCastNode != NULL;
- mCastNode = (ETHER_MULTI *) lstNext (&mCastNode->node))
- {
- /* get the CRC for the current address in the list */
- crcVal = motFecCrcGet ((char *) mCastNode->addr);
- /* get the value to be written to the proper hash register */
- if (motFecHashRegValGet (pDrvCtrl, crcVal, &csrVal, &offset) != OK)
- {
- return (ERROR);
- }
- /*
- * write to the proper hash register: be careful not
- * to override the current value.
- */
- MOT_FEC_CSR_RD (offset, csrOldVal);
- MOT_FEC_CSR_WR (offset, (csrOldVal | csrVal));
- }
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecCrcGet - compute the cyclic redoundant code
- *
- * This routine computes the 32-bit cyclic redoundant code (CRC) for the
- * 6-byte array pointed to by <pAddr>. For details on the polynomium used,
- * see:
- * .I "MPC860T Fast Ethernet Controller (Supplement to MPC860 User's Manual)"
- *
- * RETURNS: The 32-bit value representing the CRC.
- */
- LOCAL UINT32 motFecCrcGet
- (
- char * pAddr
- )
- {
- UINT32 crc = INIT_REFLECTED;
- UINT32 len = 6;
- while (len--)
- crc = crctable[(crc ^ *pAddr++) & 0xFFL] ^ (crc >> 8);
- return crc ^ XOROT;
- }
- /*******************************************************************************
- *
- * motFecHashRegValGet - get the value to be written to the hash register
- *
- * This routine computes the value to be written to the hash register
- * for the 4-byte value specified by <crcVal>. It also figures out which
- * of the two 32-bit hash register that value should be written to, and
- * returns its offset into the internal RAM in the variable pointed to
- * by <offset>.
- *
- * RETURNS: OK, always.
- */
- LOCAL STATUS motFecHashRegValGet
- (
- DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */
- UINT32 crcVal, /* CRC value */
- UINT32 * csrVal, /* value to be written to the hash register */
- UINT16 * offset /* offset into the Internal RAM */
- )
- {
- UINT32 hashIndex; /* index into the hash register */
- /*
- * bits 26-30 in the CRC value determine the index in the
- * hash register specified by bit 31.
- */
- hashIndex = ((crcVal & MOT_FEC_HASH_MASK) >> MOT_FEC_HASH_SHIFT);
- *csrVal = (0x80000000 >> hashIndex);
- /* It appears that starting at register 0x0E08 HASH_TABLE_HIGH high
- * order bit is really bit 0 of the hash table and low order bit
- * of 0x0E0C HASH_TABLE_LOW is bit 63 of the hash table.
- *
- * 0x0E0C HASH_TABLE_LOW [32:64] ==> hash_index[63:32]
- * 0x0E08 HASH_TABLE_HIGH [0 :31] ==> hash_index[31: 0]
- *
- * So this means that bit 31 of the CRC if 1 points to
- * the HASH_TABLE_LOW register, not the HASH_TABLE_HIGH.
- */
- *offset = (crcVal & 0x80000000) ? MOT_FEC_HASH_L_OFF : MOT_FEC_HASH_H_OFF;
- return (OK);
- }
- /*****************************************************************************
- *
- * motFecPollSend - transmit a packet in polled mode
- *
- * This routine is called by a user to try and send a packet on the
- * device. It sends a packet directly on the network, without having to
- * go through the normal process of queuing a packet on an output queue
- * and then waiting for the device to decide to transmit it.
- *
- * These routine should not call any kernel functions.
- *
- * SEE ALSO: motFecPollReceive()
- *
- * RETURNS: OK or EAGAIN.
- */
- LOCAL STATUS motFecPollSend
- (
- DRV_CTRL *pDrvCtrl, /* pointer to DRV_CTRL structure */
- M_BLK_ID pMblk /* pointer to the mBlk/cluster pair */
- )
- {
- UINT16 pktType = 0; /* packet type (unicast or multicast) */
- int retVal; /* holder for return value */
- char * pBuf = NULL; /* pointer to data to be sent */
- MOT_FEC_TBD_ID pTbd = NULL; /* pointer to the current ready TBD */
- int ix = 0; /* a counter */
- int len = 0; /* length of data to be sent */
- UINT16 tbdStatus; /* holder for the TBD status */
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("motFecPollSendn"), 0, 0, 0, 0, 0, 0);
- if (pMblk == NULL)
- {
- goto motFecPollSendError;
- }
- /* set the packet type to multicast or unicast */
- if (pMblk->mBlkHdr.mData[0] & (UINT8) 0x01)
- {
- pktType = PKT_TYPE_MULTI;
- }
- else
- {
- pktType = PKT_TYPE_UNI;
- }
- /* get the current free TBD */
- pTbd = motFecTbdGet (pDrvCtrl);
- /* get our own cluster */
- pBuf = (char *)pDrvCtrl->pTxPollBuf;
- if ((pTbd == NULL) || (pBuf == NULL))
- {
- goto motFecPollSendError;
- }
- /* copy data but do not free the Mblk */
- len = netMblkToBufCopy (pMblk, pBuf, NULL);
- len = max (ETHERSMALL, len);
- /* flush the cache, if necessary */
- MOT_FEC_CACHE_FLUSH (pBuf, len);
- /* set up the current TBD */
- MOT_FEC_BD_LONG_WR (pTbd, MOT_FEC_BD_ADDR_OFF, (UINT32) pBuf);
- MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_LEN_OFF, (UINT32) len);
- MOT_FEC_BD_WORD_RD (pTbd, MOT_FEC_BD_STAT_OFF, tbdStatus);
- MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF,
- (MOT_FEC_TBD_LAST | MOT_FEC_TBD_CRC
- | MOT_FEC_TBD_RDY | tbdStatus));
- /* kick the transmitter */
- MOT_FEC_TX_ACTIVATE;
- /* Flush the write pipe */
- CACHE_PIPE_FLUSH ();
- /* up-date statistics */
- if (pktType == PKT_TYPE_MULTI)
- {
- pDrvCtrl->endObj.mib2Tbl.ifOutNUcastPkts += 1;
- }
- else
- {
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
- }
- do
- {
- retVal = motFecTbdCheck (pDrvCtrl, pTbd);
- if (ix++ == MOT_FEC_WAIT_MAX)
- break;
- } while (retVal == MOT_FEC_TBD_BUSY);
- /* correct statistics, if necessary */
- if ((retVal == MOT_FEC_TBD_ERROR) || (ix == MOT_FEC_WAIT_MAX))
- {
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);
- if (pktType == PKT_TYPE_MULTI)
- {
- pDrvCtrl->endObj.mib2Tbl.ifOutNUcastPkts -= 1;
- }
- else
- {
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);
- }
- }
- /* clean this buffer descriptor, mirror motFecTbdInit() */
- if (pDrvCtrl->tbdIndex == (pDrvCtrl->tbdNum - 1))
- {
- MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF,
- MOT_FEC_TBD_WRAP);
- }
- else
- {
- MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF, 0);
- }
- /* Flush the write pipe */
- CACHE_PIPE_FLUSH ();
- /* update some indeces for a correct handling of the TBD ring */
- pDrvCtrl->tbdIndex = (pDrvCtrl->tbdIndex + 1)
- % (pDrvCtrl->tbdNum);
- pDrvCtrl->usedTbdIndex = (pDrvCtrl->usedTbdIndex + 1)
- % (pDrvCtrl->tbdNum);
- if (ix == MOT_FEC_WAIT_MAX)
- return (EAGAIN);
- return (OK);
- motFecPollSendError:
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);
- return (EAGAIN);
- }
- /*******************************************************************************
- *
- * motFecPollReceive - receive a packet in polled mode
- *
- * This routine is called by a user to try and get a packet from the
- * device. It returns EAGAIN if no packet is available. The caller must
- * supply a M_BLK_ID with enough space to contain the received packet. If
- * enough buffer is not available then EAGAIN is returned.
- *
- * These routine should not call any kernel functions.
- *
- * SEE ALSO: motFecPollSend()
- *
- * RETURNS: OK or EAGAIN.
- */
- LOCAL STATUS motFecPollReceive
- (
- DRV_CTRL *pDrvCtrl, /* pointer to DRV_CTRL structure */
- M_BLK_ID pMblk /* pointer to the mBlk/cluster pair */
- )
- {
- int retVal = OK; /* holder for return value */
- MOT_FEC_RBD_ID pRbd = NULL; /* generic rbd pointer */
- UINT16 rbdStatus = 0; /* holder for the status of this RBD */
- UINT16 rbdLen = 0; /* number of bytes received */
- char * pBuf = NULL; /* a rx data pointer */
- char * pData = NULL; /* a rx data pointer */
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("motFecPollReceiven"), 0, 0, 0, 0, 0, 0);
- if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)
- return (EAGAIN);
- /* get the first available RBD */
- MOT_FEC_NEXT_RBD (pDrvCtrl, pRbd);
- /* Make cache consistent with memory */
- MOT_FEC_BD_CACHE_INVAL (pRbd, MOT_FEC_RBD_SZ);
- /* read the RBD status word */
- MOT_FEC_BD_WORD_RD (pRbd, MOT_FEC_BD_STAT_OFF,
- rbdStatus);
- /* if it's not ready, don't touch it! */
- if ((rbdStatus & MOT_FEC_RBD_EMPTY) == MOT_FEC_RBD_EMPTY)
- {
- return (EAGAIN);
- }
- /* pass the packet up only if reception was Ok */
- if (rbdStatus & MOT_FEC_RBD_ERR)
- {
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("motFecReceive: bad rbdn"),
- 1, 2, 3, 4, 5, 6);
- goto motFecPollReceiveEnd;
- }
- /* get the actual amount of received data */
- MOT_FEC_BD_WORD_RD (pRbd, MOT_FEC_BD_LEN_OFF,
- rbdLen);
- if (rbdLen < ETHERSMALL)
- {
- MOT_FEC_RX_LS_ADD;
- goto motFecPollReceiveEnd;
- }
- /*
- * Upper layer provides the buffer. If buffer is not large enough,
- * we do not copy the received buffer.
- */
- if (pMblk->mBlkHdr.mLen < rbdLen)
- {
- goto motFecPollReceiveEnd;
- }
- MOT_FEC_BD_LONG_RD (pRbd, MOT_FEC_BD_ADDR_OFF, pData);
- /* up-date statistics */
- if ((*pData ) & (UINT8) 0x01)
- {
- pDrvCtrl->endObj.mib2Tbl.ifInNUcastPkts += 1;
- }
- else
- {
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
- }
- /* set up the mBlk properly */
- pMblk->mBlkHdr.mFlags |= M_PKTHDR;
- pMblk->mBlkHdr.mLen = (rbdLen - ETHER_CRC_LEN) & ~0xc000;
- pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen;
- /* Make cache consistent with memory */
- MOT_FEC_CACHE_INVAL ((char *) pData, pMblk->mBlkHdr.mLen);
- bcopy ((char *) pData, (char *) pMblk->mBlkHdr.mData,
- ((rbdLen - ETHER_CRC_LEN) & ~0xc000));
- /* put the used RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- return (retVal);
- motFecPollReceiveEnd:
- END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
- /* put the errored RBD on the RBD queue */
- motFecRbdClean (pDrvCtrl, pBuf);
- return (EAGAIN);
- }
- /*******************************************************************************
- *
- * motFecPollStart - start polling mode
- *
- * This routine starts polling mode by disabling ethernet interrupts and
- * setting the polling flag in the END_CTRL stucture.
- *
- * SEE ALSO: motFecPollStop()
- *
- * RETURNS: OK, or ERROR if polling mode could not be started.
- */
- LOCAL STATUS motFecPollStart
- (
- DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- int intLevel; /* current intr level */
- int retVal; /* convenient holder for return value */
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("motFecPollStartn"), 0, 0, 0, 0, 0, 0);
- intLevel = intLock();
- /* disable system interrupt: reset relevant bit in SIMASK */
- SYS_FEC_INT_DISABLE (pDrvCtrl, retVal);
- if (retVal == ERROR)
- return (ERROR);
- /* mask chip interrupts */
- MOT_FEC_INT_DISABLE;
- MOT_FEC_FLAG_SET (MOT_FEC_POLLING);
- intUnlock (intLevel);
- return (OK);
- }
- /*******************************************************************************
- *
- * motFecPollStop - stop polling mode
- *
- * This routine stops polling mode by enabling ethernet interrupts and
- * resetting the polling flag in the END_CTRL structure.
- *
- * SEE ALSO: motFecPollStart()
- *
- * RETURNS: OK, or ERROR if polling mode could not be stopped.
- */
- LOCAL STATUS motFecPollStop
- (
- DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */
- )
- {
- int intLevel;
- int retVal; /* convenient holder for return value */
- intLevel = intLock();
- /* enable system interrupt: set relevant bit in SIMASK */
- SYS_FEC_INT_ENABLE (pDrvCtrl, retVal);
- if (retVal == ERROR)
- return (ERROR);
- /* enable chip interrupts */
- MOT_FEC_INT_ENABLE;
- /* set flags */
- MOT_FEC_FLAG_CLEAR (MOT_FEC_POLLING);
- intUnlock (intLevel);
- MOT_FEC_LOG (MOT_FEC_DBG_POLL, ("motFecPollStop... endn"),
- 0, 0, 0, 0, 0, 0);
- return (OK);
- }
- #ifdef MOT_FEC_DBG
- void motFecCsrShow
- (
- )
- {
- UINT32 csrVal;
- DRV_CTRL * pDrvCtrl = pDrvCtrlDbg;
- MOT_FEC_CSR_RD (MOT_FEC_ADDR_L_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Addr low: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_ADDR_H_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Addr high: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_HASH_H_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Hash table high: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_HASH_L_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Hash table low: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_START_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx ring start: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_TX_START_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Tx ring start: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_BUF_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx max buffer: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_CTRL_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Ethernet Controller: 0x%xn"),
- (csrVal & MOT_FEC_CTRL_MASK),
- 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_EVENT_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Interrupt event: 0x%xn"),
- (csrVal & MOT_FEC_EVENT_MSK),
- 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_MASK_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Interrupt mask: 0x%xn"),
- (csrVal & MOT_FEC_EVENT_MSK),
- 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_VEC_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Interrupt vector/level: 0x%xn"),
- (csrVal & MOT_FEC_VEC_MSK),
- 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_ACT_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx active: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_TX_ACT_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Tx active: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_MII_DATA_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("MII data : 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_MII_SPEED_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("MII speed : 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_BOUND_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx FIFO bound: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_FIFO_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx FIFO base: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_TX_FIFO_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Tx FIFO base: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_SDMA_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("SDMA Function Code: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_CTRL_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx Control Register: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_RX_FR_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Rx Max frame length: 0x%xn"),
- (csrVal & MOT_FEC_RX_FR_MSK),
- 0, 0, 0, 0, 0);
- MOT_FEC_CSR_RD (MOT_FEC_TX_CTRL_OFF, csrVal);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("Tx Control Register: 0x%xn"),
- csrVal, 0, 0, 0, 0, 0);
- }
- void motFecRbdShow
- (
- int rbdNum
- )
- {
- UINT16 status;
- UINT16 length;
- UINT32 buffer;
- MOT_FEC_WORD_RD ((UINT32 *)(pDrvCtrlDbg->rbdBase +
- (rbdNum * MOT_FEC_RBD_SZ) +
- MOT_FEC_BD_STAT_OFF), status);
- MOT_FEC_WORD_RD ((UINT32 *)(pDrvCtrlDbg->rbdBase +
- (rbdNum * MOT_FEC_RBD_SZ) +
- MOT_FEC_BD_LEN_OFF), length);
- MOT_FEC_LONG_RD ((UINT32 *)(pDrvCtrlDbg->rbdBase +
- (rbdNum * MOT_FEC_RBD_SZ) +
- MOT_FEC_BD_ADDR_OFF), buffer);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("rbdStatus=0x%x rbdLen=0x%x rbdBuf=0x%xn"),
- status, length, buffer, 0, 0, 0);
- }
- void motFecErrorShow
- (
- )
- {
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("TxBab=0x%x RxBab=0x%xn"),
- motFecBabTxErr,
- motFecBabRxErr,
- 0, 0, 0, 0);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("TxLc=0x%x TxUr=0x%x TxCsl=0x%x n
- TxRl=0x%xn"),
- motFecTxLcErr,
- motFecTxUrErr,
- motFecTxCslErr,
- motFecTxRlErr,
- 0, 0);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("RxLg=0x%x RxNo=0x%x RxCrc=0x%x n
- RxOv=0x%x RxTr=0x%xn"),
- motFecRxLgErr,
- motFecRxNoErr,
- motFecRxCrcErr,
- motFecRxOvErr,
- motFecRxTrErr,
- 0);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("RxLs=0x%x RxMem=0x%xn"),
- motFecRxLsErr,
- motFecRxMemErr,
- 0, 0, 0, 0);
- }
- void motFecDrvShow
- (
- )
- {
- DRV_CTRL * pDrvCtrl = pDrvCtrlDbg;
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("pDrvCtrl=0x%x pNetPool=0x%x n
- pClPool=0x%xn"),
- (int) pDrvCtrl,
- (int) pDrvCtrl->endObj.pNetPool,
- (int) pDrvCtrl->pClPoolId, 0, 0, 0);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("bufBase=0x%x bufSize=0x%x pClBlkArea=0x%xn
- clBlkSize=0x%x pMBlkArea=0x%x n
- mBlkSize=0x%xn"),
- (int) pDrvCtrl->pBufBase,
- pDrvCtrl->bufSize,
- (int) pDrvCtrl->pClBlkArea,
- pDrvCtrl->clBlkSize,
- (int) pDrvCtrl->pMBlkArea,
- pDrvCtrl->mBlkSize);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("tbdNum=%d tbdBase=0x%xtbdIndex=%d n
- usedTbdIndex=%d n
- cleanTbdNum=%d txStall=%d n"),
- pDrvCtrl->tbdNum,
- (int) pDrvCtrl->tbdBase,
- pDrvCtrl->tbdIndex,
- pDrvCtrl->usedTbdIndex,
- pDrvCtrl->cleanTbdNum,
- pDrvCtrl->txStall);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("rbdNum=%d rbdBase=0x%x rbdIndex=%d n"),
- pDrvCtrl->rbdNum,
- (int) pDrvCtrl->rbdBase,
- pDrvCtrl->rbdIndex,
- 0, 0, 0);
- }
- void motFecMiiShow
- (
- )
- {
- DRV_CTRL * pDrvCtrl = pDrvCtrlDbg;
- UCHAR speed [20];
- UCHAR mode [20];
- strcpy ((char *) speed, (pDrvCtrl->phyInfo->phySpeed == MOT_FEC_100MBS) ?
- "100Mbit/s" : "10Mbit/s");
- strcpy ((char *) mode, (pDrvCtrl->phyInfo->phyMode == MOT_FEC_PHY_FD) ?
- "full duplex" : "half duplex");
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("phySpeed=%s phyMode=%s phyAddr=0x%xn
- isoPhyAddr=0x%x phyFlags=0x%xn
- phyDefMode=0x%xn"),
- (int) &speed[0],
- (int) &mode[0],
- pDrvCtrl->phyInfo->phyAddr,
- pDrvCtrl->phyInfo->isoPhyAddr,
- pDrvCtrl->phyInfo->phyFlags,
- pDrvCtrl->phyInfo->phyDefMode);
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("phyStatus=0x%x phyCtrl=0x%x phyAds=0x%xn
- phyPrtn=0x%x phyExp=0x%x phyNext=0x%xn"),
- pDrvCtrl->phyInfo->miiRegs.phyStatus,
- pDrvCtrl->phyInfo->miiRegs.phyCtrl,
- pDrvCtrl->phyInfo->miiRegs.phyAds,
- pDrvCtrl->phyInfo->miiRegs.phyPrtn,
- pDrvCtrl->phyInfo->miiRegs.phyExp,
- pDrvCtrl->phyInfo->miiRegs.phyNext);
- }
- void motFecMibShow
- (
- )
- {
- DRV_CTRL * pDrvCtrl = pDrvCtrlDbg;
- MOT_FEC_LOG (MOT_FEC_DBG_ANY, ("ifOutNUcastPkts=%d ifOutUcastPkts=%dn
- ifInNUcastPkts=%dn
- ifInUcastPkts=%d ifOutErrors=%dn"),
- pDrvCtrl->endObj.mib2Tbl.ifOutNUcastPkts,
- pDrvCtrl->endObj.mib2Tbl.ifOutUcastPkts,
- pDrvCtrl->endObj.mib2Tbl.ifInNUcastPkts,
- pDrvCtrl->endObj.mib2Tbl.ifInUcastPkts,
- pDrvCtrl->endObj.mib2Tbl.ifOutErrors,
- 0);
- }
- #endif /* MOT_FEC_DBG */
- /*******************************************************************************
- *
- * motRevNumGet - Get the processor revision number
- *
- * This routine will return the lower 16 bits of the IMMR (SPR #638)
- * which will contain the processor revision number.
- #
- * RETURNS: processor revision number (in r3)
- *
- * NOMANUAL
- */
- LOCAL int motRevNumGet(void)
- {
- int rev;
- rev = vxImmrDevGet();
- return(rev);
- }