📄 el3c90xend.c
字号:
** RETURNS: OK or ERROR**/LOCAL STATUS el3c90xStart ( void * pEnd /* device to be started */ ) { STATUS result; EL3C90X_DEVICE * pDrvCtrl; int flags; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); pDrvCtrl->txBlocked = FALSE; /* perform all initialization memory, ring buffer etc */ el3c90xInit(pDrvCtrl); flags = END_FLAGS_GET (&pDrvCtrl->endObj); flags |= IFF_RUNNING; END_FLAGS_SET (&pDrvCtrl->endObj, flags); SYS_INT_CONNECT (pDrvCtrl, el3c90xInt, (int)pDrvCtrl, &result); if (result == ERROR) return ERROR; ENDLOGMSG (("Interrupt connected.\n", 1, 2, 3, 4, 5, 6)); SYS_INT_ENABLE (pDrvCtrl); ENDLOGMSG (("interrupt enabled.\n", 1, 2, 3, 4, 5, 6)); return (OK); }/********************************************************************************* el3c90xStop - 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 el3c90xStop ( void * pEnd /* device to be stopped */ ) { STATUS result = OK; EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); el3c90xDevStop (pDrvCtrl); SYS_INT_DISCONNECT (pDrvCtrl, el3c90xInt, (int)pDrvCtrl, &result); if (result == ERROR) { ENDLOGMSG (("Could not diconnect interrupt!\n", 1, 2, 3, 4, 5, 6)); } SYS_INT_DISABLE (pDrvCtrl); return (result); }/******************************************************************************** el3c90xUnload - 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 el3c90xUnload ( void * pEnd /* device to be unloaded */ ) { EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); END_OBJECT_UNLOAD (&pDrvCtrl->endObj); /* Free the shared DMA memory. */ if (pDrvCtrl->flags & EL_MEM_ALLOC_FLAG) { /* free the memory allocated for descriptors */ if (pDrvCtrl->pDescMem != NULL) cacheDmaFree (pDrvCtrl->pDescMem); /* free the memory allocated for clusters */ if (pDrvCtrl->clDesc.memArea != NULL) cacheDmaFree (pDrvCtrl->clDesc.memArea); /* Free the memory allocated for mBlks and clBlks */ if (pDrvCtrl->mClCfg.memArea != NULL) free (pDrvCtrl->mClCfg.memArea); } if (pDrvCtrl->endObj.pNetPool != NULL) free (pDrvCtrl->endObj.pNetPool); return (OK); }/********************************************************************************* el3c90xIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, OK or ERROR or EINVAL.*/LOCAL int el3c90xIoctl ( void * pEnd, /* device ptr*/ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); switch (cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj), END_HADDR_LEN(&pDrvCtrl->endObj)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->endObj), (char *)data, END_HADDR_LEN(&pDrvCtrl->endObj)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pDrvCtrl->endObj, value); } else { END_FLAGS_SET (&pDrvCtrl->endObj, value); } if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_UP) { el3c90xInit (pDrvCtrl); } else { if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_RUNNING) el3c90xDevStop (pDrvCtrl); } error = 0; break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); break; case EIOCPOLLSTART: error = el3c90xPollStart(pDrvCtrl); break; case EIOCPOLLSTOP: error = el3c90xPollStop(pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); *(int *)data = EL_MIN_FBUF; break; case EIOCGMWIDTH: if (data == NULL) return (EINVAL); break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = EH_SIZE; break; default: error = EINVAL; } return (error); }/********************************************************************************* el3c90xSend - the driver send routine** This routine takes a M_BLK_ID 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 END_ERR_BLOCK or ERROR.*/LOCAL STATUS el3c90xSend ( void * pEnd, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { EL3C90X_DEVICE * pDrvCtrl; EL_DESC_CHAIN * pTxChain = NULL; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); /* return if in polled mode */ if (pDrvCtrl->flags & EL_POLLING) return (ERROR); DRV_LOG (DRV_DEBUG_TX, "Send\n", 1, 2, 3, 4, 5, 6); END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* get a free download descriptor */ if ((pTxChain = el3c90xDndGet (pDrvCtrl)) == NULL) { DRV_LOG (DRV_DEBUG_TX, "Out of TMDs!\n", 1, 2, 3, 4, 5, 6); pDrvCtrl->txBlocked = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } /* Pack the data into the descriptor. */ if (el3c90xDndSet(pDrvCtrl, pTxChain, pMblk) == ERROR) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ el3c90xDndFree (pDrvCtrl, pTxChain); END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (ERROR); } /* set the interrupt bit for the downloaded packet */ pTxChain->pDesc->status |= PCI_SWAP (EL_TXSTAT_DL_INTR); el3c90xDndEnqueue (pDrvCtrl, pTxChain); END_TX_SEM_GIVE (&pDrvCtrl->endObj); /* kick the reciever if blocked, parallel tasking */ el3c90xRxKick (pDrvCtrl); return (OK); }/******************************************************************************* el3c90xMCastAdd - 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 el3c90xMCastAdd ( void * pEnd, /* device pointer */ char * pAddress /* new address to add */ ) { int error; EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddress)) == ENETRESET) el3c90xMcastConfig (pDrvCtrl); return (OK); }/******************************************************************************* el3c90xMCastDel - 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 el3c90xMCastDel ( void * pEnd, /* device pointer */ char * pAddress /* address to be deleted */ ) { int error; EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList, (char *)pAddress)) == ENETRESET) el3c90xMcastConfig (pDrvCtrl); return (OK); }/******************************************************************************* el3c90xMCastGet - 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 el3c90xMCastGet ( void * pEnd, /* device pointer */ MULTI_TABLE * pTable /* address table to be filled in */ ) { EL3C90X_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/********************************************************************************* el3c90xPollSend - 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 el3c90xPollSend ( void * pEnd, /* device pointer */ M_BLK_ID pMblk /* packet to send */ ) { EL3C90X_DEVICE * pDrvCtrl; EL_DESC_CHAIN * pTxChain = NULL; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); DRV_LOG (DRV_DEBUG_POLL_TX, "PTX b\n", 1, 2, 3, 4, 5, 6); /* check if download engine is still busy */ if (el3c90xCsrReadLong (pDrvCtrl, EL_DOWNLIST_PTR, NONE)) { DRV_LOG (DRV_DEBUG_POLL_TX, "transmitter busy\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } /* check if a download descriptor is available */ if ((pTxChain = el3c90xDndGet (pDrvCtrl)) == NULL) return (EAGAIN); /* Pack the mBlk into the download descriptor. */ if (el3c90xDndMblkPack (pDrvCtrl, pTxChain, pMblk) == ERROR) { el3c90xDndFree (pDrvCtrl, pTxChain); return (EAGAIN); } el3c90xCsrWriteLong (pDrvCtrl, EL_DOWNLIST_PTR, (UINT32)EL3C90X_CACHE_VIRT_TO_PHYS (pTxChain->pDesc), NONE); /* wait until download has completed */ while (el3c90xCsrReadLong (pDrvCtrl, EL_DOWNLIST_PTR, NONE)) ; netMblkClChainFree (pTxChain->pMblk); el3c90xDndFree (pDrvCtrl, pTxChain); DRV_LOG (DRV_DEBUG_POLL_TX, "PTX e\n", 1, 2, 3, 4, 5, 6);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -