📄 wancomend.c
字号:
* Establish the memory area that we will share with the device. If * the caller has provided an area, then we assume it is non-cacheable * and will not require the use of the special cache routines. * If the caller did not provide an area, then we must obtain it from * the system, using the cache savvy allocation routine. */ switch ( (int) pDrvCtrl->pMemBase ) { case NONE : /* we must obtain it */ /* this driver can't handle write incoherent caches */ if ( !CACHE_DMA_IS_WRITE_COHERENT () ) { WANCOM_DRV_LOG (DRV_DEBUG_LOAD, ("wancomEndLoad: shared memory not cache coherent\n"), 1, 2, 3, 4, 5, 6); return(ERROR); } /* Allocate NON cached memory for Rx & Tx descriptors */ pDrvCtrl->pMemBase = cacheDmaMalloc (descSize); if ( pDrvCtrl->pMemBase == NULL ) /* no memory available */ { WANCOM_DRV_LOG (DRV_DEBUG_LOAD, ("wancomEndLoad: could not obtain descriptors memory\n"), 1, 2, 3, 4, 5, 6); return(ERROR); } /* Allocate cached memory for Rx buffers */ pDrvCtrl->pClsBase = cacheDmaMalloc(buffSize); if ( pDrvCtrl->pClsBase == NULL ) /* no memory available */ { WANCOM_DRV_LOG (DRV_DEBUG_LOAD, ("wancomEndLoad: could not obtain Rx buffer memory\n"), 1, 2, 3, 4, 5, 6); return(ERROR); } pDrvCtrl->memSize = descSize + buffSize; pDrvCtrl->cacheFuncs = cacheDmaFuncs; break; default : return ERROR; /* the user provided an area - NOT Supported !! */ } /* zero the shared memory */ memset (pDrvCtrl->pMemBase, 0, (int) descSize); memset (pDrvCtrl->pClsBase, 0, (int) buffSize); /* pool of mblks */ if ( wancomMclBlkConfig.mBlkNum == 0 ) wancomMclBlkConfig.mBlkNum = (pDrvCtrl->nRFDs) * 4; /* pool of clusters */ if ( wancomClDescTbl[0].clNum == 0 ) { wancomClDescTbl[0].clNum = ((pDrvCtrl->nRFDs) * 2); wancomClDescTbl[0].clSize = RX_BUFFER_DEFAULT_SIZE; } wancomClDescTbl[0].memSize = (wancomClDescTbl[0].clNum * (wancomClDescTbl[0].clSize + CL_OVERHEAD)); wancomClDescTbl[0].memArea = pDrvCtrl->pClsBase; /* align the shared memory (64 bit aligment) */ wancomClDescTbl[0].memArea = (char *) (((u_long) wancomClDescTbl[0].memArea + 0xF) & ~0x3); /* pool of cluster blocks */ if ( wancomMclBlkConfig.clBlkNum == 0 ) wancomMclBlkConfig.clBlkNum = wancomClDescTbl[0].clNum; /* get memory for mblks */ if ( wancomMclBlkConfig.memArea == NULL ) { /* memory size adjusted to hold the netPool pointer at the head */ wancomMclBlkConfig.memSize = ( (wancomMclBlkConfig.mBlkNum * (M_BLK_SZ + 4)) + (wancomMclBlkConfig.clBlkNum * CL_BLK_SZ + 4)); if ( (wancomMclBlkConfig.memArea = (char *) memalign (4, wancomMclBlkConfig.memSize)) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Failed to allocate memory for Mblk and Clblk\n"), 0, 0, 0, 0, 0, 0); return(ERROR); } /* store the pointer to the cluster area */ pDrvCtrl->pMemArea = wancomMclBlkConfig.memArea; } /* init the mem pool */ if ( netPoolInit (pDrvCtrl->endObj.pNetPool, &wancomMclBlkConfig, &wancomClDescTbl[0], wancomClDescTblNumEnt, NULL) == ERROR ) { WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("netPoolInit failed\n"), 0, 0, 0, 0, 0, 0); return(ERROR); } if ( (pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, RX_BUFFER_DEFAULT_SIZE, FALSE)) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("netClPoolIdGet failed\n"), 0, 0, 0, 0, 0, 0); return(ERROR); } /* carve up the shared-memory region */ /* Set the Tx descriptors chain */ /* First ready CFD must be 4LW aligned (i.e. Desc_Address[3:0]=0000). */ pTxDesc = (TX_DESC*) (( (UINT32)pDrvCtrl->pMemBase & 0xFFFFFFF0 ) + 0x10); pDrvCtrl->usedTxDescPtr = pTxDesc; pDrvCtrl->currTxDescPtr = pTxDesc; /* save the first desc pointer to link with the last descriptor */ pTxFirstDesc = pTxDesc; pTxPrevDesc = pTxDesc; /* initialize the CFD ring */ for ( ix = 0; ix < pDrvCtrl->nCFDs; ix++ ) { pTxPrevDesc = pTxDesc; pTxDesc->cmd_sts = (RX_COMMAND)NULL; pTxDesc->buf_ptr = (unsigned)NULL; pTxDesc->pointerToRxQueue = (unsigned)NULL; pTxDesc->bytecnt = 0; pTxDesc->shadowOwner = SHADOW_OWNER_BY_GT; pTxDesc->next_desc_ptr = (UINT32) pTxDesc + TX_DESC_ALIGNED_SIZE; pTxDesc = (TX_DESC*)pTxDesc->next_desc_ptr; } /* Closing Tx descriptors ring */ pTxPrevDesc->next_desc_ptr = (UINT32)pTxFirstDesc; WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Tx ring start at 0x%x\n"),pTxFirstDesc, 0, 0, 0, 0, 0); WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Tx ring last at 0x%x\n"),pTxPrevDesc, 0, 0, 0, 0, 0); WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Tx ring last point at 0x%x\n"), pTxPrevDesc->next_desc_ptr, 0, 0, 0, 0, 0); /* Set the Rx descriptors chain */ /* First ready RFD pointer */ pRxDesc = (RX_DESC*) pTxDesc; WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Rx queue first desc at 0x%x\n"),(UINT32)pRxDesc, 0, 0, 0, 0, 0); pDrvCtrl->headRxDescPtr = pRxDesc; pRxTailDesc = pRxDesc; /* initialize the RFD queue */ for ( ix = 0; ix < pDrvCtrl->nRFDs - 1; ix++ ) /* save place for dummy desc */ { if ( (bufferPtr = (UINT32)netClusterGet(pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId)) == (UINT32)NULL ) { logMsg("Fail to retrieve a Rx cluster\n",0,0,0,0,0,0); return(ERROR); } pRxTailDesc = pRxDesc; pRxDesc->buf_ptr = bufferPtr; pRxDesc->cmd_sts = OWNER_BY_GT | ENABLE_INTERRUPT | LAST | FIRST; pRxDesc->bufsize = RX_BUFFER_DEFAULT_SIZE; pRxDesc->bytecnt = 0; pRxDesc->next_desc_ptr = (UINT32) pRxDesc + RX_DESC_ALIGNED_SIZE; pRxDesc = (RX_DESC*)pRxDesc->next_desc_ptr; } /* Set the Tail descriptor special Command Status word */ pRxTailDesc->cmd_sts = FIRST | LAST | ENABLE_INTERRUPT; pDrvCtrl->tailRxDescPtr = pRxTailDesc; /* Creating Rx queue end dummy (following the tail) */ pRxDummyDesc = (RX_DESC*)pRxTailDesc->next_desc_ptr; pRxDummyDesc->cmd_sts = FIRST | LAST | ENABLE_INTERRUPT; pRxDummyDesc->next_desc_ptr = (unsigned)NULL; pDrvCtrl->dummyRxDescPtr = pRxDummyDesc; WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Rx queue Tail at 0x%x\n"), pDrvCtrl->tailRxDescPtr, 0, 0, 0, 0, 0); WANCOM_DRV_LOG (DRV_DEBUG_MEM, ("Rx queue dummy at 0x%x\n"), pDrvCtrl->dummyRxDescPtr, 0, 0, 0, 0, 0); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); WANCOM_DRV_LOG (DRV_DEBUG_LOAD, ("wancomInitMem... Done\n"), 0, 0, 0, 0, 0, 0); return OK; }/**************************************************************************** wancomStart - start the device** This routine:* 1) Connects the driver ISR.* 2) Enables interrupts.* 3) Write the pointer to the first descriptor to the SDMA's first and current* descriptor * 4) Initialize and enable the Ethernet port by writing to the corresponding * port configuration and command registers.* 5) Initialize and enable the SDMA engine by writing to the corresponding * SDMA configuration and command registers.** RETURNS: OK, or ERROR if the device could not be initialized.*/LOCAL STATUS wancomStart ( WANCOM_DRV_CTRL *pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { int retVal; UINT32 portStatus; WANCOM_DRV_LOG (DRV_DEBUG_START, ("Starting end...\n"), 1, 2, 3, 4, 5, 6); /* must have been attached */ if ( !pDrvCtrl->attached ) return(ERROR); /* connect the int handler */ WANCOM_SYS_INT_CONNECT (pDrvCtrl, wancomInt, (int) pDrvCtrl, &retVal); if ( retVal == ERROR ) return(ERROR); /* Clear all Ethernet port interrupts */ GT64260_INT_ACK (0xFFFFFFFF); /* enable chip interrupts after wancomReset disabled them */ GT64260_INT_ENABLE; /* enable system interrupts after wancomReset disabled them */ WANCOM_SYS_INT_ENABLE (pDrvCtrl); /* Assigment of FRDP CRDP and CTRP of priority queue 0 */ PORT_REG_WRITE(FIRST_RX_DESC_PTR0_OFFSET, (UINT32)pDrvCtrl->headRxDescPtr); PORT_REG_WRITE(CURRENT_RX_DESC_PTR0_OFFSET,(UINT32)pDrvCtrl->headRxDescPtr); PORT_REG_WRITE(CURRENT_TX_DESC_PTR0_OFFSET,(UINT32)pDrvCtrl->currTxDescPtr); /* Assign port configuration and command. */ /* Port config register has already been init by address table routine */ PORT_REG_WRITE(PORT_CONFIG_EXTEND_REG, pDrvCtrl->port.portConfigExtend); PORT_REG_WRITE(PORT_COMMAND_REG, pDrvCtrl->port.portCommand); PORT_REG_WRITE(SDMA_CONFIGURATION_REG, pDrvCtrl->port.portSdmaConfig); PORT_REG_WRITE(SDMA_COMMAND_REG, ENABLE_RX_DMA); /* enable Rx */ /* set some flags to default values */ pDrvCtrl->rxHandle = FALSE; pDrvCtrl->txHandle = FALSE; pDrvCtrl->txStall = FALSE; /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* Check if link is up */ PORT_REG_READ(PORT_STATUS_REG, &portStatus); if ( !(portStatus & LINK_UP_BIT) ) { WANCOM_DRV_LOG(DRV_DEBUG_ERR, ("Port %d link down. Check line connection.\n"), pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } WANCOM_DRV_LOG (DRV_DEBUG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6); return(OK); }/**************************************************************************** wancomStop - stop the wancom interface** This routine marks the interface as inactive, disables interrupts and * resets the chip. It brings down the interface to a non-operational state. * To bring the interface back up, wancomStart() must be called.** RETURNS: OK, always.*/LOCAL STATUS wancomStop ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { /* disable system interrupt */ WANCOM_SYS_INT_DISABLE (pDrvCtrl); /* disable chip interrupt */ GT64260_INT_DISABLE; /* mark the interface as down */ END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); wancomReset(pDrvCtrl); /* wait for the reset... */ taskDelay (2); return OK; } /******************************************************************************** wancomSend - send an Ethernet packet** This routine() takes a M_BLK_ID and 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.** muxSend() calls this routine each time it wants to send a packet.** RETURNS: N/A*/LOCAL STATUS wancomSend ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ M_BLK * pMblk /* pointer to the mBlk/cluster pair */ ) { BOOL firstDesc; TX_DESC* pTxDescCurr; TX_DESC* pTxDescLast; TX_DESC* pTxDescFirst; M_BLK * pTuple; WANCOM_DRV_LOG (DRV_DEBUG_TX, ("wancomSend...\n"), 1, 2, 3, 4, 5, 6); if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) ) { return(wancomPollSend(pDrvCtrl, pMblk)); } /* check for CFDs availability */ /* get the current free CFD */ WANCOM_FREE_CFD_GET (pTxDescCurr); if ( pTxDescCurr == NULL ) { logMsg("General Send ERROR\n",0,0,0,0,0,0); /* assaf */ } WANCOM_DRV_LOG (DRV_DEBUG_TX, ("First free Tx desc 0x%x\n"), (UINT32)pTxDescCurr, 0, 0, 0, 0, 0); /* if the owner is the GT return ERROR to prevent data destruction */ if ( pTxDescCurr->cmd_sts & OWNER_BY_GT ) { WANCOM_DRV_LOG (DRV_DEBUG_TX, ("wancomSend...NO CFDS \n"), 1, 2, 3, 4, 5, 6); logMsg("wancomSend...NO CFDS \n", 1, 2, 3, 4, 5, 6); /* set to stall condition */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); pDrvCtrl->txStall = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return(END_ERR_BLOCK); } /* interlock with wancomCFDFree */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* In case of multiple packets */ while ( pMblk != NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_TX, ("Tx process packet 0x%x \n"), (UINT32)pMblk, 0, 0, 0, 0, 0); firstDesc = TRUE; /* Processing the first descriptor of a packet */ pTuple = pMblk; pTxDescFirst = pTxDescCurr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -