📄 ixethaccend.c
字号:
*(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ ixEthAccEndPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ ixEthAccEndPollStop (pDrvCtrl); break;#ifdef INCLUDE_RFC_2233 case EIOCGMIB2233: if ((data == NULL) || (pDrvCtrl->end.pMib2Tbl == NULL)) error = EINVAL; else *((M2_ID **)data) = pDrvCtrl->end.pMib2Tbl; break; case EIOCGPOLLCONF: if ((data == NULL)) error = EINVAL; else { *((END_IFDRVCONF **)data) = &pDrvCtrl->endStatsConf; IXP_DRV_LOG (IXP_DRV_DEBUG_MIB, "EIOCGPOLLCONF\n",0,0,0,0,0,0); } break; case EIOCGPOLLSTATS: if ((data == NULL)) error = EINVAL; else { error = ixEthAccEndMIBStatsDump(pDrvCtrl); if (error == OK) { *((END_IFCOUNTERS **)data) = &pDrvCtrl->endStatsCounters; IXP_DRV_LOG (IXP_DRV_DEBUG_MIB, "EIOCGPOLLSTATS\n",0,0,0,0,0,0); } } break;#else /* INCLUDE_RFC_2233 */ case EIOCGMIB2: /* return 1213 MIB information */ if (data == NULL) return(EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break;#endif /* INCLUDE_RFC_2233 */ case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return(EINVAL); *(int *)data = IxEthAccEnd_MIN_FBUF; break; case EIOCMULTIADD: error = ixEthAccEndMCastAdd (pDrvCtrl, (char *) data); break; case EIOCMULTIDEL: error = ixEthAccEndMCastDel (pDrvCtrl, (char *) data); break; case EIOCMULTIGET: error = ixEthAccEndMCastGet (pDrvCtrl, (MULTI_TABLE *) data); 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); } /* up-date statistics */ if (pMblk->mBlkHdr.mFlags & M_MCAST) { END_INC_IN_MCAST(pMblk->mBlkHdr.mData,len); } else if (pMblk->mBlkHdr.mFlags & M_BCAST) { END_INC_IN_BCAST(pMblk->mBlkHdr.mData,len); } else { END_INC_IN_UCAST(pMblk->mBlkHdr.mData,len); } 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. */ if (pMblk->mBlkHdr.mData[0] & (UINT8)0x01) { END_INC_OUT_MCAST(pMblk->mBlkHdr.mData, len); } else { END_INC_OUT_UCAST(pMblk->mBlkHdr.mData, len); } /* 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; error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress); if (error == ENETRESET) { ixEthAccEndConfig (pDrvCtrl); } ixEthAccPortMulticastAddressJoin(pDrvCtrl->unit, (IxEthAccMacAddr *)pAddress); return(OK); }/******************************************************************************* ixEthAccEndMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastDel ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ) { int error; error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress); ixEthAccPortMulticastAddressLeave(pDrvCtrl->unit, (IxEthAccMacAddr *)pAddress); if (error == ENETRESET) { ixEthAccEndConfig (pDrvCtrl); } return(OK); }/******************************************************************************* ixEthAccEndMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastGet ( END_DEVICE *pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { return(etherMultiGet (&pDrvCtrl->end.multiList, pTable)); }/********************************************************************************* ixEthAccEndStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndStop(END_DEVICE *pDrvCtrl /* device to be stopped */){ STATUS result = OK; /* If that port doesn't exist then just return */ if ( ixEthAccPhyAddresses[ pDrvCtrl->unit ] == 0xffffffff ) return OK; SYS_INT_DISCONNECT (pDrvCtrl, IxEthAccEndInt, (int)pDrvCtrl, &result); if (result == ERROR) { IXP_DRV_LOG (IXP_DRV_DEBUG_ERROR, "ixEthAccEndStop: Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } /* register callbacks which discard the traffic */ result = ixEthAccPortTxDoneCallbackRegister( pDrvCtrl->unit, ixEthAccEndTxDoneCallbackShutdown, (UINT32) pDrvCtrl); if ( result != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD), "Error:Registering IxEthAcc Tx Callbacks for shutdown Port[%d]\n", pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } result = ixEthAccPortRxCallbackRegister( pDrvCtrl->unit, ixEthAccEndRxCallbackShutdown, (UINT32) pDrvCtrl); if ( result != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD), "Error:Registering IxEthAcc Rx Callbacks for shutdown Port[%d]\n", pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } /* now, shutdown the hw level */ result = ixdp425EthLibStop(pDrvCtrl->unit); if ( result != IX_SUCCESS) { IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD), "ixdp425EthLibStop Failed Port[%d]\n", pDrvCtrl->unit,2,3,4,5,6); return ERROR; } /* Wait aprox 1/2 sec for spin down */ taskDelay(sysClkRateGet()/2); END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING)); return(result);}/******************************************************************************** ixEthAccEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndUnload(END_DEVICE* pDrvCtrl /* device to be unloaded *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -