📄 dec21x40end.c
字号:
if (usrFlags & DEC_USR_THR_MSK) csr6Val |= (usrFlags & DEC_USR_THR_MSK) >> DEC_USR_THR_SHF; if (usrFlags & DEC_USR_SB) csr6Val |= CSR6_SB; if (usrFlags & DEC_USR_PB) csr6Val |= CSR6_PB; if (usrFlags & DEC_USR_SC) csr6Val |= CSR6_21140_SC; if (usrFlags & DEC_USR_CA) csr6Val |= CSR6_CAE; } else dec21040AuiTpInit (pDrvCtrl); /* Write start of receive ring */ DEC_CSR_WRITE (CSR3, DEC_VIRT_TO_PCI(pDrvCtrl->rxRing)); /* Write start of transmit ring */ DEC_CSR_WRITE (CSR4, DEC_VIRT_TO_PCI(pDrvCtrl->txRing)); /* clear the status register */ DEC_CSR_WRITE (CSR5, 0xffffffff); /* setup CSR6 - start transmitter */ DEC_CSR_WRITE (CSR6, csr6Val | CSR6_ST); /* 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); 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; 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); /* stop transmit and receive */ DEC_CSR_RESET (CSR6, CSR6_ST | CSR6_SR); /* Disable LAN interrupts */ SYS_INT_DISABLE (pDrvCtrl); /* disconnect interrupt */ SYS_INT_DISCONNECT (pDrvCtrl, dec21x40Int, (int)pDrvCtrl, &retVal); return (retVal); }/********************************************************************************* 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; logMsg ("%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_PRINT (DRV_DEBUG_IOCTL, ("endFlags=0x%x savedFlags=0x%x newFlags=0x%x\n", END_FLAGS_GET(pEndObj), savedFlags, DRV_FLAGS_GET())); 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; byte<6; byte++) { eAddrByte = eAddr[byte]; for (bit=0; bit<8; bit++) { msb = crc >> 31; crc <<= 1; if (msb ^ (eAddrByte & 0x1)) { crc ^= DEC_CRC_POLY; crc |= 0x1; } eAddrByte >>= 1; } } /* * return the upper 9 bits of the CRC in a decreasing order of * significance. * crc <31..23> as index <0..8> */ index = 0; for (bit=0; bit<9; bit++) index |= ((crc >> (31-bit)) & 0x1) << bit; return index; }/********************************************************************************* dec21x40IASetup - set up physical and multicast addresses** This routine sets up a filter frame to filter the physical addresses* and all the current multicast addresses.** While the first call to this routine during chip initialization requires* that the receiver be turned off, subsequent calls do not.* * RETURNS: OK or ERROR.*/LOCAL STATUS dec21x40IASetup ( DRV_CTRL * pDrvCtrl /* pointer to device control structure */ ) { UINT8 ethBcastAdrs[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; UINT8 *pFltrFrm; UINT8 *pAdrs; ETHER_MULTI *pMCastNode; DEC_TD *pTxD; ULONG csr7Val; char * pBuf; int index; int timeout; DRV_LOG (DRV_DEBUG_IOCTL, "IASetup\n", 0, 0, 0, 0, 0, 0); /* gain exclusive access to transmitter */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -