📄 rtl81x9.c
字号:
} if (ix == RTL_TIMEOUT) DRV_LOG (DRV_DEBUG_ALL, "rtl81x9Wait - rtlPci%d: command never completed!\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); return; }/********************************************************************************* rtl81x9Reset - Reset the chip** This routine does a soft reset on the chip.** RETURNS: OK, Always. */LOCAL STATUS rtl81x9Reset ( RTL81X9END_DEVICE * pDrvCtrl /* pointer to device control structure */ ) { /* issue the reset command */ /*DRV_LOG (DRV_DEBUG_LOAD, " rtl81x9Reset\n",0,0,0,0,0,0);*/ /*rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RESET, RTL_WIN_0);*/ rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RESET, RTL_WIN_0); rtl81x9Wait(pDrvCtrl); /* wait for the command to complete */ /* wait for a while */ SYS_DELAY(10);/*vicadd*/ return OK; } /********************************************************************************* rtl81x9LowPowerMode - Enter low power mode*** RETURNS: N/A** NOMANUAL*/void rtl81x9LowPowerMode (RTL81X9END_DEVICE* pDrvCtrl) {/* rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CFG_9346, 0xC0, RTL_WIN_0); rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CONFIG_1, 0x03, RTL_WIN_0);*/ }/********************************************************************************* rtl81x9NormalPowerMode - Come out of Low power mode*** RETURNS: N/A** NOMANUAL*//*void rtl81x9NormalPowerMode (RTL81X9END_DEVICE* pDrvCtrl) { rtl81x9CsrWrite(pDrvCtrl, RTL_REGS_CONFIG_1, 0x00, RTL_WIN_0); }*//********************************************************************************* rtl81x9Stop - stop the device** This routine marks the interface as down and resets the device. This* includes disabling interrupts, stopping the transmitter and receiver.** The complement of this routine is rtl81x9Start. Once a unit is* stop in this routine, it may be re-initialized to a running state by* rtl81x9Start.** RETURNS: OK or ERROR*/LOCAL STATUS rtl81x9Stop ( RTL81X9END_DEVICE * pDrvCtrl ) { STATUS result = OK; DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9Stop\n",0,0,0,0,0,0); /* Disable interrupts by clearing the interrupt mask. */ rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE); /* Stop the chip's Tx and Rx DMA processes. */ rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CHIP_CMD, 0x00, NONE); /* Green! Put the chip in low-power mode. */ rtl81x9LowPowerMode (pDrvCtrl); SYS_INT_DISCONNECT (pDrvCtrl, rtl81x9Int, (int)pDrvCtrl, &result); if (result == ERROR) DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9Stop - Could not disconnect interrupt!\n" ,0,0,0,0,0,0); return result; }/******************************************************************************** rtl81x9AddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the rtl81x9AddrAdd() routine) and sets the* device's filter correctly.** NOMANUAL*/LOCAL void rtl81x9AddrFilterSet ( RTL81X9END_DEVICE *pDrvCtrl ) { ETHER_MULTI* pCurr; rtl_ib* pIb; u_char* pCp; u_char c; u_long crc; u_long carry; int i, j; pIb = pDrvCtrl->ib; RTL_ADDRF_CLEAR (pIb); pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end); while (pCurr != NULL) { pCp = (unsigned char *)&pCurr->addr; crc = 0xFFFFFFFF; /* initial value */ for (i = 0; i < 6; i++) { c = *(pCp + i); for (j = 0; j < 8; j++) { carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01); crc <<= 1; c >>= 1; if (carry) crc = (crc ^ 0x04c11db6) | carry; } } /* Just want the 6 most significant bits. */ crc = crc >> 26; /* Turn on the corresponding bit in the filter. */ RTL_ADDRF_SET (pIb, crc); pCurr = END_MULTI_LST_NEXT(pCurr); } }/********************************************************************************* rtl81x9PollReceive - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.*/LOCAL STATUS rtl81x9PollReceive ( RTL81X9END_DEVICE *pDrvCtrl, M_BLK_ID pMblk ) { int len, wrapSize; char* pNewCluster; CL_BLK_ID pClBlk; RTL_RX_DATA *rxData; USHORT cur_rx; USHORT limit; USHORT max_bytes = 0, rx_bytes = 0; char *readPtr; /*return OK; */ /* test only */ /* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9PollReceive\n",0,0,0,0,0,0);*/ /* Disable interrupts by clearing the interrupt mask. *//* rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);vicadd*/ cur_rx = ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, NONE) + 16) % RTL_RXBUFLEN); /* Enable interrupts by setting the interrupt mask. *//* rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);vicadd*/ 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) { readPtr = (pDrvCtrl->ptrRxBufSpace + cur_rx); rxData = (RTL_RX_DATA *) readPtr; if ((rxData->rxPktLen >> 16) == RTL_RX_UNFINISHED) 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; } break; } /* No errors; receive the packet. */ len = rxData->rxPktLen; /* get packet length */ 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) break; /* If we cannot get a buffer to loan then bail out. */ pNewCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId); if (pNewCluster == NULL) { DRV_LOG (DRV_DEBUG_POLL_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_POLL_RX, "Out of Cluster 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 */ memcpy (pNewCluster, pDrvCtrl->ptrRxBufSpace, wrapSize); cur_rx = (wrapSize + RTL_CRC_SIZE + 4 + 3) & ~3; } 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); /*RV_LOG (DRV_DEBUG_ALL,"Capr=%X\n",(cur_rx - 16) , 0, 0, 0, 0, 0);*/ /* Enable interrupts by setting the interrupt mask. *//* rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);vicadd*/ /* 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); return OK; }cleanRXD: return ERROR; }/********************************************************************************* rtl81x9PollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.*/LOCAL STATUS rtl81x9PollSend ( RTL81X9END_DEVICE* pDrvCtrl, M_BLK_ID pMblk ) { /*int txDesc;*/ int level; int len = 0; char* pBuf; ULONG tx_val; u_short stat;/* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9PollSend\n",0,0,0,0,0,0);*/ if (!(pDrvCtrl->flags & RTL_FLG_POLLING)) level = intLock (); /* now templateInt won't get confused vic test */ rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS, 0xffff, NONE); /* find Tx Descriptor */ if (pDrvCtrl->freeDesc != 0) { if (pDrvCtrl->pDescMem[pDrvCtrl->nextDesc] == NULL) { pBuf = (pDrvCtrl->txmemspace + (pDrvCtrl->nextDesc * RTL81x9_BUFSIZE)); pBuf += pDrvCtrl->offset; /* take care of the alignment */ len = netMblkToBufCopy (pMblk, pBuf, NULL); netMblkClChainFree(pMblk); len = max (len, ETHERSMALL); tx_val = len + (3 << 16); rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_ADDR0 + (pDrvCtrl->nextDesc * 4), (int) pBuf, RTL_WIN_0); rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_STATUS0 + (pDrvCtrl->nextDesc * 4), tx_val, RTL_WIN_0); /*DRV_LOG (DRV_DEBUG_ALL, "No=%x txstatus=%x\n", pDrvCtrl->nextDesc, tx_val, 0, 0, 0, 0); */ stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE); while(!(stat & 0x04)) { stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE); } /*pDrvCtrl->pDescMem[pDrvCtrl->nextDesc] = pBuf;*/ /*netClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[pDrvCtrl->nextDesc]);*/ pDrvCtrl->nextDesc++; if (pDrvCtrl->nextDesc == 4) pDrvCtrl->nextDesc = 0; /*if (pDrvCtrl->freeDesc != 0) pDrvCtrl->freeDesc--;*/ } else { DRV_LOG (DRV_DEBUG_TX, "Next Desc %d is not free yet\n", pDrvCtrl->nextDesc, 0, 0, 0, 0, 0); netMblkClChainFre
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -