📄 dec21x40end.c
字号:
/* get a free transmit descriptor */ pTxD = dec21x40TxDGet (pDrvCtrl); if (pTxD == NULL) { END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (ERROR); } /* get a buffer */ pBuf = NET_BUF_ALLOC(); if (pBuf == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "netClusterGet failed\n", 1, 2, 3, 4, 5, 6); END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (ERROR); } /* align the frame */ pFltrFrm = (UINT8 *) (((int)pBuf + 0x3) & ~0x3); /* clear all entries */ bzero (pFltrFrm, FLTR_FRM_SIZE); /* install multicast addresses */ for (pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrl->endObj); pMCastNode != NULL; pMCastNode = END_MULTI_LST_NEXT (pMCastNode)) { index = dec21x40HashIndex (pMCastNode->addr); pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8); } /* install an ethernet broadcast address */ index = dec21x40HashIndex (ethBcastAdrs); pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8); /* install the physical address */ pAdrs = (UINT8 *)END_HADDR (&pDrvCtrl->endObj); for (index=0; index<6; index++) pFltrFrm [FLTR_FRM_PHY_ADRS_OFF + DEC_FLT_INDEX(index)] = pAdrs[index]; /* transmit the frame */ pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pFltrFrm)); pTxD->tDesc3 = 0; /* frame type is SETUP, filtering mode is HASH + 1 perfect */ pTxD->tDesc1 |= PCISWAP (TDESC1_SET | TDESC1_FT0); pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK); pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(FLTR_FRM_SIZE)); pTxD->tDesc1 &= PCISWAP (~(TDESC1_LS|TDESC1_FS)); pTxD->tDesc0 = PCISWAP(TDESC0_OWN); /* ready for transmit */ CACHE_PIPE_FLUSH(); /* Advance our management index */ pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds; /* mask interrupts */ csr7Val = DEC_CSR_READ (CSR7); DEC_CSR_WRITE (CSR7, 0); /* start tx */ if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART)) DEC_CSR_WRITE (CSR1, CSR1_TPD); /* wait for completion */ timeout=0xffffff; while (timeout && (pTxD->tDesc0 != (~PCISWAP (TDESC0_OWN)))) timeout--; /* restore TXD bits */ pTxD->tDesc0 = 0; pTxD->tDesc1 &= PCISWAP (~(TDESC1_SET | TDESC1_FT0)); pTxD->tDesc1 |= PCISWAP (TDESC1_LS | TDESC1_FS); pTxD->tDesc2 = 0; CACHE_PIPE_FLUSH(); /* restore interrupts */ DEC_CSR_WRITE (CSR7, csr7Val); /* free the buffer */ NET_BUF_FREE (pBuf); /* release exclusive access */ END_TX_SEM_GIVE (&pDrvCtrl->endObj); /* return success */ return (OK); }/********************************************************************************* dec21x40MCastAddrAdd - add a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x40MCastAddrAdd ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAdd\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) return dec21x40IASetup (pDrvCtrl); return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* dec21x40MCastAddrDel - remove a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x40MCastAddrDel ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDel\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); if (retVal == ENETRESET) return dec21x40IASetup (pDrvCtrl); return ((retVal == OK) ? OK : ERROR); }/********************************************************************************* dec21x40MCastAddrGet - retreive current multicast address list*** RETURNS: OK on success; otherwise ERROR.*/LOCAL STATUS dec21x40MCastAddrGet ( DRV_CTRL * pDrvCtrl, MULTI_TABLE *pTable ) { DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrGet\n", 0, 0, 0, 0, 0, 0); return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/********************************************************************************* dec21x40Send - transmit an ethernet packet** RETURNS: OK on success; and ERROR otherwise.*/LOCAL STATUS dec21x40Send ( DRV_CTRL *pDrvCtrl, M_BLK *pMblk ) { DEC_TD * pTxD; char * pBuf; int len; int s; DRV_PRINT (DRV_DEBUG_TX, ("S:0x%x ", pDrvCtrl->txIndex));#if 0 if (pDrvCtrl->txBlocked) return (END_ERR_BLOCK); /* transmitter not ready */#endif /* Gain exclusive access to transmit */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* Get the next TXD */ pTxD = dec21x40TxDGet (pDrvCtrl); pBuf = NET_BUF_ALLOC(); if ((pTxD == NULL) || (pBuf == NULL)) { DRV_LOG (DRV_DEBUG_TX, "No available TxBufs \n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); END_TX_SEM_GIVE (&pDrvCtrl->endObj); if (pBuf) NET_BUF_FREE (pBuf); if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked) dec21x40TxRingClean (pDrvCtrl); s = intLock(); pDrvCtrl->txBlocked = TRUE; /* transmitter not ready */ intUnlock(s); return (END_ERR_BLOCK); /* just return without freeing mBlk chain */ } /* copy and free the MBLK */ len = netMblkToBufCopy (pMblk, pBuf, NULL); NET_MBLK_CHAIN_FREE (pMblk); /* setup the transmit buffer pointers */ pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf)); pTxD->tDesc3 = 0; /* setup frame len */ pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK); pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(len)); /* transfer ownership to device */ pTxD->tDesc0 = PCISWAP(TDESC0_OWN); CACHE_PIPE_FLUSH(); /* Save the buf info */ pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf = pBuf; /* Advance our management index */ pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds; if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART)) DEC_CSR_WRITE (CSR1, CSR1_TPD); END_TX_SEM_GIVE (&pDrvCtrl->endObj); /* update statistics */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); return (OK); }/********************************************************************************* dec21x40Recv - pass a received frame to the upper layer*** RETURNS: OK, always.*/LOCAL STATUS dec21x40Recv ( DRV_CTRL * pDrvCtrl, DEC_RD * pRxD ) { END_OBJ * pEndObj = &pDrvCtrl->endObj; M_BLK_ID pMblk; /* MBLK to send upstream */ CL_BLK_ID pClBlk; /* pointer to clBlk */ char * pBuf; /* A replacement buffer for the current RxD */ char * pData; /* Data pointer for the current RxD */ int len; /* Len of the current data */ DRV_PRINT (DRV_DEBUG_RX, ("R")); /* check for errors */ if (pRxD->rDesc0 & PCISWAP(RDESC0_ES)) { DRV_PRINT (DRV_DEBUG_RX, ("- ")); END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1); goto cleanRxD; } DRV_PRINT (DRV_DEBUG_RX, ("+ ")); END_ERR_ADD (pEndObj, MIB2_IN_UCAST, +1); /* Allocate an MBLK, and a replacement buffer */ pMblk = NET_MBLK_ALLOC(); pBuf = NET_BUF_ALLOC(); pClBlk = NET_CL_BLK_ALLOC(); if ((pMblk == NULL) || (pBuf == NULL) || (pClBlk == NULL)) { DRV_LOG (DRV_DEBUG_RX, "No available RxBufs \n", 0, 0, 0, 0, 0, 0); END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1); if (pMblk) NET_MBLK_FREE (pMblk); if (pBuf) NET_BUF_FREE (pBuf); if (pClBlk) NET_CL_BLK_FREE (pClBlk); goto cleanRxD; } /* Get the data pointer and len from the current RxD */ len = DEC_FRAME_LEN_GET (PCISWAP (pRxD->rDesc0)) - ETH_CRC_LEN; pData = (char *) DEC_PCI_TO_VIRT (PCISWAP (pRxD->rDesc2)); /* Associate the data pointer with the MBLK */ NET_CL_BLK_JOIN (pClBlk, pData, DEC_BUFSIZ); /* Associate the data pointer with the MBLK */ NET_MBLK_CL_JOIN (pMblk, pClBlk); 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 */ /* Make cache consistent with memory */ DEC_CACHE_INVALIDATE (pData, len); /* Install the new data buffer */ pRxD->rDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf)); /* mark the descriptor ready to receive */ pRxD->rDesc0 = PCISWAP (RDESC0_OWN); /* advance management index */ pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds; CACHE_PIPE_FLUSH(); /* send the frame to the upper layer, and possibly switch to system mode */ END_RCV_RTN_CALL (pEndObj, pMblk); return (OK);cleanRxD: /* mark the descriptor ready to receive */ pRxD->rDesc0 = PCISWAP (RDESC0_OWN); CACHE_PIPE_FLUSH(); /* advance management index */ pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds; return (OK); }/********************************************************************************* dec21x40RxIntHandle - perform receive processing** RETURNS: N/A*/LOCAL void dec21x40RxIntHandle ( DRV_CTRL * pDrvCtrl ) { DEC_RD *pRxD; pDrvCtrl->rxHandling = TRUE; while ((pRxD = dec21x40RxDGet (pDrvCtrl))) dec21x40Recv (pDrvCtrl, pRxD); DEC_CSR_UPDATE (CSR7, CSR7_RIM); /* turn on Rx interrupts */ pDrvCtrl->rxHandling = FALSE; }/********************************************************************************* dec21x40RxDGet - get a ready receive descriptor** RETURNS: a filled receive descriptor, otherwise NULL.*/LOCAL DEC_RD * dec21x40RxDGet ( DRV_CTRL *pDrvCtrl ) { DEC_RD *pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex; DEC_CACHE_INVALIDATE (pRxD, RD_SIZ); /* check if the descriptor is owned by the chip */ if (pRxD->rDesc0 & PCISWAP (RDESC0_OWN)) return NULL; return pRxD; }/*******
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -