📄 dp8381~1.c
字号:
if (tok == NULL) return ERROR; pDrvCtrl->dmaBufSize = strtoul (tok, NULL, NULL); /* Transmit descriptor count. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->txDescCount = strtoul (tok, NULL, NULL); if (pDrvCtrl->txDescCount == 0) pDrvCtrl->txDescCount = DP_TX_DESC_COUNT_DEFAULT; /* Receive descriptor count. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->rxDescCount = strtoul (tok, NULL, NULL); if (pDrvCtrl->rxDescCount == 0) pDrvCtrl->rxDescCount = DP_RX_DESC_COUNT_DEFAULT; /* Cluster count and mBlk count. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->clCount = strtoul (tok, NULL, NULL); if (pDrvCtrl->clCount == 0) pDrvCtrl->clCount = (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount + DP_CL_EXTRA_DEFAULT); else if (pDrvCtrl->clCount < (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount + DP_CL_EXTRA_MIN)) pDrvCtrl->clCount = (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount + DP_CL_EXTRA_MIN); pDrvCtrl->mBlkCount = pDrvCtrl->clCount * 2; DRV_LOG (DRV_DEBUG_LOAD, "unit=%d, pDmaBuf=0x%x, dmaBufSize=%d, " "txDescCount=%d, rxDescCount=%d, clCount=%d\n", pDrvCtrl->unit, (UINT32)pDrvCtrl->pDmaBuf, pDrvCtrl->dmaBufSize, pDrvCtrl->txDescCount, pDrvCtrl->rxDescCount, pDrvCtrl->clCount); return OK; }/********************************************************************************* dp83815MemInit - initialize queues and netpool for the device** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815MemInit ( END_DEVICE * pDrvCtrl /* device to be initialized */ ) { M_CL_CONFIG mclBlkConfig; CL_DESC clDescTbl[1]; char* pMemBuf; UINT32 txQMemSize; UINT32 rxQMemSize; UINT32 totalSize; /* Allocate memory for the net pool */ if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "Could not allocate net pool memory\n", 1, 2, 3, 4, 5, 6); goto dpMemInitFail; } /* Allocate memory for mBlks and clBlks */ mclBlkConfig.mBlkNum = pDrvCtrl->mBlkCount; mclBlkConfig.clBlkNum = pDrvCtrl->clCount; mclBlkConfig.memSize = ((mclBlkConfig.mBlkNum * MBLK_SIZE) + (mclBlkConfig.clBlkNum * CLBLK_SIZE)); mclBlkConfig.memArea = pDrvCtrl->pMclMem = memalign (sizeof (long), mclBlkConfig.memSize); if (mclBlkConfig.memArea == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "Could not allocate mclBlk memory\n", 1, 2, 3, 4, 5, 6); goto dpMemInitFail; } /* Allocate memory for clusters, Tx and Rx Queues */ /* Get the total memory size needed */ clDescTbl[0].clSize = DP_BUF_SIZE; clDescTbl[0].clNum = pDrvCtrl->clCount; clDescTbl[0].memSize = ((pDrvCtrl->clCount * (DP_BUF_SIZE + ( 2 * sizeof (long)))) + sizeof(int)); txQMemSize = DP_QUEUE_ELE_SIZE * pDrvCtrl->txDescCount; rxQMemSize = DP_QUEUE_ELE_SIZE * pDrvCtrl->rxDescCount; totalSize = clDescTbl[0].memSize + txQMemSize + rxQMemSize + DP_ALIGN; /* If user has specified DevMem, validate; else allocate memory */ if ((pDrvCtrl->pDmaBuf != NULL) && (pDrvCtrl->pDmaBuf != (char*)NONE)) { if (pDrvCtrl->dmaBufSize < totalSize) { DRV_LOG (DRV_DEBUG_LOAD, "Dp: not enough memory provided, " "need %ul got %d\n", totalSize,pDrvCtrl->dmaBufSize, 3, 4, 5, 6); goto dpMemInitFail; } /* assume pool is cache coherent, copy null structure */ pDrvCtrl->cacheFuncs = cacheNullFuncs; } else { /* Because the structures that are shared between the device * and the driver may share cache lines, the possibility exists * that the driver could flush a cache line for a structure and * wipe out an asynchronous change by the device to a neighboring * structure. Therefore, this driver cannot operate with memory * that is not write coherent. We check for the availability of * such memory here, and abort if the system did not give us what * we need. */ if (!CACHE_DMA_IS_WRITE_COHERENT ()) { printf ("dp: device requires cache coherent memory\n"); return (ERROR); } pDrvCtrl->pDmaBuf = (char*) cacheDmaMalloc (totalSize);/*hanzhf*/ if (pDrvCtrl->pDmaBuf == NULL) goto dpMemInitFail; /* copy the DMA structure */ pDrvCtrl->cacheFuncs = cacheDmaFuncs;/*hanzhf*/ pDrvCtrl->flags |= DP83815_BUF_LOCAL; DRV_LOG (DRV_DEBUG_LOAD, "DevMem allocated, pDmaBuf=0x%x\n", (UINT32)pDrvCtrl->pDmaBuf, 2, 3, 4, 5, 6); } /* Clear and align memory */ memset (pDrvCtrl->pDmaBuf, 0, totalSize); pMemBuf = (char*)(((UINT32)pDrvCtrl->pDmaBuf + DP_ALIGN) & ~(DP_ALIGN - 1)); /* Initialize the memory pool. */ clDescTbl[0].memArea = pMemBuf; if (netPoolInit (pDrvCtrl->end.pNetPool, &mclBlkConfig, clDescTbl, 1, NULL) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Failed to intialize memory pool\n", 1, 2, 3, 4, 5, 6); goto dpMemInitFail; }#ifdef DRV_DEBUG dp83815Pool = pDrvCtrl->end.pNetPool;#endif /* Create Tx and Rx queues */ pMemBuf += clDescTbl[0].memSize; if (dp83815QueueCreate (pDrvCtrl, &pDrvCtrl->txQueue, pMemBuf, pDrvCtrl->txDescCount, DP_QUEUE_TYPE_TX) != OK) { printf ("Eth%d: Failed to create tx queue\n", pDrvCtrl->unit); goto dpMemInitFail; } pMemBuf += txQMemSize; if (dp83815QueueCreate (pDrvCtrl, &pDrvCtrl->rxQueue, pMemBuf, pDrvCtrl->rxDescCount, DP_QUEUE_TYPE_RX) != OK) { printf ("Eth%d: Failed to create rx queue\n", pDrvCtrl->unit); goto dpMemInitFail; } DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6); return OK; dpMemInitFail: { /* free memory allocated for mBlk-clBlks */ if (mclBlkConfig.memArea != NULL) /* free memory allocated for clusters and Tx/Rx Queues */ if ((pDrvCtrl->flags & DP83815_BUF_LOCAL) && (pDrvCtrl->pDmaBuf != NULL)) cacheDmaFree (pDrvCtrl->pDmaBuf); /* free memory allocated for net pool */ if (pDrvCtrl->end.pNetPool != NULL) free (pDrvCtrl->end.pNetPool); DRV_LOG (DRV_DEBUG_LOAD, "Memory Init failed..\n", 1, 2, 3, 4, 5, 6); return ERROR; } }/******************************************************************************** dp83815Start - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS dp83815Start ( VOID * pObj /* device ID */ ) { END_DEVICE *pDrvCtrl = pObj; /* device to be started */ UINT32 iobase = pDrvCtrl->baseAddr; /* base address of device */ STATUS result; /* Install interrupt vector */ SYS_INT_CONNECT (pDrvCtrl, dp83815Int, (int)pDrvCtrl, &result); if (result == ERROR) { return ERROR; } DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6); /* Turn on device interrupts */ DP_REG32_WRITE (DP_IMR,DP_IMR_RXOK ); DP_REG32_WRITE (DP_IER, DP_IER_IE); /* Enable Tx/Rx */ DP_REG32_WRITE (DP_CR, DP_CR_TXE | DP_CR_RXE); /* Enable the interrupt */ SYS_INT_ENABLE (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "Interrupt enabled.\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* dp83815Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void dp83815Int ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { UINT32 iobase = pDrvCtrl->baseAddr; UINT32 regIsr; regIsr = DP_REG32_READ (DP_ISR); DRV_LOG (DRV_DEBUG_INT, "dp%d: intStatus=0x%x ", pDrvCtrl->unit, regIsr, 3, 4, 5, 6); if (regIsr & DP_ISR_RXOK) { DRV_LOG (DRV_DEBUG_INT, "RX_INT ", pDrvCtrl->unit, 2, 3, 4, 5, 6); if ((pDrvCtrl->flags & DP83815_RCV) == NULL) { pDrvCtrl->flags |= DP83815_RCV; netJobAdd ((FUNCPTR)dp83815Recv, (int)pDrvCtrl, 0,0,0,0); } } DRV_LOG (DRV_DEBUG_INT, "\n", 1, 2, 3, 4, 5, 6); }/********************************************************************************* dp83815Recv - process the next incoming packet** Handle one incoming packet. The packet is checked for errors and sent* to the upper layer.** RETURNS: OK on success or ERROR.*/LOCAL STATUS dp83815Recv ( END_DEVICE *pDrvCtrl /* device structure */ ) { UINT32 cmdsts; int len; VIRT_ADDR rxDesc; M_BLK_ID pNewMblk; M_BLK_ID pRxMblk; UINT iobase = pDrvCtrl->baseAddr; /* Process all received packets */ for (rxDesc = dp83815RxDescGet (pDrvCtrl); (rxDesc != NULL); rxDesc = dp83815RxDescGet (pDrvCtrl)) { DRV_LOG (DRV_DEBUG_RX, "Rx: rxDesc=0x%x, CMDSTS = 0x%x\n", (UINT32)rxDesc, DP_DESC_CMDSTS_XLATE_GET(rxDesc), 3, 4, 5, 6); /* Increment the packet count */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); cmdsts = DP_DESC_CMDSTS_XLATE_GET (rxDesc); /* Send the packet to the stack if no errors */ if ((cmdsts & DP_DESC_CMDSTS_RX_ERRORS) == 0) { len = (cmdsts & DP_DESC_CMDSTS_SIZE) - ETH_CRC_LEN; /* Allocate a new replacement mblock tuple (mblk-clblk-cluster) */ pNewMblk = netTupleGet (pDrvCtrl->end.pNetPool, DP_BUF_SIZE, M_DONTWAIT, MT_DATA, FALSE); pRxMblk = (M_BLK_ID) DP_DESC_MBLKPTR_GET (rxDesc); END_CACHE_INVALIDATE (pRxMblk->mBlkHdr.mData, len); if (pNewMblk) { /* Replace the data buffer in the rxDesc */ DP_DESC_BUFPTR_XLATE_SET (rxDesc, (pNewMblk->mBlkHdr.mData+4));/*hanzhf*/ DP_DESC_MBLKPTR_SET (rxDesc, pNewMblk); /* Update the received Mblk */ pRxMblk->mBlkHdr.mData+=2;/*hanzhf*/ pRxMblk->mBlkHdr.mLen = len; pRxMblk->mBlkHdr.mFlags |= M_PKTHDR; pRxMblk->mBlkPktHdr.len = len; /* Make the data coherent and sent to the stack */ DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6); dp83815memAlign((char*)(pRxMblk->mBlkHdr.mData+4), len);/*hanzhf*/#ifdef DRV_DEBUG if (dp83815Debug & DRV_DEBUG_RX) dumpPkt (pRxMblk->mBlkHdr.mData, len);#endif END_RCV_RTN_CALL(&pDrvCtrl->end, pRxMblk); } else { /* Increment the dropped packet count -- no resources */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); } } else { /* Increment error statistics */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); /* bad packet */ } /* 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); } pDrvCtrl->flags &= ~(DP83815_RCV); return OK; }/********************************************************************************* dp83815Send - the driver send routine** 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. ** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815Send ( VOID * pObj, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { END_DEVICE * pDrvCtrl = pObj; /* device ptr */ VIRT_ADDR txDesc; UINT32 cmdsts,temp;/* hanzhf*/ UINT32 iobase = pDrvCtrl->baseAddr; M_BLK_ID pTxMblk; int len;#if 0 BOOL doCopy = (pMblk->mBlkHdr.mNext) ? TRUE: FALSE;#else BOOL doCopy = 1;#endif if (pDrvCtrl->flags & DP83815_POLLING) { netMblkClChainFree (pMblk);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -