📄 dec21x40end.c
字号:
goto restart; } else { DRV_LOG (DRV_DEBUG_LOAD, "10Mbps link failed - aborting\n", 0,0,0,0,0,0); return ERROR; } } } /* setup ethernet address and filtering mode */ dec21x40IASetup (pDrvCtrl); /* set operating mode and start the receiver */ dec21x40ModeSet (pDrvCtrl); /* set up the interrupts */ pDrvCtrl->intrMask = (CSR7_NIM | /* normal interrupt mask */ CSR7_RIM | /* rcv interrupt mask */ CSR7_TIM | /* xmit interrupt mask */ CSR7_TUM | /* xmit buff unavailble mask */ CSR7_AIM | /* abnormal interrupt mask */ CSR7_SEM | /* system error mask */ CSR7_RUM ); /* rcv buff unavailable mask */ DEC_CSR_WRITE (CSR7, pDrvCtrl->intrMask); if (DRV_FLAGS_ISSET (DEC_21040)) DEC_CSR_UPDATE (CSR7, CSR7_21040_LFM); /* link fail mask */ /* Connect the interrupt handler */ SYS_INT_CONNECT (pDrvCtrl, dec21x40Int, pDrvCtrl, &retVal); if (retVal == ERROR) return (ERROR); /* mark the interface -- up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* Enable LAN interrupts */ SYS_INT_ENABLE (pDrvCtrl); pDrvCtrl->rxLen = 0; pDrvCtrl->rxMaxLen = RWIN; return OK; }/********************************************************************************* dec21x40Stop - stop the device** This routine disables interrupts, and resets the device.** RETURNS: OK or ERROR*/LOCAL STATUS dec21x40Stop ( DRV_CTRL *pDrvCtrl ) { int retVal = OK; PHY_INFO * pPhyInfo = pDrvCtrl->pPhyInfo; DRV_LOG (DRV_DEBUG_LOAD, "Stop\n", 0, 0, 0, 0, 0, 0); /* mark the interface -- down */ END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); /* Disable LAN interrupts */ SYS_INT_DISABLE (pDrvCtrl); /* stop transmit and receive */ DEC_CSR_RESET (CSR6, CSR6_ST | CSR6_SR); if ((pPhyInfo != NULL) && MII_PHY_FLAGS_ARE_SET (MII_PHY_INIT)) { if (intCnt == 0) { if (miiPhyUnInit (pPhyInfo) == ERROR) return (ERROR); free (pPhyInfo); } else { /* * Defer these to task level since they cannot be performed at * interrupt level */ netJobAdd ((FUNCPTR) miiPhyUnInit, (int) pPhyInfo, 0,0,0,0); netJobAdd ((FUNCPTR) free, (int) pPhyInfo, 0,0,0,0); } pDrvCtrl->pPhyInfo = NULL; } /* disconnect interrupt */ SYS_INT_DISCONNECT (pDrvCtrl, dec21x40Int, (int)pDrvCtrl, &retVal); return (retVal); }/********************************************************************************* dec21x40MediaChange - start the device** Restarts the device after cleaning up the transmit and receive queues. This* routine should be called only after dec21x40Stop().** RETURNS: OK or ERROR*/LOCAL STATUS dec21x40MediaChange ( DRV_CTRL *pDrvCtrl ) { if (dec21x40Stop (pDrvCtrl) == ERROR) return (ERROR); DRV_LOG (DRV_DEBUG_ALL, "%s%d - stopped device.\n", (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); netJobAdd ((FUNCPTR) dec21x40Restart, (int) pDrvCtrl, 0,0,0,0); return (OK); }/********************************************************************************* dec21x40Restart - start the device** Restarts the device after cleaning up the transmit and receive queues. This* routine should be called only after dec21x40Stop().** RETURNS: OK or ERROR*/LOCAL void dec21x40Restart ( DRV_CTRL *pDrvCtrl ) { DEC_TD *pTxD = pDrvCtrl->txRing; FREE_BUF *pFreeBuf = pDrvCtrl->freeBuf; int count; DRV_LOG (DRV_DEBUG_ALL, "%s%d - restarting device.\n", (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); /* cleanup the tx and rx queues */ dec21x40TxRingClean (pDrvCtrl); dec21x40RxIntHandle (pDrvCtrl); /* drop rest of the queued tx packets */ for (count=pDrvCtrl->numTds; count; count--, pTxD++, pFreeBuf++) { if (pFreeBuf->pClBuf != NULL) { NET_BUF_FREE(pFreeBuf->pClBuf); pFreeBuf->pClBuf = NULL; } DEC_CACHE_INVALIDATE (pTxD, TD_SIZ); if (pTxD->tDesc1 & PCISWAP(TDESC1_SET)) { pTxD->tDesc1 &= PCISWAP(~(TDESC1_SET | TDESC1_FT0)); pTxD->tDesc0 = 0; } else if (pTxD->tDesc0 & PCISWAP(TDESC0_OWN|TDESC0_ES)) { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1); pTxD->tDesc0 = 0; } } /* Reset indices */ pDrvCtrl->rxIndex=0; pDrvCtrl->txIndex=0; pDrvCtrl->txDiIndex=0; /* Restart the device */ dec21x40Start (pDrvCtrl); }/********************************************************************************* dec21x40Ioctl - interface ioctl procedure** Process an interface ioctl request.** This routine implements the network interface control functions.* It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,* EIOCMULTIDEL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.** RETURNS: OK if successful, otherwise EINVAL.*/LOCAL int dec21x40Ioctl ( DRV_CTRL * pDrvCtrl, int cmd, caddr_t data ) { int error=0; long value; int savedFlags; END_OBJ * pEndObj=&pDrvCtrl->endObj; DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 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)); dec21x40IASetup (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 IIF_PROMISC and IFF_ALLMULTI */ savedFlags = DRV_FLAGS_GET(); if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC)) DRV_FLAGS_SET (DEC_PROMISC); else DRV_FLAGS_CLR (DEC_PROMISC); if (END_FLAGS_GET(pEndObj) & (IFF_MULTICAST | IFF_ALLMULTI)) DRV_FLAGS_SET (DEC_MCAST); else DRV_FLAGS_CLR (DEC_MCAST); DRV_LOG (DRV_DEBUG_IOCTL, "endFlags=0x%x savedFlags=0x%x newFlags=0x%x\n", END_FLAGS_GET(pEndObj), savedFlags, DRV_FLAGS_GET(), 0, 0, 0); if ((DRV_FLAGS_GET() != savedFlags) && (END_FLAGS_GET(pEndObj) & IFF_UP)) dec21x40ModeSet (pDrvCtrl); break; case EIOCGFLAGS: /* move to mux */ 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: /* move to mux */ error = dec21x40MCastAddrAdd (pDrvCtrl, (char *)data); break; case EIOCMULTIDEL: /* move to mux */ error = dec21x40MCastAddrDel (pDrvCtrl, (char *)data); break; case EIOCMULTIGET: /* move to mux */ error = dec21x40MCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data); break; case EIOCPOLLSTART: /* move to mux */ dec21x40PollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* move to mux */ dec21x40PollStop (pDrvCtrl); break; case EIOCGMIB2: /* move to mux */ if (data == NULL) error=EINVAL; else bcopy((char *)&pEndObj->mib2Tbl, (char *)data, sizeof(pEndObj->mib2Tbl)); break; default: error = EINVAL; } return (error); }/********************************************************************************* dec21x40ModeSet - promiscuous & multicast operation and start receiver** RETURNS: N/A*/LOCAL void dec21x40ModeSet ( DRV_CTRL *pDrvCtrl ) { int opMode = CSR6_SR; /* start receiver */ DRV_LOG (DRV_DEBUG_IOCTL, "ModeSet\n", 0, 0, 0, 0, 0, 0); if (DRV_FLAGS_ISSET (DEC_MCAST)) opMode |= CSR6_PM; /* rx multicast */ if (DRV_FLAGS_ISSET (DEC_PROMISC)) opMode |= CSR6_PR; /* rx promiscuous */ DEC_CSR_WRITE (CSR6, (DEC_CSR_READ (CSR6) & ~(CSR6_PM|CSR6_PR)) | opMode); return; }/********************************************************************************* dec21x40HashIndex - compute the hash index for an ethernet address** RETURNS: hash index for an ethernet address.*/LOCAL int dec21x40HashIndex ( char * eAddr ) { UINT8 eAddrByte; int index; /* hash index - return value */ int byte; /* loop - counter */ int bit; /* loop - counter */ UINT crc = 0xffffffff; UINT8 msb; for (byte=0; b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -