ixethaccend.c
来自「ixEthAccEnd END network interface driver」· C语言 代码 · 共 1,681 行 · 第 1/4 页
C
1,681 行
/* Upper layer must provide a valid buffer. */ if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "PRX bad mblk\n", 1, 2, 3, 4, 5, 6); return(EAGAIN); } END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); bcopy (pPacket, pMblk->m_data, len); pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len; /* set the data len */ pMblk->mBlkPktHdr.len = len; /* set the total len */ IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6); IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6); return(OK);#else return(ERROR);#endif /* IXE_ETHACC_POLL_ENABLE */}/********************************************************************************* ixEthAccEndPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success. EAGAIN if device is busy.*/LOCAL STATUS ixEthAccEndPollSend(END_DEVICE* pDrvCtrl, /* device to be polled */M_BLK_ID pMblk /* packet to send */){#ifdef IXE_ETHACC_POLL_ENABLE int len; u_short stat; IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6); stat = ixEthAccEndStatusRead (pDrvCtrl); /* dummy code */ if ((stat & IxEthAccEnd_TINT) == 0) return((STATUS) EAGAIN); len = max (ETHERSMALL, pMblk->m_len); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* Free the data if it was accepted by device */ netMblkClFree (pMblk); IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "leaving ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6); return(OK);#else return(ERROR);#endif /* IXE_ETHACC_POLL_ENABLE */}/******************************************************************************* ixEthAccEndMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastAdd(END_DEVICE *pDrvCtrl, /* device pointer */char* pAddress /* new address to add */){ int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) ixEthAccEndConfig (pDrvCtrl); return(OK);}/******************************************************************************* ixEthAccEndMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastDel(END_DEVICE *pDrvCtrl, /* device pointer */char* pAddress /* address to be deleted */){ int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) ixEthAccEndConfig (pDrvCtrl); return(OK);}/******************************************************************************* ixEthAccEndMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastGet(END_DEVICE *pDrvCtrl, /* device pointer */MULTI_TABLE* pTable /* address table to be filled in */){ return(etherMultiGet (&pDrvCtrl->end.multiList, pTable));}/********************************************************************************* ixEthAccEndStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndStop(END_DEVICE *pDrvCtrl /* device to be stopped */){ STATUS result = OK; ixEthAccShutdown = TRUE; /* If that port doesn't exist then just return */ if ( ixEthAccPhyAddresses[ pDrvCtrl->unit ] == 0xffffffff ) return OK;#ifdef PORT_FLUSH_EXISTS /* Flush all buffers back to stack */ ixEthAccTxPortFlush ( pDrvCtrl->unit ); ixEthAccRxPortFlush ( pDrvCtrl->unit ); /* Wait aprox 1/2 sec for flush */ taskDelay(sysClkRateGet()/2);#endif /* PORT_FLUSH_EXISTS */ /* Shut down the port */ ixEthAccPortDisable ( pDrvCtrl->unit ); /* Wait aprox 1/2 sec for spin down */ taskDelay(sysClkRateGet()/2); END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING)); SYS_INT_DISCONNECT (pDrvCtrl, IxEthAccEndInt, (int)pDrvCtrl, &result); if (result == ERROR) { IXP_DRV_LOG (IXP_DRV_DEBUG_ERROR, "ixEthAccEndStop: Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return(result);}/******************************************************************************** ixEthAccEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndUnload(END_DEVICE* pDrvCtrl /* device to be unloaded */){ END_OBJECT_UNLOAD (&pDrvCtrl->end); return(OK);}/********************************************************************************* ixEthAccEndPollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndPollStart(END_DEVICE * pDrvCtrl /* device to be polled */){ int oldLevel; oldLevel = intLock (); /* disable ints during update */ pDrvCtrl->flags |= IxEthAccEnd_POLLING; intUnlock (oldLevel); /* now IxEthAccEndInt won't get confused */ IXP_DRV_LOG (IXP_DRV_DEBUG_POLL, "STARTED\n", 1, 2, 3, 4, 5, 6); ixEthAccEndConfig (pDrvCtrl); /* reconfigure device */ return(OK);}/********************************************************************************* ixEthAccEndPollStop - stop polled mode operations** This function terminates polled mode operation. The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndPollStop(END_DEVICE * pDrvCtrl /* device to be polled */){ int oldLevel; oldLevel = intLock (); /* disable ints during register updates */ pDrvCtrl->flags &= ~IxEthAccEnd_POLLING; intUnlock (oldLevel); ixEthAccEndConfig (pDrvCtrl); IXP_DRV_LOG (IXP_DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6); return(OK);}/********************************************************************************* ixEthAccEndReset - reset device** RETURNS: N/A.*/LOCAL void ixEthAccEndReset(END_DEVICE *pDrvCtrl){}#ifdef IXE_ETHACC_POLL_ENABLE/********************************************************************************* ixEthAccEndStatusRead - get current device state/status** RETURNS: status bits.*/LOCAL UINT ixEthAccEndStatusRead(END_DEVICE *pDrvCtrl){ return(0);}#endif /* IXE_ETHACC_POLL_ENABLE */LOCAL void ixEthAccEndTxDoneCallback(UINT32 callbackTag, M_BLK *pMblk){#ifdef IXP_DRV_DEBUG END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag; M_BLK *mbufPtr;#endif /* If we are shutting down then just dump the buffer */ if ( ixEthAccShutdown ) return;#ifdef IXP_DRV_DEBUG for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next ) { IXP_DRV_LOG (IXP_DRV_DEBUG_INT, "Tx ixe[%d] Callback Hdr: 0x%08X Buff: 0x%08X Size: 0x%08X\n" , pDrvCtrl->unit , (int)mbufPtr , (int)mbufPtr->m_data , mbufPtr->m_pkthdr.len , 5, 6); }#endif /* IXP_DRV_DEBUG */ /* Free the buffer back to the pool */ netMblkClChainFree (pMblk);}LOCAL void ixEthAccEndRxCallback(UINT32 callbackTag, M_BLK *pMblk){ int oldLevel; IX_ETH_ACC_REC_BUF *pBufList; END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag; /* If we are shutting down then just dump the buffer */ if ( ixEthAccShutdown ) return; /* Expunge buffer header from cache. The data will be done later */#ifdef IXE_CACHED_BUFFERS_ENABLE IXP425_END_CACHE_INVALIDATE (pMblk, sizeof(M_BLK));#endif /* IXE_CACHED_BUFFERS_ENABLE */ /* Pass buffer off to Task level processing */ if ( pDrvCtrl->rxHandling == 0 ) { oldLevel = intLock (); /* protect IxEthAccEndInt */ /* Point to the top of the list */ pDrvCtrl->recNext = pDrvCtrl->recBufList; pBufList = pDrvCtrl->recNext; /* set the buffer */ pBufList->ix_rec_buf = pMblk; /* Bump the next available pointer */ pDrvCtrl->recNext = pBufList->ix_rec_next; /* Say we're handling */ pDrvCtrl->rxHandling = 1; intUnlock (oldLevel); netJobAdd ((FUNCPTR)ixEthAccEndHandleRcvInt, (int)pDrvCtrl, (int)pBufList,0,0,0); } else { oldLevel = intLock (); /* protect IxEthAccEndInt */ /* Point to the next block */ pBufList = pDrvCtrl->recNext; /* Check for list overflow */ if (pBufList->ix_rec_buf) { intUnlock (oldLevel); /* Drop the packet */ netMblkFree (pDrvCtrl->end.pNetPool, pMblk);#if 1 logMsg ("ixe[%d] Rx Callback: Buffer: 0x%08X - rxHandling over-run. Packet Dropped\n" ,pDrvCtrl->unit, (int)pMblk, 3, 4, 5, 6);#endif } else { pDrvCtrl->rxHandling++; /* Instrumentation */ if ( pDrvCtrl->rxHandling > pDrvCtrl->rxMaxHandling ) pDrvCtrl->rxMaxHandling = pDrvCtrl->rxHandling; /* Don't do the netJobAdd - Do a low overhead buffer add */ pBufList->ix_rec_buf = pMblk; pDrvCtrl->recNext = pBufList->ix_rec_next; intUnlock (oldLevel); IXP_DRV_LOG (IXP_DRV_DEBUG_RX_HANDLING , "Rx Callback Unit[%d] : Buffer: 0x%08X %4d %4d Bytes rxHandling: %d\n" , pDrvCtrl->unit, (int)pMblk, pMblk->m_pkthdr.len , pMblk->m_len, pDrvCtrl->rxHandling, 6); } }} #endif /* INCLUDE_IXETHACCEND */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?