📄 ei82596end.c
字号:
(sizeof (TFD) * pDrvCtrl->nTFDs) + /* pool of transmit frames */ (sizeof (TFD)); /* one TFD for polled TX */ /* Establish the memory area that we will share with the device. If * the caller has provided an area, then we assume it is non-cacheable * and will not require the use of the special cache routines. * If the caller did not provide an area, then we must obtain it from * the system, using the cache savvy allocation routine. */ switch ((int) pDrvCtrl->memBase) { case NONE : /* we must obtain it */ /* this driver can't handle incoherent caches */ if (!CACHE_DMA_IS_WRITE_COHERENT () || !CACHE_DMA_IS_READ_COHERENT ()) { printf (errMsg2); return (ERROR); } pDrvCtrl->memBase = cacheDmaMalloc (size); DRV_FLAGS_SET(EI_MEMOWN); if (pDrvCtrl->memBase == NULL) /* no memory available */ { printf (errMsg1); return (ERROR); } pDrvCtrl->cacheFuncs = cacheDmaFuncs; break; default : /* the user provided an area */ pDrvCtrl->cacheFuncs = cacheNullFuncs; DRV_FLAGS_CLR (EI_MEMOWN); break; } /* Carve up the shared memory region into the specific sections */ bzero ((char *) pDrvCtrl->memBase, size); pDrvCtrl->pScp = (SCP *) /* align to first 16 byte page */ ( ((u_long) pDrvCtrl->memBase + 0xf) & ~0xf ); pDrvCtrl->pIscp = (ISCP *)((int)pDrvCtrl->pScp + sizeScp); pDrvCtrl->pScb = (SCB *) ((int)pDrvCtrl->pIscp + sizeIscp); pDrvCtrl->pCfd = (CFD *) ((int)pDrvCtrl->pScb + sizeScb); if (eiMclBlkConfig.memArea == NULL) /* do a default allocation */ { /* memory size adjusted to hold the netPool pointer at the head */ eiMclBlkConfig.memSize = ((eiMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (eiMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)))); if ((eiMclBlkConfig.memArea = (char *) memalign (sizeof(long), eiMclBlkConfig.memSize)) == NULL) return (ERROR); } eiClDescTbl[0].memArea = (char *) ((int)pDrvCtrl->pCfd + sizeCfd); eiClDescTbl[0].memSize = ((eiClDescTbl[0].clSize + 4) * eiClDescTbl[0].clNum); if (netPoolInit (pDrvCtrl->endObj.pNetPool, &eiMclBlkConfig, &eiClDescTbl [0], eiClDescTblNumEnt, NULL) == ERROR) return (ERROR); if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, sizeof (RFD), FALSE)) == NULL) return (ERROR); pDrvCtrl->tfdPool = (TFD *) ((int)eiClDescTbl[0].memArea + eiClDescTbl[0].memSize); pDrvCtrl->pPollTfd = (TFD *) ((int)pDrvCtrl->tfdPool + (sizeof(TFD) * pDrvCtrl->nTFDs)); return (OK); }/********************************************************************************* ei82596Start - start the device** RETURNS: OK or ERROR*/LOCAL STATUS ei82596Start ( END_CTRL *pDrvCtrl ) { int ret_val; DRV_LOG (DRV_DEBUG_LOAD, "eiStart ... begin\n", 0, 0, 0, 0, 0, 0); SYS_INT_DISABLE (pDrvCtrl); /* Start the device */ if (ei82596DeviceStart (pDrvCtrl) == ERROR) return ERROR; /*goto error;*/ /* run diagnostics */ if (ei82596Diag (pDrvCtrl) == ERROR) return ERROR; /*goto error;*/ if (END_FLAGS_ISSET (&pDrvCtrl->endObj, IFF_MULTICAST)) DRV_FLAGS_SET (EI_MCAST); ei82596Config (pDrvCtrl); /* configure chip */ ei82596IASetup (pDrvCtrl); /* setup address */ /* Connect the interrupt handler */ SYS_INT_CONNECT (pDrvCtrl, ei82596Int, (int)pDrvCtrl, &ret_val); if (ret_val == ERROR) return (ERROR); /* enable interrupts */ sys596IntAck (pDrvCtrl->unit); SYS_INT_ENABLE (pDrvCtrl); /* start the watchdog */ wdCancel(pDrvCtrl->wid); wdStart(pDrvCtrl->wid, (int) pDrvCtrl->wdInterval, (FUNCPTR) ei82596WatchDog, (int) pDrvCtrl); /* start the receiver */ ei82596RxStartup (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "eiStart ... Done\n", 0, 0, 0, 0, 0, 0); /* mark the interface -- up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); return OK; }/********************************************************************************* ei82596Stop - stop the device** This routine cancels the watchdog, disables interrupts, and resets the device.** RETURNS: OK or ERROR*/LOCAL STATUS ei82596Stop ( END_CTRL *pDrvCtrl ) { int ret_val; /* mark the interface -- down */ END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); wdCancel(pDrvCtrl->wid); SYS_INT_DISABLE( pDrvCtrl ); sys596Port (pDrvCtrl->unit, PORT_RESET, 0); SYS_INT_DISCONNECT (pDrvCtrl, ei82596Int, (int)pDrvCtrl, &ret_val); return OK; }/********************************************************************************* ei82596Ioctl - interface ioctl procedure** Process an interface ioctl request.*/LOCAL int ei82596Ioctl ( END_CTRL * pDrvCtrl, int cmd, caddr_t data ) { int error=0; long value; int savedFlags; END_OBJ * pEndObj=&pDrvCtrl->endObj; DRV_LOG (DRV_DEBUG_IOCTL, "eiIoctl\n", 0, 0, 0, 0, 0, 0); switch (cmd) { case EIOCSADDR: if (data == NULL) error = EINVAL; else { /* Copy and install the new address */ bcopy ((char *)data, (char *)END_HADDR(pEndObj), END_HADDR_LEN(pEndObj)); ei82596IASetup (pDrvCtrl); } break; case EIOCGADDR: if (data == NULL) error = EINVAL; else bcopy ((char *)END_HADDR(pEndObj), (char *)data, END_HADDR_LEN(pEndObj));#ifdef DRV_DEBUG { char *cp = (char *)data; DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGADDR: %x:%x:%x:%x:%x:%x\n", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); }#endif /*DRV_DEBUG*/ break; case EIOCSFLAGS: value = (long) data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (pEndObj, value); } else END_FLAGS_SET (pEndObj, value); /* handle IFF_PROMISC and IFF_ALLMULTI */ savedFlags = DRV_FLAGS_GET(); if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC)) DRV_FLAGS_SET (EI_PROMISC); else DRV_FLAGS_CLR (EI_PROMISC); if (END_FLAGS_GET(pEndObj) & (IFF_MULTICAST | IFF_ALLMULTI)) DRV_FLAGS_SET (EI_MCAST); else DRV_FLAGS_CLR (EI_MCAST); if ((DRV_FLAGS_GET() != savedFlags) && (END_FLAGS_GET(pEndObj) & IFF_UP)) { END_FLAGS_CLR(pEndObj, IFF_UP | IFF_RUNNING); /* config down */ ei82596Config (pDrvCtrl); } break; case EIOCGFLAGS: DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS: 0x%x: 0x%x\n", pEndObj->flags, *(long *)data, 0, 0, 0, 0); if (data == NULL) error = EINVAL; else *(long *)data = END_FLAGS_GET(pEndObj); break; case EIOCMULTIADD: error = ei82596MCastAdrsAdd (pDrvCtrl, (char *)data); break; case EIOCMULTIDEL: error = ei82596MCastAdrsDel (pDrvCtrl, (char *)data); break; case EIOCMULTIGET: error = ei82596MCastAdrsGet (pDrvCtrl, (MULTI_TABLE *)data); break; case EIOCPOLLSTART: ei82596PollStart (pDrvCtrl); break; case EIOCPOLLSTOP: ei82596PollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) error=EINVAL; else bcopy((char *)&pEndObj->mib2Tbl, (char *)data, sizeof(pEndObj->mib2Tbl)); break; default: error = EINVAL; } return (error); }/********************************************************************************* ei82596MCastAdrsAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. **/LOCAL STATUS ei82596MCastAdrsAdd ( END_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_IOCTL, "eiMCastAdrsAdd - %x:%x:%x:%x:%x:%x\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]); retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) { pDrvCtrl->endObj.nMulti++; if (pDrvCtrl->endObj.nMulti > N_MCAST) { etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); pDrvCtrl->endObj.nMulti--; } else return ei82596MCastConfig (pDrvCtrl); } return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* ei82596MCastAdrsDel - delete a multicast address for the device** This routine deletes a multicast address from the current list of* multicast addresses.**/LOCAL STATUS ei82596MCastAdrsDel ( END_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_LOAD, "eiMCastAdrsDel\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) { pDrvCtrl->endObj.nMulti--; return ei82596MCastConfig (pDrvCtrl); } return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* ei82596MCastAdrsGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>**/LOCAL STATUS ei82596MCastAdrsGet ( END_CTRL * pDrvCtrl, MULTI_TABLE *pTable ) { DRV_LOG (DRV_DEBUG_LOAD, "eiMCastAdrsGet\n", 0, 0, 0, 0, 0, 0); return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/********************************************************************************* ei82596MCastConfig - configure multicast addresses.**/LOCAL STATUS ei82596MCastConfig ( END_CTRL *pDrvCtrl ) { int count=0; char *pAddr; ETHER_MULTI *pMCastNode; DRV_LOG (DRV_DEBUG_IOCTL, "eiMCastConfig\n", 0, 0, 0, 0, 0, 0); bzero ((char *)&pDrvCtrl->pCfd->cfdMcast, sizeof (AC_MCAST)); pAddr = (char *)pDrvCtrl->pCfd->cfdMcast.cmAddrList; pMCastNode = (ETHER_MULTI *)lstFirst (&pDrvCtrl->endObj.multiList); while (pMCastNode != NULL) { count++; bcopy (pMCastNode->addr, pAddr, 6); pAddr += 6; pMCastNode = (ETHER_MULTI *)lstNext (&pMCastNode->node); } pDrvCtrl->pCfd->cfdMcast.cmMcCount = count * 6; /* byte count */ SYS_INT_DISABLE( pDrvCtrl ); ei82596Action (pDrvCtrl, CFD_C_MASETUP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -