📄 dp8381~1.c
字号:
return (ERROR); } /* Check if we can transport this packet */ len = pMblk->mBlkPktHdr.len; if (len > ETH_MAX_PKT_SIZ) { netMblkClChainFree (pMblk); return (ERROR); } /* Get a free TX descriptor */ END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); txDesc = dp83815TxDescGet (pDrvCtrl); if (txDesc == NULL) { END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1); END_TX_SEM_GIVE (&pDrvCtrl->end); netMblkClChainFree (pMblk); return (ERROR); }#ifdef DRV_DEBUG if (dp83815Debug & DRV_DEBUG_TX) printf ("Send: txDesc=%p cluster count = %d size = %d, pktsz=%d", txDesc, mblkCount (pMblk), pMblk->mBlkHdr.mLen, pMblk->mBlkPktHdr.len);#endif /* copy or loan buffers*/ if (doCopy) { pTxMblk = DP_DESC_MBLKPTR_GET (txDesc); (void) netMblkToBufCopy (pMblk, pTxMblk->mBlkHdr.mData, NULL); netMblkClChainFree (pMblk); } else { netMblkClChainFree (DP_DESC_MBLKPTR_GET(txDesc)); pTxMblk = netMblkGet (pDrvCtrl->end.pNetPool, M_WAIT, MT_DATA); netMblkDup (pMblk, pTxMblk); netMblkClChainFree (pMblk); } /* update statistics of the previous transmit */ cmdsts = DP_DESC_CMDSTS_XLATE_GET (txDesc); if (cmdsts & DP_DESC_CMDSTS_TX_ERRORS) END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);/*#ifdef DRV_DEBUG if (dp83815Debug & DRV_DEBUG_TX) dumpPkt (pTxMblk->mBlkHdr.mData, len);#endif*//*hanzhf*/ /* Update the descriptor */ DP_DESC_BUFPTR_XLATE_SET (txDesc, pTxMblk->mBlkHdr.mData); DP_DESC_MBLKPTR_SET (txDesc, pTxMblk); END_CACHE_FLUSH (pTxMblk->mBlkHdr.mData, len); DP_DESC_CMDSTS_XLATE_SET (txDesc, DP_DESC_CMDSTS_OWN|len); END_CACHE_FLUSH (txDesc, DP_DESC_SIZE);/*hanzhf */#ifdef DRV_DEBUG DRV_LOG(DRV_DEBUG_TX, "begin return value is 0x%x\n", DP_DESC_CMDSTS_XLATE_GET (txDesc), 2, 3, 4, 5, 6);#endif DP_REG32_SET (DP_CR, DP_CR_TXE); END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);/*hanzhf */#ifdef DRV_DEBUG temp=DP_REG32_READ (DP_TXDP); DRV_LOG(DRV_DEBUG_TX,"read TXDP is 0x%x\n",temp,2,3,4,5,6);#endif /*Release the TX semaphore*/ END_TX_SEM_GIVE (&pDrvCtrl->end);/* hanzhf *//* DP_REG32_WRITE (DP_CR, DP_CR_TXE | DP_CR_RXE|DP_CR_SWI);*/ return (OK); }#if 0 /* NOT_USED *//********************************************************************************* dp83815TxMblkReclaim - reclaim Mblks from the TX queue** * RETURNS: N/A*/LOCAL void dp83815TxMblkReclaim ( END_DEVICE * pDrvCtrl, VIRT_ADDR descAddr ) { M_BLK_ID pMblk; DP83815_QUEUE * q; /* Reclaim buffers from all descriptors which have been transmitted. */ q = &pDrvCtrl->txQueue; END_CACHE_INVALIDATE (descAddr, DP_DESC_SIZE); while (((DP_DESC_CMDSTS_XLATE_GET(descAddr) & DP_DESC_CMDSTS_OWN) == 0) && ((pMblk=(M_BLK_ID) DP_DESC_MBLKPTR_GET(descAddr)) != NULL)) { netMblkClChainFree (pMblk); DP_DESC_MBLKPTR_SET (descAddr, NULL); descAddr = DP_QUEUE_ELE_NEXT_GET (q, descAddr); END_CACHE_INVALIDATE (descAddr, DP_DESC_SIZE); } }#endif/* NOT_USED *//********************************************************************************* dp83815Ioctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int dp83815Ioctl ( VOID * pObj, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { END_DEVICE *pDrvCtrl = pObj; /* device receiving command */ int error = 0; long value; DRV_LOG (DRV_DEBUG_IOCTL, "ioctl CMD=0x%x\n", cmd, 2, 3, 4, 5, 6); switch (cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } dp83815RxFilterConfig (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ dp83815PollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ dp83815PollStop (pDrvCtrl); break; case EIOCGMIB2: /* return MIB information */ if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = DP83815_MIN_FBUF; break; default: error = EINVAL; } return (error); }/******************************************************************************** dp83815Config - reconfigure the interface under us.** Install the Tx and Rx Queues and the Interrupt vector.* Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** This routine can be called only once after the device has been initialized.** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815Config ( END_DEVICE *pDrvCtrl /* device to be re-configured */ ) { UINT32 iobase = pDrvCtrl->baseAddr; /* reset the device */ if (dp83815Reset (pDrvCtrl) == ERROR) { printf("reset error\n"); return ERROR; } /* Install the Tx and Rx queues on the device */ DP_REG32_WRITE (DP_TXDP, END_CACHE_VIRT_TO_BUS(pDrvCtrl->txQueue.firstDescAddr)); DP_REG32_WRITE (DP_RXDP, END_CACHE_VIRT_TO_BUS(pDrvCtrl->rxQueue.firstDescAddr)); DRV_LOG (DRV_DEBUG_LOAD,"dp%d: setting TXDP=0x%x RXDP=0x%x\n", pDrvCtrl->unit, (UINT32)END_CACHE_VIRT_TO_BUS (pDrvCtrl->txQueue.firstDescAddr), (UINT32)END_CACHE_VIRT_TO_BUS (pDrvCtrl->rxQueue.firstDescAddr), 4, 5, 6); /* Setup phy capabilities */ if (dp83815PhySetup (pDrvCtrl) != OK) { printf ("eth%d: Warning PHY setup did not complete. Check cable.\n", pDrvCtrl->unit); return (ERROR); } /* Setup transmit control */ DP_REG32_WRITE (DP_TXCFG, (DP_TXCFG_DRTH_SET(0x30) | DP_TXCFG_FLTH_SET(0x10) | DP_TXCFG_MXDMA_32 | DP_TXCFG_ATP)); DRV_LOG (DRV_DEBUG_LOAD, "dp: TXCFG set to 0x%x\n", (DP_TXCFG_DRTH_SET(0x30) | DP_TXCFG_FLTH_SET(0x10) | DP_TXCFG_MXDMA_32 | DP_TXCFG_ATP), 2, 3, 4, 5, 6); /* Setup receive control */ DP_REG32_WRITE (DP_RXCFG, (DP_RXCFG_DRTH_SET(0x08) | DP_RXCFG_ALP| DP_RXCFG_ATX| DP_RXCFG_ARP| DP_RXCFG_AEP| DP_RXCFG_MXDMA_32)); DRV_LOG (DRV_DEBUG_LOAD, "dp: RXCFG set to 0x%x\n", (DP_RXCFG_DRTH_SET(0x08) | DP_RXCFG_MXDMA_32), 2, 3, 4, 5, 6); /* Setup the ethernet address */ dp83815MacAddressSet (iobase, pDrvCtrl->enetAddr); /* Receive filtering setup */ DP_REG32_WRITE (DP_RFCR, 0); dp83815RxFilterConfig (pDrvCtrl); return OK; }/********************************************************************************* dp83815PollRecv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK upon success. EAGAIN is returned when no packet is available.*/LOCAL STATUS dp83815PollRecv ( VOID * pObj, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ) { END_DEVICE *pDrvCtrl = (END_DEVICE *) pObj; UINT32 cmdsts; int len; VIRT_ADDR rxDesc; M_BLK_ID pRxMblk; UINT regIsr; UINT iobase = pDrvCtrl->baseAddr; /* Read the ISR */ regIsr = DP_REG32_READ (DP_ISR); if (regIsr) DRV_POLL_PRINT (DRV_DEBUG_POLL_RX, "Isr=0x%x ", regIsr, 2, 3, 4, 5, 6); /* Get a valid packet */ while (1) { rxDesc = dp83815RxDescGet (pDrvCtrl); if (rxDesc == NULL) return (EAGAIN); DRV_POLL_PRINT (DRV_DEBUG_POLL_RX, "rxDesc=%p ", rxDesc, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); cmdsts = DP_DESC_CMDSTS_XLATE_GET (rxDesc); if ((cmdsts & DP_DESC_CMDSTS_RX_ERRORS) != 0) { /* Cleanup and make available to receive */ DP_DESC_CMDSTS_XLATE_SET (rxDesc, DP_BUF_SIZE); END_CACHE_FLUSH (rxDesc, DP_DESC_SIZE); DP_REG32_SET (DP_CR, DP_CR_RXE); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); /* dropped */ DRV_POLL_PRINT (DRV_DEBUG_POLL_RX, "dropped ", 1, 2, 3, 4, 5, 6); continue; } else break; } /* Process the packet */ len = (cmdsts & DP_DESC_CMDSTS_SIZE) - ETH_CRC_LEN; if (!pMblk || (pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { /* Cleanup and make available to receive */ DP_DESC_CMDSTS_XLATE_SET (rxDesc, DP_BUF_SIZE); END_CACHE_FLUSH (rxDesc, DP_DESC_SIZE); DP_REG32_SET (DP_CR, DP_CR_RXE); DRV_POLL_PRINT (DRV_DEBUG_POLL_RX, "Bad Mblk \n\r", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); /* no resource */ return (EAGAIN); } pRxMblk = (M_BLK_ID) DP_DESC_MBLKPTR_GET (rxDesc); /* Copy received data and update the MBLK */ bcopy (pRxMblk->mBlkHdr.mData, pMblk->mBlkHdr.mData, len); pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; /* Cleanup the descriptor and make available for reception */
DP_DESC_CMDSTS_XLATE_SET (rxDesc, DP_BUF_SIZE); END_CACHE_FLUSH (rxDesc, DP_DESC_SIZE); DP_REG32_SET (DP_CR, DP_CR_RXE); DRV_POLL_PRINT (DRV_DEBUG_POLL_RX, "RX OK\r\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* dp83815PollSend - 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 dp83815PollSend ( VOID* pObj, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ) { END_DEVICE * pDrvCtrl = pObj; /* device ptr */ VIRT_ADDR txDesc; UINT32 cmdsts; UINT32 iobase = pDrvCtrl->baseAddr; M_BLK_ID pNewMblk; int len; if ((pDrvCtrl->flags & DP83815_POLLING) == NULL) { DRV_POLL_PRINT (DRV_DEBUG_POLL_TX, "TX: ErrorNotPolling\r\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* Get a free TX descriptor */ txDesc = dp83815TxDescGet (pDrvCtrl); if (txDesc == NULL) { END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1); netMblkClChainFree (pNewMblk); DRV_POLL_PRINT (DRV_DEBUG_POLL_TX, "TX: No txDesc\r\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } /* Get the transmit Mblk from the descriptor */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -