📄 el3c90xend.c
字号:
if (tok == NULL) return ERROR; devIoAddr = (UINT32) strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "devIoAddr : 0x%X ...\n", devIoAddr, 2, 3, 4, 5, 6); /* always use memory mapped IO if provided, else use io map */ if ((devMemAddr == NONE) && (devIoAddr == NONE)) { DRV_LOG (DRV_DEBUG_LOAD, "No memory or IO base specified ...\n", 1, 2, 3, 4, 5, 6); return (ERROR); } else if (devMemAddr != NONE) { pDrvCtrl->devAdrs = devMemAddr; pDrvCtrl->flags |= EL_MODE_MEM_IO_MAP; } else { pDrvCtrl->devAdrs = devIoAddr; } /* PCI memory base address as seen from the CPU */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase, 2, 3, 4, 5, 6); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec, 2, 3, 4, 5, 6); /* Interrupt level. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->intLevel = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->intLevel, 2, 3, 4, 5, 6); /* Caller supplied memory address. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs, 2, 3, 4, 5, 6); /* Caller supplied memory size. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->memSize = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize, 2, 3, 4, 5, 6); /* Caller supplied memory width. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->memWidth = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth, 2, 3, 4, 5, 6); /* caller supplied flags */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->flags |= strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags, 2, 3, 4, 5, 6); /* buffer multiplier */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->bufMtplr |= strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "bufMultiplier : 0x%X ...\n", pDrvCtrl->bufMtplr, 2, 3, 4, 5, 6); return OK; }/********************************************************************************* el3c90xStart - 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 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_UP | 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; 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;#ifndef INCLUDE_RFC_1213 /* New RFC 2233 mib2 interface */ case EIOCGMIB2233: if ((data == NULL) || (pDrvCtrl->endObj.pMib2Tbl == NULL)) error = EINVAL; else *((M2_ID **)data) = pDrvCtrl->endObj.pMib2Tbl; break;#endif /* INCLUDE_RFC_1213 */ 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) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ errno = EINVAL; 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); }#ifndef INCLUDE_RFC_1213 /* New RFC 2233 mib2 interface */ /* RFC 2233 mib2 counter update for outgoing packet */ if (pDrvCtrl->endObj.pMib2Tbl != NULL) { pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.pMib2Tbl, M2_PACKET_OUT, pMblk->mBlkHdr.mData, pMblk->mBlkHdr.mLen); }#endif /* INCLUDE_RFC_1213 */ /* set the interrupt bit for the downloaded packet */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -