📄 ixethaccend.c
字号:
/* duplicate the mbuf */ memcpy(newMblk->m_data, pMblk->m_data, pMblk->m_len); newMblk->m_len = pMblk->m_len; /* process the next nblk */ if (next == NULL) { /* free the current mblk */ netMblkClChainFree(pMblk); newMblk->m_next = NULL; } else { /* free the current mblk */ pMblk->m_next = 0; netMblkClChainFree(pMblk); newMblk->m_next = swapMblk(pDrvCtrl, next); } return newMblk; } else { /* drop the remaining of the chain */ netMblkClChainFree(pMblk); return NULL; }}#endif/********************************************************************************* ixEthAccEndSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer.** RETURNS: OK, ERROR, or END_ERR_BLOCK.*/LOCAL STATUS ixEthAccEndSend(END_DEVICE * pDrvCtrl, /* device ptr */M_BLK_ID pMblk /* data to send */){ int tmLen = 0; M_BLK *mbufPtr; STATUS rtnStatus = OK; char bumpFlag;#ifndef IXE_CACHED_RX_BUFFERS_ENABLE pMblk = swapMblk(pDrvCtrl, pMblk);#endif if (pMblk == NULL) return ERROR; if (pMblk->m_next) { /* Calculate total size of chained buffer */ for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next ) { /* Force outbound packets to 60 bytes minimum */ if ( mbufPtr->m_pkthdr.len && mbufPtr->m_pkthdr.len < 60 ) { bzero (mbufPtr->m_data + mbufPtr->m_pkthdr.len, (int) 60 - mbufPtr->m_pkthdr.len); mbufPtr->m_pkthdr.len = 60; } tmLen += mbufPtr->m_len; } if ( pMblk->m_pkthdr.len != tmLen ) { pMblk->m_pkthdr.len = tmLen; } /* remember a flag to increment the stats counters */ bumpFlag = pMblk->mBlkHdr.mData[0] & (UINT8) 0x01 ; #ifdef IXP_DRV_DEBUG_MBUFS elogHook(pMblk, 4, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif /* Xmit blocks and buffers come from cached memory */ for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next ) { IXP425_END_CACHE_FLUSH(mbufPtr->m_data, mbufPtr->m_len);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE /* the access component flush the mbuf header */#else IXP425_END_CACHE_FLUSH(mbufPtr, sizeof(M_BLK));#endif } } else {#ifdef INCLUDE_IXETHACC_64BYTES_PADDING /* Add padding at the end of the mbuf * this is normally done by the ixp silicon. * (unless the harware Padding/FCS generation is disabled) */ if (pMblk->m_len < 64) { char *mDataPtr = &(pMblk->m_data[pMblk->m_len]); char *mClBufPtr = &(pMblk->pClBlk->clNode.pClBuf[pMblk->pClBlk->clSize]); while((pMblk->m_len < 64) && (mDataPtr < mClBufPtr)) { *mDataPtr++ = 0; pMblk->m_len += 1; } }#endif#ifdef IXP_DRV_DEBUG_MBUFS elogHook(pMblk, 4, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif /* remember a flag to increment the stats counters */ bumpFlag = (pMblk->m_data[0] & ((UINT8)0x01)) ; /* update the length */ pMblk->m_pkthdr.len = pMblk->m_len; /* Xmit blocks and buffers can come from cached memory */ IXP425_END_CACHE_FLUSH(pMblk->m_data, pMblk->m_len);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE /* the access component flush the mbuf header */#else IXP425_END_CACHE_FLUSH(pMblk, sizeof(M_BLK));#endif } /* * Obtain exclusive access to transmitter. This is necessary because * we might have more than one stack transmitting at once. */ if (!(pDrvCtrl->flags & IxEthAccEnd_POLLING)) { END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); } /* place a transmit request */ if ( ixEthAccPortTxFrameSubmit(pDrvCtrl->unit, pMblk, IX_ETH_ACC_TX_DEFAULT_PRIORITY) != IX_ETH_ACC_SUCCESS ) { IXP_DRV_LOG (IXP_DRV_DEBUG_ERROR, "Error Tx Send Unit[%d] : Buffer:08x%08X\n", pDrvCtrl->unit, (int)pMblk, 3, 4, 5, 6);#ifdef IXP_DRV_DEBUG_MBUFS pDrvCtrl->errs++;#endif netMblkClChainFree (pMblk); rtnStatus = ERROR; } else { /* Bump the statistics counters. */ if ( bumpFlag != 0 ) END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); } if (!(pDrvCtrl->flags & IxEthAccEnd_POLLING)) { END_TX_SEM_GIVE (&pDrvCtrl->end); } DO_EVENT(IXE_EVT_XMT_SEND_EXIT); return(rtnStatus);}/********************************************************************************* ixEthAccEndIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL STATUS ixEthAccEndIoctl(END_DEVICE * pDrvCtrl, /* device receiving command */int cmd, /* ioctl command code */caddr_t data /* command argument */){ int error = 0; long value; IXP_DRV_LOG (IXP_DRV_DEBUG_IOCTL, "ixe: Ioctl:unit[%d]:CMD:0x%08X\n", pDrvCtrl->unit, cmd, 3, 4, 5, 6); switch ((UINT)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); END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } ixEthAccEndConfig (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ ixEthAccEndPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ ixEthAccEndPollStop (pDrvCtrl); break; case EIOCGMIB2: /* return MIB information */ if (data == NULL) return(EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return(EINVAL); *(int *)data = IxEthAccEnd_MIN_FBUF; break; default: error = EINVAL; } return(error);}/******************************************************************************** ixEthAccEndConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void ixEthAccEndConfig(END_DEVICE *pDrvCtrl /* device to be re-configured */){ /* Set promiscuous mode if it's asked for. */ if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC) { IXP_DRV_LOG ((IXP_DRV_DEBUG_IOCTL | IXP_DRV_DEBUG_LOAD), "Port [%d]: Setting promiscuous mode on!\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); ixEthAccPortPromiscuousModeSet(pDrvCtrl->unit); } else { IXP_DRV_LOG ((IXP_DRV_DEBUG_IOCTL | IXP_DRV_DEBUG_LOAD), "Port [%d]: Setting promiscuous mode off!\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); ixEthAccPortPromiscuousModeClear(pDrvCtrl->unit); } /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0) { ixEthAccEndAddrFilterSet (pDrvCtrl); } return;}/******************************************************************************** ixEthAccEndAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the endAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/LOCAL void ixEthAccEndAddrFilterSet(END_DEVICE *pDrvCtrl /* device to be updated */){ ETHER_MULTI* pCurr; pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end); while (pCurr != NULL) { pCurr = END_MULTI_LST_NEXT(pCurr); }}/********************************************************************************* ixEthAccEndPollRcv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK upon success. EAGAIN is returned when no packet is available.*/LOCAL STATUS ixEthAccEndPollRcv(END_DEVICE * pDrvCtrl, /* device to be polled */M_BLK_ID pMblk /* ptr to buffer */){#ifdef IXE_ETHACC_POLL_ENABLE u_short stat; char* pPacket; int len; IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv\n", 1, 2, 3, 4, 5, 6); stat = ixEthAccEndStatusRead (pDrvCtrl); if (!(stat & IxEthAccEnd_RINT)) { IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv no data\n", 1, 2, 3, 4, 5, 6); return(EAGAIN); } /* Get packet and length from device buffer/descriptor */ pPacket = NULL; /* DUMMY CODE */ len = 64; /* DUMMY CODE */ /* Upper layer must provide a valid buffer. */ if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "PRX bad mblk\n", 1, 2, 3, 4, 5, 6); return(EAGAIN); } END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); bcopy (pPacket, pMblk->m_data, len); 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 */ IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6); IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6); return(OK);#else return(ERROR);#endif /* IXE_ETHACC_POLL_ENABLE */}/********************************************************************************* ixEthAccEndPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success. EAGAIN if device is busy.*/LOCAL STATUS ixEthAccEndPollSend(END_DEVICE* pDrvCtrl, /* device to be polled */M_BLK_ID pMblk /* packet to send */){#ifdef IXE_ETHACC_POLL_ENABLE int len; u_short stat; IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6); stat = ixEthAccEndStatusRead (pDrvCtrl); /* dummy code */ if ((stat & IxEthAccEnd_TINT) == 0) return((STATUS) EAGAIN); len = max (ETHERSMALL, pMblk->m_len); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* Free the data if it was accepted by device */ netMblkClChainFree (pMblk); IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "leaving ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6); return(OK);#else return(ERROR);#endif /* IXE_ETHACC_POLL_ENABLE */}/******************************************************************************* ixEthAccEndMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastAdd(END_DEVICE *pDrvCtrl, /* device pointer */char* pAddress /* new address to add */){ int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) ixEthAccEndConfig (pDrvCtrl); return(OK);}/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -