📄 wancomend.c
字号:
** This routine frees all used command frames and notifies upper protocols* that new resources are available.** RETURNS: N/A**/LOCAL void wancomCFDFree ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { TX_DESC* pUsedCFD = NULL; WANCOM_DRV_LOG (DRV_DEBUG_TX, ("wancomCFDFree: \n"), 0, 0, 0, 0, 0, 0); /* interlock with wancomSend */ if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* process all the used CFDs until we find either: */ /* a. Descriptor that has not been transmitted yet. */ /* b. Descriptor that is in transmission process. */ WANCOM_USED_CFD_GET (pUsedCFD); FOREVER { WANCOM_DRV_LOG (DRV_DEBUG_TX, ("Start free Tx desc 0x%x\n"), (UINT32)pUsedCFD, 0, 0, 0, 0, 0); if ( pUsedCFD == NULL ) { if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_TX_SEM_GIVE (&pDrvCtrl->endObj); WANCOM_DRV_LOG (DRV_DEBUG_TX, ("General Tx ERROR...\n"), 0, 0, 0, 0, 0, 0); return; } if ( pUsedCFD->shadowOwner & SHADOW_OWNER_BY_GT ) { /* Stop release. This desc has not been transmitted yet.*/ /* Wait till next interrupt to continue the release */ break; } if ( pUsedCFD->cmd_sts & OWNER_BY_GT ) { /* Stop release. This desc is in transmission process. */ /* Wait till next interrupt to continue the release. */ break; } /* Release the mBlk chain of the transmitted packet in both polled & non-polled mode */ if ( pUsedCFD->pointerToRxQueue ) netMblkClChainFree ((M_BLK*)(pUsedCFD->pointerToRxQueue)); pUsedCFD->shadowOwner = SHADOW_OWNER_BY_GT; pUsedCFD = (TX_DESC*)pUsedCFD->next_desc_ptr; } /* Update the next descriptor to release. */ USED_CFD_SET(pUsedCFD); pDrvCtrl->txHandle = FALSE; if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_TX_SEM_GIVE (&pDrvCtrl->endObj); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* Enable interrupts only if non-polling. */ if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) GT64260_INT_ENABLE; WANCOM_DRV_LOG (DRV_DEBUG_INT, ("wancomCFDFree: Done \n"), 0, 0, 0, 0, 0, 0); }/**************************************************************************** wancomReset - reset the `wancom' interface** This routine resets the chip by aboarting any SDMA engine activity and* clearing the MIB counters.The Receiver And the Transmit Unit are in idle * state after this command is performed.** RETURNS: OK or ERROR, if the command was not successful.*/LOCAL STATUS wancomReset ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { int ix = 0; /* a counter */ UINT32 dummy; UINT32 portConfigExtend; UINT32 portSdmaCommand; /* Stop any port activity */ PORT_REG_WRITE(SDMA_COMMAND_REG, (ABORT_TRANSMIT | ABORT_RECEIVE)); /* Wait for all activity to terminate */ do { PORT_REG_READ(SDMA_COMMAND_REG, &portSdmaCommand); } while ( portSdmaCommand & (ABORT_TRANSMIT | ABORT_RECEIVE) ); /* Clear MIB counters in three stages */ /* 1) Reset portConfigExtend bit[16] to 'Clear' */ PORT_REG_READ(MIB_COUNTER_BASE, &portConfigExtend); portConfigExtend &= ~(1<<16); PORT_REG_WRITE(MIB_COUNTER_BASE, portConfigExtend); /* 2) Perform dummy reads from MIB counters */ for ( ix = MIB_COUNTER_BASE; ix < MIB_COUNTER_END; ix += 4 ) PORT_REG_READ(ix, &dummy); /* 3) Set the portConfigExtend bit[16] to 'Not effect' */ PORT_REG_READ(MIB_COUNTER_BASE, &portConfigExtend); portConfigExtend |= (1<<16); /* Reset portConfigExtend bit[16] */ PORT_REG_WRITE(MIB_COUNTER_BASE, portConfigExtend); return(OK); }/******************************************************************************** wancomIoctl - interface ioctl procedure** Process an interface ioctl request.** RETURNS: OK, or ERROR if the config command failed.*/LOCAL int wancomIoctl ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ UINT32 cmd, /* command to process */ caddr_t data /* pointer to data */ ) { int error = OK; INT8 savedFlags; long value; END_OBJ * pEndObj=&pDrvCtrl->endObj; UINT32 macH; UINT32 macL; WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); switch ( cmd ) { case EIOCSADDR: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCSADDR data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); if ( data == NULL ) error = EINVAL; else { /* Copy and install the new address */ bcopy ((char *) data, (char *) WANCOM_HADDR (&pDrvCtrl->endObj), WANCOM_HADDR_LEN (&pDrvCtrl->endObj)); macH = (data[0] << 8) | (data[1]); macL = (data[5] << 0) | (data[4] << 8) | (data[3] << 16)| (data[2] << 24); addAddressTableEntry(pDrvCtrl,macH,macL,1,0); } break; case EIOCGADDR: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCGADDR data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); if ( data == NULL ) error = EINVAL; else bcopy ((char *) WANCOM_HADDR (&pDrvCtrl->endObj), (char *) data, WANCOM_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCSFLAGS: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCSFLAGS data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); value = (long) data; if ( value < 0 ) { value = -value; value--; END_FLAGS_CLR (pEndObj, value); } else END_FLAGS_SET (pEndObj, value); WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, ("endFlags=0x%x \n"), END_FLAGS_GET(pEndObj), 0, 0, 0, 0, 0); /* handle IFF_PROMISC */ savedFlags = WANCOM_FLAG_GET(); if ( END_FLAGS_ISSET (IFF_PROMISC) ) WANCOM_FLAG_SET (WANCOM_PROMISC); else WANCOM_FLAG_CLEAR (WANCOM_PROMISC); wancomEndConfig(pDrvCtrl); break; case EIOCGFLAGS: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS: 0x%x: 0x%x\n", pEndObj->flags, *(long *)data, 0, 0, 0, 0); if ( data == NULL ) error = EINVAL; else *(long *)data = END_FLAGS_GET(pEndObj); break; case EIOCMULTIADD: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCMULTIADD data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); error = EINVAL; /* wancomMCastAddrAdd (pDrvCtrl, (char *) data); */ break; case EIOCMULTIDEL: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCMULTIDEL data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); error = EINVAL; /* wancomMCastAddrDel (pDrvCtrl, (char *) data); */ break; case EIOCMULTIGET: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCMULTIGET data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); error = EINVAL; /* wancomMCastAddrGet (pDrvCtrl, (MULTI_TABLE *) data); */ break; case EIOCPOLLSTART: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCPOLLSTART data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); wancomPollStart(pDrvCtrl); break; case EIOCPOLLSTOP: WANCOM_DRV_LOG (DRV_DEBUG_POLL, ("IOCTL about to call wancomPollStop\n"), 0, 0, 0, 0, 0, 0); wancomPollStop(pDrvCtrl); break; case EIOCGMIB2: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=EIOCGMIB2 data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0); if ( data == NULL ) error=EINVAL; else bcopy ((char *) &pEndObj->mib2Tbl, (char *) data, sizeof (pEndObj->mib2Tbl)); break; default: WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, ("INVALID IO COMMAND!! \n"), 0, 0, 0, 0, 0, 0); error = EINVAL; } return(error); }/******************************************************************************** wancomMCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS wancomMCastAddrAdd ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ char * pAddr /* address to be added */ ) { int retVal; WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, ("MCastAddrAdd\n"), 0, 0, 0, 0, 0, 0); retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr); if ( retVal == ENETRESET ) { pDrvCtrl->endObj.nMulti++; if ( pDrvCtrl->endObj.nMulti > N_MCAST ) { etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); pDrvCtrl->endObj.nMulti--; } } return((retVal == OK) ? OK : ERROR); }/********************************************************************************* wancomMCastAddrDel - delete a multicast address for the device** This routine deletes a multicast address from the current list of* multicast addresses.** RETURNS: OK or ERROR.*/LOCAL STATUS wancomMCastAddrDel ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ char * pAddr /* address to be deleted */ ) { int retVal; WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, ("wancomMCastAddrDel\n"), 0, 0, 0, 0, 0, 0); retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr); if ( retVal == ENETRESET ) { pDrvCtrl->endObj.nMulti--; } return((retVal == OK) ? OK : ERROR); }/******************************************************************************** wancomMCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>** RETURNS: OK or ERROR.*/LOCAL STATUS wancomMCastAddrGet ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ MULTI_TABLE *pTable /* table into which to copy addresses */ ) { WANCOM_DRV_LOG (DRV_DEBUG_IOCTL, ("wancomMCastAddrGet\n"), 0, 0, 0, 0, 0, 0); return(etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/******************************************************************************** wancomPollSend - transmit a packet in polled mode** This routine is called by a user to try and send a packet on the* device. It sends
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -