📄 dp8381~1.c
字号:
pNewMblk = DP_DESC_MBLKPTR_GET (txDesc); /* 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); /* Update the descriptor */ len = netMblkToBufCopy (pMblk, pNewMblk->mBlkHdr.mData, NULL); END_CACHE_FLUSH (pNewMblk->mBlkHdr.mData, len); DP_DESC_CMDSTS_XLATE_SET (txDesc, DP_DESC_CMDSTS_OWN|len); END_CACHE_FLUSH (txDesc, DP_DESC_SIZE); DP_REG32_SET (DP_CR, DP_CR_TXE); END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* Wait until the packet is transmitted */ while (1) { END_CACHE_INVALIDATE (txDesc, DP_DESC_SIZE); if ((DP_DESC_CMDSTS_XLATE_GET (txDesc) & DP_DESC_CMDSTS_OWN) == 0) { break; } DRV_POLL_PRINT (DRV_DEBUG_POLL_TX, "+", 1, 2, 3, 4, 5, 6); } return (OK); }/******************************************************************************* dp83815MCastAdd - add a multicast address for the device** Thisroutine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815MCastAdd ( VOID *pObj, /* device pointer */ char* pAddress /* new address to add */ ) { END_DEVICE *pDrvCtrl = pObj; /* device pointer */ int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) dp83815RxFilterConfig (pDrvCtrl); return (OK); }/******************************************************************************* dp83815MCastDel - 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 dp83815MCastDel ( VOID *pObj, /* device pointer */ char* pAddress /* address to be deleted */ ) { END_DEVICE *pDrvCtrl = pObj; /* device pointer */ int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) dp83815RxFilterConfig (pDrvCtrl); return (OK); }/******************************************************************************* dp83815MCastGet - 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 dp83815MCastGet ( VOID *pObj, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { END_DEVICE *pDrvCtrl = pObj; /* device pointer */ return (etherMultiGet (&pDrvCtrl->end.multiList, pTable)); }/********************************************************************************* dp83815Stop - 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 dp83815Stop ( VOID *pObj /* device to be stopped */ ) { END_DEVICE *pDrvCtrl = pObj; /* device to be stopped */ STATUS result = OK; UINT32 iobase = pDrvCtrl->baseAddr; /* Disable Tx/Rx */ DP_REG32_WRITE (DP_CR, DP_CR_TXD | DP_CR_RXD); /* Disable device interrupts */ DP_REG32_WRITE (DP_IER, DP_IER_ID); /* Disconnect interrupt routine */ SYS_INT_DISCONNECT (pDrvCtrl, dp83815Int, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return (result); }/******************************************************************************** dp83815Unload - 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 dp83815Unload ( VOID* pObj /* device to be unloaded */ ) { END_DEVICE* pDrvCtrl = pObj; /* device to be unloaded */ /* Bring down the device */ END_OBJECT_UNLOAD (&pDrvCtrl->end); /* 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 mBlks and cluster blocks */ if (pDrvCtrl->pMclMem) free (pDrvCtrl->pMclMem); /* free memory allocated for net pool */ if (pDrvCtrl->end.pNetPool != NULL) free (pDrvCtrl->end.pNetPool); /* free memory allocated for device structure */ if (pDrvCtrl != NULL) free ((char*) pDrvCtrl); return (OK); }/********************************************************************************* dp83815PollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815PollStart ( VOID * pObj /* device to be polled */ ) { END_DEVICE *pDrvCtrl = pObj; /* device to be started */ UINT32 iobase = pDrvCtrl->baseAddr; /* base address of device */ UINT oldLevel; /* Turn off device interrupts */ oldLevel = intLock(); pDrvCtrl->flags |= DP83815_POLLING; DP_REG32_WRITE (DP_IER, DP_IER_ID); intUnlock (oldLevel); DRV_POLL_PRINT(DRV_DEBUG_POLL_MODE, "PollStart ", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* dp83815PollStop - 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 dp83815PollStop ( VOID * pObj /* device to be polled */ ) { END_DEVICE *pDrvCtrl = pObj; /* device to be started */ UINT32 iobase = pDrvCtrl->baseAddr; /* base address of device */ UINT oldLevel; /* Turn on device interrupts */ oldLevel = intLock(); pDrvCtrl->flags &= ~DP83815_POLLING; DP_REG32_WRITE (DP_IER, DP_IER_IE); intUnlock (oldLevel); DRV_POLL_PRINT(DRV_DEBUG_POLL_MODE, "PollStop ", 1, 2, 3, 4, 5, 6); return (OK); }/******************************************************************************** dp83815Reset - soft reset device** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815Reset ( END_DEVICE *pDrvCtrl ) { int timeout = 100; UINT32 iobase = pDrvCtrl->baseAddr; DP_REG32_WRITE (DP_CR, DP_CR_RST); while (timeout--) { if (DP_REG32_READ (DP_ISR) == 0x03008000) return (OK); UDELAY (5); } return ERROR;}/******************************************************************************** dp83815MacAddressSet - Set the ethernet address** Sets the ethernet address from the given address field** RETURNS: void*/LOCAL void dp83815MacAddressSet ( UINT32 iobase, /* base adress of device */ char * macAddr ) { UINT16 * macAddrPtr; int i; for (i=0, macAddrPtr = (UINT16*)macAddr; i<3; i++, macAddrPtr++) { DP_REG32_WRITE (DP_RFCR, DP_RFCR_RFADDR_PMATCH1 + i*2); DP_REG32_WRITE (DP_RFDR, CPU_TO_BUS_SWAP_16 (*macAddrPtr)); } }/******************************************************************************** dp83815MacAddressGet - get the ethernet address** Gets the ethernet address fro ROM and writes into the given address field** RETURNS: void*/LOCAL void dp83815MacAddressGet ( UINT32 iobase, /* base adress of device */ char * macAddr ) { UINT16 * macAddrPtr; int i; for (i=0, macAddrPtr = (UINT16*)macAddr; i<3; i++, macAddrPtr++) { DP_REG32_WRITE (DP_RFCR, DP_RFCR_RFADDR_PMATCH1 + i*2); *macAddrPtr = NET_TO_CPU_SWAP_16 (DP_REG32_READ (DP_RFDR)); } }/******************************************************************************** dp83815QueueCreate - create a circular queue of descriptors** This routine allocates a descriptor buffer array aligned on a word* boundary, initializes and links the array to make a circular queue.** RETURNS: OK or ERROR*/LOCAL STATUS dp83815QueueCreate ( END_DEVICE * pDrvCtrl, DP83815_QUEUE * q, char * pMem, int count, int qtype ) { int i; VIRT_ADDR descAddr; M_BLK_ID pMblk = NULL; /* pointer to the mBlk */ /* Initialize queue data */ q->curDescAddr = q->firstDescAddr = pMem; q->lastDescAddr = q->firstDescAddr + ((count -1) * DP_QUEUE_ELE_SIZE); q->count = count; /* Initialize each buffer descriptor, and link them into circular queue */ for (i=0, descAddr=q->firstDescAddr; i<count; i++, descAddr+=DP_QUEUE_ELE_SIZE) { DP_DESC_LNK_XLATE_SET (descAddr, descAddr + DP_QUEUE_ELE_SIZE); /* Update the size, BUFPTR, and MBLKPTR fields for RX descriptors */ if ((qtype == DP_QUEUE_TYPE_RX) || (qtype == DP_QUEUE_TYPE_TX)) { /* get a mBlk/clBlk/cluster tuple */ pMblk = netTupleGet (pDrvCtrl->end.pNetPool, DP_BUF_SIZE, M_DONTWAIT, MT_DATA, FALSE); if (pMblk == NULL) { dp83815QueueDelete (q); return (ERROR); } DP_DESC_CMDSTS_XLATE_SET (descAddr, DP_BUF_SIZE); if (qtype == DP_QUEUE_TYPE_RX) /*hanzhf*/ DP_DESC_CMDSTS_XLATE_SET (descAddr, 0x20000000|DP_BUF_SIZE); DP_DESC_BUFPTR_XLATE_SET (descAddr, pMblk->mBlkHdr.mData); if (qtype == DP_QUEUE_TYPE_RX) /*hanzhf*/ DP_DESC_BUFPTR_XLATE_SET (descAddr, (pMblk->mBlkHdr.mData+4)); DP_DESC_MBLKPTR_SET (descAddr, pMblk); } } /* Make the queue circular */ DP_DESC_LNK_XLATE_SET (q->lastDescAddr, q->firstDescAddr); return OK;}/******************************************************************************** dp83815QueueDelete - frees an allocated descriptor queue** This routine frees all allocated memory for a descriptor queue.** RETURNS: OK*/LOCAL STATUS dp83815QueueDelete ( struct dp83815_queue *q ) { int i; VIRT_ADDR descAddr; M_BLK_ID pMblk = NULL; /* pointer to the mBlk */ /* Free all mBlk/clBlk/cluster tuples in the queue */ for (i=0, descAddr=q->firstDescAddr; (i < q->count); i++, descAddr += DP_QUEUE_ELE_SIZE) { pMblk = (M_BLK_ID) DP_DESC_MBLKPTR_GET (descAddr); if (pMblk != NULL) netMblkClFree (pMblk); } return (OK); }/************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -