📄 rtl81x9.c
字号:
) { int txDesc; for (txDesc=0; txDesc < RTL_NUM_TX_DESC; txDesc++) { u_long txstatus; txstatus = rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_TX_STATUS0 + (txDesc*4), NONE); if (txstatus & RTL_TX_STATUS_OK) { /* Has the packet been sent previously */ if ((txstatus & RTL_TX_HOST_OWNS) && (pDrvCtrl->pDescMem[txDesc] != NULL)) { /* Clear the buffer that was registered to the Descriptor */ /*vicadd netClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/ pDrvCtrl->pDescMem[txDesc] = NULL; pDrvCtrl->freeDesc++; if (pDrvCtrl->freeDesc > RTL_NUM_TX_DESC) pDrvCtrl->freeDesc = RTL_NUM_TX_DESC; } } else if (txstatus & (RTL_TX_UNDERRUN | RTL_TX_OUT_OF_WINDOW | RTL_TX_ABORTED )) { /* Clear the buffer that was registered to the Descriptor */ /*vicaddnetClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/ pDrvCtrl->pDescMem[txDesc] = NULL; rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_STATUS0 + (txDesc*4), RTL_TX_HOST_OWNS, NONE); } } }/********************************************************************************* rtl81x9HandleRecvInt - task level interrupt service for input packets** This routine is called by the interrupt service routine to do any * message received processing.** RETURNS: N/A.*/LOCAL void rtl81x9HandleRecvInt ( RTL81X9END_DEVICE *pDrvCtrl ) { int len, wrapSize; M_BLK_ID pMblk; char* pNewCluster; CL_BLK_ID pClBlk; RTL_RX_DATA *rxData; USHORT cur_rx; /*USHORT limit,max_bytes = 0;*/ USHORT rx_bytes = 0; char *readPtr; /* Disable interrupts by clearing the interrupt mask. */ cur_rx = ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, NONE) + 16) % RTL_RXBUFLEN);/* limit = (rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_ADDR, NONE) % RTL_RXBUFLEN); if (limit < cur_rx) max_bytes = (RTL_RXBUFLEN - cur_rx) + limit; else max_bytes = limit - cur_rx;*/ while ((rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & RTL_CMD_RX_BUF_EMPTY) == 0) { /*rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE) ;*//*test*/ readPtr = (pDrvCtrl->ptrRxBufSpace + cur_rx); rxData = (RTL_RX_DATA *) readPtr; if ((rxData->rxPktLen >> 16) == RTL_RX_UNFINISHED) { DRV_LOG (DRV_DEBUG_ALL, "RxHandError 0fff0: ", 1, 2, 3, 4, 5, 6); break; } if (!(rxData->rxStatusFlags & RTL_RX_STATUS_OK)) { if (rxData->rxStatusFlags & (RTL_RX_BAD_SYMBOL| RTL_RX_RUNT| RTL_RX_TOO_LONG| RTL_RX_CRC_ERROR| RTL_RX_BAD_ALIGN)) { /*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0); rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB| RTL_CMD_RX_ENB, RTL_WIN_0);*/ rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0); rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB| RTL_CMD_RX_ENB, RTL_WIN_0); rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0); /*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/ cur_rx = 0; /*DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6); i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE); DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/ rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0); } break; } /* No errors; receive the packet. */ len = rxData->rxPktLen; /* get packet length */ /*DRV_LOG (DRV_DEBUG_RX, "Rmask %x", rtl81x9CsrReadWord(pDrvCtrl, RTL_REGS_INTR_MASK, NONE), 0, 0, 0, 0, 0); *//*test*/ rx_bytes += len + 4; len -= RTL_CRC_SIZE; /* * Avoid trying to read more bytes than we know * the chip has prepared for us. */ /*if (rx_bytes > max_bytes) { DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes=%x max_bytes=%x\n", rx_bytes, max_bytes, 0, 0, 0, 0); break; unknow what do }*/ if(len>1518) { /*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0); rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB| RTL_CMD_RX_ENB, RTL_WIN_0);*/ rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0); rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB| RTL_CMD_RX_ENB, RTL_WIN_0); rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0); /*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/ cur_rx = 0; DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6); /*i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);*/ /*DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/ rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0); DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes>1518=%x \n", len, 0, 0, 0, 0, 0); break; } /* DRV_LOG (DRV_DEBUG_LOAD, "Rx_Bytes=%x len=%x max_byte=%x\n", rx_bytes, len, max_bytes, 4, 5, 6);*/ /* If we cannot get a buffer to loan then bail out. */ pNewCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId); /*DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);*/ if (pNewCluster == NULL) { DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) { netClFree (pDrvCtrl->end.pNetPool, pNewCluster); DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* * OK we've got a spare, let's get an M_BLK_ID and marry it to the * one in the ring. */ if ((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); netClFree (pDrvCtrl->end.pNetPool, pNewCluster); DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* Copy the data found into the new cluster, we have (+4) to get us past the */ /* data that the rtl chip places at the start of the message and we remove */ /* the CRC from the end of the message */ if ((readPtr + len) >= (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN)) { wrapSize = (int) ((readPtr + len) - (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN)); /* Copy in first section of message as stored */ /* at the end of the ring buffer */ memcpy (pNewCluster, readPtr + 4, len - wrapSize); /* Copy in end of message as stored */ /* at the start of the ring buffer */ /*vicadd*/#ifdef CPU_PENTIUM memcpy (pNewCluster +len - wrapSize -4, pDrvCtrl->ptrRxBufSpace, wrapSize+0x04); /* there have some error compiler's bug in this line*/ /* If I just copy the correct bytes the last two bytes will*/ /* have some trouble, so I copy extra bytes to fix the CPU or*/ /* OS's bug vic */ #else memcpy (pNewCluster /*+len - wrapSize -4*/, pDrvCtrl->ptrRxBufSpace, wrapSize/*+0x04*/);#endif cur_rx = (wrapSize + RTL_CRC_SIZE + 4 + 3) & ~3; /*DRV_LOG (DRV_DEBUG_ALL, "wrapsize=%x readptr=%x len=%x pNew=%x newwrapsize %x\n",wrapSize,readPtr,len,pNewCluster,pNewCluster-wrapSize ,6); DRV_LOG (DRV_DEBUG_ALL, "header=%02x %02x %02x %02x %02x %02x \n",readPtr[4],readPtr[5],readPtr[6],readPtr[7],readPtr[8],readPtr[9]); DRV_LOG (DRV_DEBUG_ALL, "newheader=%02x %02x %02x %02x %02x %02x \n",pNewCluster[0],pNewCluster[1],pNewCluster[2],pNewCluster[3],pNewCluster[4],pNewCluster[5]);*/ /*DRV_LOG (DRV_DEBUG_ALL, "len=%02x \n",len,2, 3, 4, 5, 6);*/ } else { memcpy (pNewCluster, readPtr + 4, len); cur_rx = (cur_rx + len + RTL_CRC_SIZE + 4 + 3) & ~3; } /* Disable interrupts by clearing the interrupt mask. *//*vicadd rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);*/ /* We then write the CAPR as the next ptr we will read minus 0x10 which */ /* give us a little leeway to ensure that there is no overflow */ rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, (cur_rx - 16), RTL_WIN_0); /*DRV_LOG (DRV_DEBUG_ALL, "CAPR=%x len=%d\n",(cur_rx - 16), len, 0, 0, 0, 0);*/ /* Enable interrupts by setting the interrupt mask. *//*vicadd rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);*/ /* Join the cluster to the MBlock */ netClBlkJoin (pClBlk, pNewCluster, len, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk); /* make the packet data coherent */ RTL_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len); pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL (&pDrvCtrl->end, pMblk); }cleanRXD: } /********************************************************************************* rtl81x9Ioctl - interface ioctl procedure** Process an interface ioctl request.** This routine implements the network interface control functions.* It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,* EIOCMULTIDRTL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.** RETURNS: OK if successful, otherwise EINVAL.*/LOCAL int rtl81x9Ioctl ( RTL81X9END_DEVICE * pDrvCtrl, int cmd, caddr_t data ) { int error = 0; long value; switch (cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; /* HRTLP: WHY ??? */ END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } rtl81x9Config (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: error = rtl81x9PollStart (pDrvCtrl); break; case EIOCPOLLSTOP: error = rtl81x9PollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); *(int *)data = RTL_MIN_FBUF; break; case EIOCGMWIDTH: if (data == NULL) return (EINVAL); *(int *)data = pDrvCtrl->memWidth; break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = 14; break; default: error = EINVAL; } return (error); }/********************************************************************************* rtl81x9Wait - wait for the command completion** This function waits for the command completion* It is possible the chip can wedge and the 'command in progress' bit may* never clear. Hence, we wait only a finite amount of time to avoid getting* caught in an infinite loop. Normally this delay routine would be a macro,* but it isn't called during normal operation so we can afford to make it a* function.** RETURNS: N/A*/LOCAL void rtl81x9Wait ( RTL81X9END_DEVICE * pDrvCtrl /* device control structure */ ) { register int ix; for (ix = 0; ix < RTL_TIMEOUT; ix++) { /*if ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & 0x10) == 0)*/ if ((rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & 0x10) == 0) break; /*vicadd*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -