📄 ne2000end.c
字号:
END_HADDR_LEN(&pDrvCtrl->endObj)); ENDLOGMSG (("ne2000Ioctl get phy addr.\n", 0, 0, 0, 0, 0, 0)); 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); ENDLOGMSG (("ne2000Ioctl set flag.\n", 0, 0, 0, 0, 0, 0)); ne2000Config (pDrvCtrl, TRUE); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); ENDLOGMSG (("ne2000Ioctl get phy addr.\n", 0, 0, 0, 0, 0, 0)); break; case EIOCPOLLSTART: ne2000PollStart (pDrvCtrl); ENDLOGMSG (("ne2000Ioctl pool start.\n", 0, 0, 0, 0, 0, 0)); break; case EIOCPOLLSTOP: ne2000PollStop (pDrvCtrl); ENDLOGMSG (("ne2000Ioctl pool stop.\n", 0, 0, 0, 0, 0, 0)); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); ENDLOGMSG (("ne2000Ioctl get mib table.\n", 0, 0, 0, 0, 0, 0)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); ENDLOGMSG (("ne2000Ioctl get buffer.\n", 0, 0, 0, 0, 0, 0)); break; default: error = EINVAL; ENDLOGMSG (("ne2000Ioctl do nothing.\n", 0, 0, 0, 0, 0, 0)); } return (error); }/********************************************************************************* ne2000Start - start the device*** RETURNS: OK or ERROR**/LOCAL STATUS ne2000Start ( void* pCookie ) { UCHAR rxFilter; /* receiver configuration */#ifdef DEBUG static buf [256];#endif STATUS result; NE2000END_DEVICE* pDrvCtrl = (NE2000END_DEVICE *) pCookie; SYS_INT_CONNECT (pDrvCtrl, ne2000Int, (int)pDrvCtrl, &result); if (result == ERROR) return (ERROR); #ifdef _USE_RECV_DMA_ pDrvCtrl->imask = 0; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) ne2000AddrFilterSet (pDrvCtrl); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP); if (pDrvCtrl->byteAccess) SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS_8 | DCON_LOOPBK_OFF); else SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | DCON_LOOPBK_OFF); SYS_ENET_ADDR_GET (pDrvCtrl); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, 0x00); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, 0x00); rxFilter = RCON_BROAD; if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) { rxFilter |= RCON_GROUP; } ENDLOGMSG (("\tMulticast mode %s\n", (rxFilter & RCON_GROUP) ? "on" : "off", 0, 0, 0, 0, 0)); if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC) { rxFilter |= RCON_PROM; } ENDLOGMSG (("\tPromiscuous mode %s\n", (rxFilter & RCON_PROM) ? "on" : "off", 0, 0, 0, 0, 0)); ENDLOGMSG (("\tsetting rxFilter = 0x%x\n", rxFilter,2,3,4,5,6)); SYS_OUT_CHAR (pDrvCtrl, ENE_RCON, rxFilter); SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_LB1); SYS_OUT_CHAR (pDrvCtrl, ENE_RSTART, NE2000_PSTART); SYS_OUT_CHAR (pDrvCtrl, ENE_RSTOP, NE2000_PSTOP); SYS_OUT_CHAR (pDrvCtrl, ENE_BOUND, NE2000_PSTART); SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, (char)0xff); pDrvCtrl->imask = 0; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE1 | CMD_STOP); SYS_OUT_CHAR (pDrvCtrl, ENE_STA0, pDrvCtrl->enetAddr[0]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA1, pDrvCtrl->enetAddr[1]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA2, pDrvCtrl->enetAddr[2]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA3, pDrvCtrl->enetAddr[3]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA4, pDrvCtrl->enetAddr[4]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA5, pDrvCtrl->enetAddr[5]); ENDLOGMSG (("enet addr %02x:%02x:%02x:%02x:%02x:%02x\n", pDrvCtrl->enetAddr[0] & 0xff, pDrvCtrl->enetAddr[1] & 0xff, pDrvCtrl->enetAddr[2] & 0xff, pDrvCtrl->enetAddr[3] & 0xff, pDrvCtrl->enetAddr[4] & 0xff, pDrvCtrl->enetAddr[5] & 0xff)); ne2000AddrFilterSet (pDrvCtrl); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR0, pDrvCtrl->mcastFilter[0]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR1, pDrvCtrl->mcastFilter[1]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR2, pDrvCtrl->mcastFilter[2]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR3, pDrvCtrl->mcastFilter[3]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR4, pDrvCtrl->mcastFilter[4]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR5, pDrvCtrl->mcastFilter[5]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR6, pDrvCtrl->mcastFilter[6]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR7, pDrvCtrl->mcastFilter[7]);#ifdef DEBUG ENDLOGMSG ((("Setting multicast addresses to:\n"),1,2,3,4,5,6)); sprintf(buf, "enet mcast %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", pDrvCtrl->mcastFilter[0] & 0xff, pDrvCtrl->mcastFilter[1] & 0xff, pDrvCtrl->mcastFilter[2] & 0xff, pDrvCtrl->mcastFilter[3] & 0xff, pDrvCtrl->mcastFilter[4] & 0xff, pDrvCtrl->mcastFilter[5] & 0xff, pDrvCtrl->mcastFilter[6] & 0xff, pDrvCtrl->mcastFilter[7] & 0xff); ENDLOGMSG (((buf),1,2,3,4,5,6));#endif /* DEBUG */ #endif END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); #ifdef _USE_RECV_DMA_ SYS_OUT_CHAR (pDrvCtrl, ENE_CURR, NE2000_PSTART + 1); pDrvCtrl->nextPacket = NE2000_PSTART + 1; SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_NORMAL); #endif pDrvCtrl->imask = (pDrvCtrl->flags & END_POLLING) ? 0 : NE2000_ALL_INTS; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); SYS_INT_ENABLE (pDrvCtrl); ne2000DmaInit(); return (OK); }/******************************************************************************** ne2000Config - reconfigure the interface under us.*** NOMANUAL*/LOCAL void ne2000Config ( NE2000END_DEVICE *pDrvCtrl, BOOL intEnable ) { UCHAR rxFilter; #ifdef DEBUG static buf [256];#endif ENDLOGMSG (("ne2000Config: enter (intEnable=%d)\n", intEnable, 0, 0, 0, 0, 0)); pDrvCtrl->imask = 0; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) ne2000AddrFilterSet (pDrvCtrl); pDrvCtrl->flags &= (END_POLLING | END_OVERWRITE | END_OVERWRITE2); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP); if (pDrvCtrl->byteAccess) SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS_8 | DCON_LOOPBK_OFF); else SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | DCON_LOOPBK_OFF); SYS_ENET_ADDR_GET (pDrvCtrl); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, 0x00); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, 0x00); rxFilter = RCON_BROAD; if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) { rxFilter |= RCON_GROUP; } ENDLOGMSG (("\tMulticast mode %s\n", (rxFilter & RCON_GROUP) ? "on" : "off", 0, 0, 0, 0, 0)); if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC) { rxFilter |= RCON_PROM; } ENDLOGMSG (("\tPromiscuous mode %s\n", (rxFilter & RCON_PROM) ? "on" : "off", 0, 0, 0, 0, 0)); ENDLOGMSG (("\tsetting rxFilter = 0x%x\n", rxFilter,2,3,4,5,6)); SYS_OUT_CHAR (pDrvCtrl, ENE_RCON, rxFilter); SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_LB1); SYS_OUT_CHAR (pDrvCtrl, ENE_RSTART, NE2000_PSTART); SYS_OUT_CHAR (pDrvCtrl, ENE_RSTOP, NE2000_PSTOP); SYS_OUT_CHAR (pDrvCtrl, ENE_BOUND, NE2000_PSTART); SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, (char)0xff); pDrvCtrl->imask = 0; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE1 | CMD_STOP); SYS_OUT_CHAR (pDrvCtrl, ENE_STA0, pDrvCtrl->enetAddr[0]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA1, pDrvCtrl->enetAddr[1]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA2, pDrvCtrl->enetAddr[2]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA3, pDrvCtrl->enetAddr[3]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA4, pDrvCtrl->enetAddr[4]); SYS_OUT_CHAR (pDrvCtrl, ENE_STA5, pDrvCtrl->enetAddr[5]); ENDLOGMSG (("enet addr %02x:%02x:%02x:%02x:%02x:%02x\n", pDrvCtrl->enetAddr[0] & 0xff, pDrvCtrl->enetAddr[1] & 0xff, pDrvCtrl->enetAddr[2] & 0xff, pDrvCtrl->enetAddr[3] & 0xff, pDrvCtrl->enetAddr[4] & 0xff, pDrvCtrl->enetAddr[5] & 0xff)); ne2000AddrFilterSet (pDrvCtrl); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR0, pDrvCtrl->mcastFilter[0]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR1, pDrvCtrl->mcastFilter[1]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR2, pDrvCtrl->mcastFilter[2]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR3, pDrvCtrl->mcastFilter[3]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR4, pDrvCtrl->mcastFilter[4]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR5, pDrvCtrl->mcastFilter[5]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR6, pDrvCtrl->mcastFilter[6]); SYS_OUT_CHAR (pDrvCtrl, ENE_MAR7, pDrvCtrl->mcastFilter[7]);#ifdef DEBUG ENDLOGMSG ((("Setting multicast addresses to:\n"),1,2,3,4,5,6)); sprintf(buf, "enet mcast %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", pDrvCtrl->mcastFilter[0] & 0xff, pDrvCtrl->mcastFilter[1] & 0xff, pDrvCtrl->mcastFilter[2] & 0xff, pDrvCtrl->mcastFilter[3] & 0xff, pDrvCtrl->mcastFilter[4] & 0xff, pDrvCtrl->mcastFilter[5] & 0xff, pDrvCtrl->mcastFilter[6] & 0xff, pDrvCtrl->mcastFilter[7] & 0xff); ENDLOGMSG (((buf),1,2,3,4,5,6));#endif /* DEBUG */ SYS_OUT_CHAR (pDrvCtrl, ENE_CURR, NE2000_PSTART + 1); pDrvCtrl->nextPacket = NE2000_PSTART + 1; SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_NORMAL); ENDLOGMSG (("ne2000Config: done\n", 0, 0, 0, 0, 0, 0)); pDrvCtrl->imask = ((pDrvCtrl->flags & END_POLLING) ? 0 : NE2000_ALL_INTS); if (intEnable) SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); }/********************************************************************************/LOCAL void ne2000OverwriteRecover ( NE2000END_DEVICE *pDrvCtrl, UCHAR cmdStatus ) { UCHAR stat; BOOL reSend; int recvLen = 0; ENDLOGMSG (("ne2000OverwriteRecover: enter (flags=%x, imask=%x)\n", pDrvCtrl->flags,pDrvCtrl->imask,0,0,0,0)); if (!(pDrvCtrl->flags & END_OVERWRITE2)) { ENDLOGMSG (("ne2000OverwriteRecover: bad flags\n", 0,0,0,0,0,0));#ifdef DEBUG SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0); taskSuspend (0);#else return;#endif } taskDelay ((sysClkRateGet() + 624)/ 625); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, 0x00); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, 0x00); if ((cmdStatus & CMD_TXP) == 0) reSend = FALSE; else { SYS_IN_CHAR (pDrvCtrl, ENE_INTSTAT, &stat); if ((stat & (ISTAT_PTX | ISTAT_TXE)) == 0) { reSend = TRUE; } else { reSend = FALSE; } } SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_LB1); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); pDrvCtrl->flags &= ~END_OVERWRITE; pDrvCtrl->current = ne2000GetCurr (pDrvCtrl); #ifdef _USE_RECV_DMA_ if(pDrvCtrl->current>= pDrvCtrl->nextPacket) { recvLen = (pDrvCtrl->current-pDrvCtrl->nextPacket)*RECV_PAGE_SIZE; } else { recvLen = ((NE2000_PSTOP-pDrvCtrl->nextPacket)+(pDrvCtrl->current-NE2000_PSTART))*RECV_PAGE_SIZE; } ne2000DmaRecv(pDrvCtrl , (((UINT)pDrvCtrl->nextPacket << 8) & 0x0000ffff) , recvLen); #else ne2000HandleRcvInt (pDrvCtrl); #endif }/********************************************************************************** RETURNS: N/A.*/LOCAL void ne2000Int(NE2000END_DEVICE *pDrvCtrl){ UCHAR val; UCHAR intStat; UCHAR txStat; UCHAR rxStat; pDrvCtrl->stats.interrupts++; SYS_IN_CHAR (pDrvCtrl, ENE_INTSTAT, &intStat); intStat &= pDrvCtrl->imask; SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, intStat); SYS_IN_CHAR (pDrvCtrl, ENE_TSTAT, &txStat); SYS_IN_CHAR (pDrvCtrl, ENE_RSTAT, &rxStat); ENDLOGMSG (("ne2000Int: intStat=%02x imask=%02x txStat=%02x rxStat=%02x\n", intStat, pDrvCtrl->imask, txStat, rxStat, 0, 0)); if(TRUE == recvIntLog) { logMsg ("ne2000Int: intStat=%02x imask=%02x txStat=%02x rxStat=%02x\n", intStat, pDrvCtrl->imask, txStat, rxStat, 0, 0); } SYS_IN_CHAR (pDrvCtrl, ENE_COLCNT, &val); pDrvCtrl->stats.collisions += val; SYS_IN_CHAR (pDrvCtrl, ENE_ALICNT, &val); pDrvCtrl->stats.aligns += val; SYS_IN_CHAR (pDrvCtrl, ENE_CRCCNT, &val); pDrvCtrl->stats.crcs += val; SYS_IN_CHAR (pDrvCtrl, ENE_MPCNT, &val); pDrvCtrl->stats.missed += val; if (intStat & ISTAT_OVW) /* Overwrite */ { UCHAR cmdStat; UCHAR currNo ; UCHAR bnry ; currNo = ne2000GetCurr(pDrvCtrl); SYS_IN_CHAR (pDrvCtrl, ENE_BOUND , &bnry); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); if (!(pDrvCtrl->flags & END_OVERWRITE2)) { pDrvCtrl->flags |= (END_OVERWRITE | END_OVERWRITE2); pDrvCtrl->lastError.errCode = END_ERR_WARN; pDrvCtrl->lastError.pMesg = "Overwrite"; netJobAdd ((FUNCPTR) muxError, (int) &pDrvCtrl->endObj, (int) &pDrvCtrl->lastError, 0, 0, 0); pDrvCtrl->stats.overwrite++; SYS_IN_CHAR (pDrvCtrl, ENE_COLCNT, &cmdStat); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP); ENDLOGMSG (("ne2000Int: overwrite detected\n", 0, 0, 0, 0, 0, 0)); netJobAdd ((FUNCPTR) ne2000OverwriteRecover, (int) pDrvCtrl, cmdStat, 0, 0, 0); } pDrvCtrl->imask = 0; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); return; } if (intStat & ISTAT_RXE) /* Receive-error */ { if (!pDrvCtrl->lastIntError) { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); pDrvCtrl->lastError.errCode = END_ERR_WARN; pDrvCtrl->lastError.pMesg = "receive error"; netJobAdd ((FUNCPTR) muxError, (int) &pDrvCtrl->endObj, (int) &pDrvCtrl->lastError, 0, 0, 0); } ++pDrvCtrl->lastIntError; pDrvCtrl->stats.rerror++; if (rxStat & RSTAT_OVER) pDrvCtrl->stats.overruns++; if (rxStat & RSTAT_DIS) pDrvCtrl->stats.disabled++; if (rxStat & RSTAT_DFR) pDrvCtrl->stats.deferring++; } if (intStat & ISTAT_TXE) /* Transmit error-packet not sent */ { if (!pDrvCtrl->lastIntError) { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1); pDrvCtrl->lastError.errCode = END_ERR_WARN; pDrvCtrl->lastError.pMesg = "transmit error"; netJobAdd ((FUNCPTR) muxError, (int) &pDrvCtrl->endObj, (int) &pDrvCtrl->lastError, 0, 0, 0); } ++pDrvCtrl->lastIntError; pDrvCtrl->stats.terror++; if (txStat & TSTAT_ABORT) { pDrvCtrl->stats.aborts++; pDrvCtrl->stats.collisions += 16; } if (txStat & TSTAT_UNDER) pDrvCtrl->stats.underruns++; } if (intStat & ISTAT_PTX) /* Transmit-packet sent */ { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); if (txStat & TSTAT_CDH) pDrvCtrl->stats.heartbeats++; if (txStat & TSTAT_OWC) pDrvCtrl->stats.outofwindow++; if (txStat & TSTAT_PTX) pDrvCtrl->stats.tnoerror++; } if (!(intStat & (ISTAT_RXE | ISTAT_TXE))) pDrvCtrl->lastIntError = 0; if (intStat & ISTAT_PRX) { int recvLen = 0; pDrvCtrl->current = ne2000GetCurr (pDrvCtrl); ENDLOGMSG(("ne2000Int: input packet (flags=%x, current=%d)\n", pDrvCtrl->flags, pDrvCtrl->current, 0, 0, 0, 0)); if (!(pDrvCtrl->flags & END_RECV_HANDLING_FLAG)) { /* Disable RX int */ pDrvCtrl->imask &= ~IM_PRXE; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); pDrvCtrl->flags |= END_RECV_HANDLING_FLAG; #ifdef _USE_RECV_DMA_ if(pDrvCtrl->current>= pDrvCtrl->nextPacket) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -