📄 ns83902end.c
字号:
} saveFlags = DRV_FLAGS_GET(); if (DRV_FLAGS_GET() != saveFlags && (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_UP)) { END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); ns83902Config( pDrvCtrl ); } break; case EIOCGFLAGS: if (data == NULL) error = EINVAL; else *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); break; case EIOCMULTIADD: /* move to mux */ error = ns83902MCastAddrAdd (pDrvCtrl, (char *)data); break; case EIOCMULTIDEL: /* move to mux */ error = ns83902MCastAddrDel (pDrvCtrl, (char *)data); break; case EIOCMULTIGET: /* move to mux */ error = ns83902MCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data); break; case EIOCPOLLSTART: /* move to mux */ error = ns83902PollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* move to mux */ error = ns83902PollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; default: error = EINVAL; } return (error); } /********************************************************************************* ns83902Stop - 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 ns83902Stop ( NS83902_END_DEVICE* pDrvCtrl ) { STATUS result = OK; END_FLAGS_CLR (&pDrvCtrl->endObj,IFF_UP | IFF_RUNNING ); /* Stop the device. */ NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_STP | CR_ABORT, CR_RPAGE0); /* disable all interrupts */ NS83902_REG_SET (pDrvCtrl, NS83902_IMR, IMR_DISABLE, CR_RPAGE0); /* Disable LAN interrupts */ SYS_INT_DISABLE (pDrvCtrl); /* disconnect interrupt */ SYS_INT_DISCONNECT (pDrvCtrl, ns83902Int, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (NS83902_DEBUG_TMP, "Could not diconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return (result); }/******************************************************************************** ns83902Unload - 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.*/LOCAL STATUS ns83902Unload ( NS83902_END_DEVICE* pDrvCtrl ) { if (pDrvCtrl != NULL) { END_OBJECT_UNLOAD (&pDrvCtrl->endObj); /* free resources */ if (pDrvCtrl->pCluster != NULL) free (pDrvCtrl->pCluster); } return (OK); }/********************************************************************************* ns83902MCastAddrAdd - add a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS ns83902MCastAddrAdd ( NS83902_END_DEVICE* pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (NS83902_DEBUG_IOCTL, "MCastAddrAdd\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) return ns83902AddrFilterSet (pDrvCtrl, pAddr, TRUE); return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* ns83902MCastAddrDel - remove a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS ns83902MCastAddrDel ( NS83902_END_DEVICE* pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (NS83902_DEBUG_IOCTL, "MCastAddrDel\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) return ns83902AddrFilterSet (pDrvCtrl, pAddr, FALSE); return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* ns83902MCastAddrGet - retreive current multicast address list*** RETURNS: OK on success; otherwise ERROR.*/LOCAL STATUS ns83902MCastAddrGet ( NS83902_END_DEVICE* pDrvCtrl, MULTI_TABLE * pTable ) { DRV_LOG (NS83902_DEBUG_IOCTL, "MCastAddrGet\n", 0, 0, 0, 0, 0, 0); return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/********************************************************************************* ns83902PollStart - starting polling mode** RETURNS: OK, always.*/LOCAL STATUS ns83902PollStart ( NS83902_END_DEVICE* pDrvCtrl ) { int intLevel; DRV_LOG (NS83902_DEBUG_POLL, "S ", 0, 0, 0, 0, 0, 0); intLevel = intLock(); /* disable all interrupts */ NS83902_REG_SET (pDrvCtrl, NS83902_IMR, IMR_DISABLE, CR_RPAGE0); DRV_FLAGS_SET (NS83902_FLAG_POLL); intUnlock (intLevel); return (OK); }/********************************************************************************* ns83902PollStop - stop polling mode** RETURNS: OK, always.*/LOCAL STATUS ns83902PollStop ( NS83902_END_DEVICE* pDrvCtrl ) { int intLevel; intLevel = intLock(); /* enable interrupts */ NS83902_REG_SET (pDrvCtrl, NS83902_IMR, IMR_ENABLE, CR_RPAGE0); DRV_FLAGS_CLR(NS83902_FLAG_POLL); DRV_LOG (NS83902_DEBUG_POLL, "s", 0, 0, 0, 0, 0, 0); intUnlock (intLevel); return (OK); }/********************************************************************************* ns83902PollSend - send a packet in polled mode** RETURNS: OK on success, EAGAIN on failure*/LOCAL STATUS ns83902PollSend ( NS83902_END_DEVICE* pDrvCtrl, M_BLK* pMblk ) { return (ns83902Send (pDrvCtrl, pMblk)); }/********************************************************************************* ns83902PollReceive - get a packet in polled mode** RETURNS: OK on success, EAGAIN on failure.*/LOCAL STATUS ns83902PollReceive ( NS83902_END_DEVICE* pDrvCtrl, M_BLK* pMblk ) { STATUS nRetValue = OK; NS83902_CLUSTER pCluster; int len; DRV_LOG (NS83902_DEBUG_POLL, "Start Poll Read!\n", 1, 2, 3, 4, 5, 6); if ((pCluster = ns83902ReadFrame (pDrvCtrl)) == NULL) nRetValue = EAGAIN; else { NS83902_RX_FRAME* pRx = (NS83902_RX_FRAME*)pCluster; len = pRx->rxHdr.count; pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len; /* set the data len */ pMblk->mBlkPktHdr.len = len; /* set the total len */ pMblk->mBlkHdr.mData += 2; bcopy ((char *)&pRx->enetHdr, (char *)pMblk->mBlkHdr.mData, len); netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pRx); } DRV_LOG (NS83902_DEBUG_POLL, "End Poll Read!\n", 1, 2, 3, 4, 5, 6); return nRetValue; }/********************************************************************************* ns83902HashIndex - compute the hash index for an ethernet address** RETURNS: hash index for an ethernet address.*/LOCAL int ns83902HashIndex ( 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 ^= NS83902_CRC_POLY; crc |= 0x1; } eAddrByte >>= 1; } } /* Just want the 6 most significant bits. */ index = crc >> 26 ; return index; }/******************************************************************************** ns83902AddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the MCastAddrAdd() routine) and sets the* device's filter correctly.** NOMANUAL*/LOCAL STATUS ns83902AddrFilterSet ( NS83902_END_DEVICE* pDrvCtrl, char* pAddr, BOOL bSet ) { UINT8 nHashIndex; /* get hash index for the address */ nHashIndex = ns83902HashIndex (pAddr); /* Turn on the corresponding bit in the filter. */ ns83902MARSet (pDrvCtrl, nHashIndex, bSet); return OK; }/********************************************************************************* ns83902MARSet - sets/resets the MAR for the specified hash index** This routine sets/resets the MAR bit for the specified hash index** RETURNS: OK or ERROR.*/LOCAL void ns83902MARSet ( NS83902_END_DEVICE* pDrvCtrl, UINT8 index, /* hash index */ BOOL bSet /* Set/Reset */ ) { UINT8 nRegOffset = index; UINT8 nBitPosition = index; UINT8 nBitMask = (UINT8)0x01; UINT8 nValue; /* Find register and bit position */ nBitPosition = nBitPosition & 0x07; /* 3 LSB bits */ nBitMask <<= nBitPosition; nRegOffset >>= 3; /* next 3 bits */ /* set the bit in bit array*/ NS83902_REG_GET (pDrvCtrl, NS83902_MAR0 + nRegOffset, nValue, CR_RPAGE1); DRV_LOG (NS83902_DEBUG_LOAD, "Hash Index:%d MAR Offset:%d value:%d\n", index, nRegOffset, nValue, 4, 5, 6); if (bSet) { nValue |= nBitMask; /* set */ } else { nBitMask = ~nBitMask; /* reset */ nValue &= nBitMask; } NS83902_REG_SET (pDrvCtrl, NS83902_MAR0 + nRegOffset, nValue, CR_RPAGE1); DRV_LOG (NS83902_DEBUG_LOAD, "Hash Index:%d MAR Offset:%d value:%d\n", index, nRegOffset, nValue, 4, 5, 6); }/********************************************************************************* ns83902RegRead - read the current value of a NIC register** This routine reads the register values of a NIC register** RETURNS: register value.*/LOCAL UINT8 ns83902RegRead ( NS83902_END_DEVICE* pDrvCtrl, int reg, int page ) { UINT8 value; int oldLevel = intLock(); if ((pDrvCtrl)->regPage != (page)) { /* Set the register page */ UINT8 cr; (pDrvCtrl)->regPage = (page); NS83902_CR_GET ((pDrvCtrl), cr); NS83902_CR_SET ((pDrvCtrl), (cr & !CR_PAGE_MASK) | (page)); } SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->pNic + reg * pDrvCtrl->regInterval,value); SYS_NS83902_DELAY(); intUnlock (oldLevel); return (value); } /********************************************************************************* ns83902RegSet - set a NIC register** This routine reads and displays the register values of the NIC registers** RETURNS: N/A.*/LOCAL void ns83902RegSet ( NS83902_END_DEVICE* pDrvCtrl, int reg, int value, int page ) { int oldLevel = intLock(); if (pDrvCtrl->regPage != pa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -