📄 m5200fecend.c
字号:
return (ERROR); MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecStop... Done \n"), 1, 2, 3, 4, 5, 6); return OK; }/**************************************************************************** motFecReset - reset the `motFec' interface** This routine resets the chip by setting the Reset bit in the Ethernet* Control Register. The ETHER_EN bit is cleared, and all the FEC registers* take their default values. In addition, any transmission/reception* currently in progress is abruptly aborted.** RETURNS: OK, always.*/LOCAL STATUS motFecReset ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { UINT32 status = 0; volatile int delay; /* * Clear FIFO status registers */ MOT_FEC_CSR_RD (MOT_FEC_RXFIFO_STAT_OFF, status); MOT_FEC_CSR_WR (MOT_FEC_RXFIFO_STAT_OFF, (status & 0x80f00000)); MOT_FEC_CSR_RD (MOT_FEC_TXFIFO_STAT_OFF, status); MOT_FEC_CSR_WR (MOT_FEC_TXFIFO_STAT_OFF, (status & 0x80f00000)); /* * reset the FIFOs */ MOT_FEC_CSR_WR (MOT_FEC_RESET_OFF, 0x03000000); for (delay = 0;delay < 16*4;delay++) {}; MOT_FEC_CSR_WR (MOT_FEC_RESET_OFF, 0x01000000); /* issue a reset command to the FEC chip */ MOT_FEC_CSR_RD (MOT_FEC_CTRL_OFF, status); MOT_FEC_CSR_WR (MOT_FEC_CTRL_OFF, status | MOT_FEC_ETH_RES); /* wait at least 16 clock cycles */ for (delay = 0;delay < 16*4;delay++) {}; return (OK); }/******************************************************************************** motFecInt - entry point for handling interrupts from the FEC** The interrupting events are acknowledged to the device, so that the device* will de-assert its interrupt signal. The amount of work done here is kept* to a minimum; the bulk of the work is deferred to the netTask.** RETURNS: N/A*/LOCAL void motFecInt ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { UINT32 event = 0; /* event intr register */ UINT32 mask = 0; /* holder for the mask intr register */ UINT32 status; /* status word */ /* read and save the interrupt event register */ MOT_FEC_CSR_RD (MOT_FEC_EVENT_OFF, event); /* clear all interrupts */ MOT_FEC_CSR_WR (MOT_FEC_EVENT_OFF, (event & MOT_FEC_EVENT_MSK)); /* read the interrupt mask register */ MOT_FEC_CSR_RD (MOT_FEC_MASK_OFF, mask); /* read CSR status word again */ MOT_FEC_CSR_RD (MOT_FEC_EVENT_OFF, status); MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: event 0x%x, status 0x%x\n"), (event & MOT_FEC_EVENT_MSK), status, 0, 0, 0, 0); /* handle bus error interrupts */ if (event & (MOT_FEC_EVENT_XFIFO_ERR | MOT_FEC_EVENT_RFIFO_ERR)) { MOT_FEC_CSR_RD (MOT_FEC_MASK_OFF, status); MOT_FEC_CSR_WR (MOT_FEC_MASK_OFF, (status & (~(MOT_FEC_EVENT_XFIFO_ERR | MOT_FEC_EVENT_RFIFO_ERR)))); MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: bus error, restart chip\n"), 0, 0, 0, 0, 0, 0); /* stop and restart the device */ (void) netJobAdd ((FUNCPTR) motFecStop, (int) pDrvCtrl, event, 0, 0, 0); (void) netJobAdd ((FUNCPTR) motFecStart, (int) pDrvCtrl, event, 0, 0, 0); } /* handle babbling transmit error interrupts */ if ((event & MOT_FEC_EVENT_BABT) == MOT_FEC_EVENT_BABT) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: babbling tx error\n"), 0, 0, 0, 0, 0, 0); } /* handle babbling receive error interrupts */ if ((event & MOT_FEC_EVENT_BABR) == MOT_FEC_EVENT_BABR) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: babbling rx error\n"), 0, 0, 0, 0, 0, 0); } /* handle late collision interrupts */ if ((event & MOT_FEC_EVENT_LAT_COL) == MOT_FEC_EVENT_LAT_COL) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("collision occured\n"), 0, 0, 0, 0, 0, 0); } /* handle collision retry limit interrupts */ if ((event & MOT_FEC_EVENT_COL_RETRY) == MOT_FEC_EVENT_COL_RETRY) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("collision retry limit\n"), 0, 0, 0, 0, 0, 0); } /* handle collision retry limit interrupts */ if ((event & MOT_FEC_EVENT_XFIFO_UN) == MOT_FEC_EVENT_XFIFO_UN) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("transmit FIFO underrun\n"), 0, 0, 0, 0, 0, 0); } /* handle heartbeat check fail interrupts */ if ((event & MOT_FEC_EVENT_HB) == MOT_FEC_EVENT_HB) { if (_func_motFecHbFail != NULL) (* _func_motFecHbFail) (pDrvCtrl); MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: heartbeat check fail\n"), 0, 0, 0, 0, 0, 0); } /* handle mii frame completion interrupts */ if ((event & MOT_FEC_EVENT_MII) == MOT_FEC_EVENT_MII) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: mii transfer\n"), 0, 0, 0, 0, 0, 0); /* let the PHY configuration task finish off its job */ MOT_FEC_MII_SEM_GIVE; } /* handle graceful transmit interrupts */ if ((event & MOT_FEC_EVENT_GRA) == MOT_FEC_EVENT_GRA) { MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: graceful transmit\n"), 0, 0, 0, 0, 0, 0); /* let the Stop task finish off its job */ MOT_FEC_GRA_SEM_GIVE; } } /* * MPC5200 SmartComm ethernet receive interrupt handler */LOCAL void sdmaFecRecInt(DRV_CTRL * pDrvCtrl) { /* Frame received? */ if(TaskIntStatus(rxTaskId) == rxTaskId) { TaskIntClear(rxTaskId); intDisable(INUM_SDMA_TASK3);/*Disable receive ints*/ (void) netJobAdd ((FUNCPTR) motFecRxHandle, (int) pDrvCtrl, 0, 0, 0, 0); } }/* * MPC5200 SmartComm ethernet transmit interrupt handler */LOCAL void sdmaFecTransInt(DRV_CTRL * pDrvCtrl) { if(TaskIntStatus(txTaskId) == txTaskId) { TaskIntClear(txTaskId); intDisable(INUM_SDMA_TASK2);/*Disable transmit ints*/ (void) netJobAdd ((FUNCPTR) motFecTxHandle, (int) pDrvCtrl, 0, 0, 0, 0); } }LOCAL void motFecTxHandle (DRV_CTRL *pDrvCtrl){ int intLevel; /* current intr level */ MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecTxHandle: tbdIndex=%d usedTbdIndex=%d cleanTbdNum=%d\n"), pDrvCtrl->tbdIndex, pDrvCtrl->usedTbdIndex, pDrvCtrl->cleanTbdNum, 0, 0, 0); /* while tx interrupts to be processed */motFecTxProcess: motFecTbdClean (pDrvCtrl); intLevel = intLock(); if (TaskIntPending(txTaskId)) { intUnlock (intLevel); goto motFecTxProcess; } else { /* re-enable transmit interrupts */ intEnable(INUM_SDMA_TASK2);/*Enable transmit ints*/ intUnlock (intLevel); } }LOCAL void motFecRxHandle (DRV_CTRL *pDrvCtrl){ int intLevel; /* current intr level */ MOT_FEC_LOG (MOT_FEC_DBG_RX, ("motFecRxHandle: \n"), 0, 0, 0, 0, 0, 0); /* while rx interrupts to be processed */motFecRxProcess: motFecHandleRecvInt (pDrvCtrl); intLevel = intLock(); if (TaskIntPending(rxTaskId)) { intUnlock (intLevel); goto motFecRxProcess; } else { /* re-enable receive and transmit interrupts */ intEnable(INUM_SDMA_TASK3);/*Enable receive ints*/ intUnlock (intLevel); } } /******************************************************************************** motFecSend - send an Ethernet packet** This routine() takes a M_BLK_ID and 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.** muxSend() calls this routine each time it wants to send a packet.** RETURNS: OK, or END_ERR_BLOCK, if no resources are available, or ERROR,* if the device is currently working in polling mode.*/LOCAL STATUS motFecSend ( DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ M_BLK * pMblk /* pointer to the mBlk/cluster pair */ ) { UINT8 fragNum = 0; /* number of fragments in this mBlk */ UINT16 pktType = 0; /* packet type (unicast or multicast) */ MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend...\n"), 1, 2, 3, 4, 5, 6); END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* check device mode */ if (MOT_FEC_FLAG_ISSET (MOT_FEC_POLLING)) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ errno = EINVAL; return (ERROR); } /* walk the mBlk */ if (motFecMblkWalk (pMblk, &fragNum, &pktType) == ERROR) { goto motFecSendError; } /* check we have enough resources */ if ((pDrvCtrl->cleanTbdNum) == 0) { motFecTbdClean (pDrvCtrl); if (pDrvCtrl->cleanTbdNum == 0) { pDrvCtrl->txStall = TRUE; motFecTbdClean (pDrvCtrl); goto motFecSendError; } } if ((pDrvCtrl->cleanTbdNum) >= fragNum) { /* transmit the packet in zero-copy mode */ if (motFecPktTransmit (pDrvCtrl, pMblk, fragNum, pktType) == ERROR) { goto motFecSendError; } } else { /* transmit the packet in copy mode */ fragNum = 1; if (motFecPktCopyTransmit (pDrvCtrl, pMblk, fragNum, pktType) == ERROR) { goto motFecSendError; } } END_TX_SEM_GIVE (&pDrvCtrl->endObj); MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend...Done\n"), 1, 2, 3, 4, 5, 6); return (OK);motFecSendError: END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); }/******************************************************************************** motFecPktTransmit - transmit a packet** This routine transmits the packet described by the given parameters* over the network, without copying the mBlk to the driver's buffer.* It also updates statistics.** RETURNS: OK, or ERROR if no resources were available.*/LOCAL STATUS motFecPktTransmit ( DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ M_BLK * pMblk, /* pointer to the mBlk */ UINT8 fragNum, /* number of fragments */ UINT16 pktType /* packet type */ ) { UINT16 bufLen = 0; /* length of this fragment */ UINT16 pktLen = 0; /* length of this packet */ UINT16 totLen = 0; /* length of data to be sent */ char * pBuf = NULL; /* pointer to data to be sent */ MOT_FEC_TBD_ID pTbd = NULL; /* pointer to the current ready TBD */ MOT_FEC_TBD_LIST_ID pTbdList = NULL;/* pointer to the TBD list*/ UINT16 tbdStatus; /* holder for the TBD status */ M_BLK * pCurr = pMblk; /* holder for the current mBlk */ MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecPktTransmit...\n"), 1, 2, 3, 4, 5, 6); /* get the current free TBD */ pTbdList = motFecTbdListSet (pDrvCtrl, fragNum); if (pTbdList == (MOT_FEC_TBD_LIST_ID) NULL) { /* set to stall condition */ pDrvCtrl->txStall = TRUE; return (ERROR); } /* store the Mblk pointer */ pTbdList->pBuf = (UCHAR *) pMblk; pTbdList->bufType = BUF_TYPE_MBLK; /* store the packet type */ pTbdList->pktType = pktType; pCurr = pMblk; /* get the total packet lenght */ pktLen = pMblk->mBlkPktHdr.len; /* for each mBlk fragment, set up the related TBD */ while (fragNum > 0) { pBuf = pCurr->mBlkHdr.mData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -