motfecend.c
来自「Tornado 2.0.2 source code!vxworks的源代码」· C语言 代码 · 共 1,985 行 · 第 1/5 页
C
1,985 行
if (!pDrvCtrl->loaded) return (ERROR); if (vxMemProbe ((char *) (pDrvCtrl->motCpmAddr + MOT_FEC_CSR_OFF), VX_READ, 4, &bucket[0]) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_START, (": need MMU mapping for address 0x%x\n"), (UINT32) pDrvCtrl->motCpmAddr, 2, 3, 4, 5, 6); return (ERROR); } /* reset the chip */ if (motFecReset (pDrvCtrl) != OK) return (ERROR); if (motFecTbdInit (pDrvCtrl) == ERROR) return (ERROR); if (motFecRbdInit (pDrvCtrl) == ERROR) return (ERROR); /* set some flags to default values */ pDrvCtrl->txStall = FALSE; pDrvCtrl->tbdIndex = 0; pDrvCtrl->usedTbdIndex = 0; pDrvCtrl->cleanTbdNum = pDrvCtrl->tbdNum; pDrvCtrl->rbdIndex = 0; /* connect the interrupt handler */ SYS_FEC_INT_CONNECT (pDrvCtrl, motFecInt, (int) pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* enable system interrupt: set relevant bit in SIMASK */ SYS_FEC_INT_ENABLE (pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* call the BSP to do any other initialization (port D) */ SYS_FEC_ENET_ENABLE; /* configure some chip's registers */ if (motFecPrePhyConfig (pDrvCtrl) == ERROR) return (ERROR); /* initialize some fields in the PHY info structure */ if (motFecPhyPreInit (pDrvCtrl) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("Failed to pre-initialize the PHY\n"), 0, 0, 0, 0, 0, 0); return (ERROR); } /* initialize the Physical medium layer */ if (_func_motFecPhyInit == NULL) return (ERROR); if (((* _func_motFecPhyInit) (pDrvCtrl)) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("Failed to initialize the PHY\n"), 0, 0, 0, 0, 0, 0); return (ERROR); } /* configure other chip's registers */ if (motFecPostPhyConfig (pDrvCtrl) == ERROR) return (ERROR); /* correct the speed for the mib2 stuff */ pDrvCtrl->endObj.mib2Tbl.ifSpeed = pDrvCtrl->phyInfo->phySpeed; if (END_FLAGS_ISSET (IFF_MULTICAST)) MOT_FEC_FLAG_SET (MOT_FEC_MCAST); /* enable the Ethernet Controller */ MOT_FEC_ETH_ENABLE; /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* startup the receiver */ MOT_FEC_RX_ACTIVATE; /* Flush the write pipe */ CACHE_PIPE_FLUSH (); MOT_FEC_LOG (MOT_FEC_DBG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6); return (OK); }/**************************************************************************** motFecStop - stop the 'motfec' interface** This routine marks the interface as inactive, disables interrupts and * the Ethernet Controller. As a result, reception is stopped immediately,* and transmission is stopped after a bad CRC is appended to any frame* currently being transmitted. The reception/transmission control logic* (FIFO pointers, buffer descriptors, etc.) is reset. To bring the * interface back up, motFecStart() must be called.** RETURNS: OK, always.*/LOCAL STATUS motFecStop ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { int retVal; /* convenient holder for return value */ MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecStop...\n"), 1, 2, 3, 4, 5, 6); /* mark the interface as down */ END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* issue a graceful transmit command */ MOT_FEC_CSR_WR (MOT_FEC_TX_CTRL_OFF, MOT_FEC_TX_CTRL_GRA); /* wait for the related interrupt */ MOT_FEC_GRA_SEM_TAKE; /* mask chip interrupts */ MOT_FEC_INT_DISABLE; /* disable the Ethernet Controller */ MOT_FEC_ETH_DISABLE; /* disable system interrupt: reset relevant bit in SIMASK */ SYS_FEC_INT_DISABLE (pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* disconnect the interrupt handler */ SYS_FEC_INT_DISCONNECT (pDrvCtrl, motFecInt, (int)pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* call the BSP to disable the Port D */ SYS_FEC_ENET_DISABLE; if (motFecBdFree (pDrvCtrl) != OK) 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 */ ) { /* issue a reset command to the FEC chip */ MOT_FEC_CSR_WR (MOT_FEC_CTRL_OFF, MOT_FEC_ETH_RES); /* wait at least 16 clock cycles */ taskDelay (1); 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 */ CACHE_PIPE_FLUSH (); /* 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)); CACHE_PIPE_FLUSH (); /* 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_BERR) == MOT_FEC_EVENT_BERR) { 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_BAB_TX_ADD; 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_BAB_RX_ADD; MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: babbling rx error\n"), 0, 0, 0, 0, 0, 0); } /* handle transmit and receive interrupts */ if ((((event & MOT_FEC_EVENT_TXF) == MOT_FEC_EVENT_TXF) && ((mask & MOT_FEC_EVENT_TXF) == MOT_FEC_EVENT_TXF)) || (((event & MOT_FEC_EVENT_RXF) == MOT_FEC_EVENT_RXF) && ((mask & MOT_FEC_EVENT_RXF) == MOT_FEC_EVENT_RXF))) { /* disable tx/rx interrupts */ MOT_FEC_CSR_WR (MOT_FEC_MASK_OFF, (mask & (~(MOT_FEC_EVENT_TXF | MOT_FEC_EVENT_RXF)))); MOT_FEC_LOG (MOT_FEC_DBG_INT, ("motFecInt: tx/rx intr\n"), 0, 0, 0, 0, 0, 0); (void) netJobAdd ((FUNCPTR) motFecRxTxHandle, (int) pDrvCtrl, 0, 0, 0, 0); } /* handle heartbeat check fail interrupts */ if ((event & MOT_FEC_EVENT_HB) == MOT_FEC_EVENT_HB) { MOT_FEC_HB_FAIL_ADD; 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; } }/******************************************************************************** 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; END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (ERROR); } /* walk the mBlk */ if (motFecMblkWalk (pMblk, &fragNum, &pktType) == ERROR) { goto motFecSendError; } /* check we have enough resources */ if ((pDrvCtrl->cleanTbdNum) == 0) { /* SPR 30135 - make sure muxTxRestart() will be called later */ pDrvCtrl->txStall = TRUE; goto motFecSendError; } if ((pDrvCtrl->cleanTbdNum) >= fragNum) { /* transmit the packet in zero-copy mode */ if (motFecPktTransmit (pDrvCtrl
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?