⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m8260fccend.c

📁 Embedded Planet公司的ep8260单板计算机的BSP包(VxWorks)
💻 C
📖 第 1 页 / 共 5 页
字号:
     */

    clNum = pDrvCtrl->rbdNum + MOT_FCC_BD_LOAN_NUM + MOT_FCC_TX_POLL_NUM + MOT_FCC_TX_CL_NUM;

    /* pool of mblks */
    if (mclBlkConfig.mBlkNum == 0){
	mclBlkConfig.mBlkNum = clNum * pDrvCtrl->mblkMult;
    }

    /* pool of clusters, including loaning buffers */
    if (clDescTbl[0].clNum == 0) {
	clDescTbl[0].clNum = clNum * pDrvCtrl->clMult;
	clDescTbl[0].clSize = MOT_FCC_MAX_CL_LEN;
    } 
    /* there's a cluster overhead and an alignment issue */
    clDescTbl[0].memSize = clDescTbl[0].clNum * (clDescTbl[0].clSize + CL_OVERHEAD) + CL_ALIGNMENT - 1;

    /*
     * Now we'll deal with the data buffers.  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 has not provided 
     * an area, then we must obtain it from the system, but we will not be
     * using the cache savvy allocation routine, since we will flushing or
     * invalidate the data cache itself as appropriate. This speeds up
     * driver operation, as the network stack will be able to process data
     * in a cacheable area.
     */

    switch ((int) pDrvCtrl->pBufBase) {
      case NONE :			     /* we must obtain it */
	clDescTbl[0].memArea = (char *) memalign(CL_ALIGNMENT, clDescTbl[0].memSize);
	if(clDescTbl[0].memArea == NULL){
	    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccInitMem: could not obtain memory\n"),0,0,0,0,0,0);
	    return ERROR;
	}
	/* store the pointer to the clBlock area and its size */
	pDrvCtrl->pBufBase = clDescTbl[0].memArea;
	pDrvCtrl->bufSize = clDescTbl[0].memSize;
	MOT_FCC_FLAG_SET (MOT_FCC_OWN_BUF_MEM);
	/* cache functions descriptor for data buffers */
	motFccBufCacheFuncs.flushRtn = cacheArchFlush;
	motFccBufCacheFuncs.invalidateRtn = cacheArchInvalidate;
	motFccBufCacheFuncs.virtToPhysRtn = NULL;
	motFccBufCacheFuncs.physToVirtRtn = NULL;
	pDrvCtrl->bufCacheFuncs = motFccBufCacheFuncs;
	break;

      default :			       /* the user provided an area */
	if (pDrvCtrl->bufSize == 0) {
	    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccInitMem: not enough memory\n"),0,0,0,0,0,0);
	    return ERROR;
	}

	/* 
	 * check the user provided enough memory with reference
	 * to the given number of receive/transmit frames, if any.
	 */
	if (pDrvCtrl->bufSize < clDescTbl[0].memSize) {
	    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccInitMem: not enough memory\n"),0,0,0,0,0,0);
	    return ERROR;
	}
	/* Set memArea to the buffer base */
	clDescTbl[0].memArea = pDrvCtrl->pBufBase;
	MOT_FCC_FLAG_CLEAR (MOT_FCC_OWN_BUF_MEM);
	pDrvCtrl->bufCacheFuncs = cacheNullFuncs;
	break;
    }

    /* zero and align the shared memory */
    memset (pDrvCtrl->pBufBase, 0, (int) pDrvCtrl->bufSize);
    pDrvCtrl->pBufBase = (char *) ROUND_UP((UINT32)pDrvCtrl->pBufBase,CL_ALIGNMENT);
 
    /* pool of cluster blocks */
    if (mclBlkConfig.clBlkNum == 0){
	mclBlkConfig.clBlkNum = clDescTbl[0].clNum;
    }
    /* get memory for mblks */
    if (mclBlkConfig.memArea == NULL) {
	/* memory size adjusted to hold the netPool pointer at the head */
	mclBlkConfig.memSize = ((mclBlkConfig.mBlkNum * (M_BLK_SZ + MBLK_ALIGNMENT))
				+ (mclBlkConfig.clBlkNum * (CL_BLK_SZ + CL_ALIGNMENT)));
	mclBlkConfig.memArea = (char *) memalign (MBLK_ALIGNMENT, mclBlkConfig.memSize);
	if (mclBlkConfig.memArea == NULL) {
	    return ERROR;
	}
	/* store the pointer to the mBlock area */
	pDrvCtrl->pMBlkArea = mclBlkConfig.memArea;
	pDrvCtrl->mBlkSize = mclBlkConfig.memSize;
    }

    /* init the mem pool */
    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &mclBlkConfig, &clDescTbl[0], clDescTblNumEnt, NULL) == ERROR) {
	return ERROR;
    }
    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, MOT_FCC_MAX_CL_LEN, FALSE)) == NULL) {
	return ERROR;
    }
    pDrvCtrl->unStallThresh = (pDrvCtrl->tbdNum >> 2);	/* wait for 25% available before restart MUX */
    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccInitMem... Done\n"), 0, 0, 0, 0, 0, 0);
    return OK;
}

/**************************************************************************
*
* motFccStart - start the device
*
* This routine starts the FCC device and brings it up to an operational
* state.  The driver must have already been loaded with the motFccEndLoad()
* routine.
*
* INTERNAL
* The speed field inthe phyInfo structure is only set after the call
* to the physical layer init routine. On the other hand, the mib2 
* interface is initialized in the motFccEndLoad() routine, and the default
* value of 10Mbit assumed there is not always correct. We need to
* correct it here.
*
* RETURNS: OK, or ERROR if the device could not be started.
*
*/
LOCAL STATUS motFccStart(DRV_CTRL *pDrvCtrl)
{
int	retVal;		/* convenient holder for return value */
char	bucket[4];	/* holder for vxMemProbe */

    MOT_FCC_LOG (MOT_FCC_DBG_START, "Starting end...\n", 1, 2, 3, 4, 5, 6);

    /* must have been loaded */
    if (!pDrvCtrl->loaded)
	return ERROR;

    if (vxMemProbe ((char *) (pDrvCtrl->fccIramAddr), VX_READ, 4, &bucket[0]) != OK) {
        MOT_FCC_LOG (MOT_FCC_DBG_START, ": need MMU mapping for address 0x%x\n",
                   (UINT32) pDrvCtrl->fccIramAddr, 2, 3, 4, 5, 6);
	return ERROR;
    }

    if(motFccTbdInit(pDrvCtrl) == ERROR || motFccRbdInit(pDrvCtrl) == ERROR)
	return ERROR;

    /* set some flags to default values */
    pDrvCtrl->txStall = FALSE;
    pDrvCtrl->tbdIndex = 0;
    pDrvCtrl->usedTbdIndex = 0;
    pDrvCtrl->cleanTbdNum = pDrvCtrl->tbdNum;
    pDrvCtrl->rbdIndex = 0;

    /* acknowledge system interrupt */
    SYS_FCC_INT_ACK (pDrvCtrl, retVal);
    if (retVal == ERROR)
	return ERROR;
	
    /* connect the interrupt handler */
    SYS_FCC_INT_CONNECT (pDrvCtrl, motFccInt, (int) pDrvCtrl, retVal);
    if (retVal == ERROR)
	return ERROR;

    /* enable system interrupt: set relevant bit in SIMNR_L */
    SYS_FCC_INT_ENABLE (pDrvCtrl, retVal);
    if (retVal == ERROR)
	return ERROR;
	
    /* call the BSP to do any other initialization (MII interface) */
    SYS_FCC_ENET_ENABLE;

    /* initialize some fields in the PHY info structure */
    if (motFccPhyPreInit (pDrvCtrl) != OK) {
	MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("Failed to pre-initialize the PHY\n"), 0, 0, 0, 0, 0, 0);
	return ERROR;
    }

    /* initialize the Physical medium layer */
    if (_func_motFccPhyInit == NULL)
	return ERROR;

    if (((* _func_motFccPhyInit) (pDrvCtrl->phyInfo)) != OK) {
	MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("Failed to initialize the PHY\n"), 0, 0, 0, 0, 0, 0);
	return ERROR;
    }

    /* initialize the chip */
    if (motFccInit (pDrvCtrl) == ERROR)
	return ERROR;

    /* correct the speed for the mib2 stuff */
    pDrvCtrl->endObj.mib2Tbl.ifSpeed = pDrvCtrl->phyInfo->phySpeed;

    /* startup the transmitter */
    pDrvCtrl->fccReg->fcc_gmr |= M8260_GFMR_ENT;

    /* mark the interface as up */
    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));

    /* startup the receiver */
    MOT_FCC_RX_ACTIVATE;

    /* Flush the write pipe */
    CACHE_PIPE_FLUSH ();

    MOT_FCC_LOG (MOT_FCC_DBG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6);
    return OK;
}

/**************************************************************************
*
* motFccStop - stop the 'motfcc' interface
*
* This routine marks the interface as inactive, disables interrupts and 
* the Ethernet Controller. As a result, reception is stopped immediately,
* and transmission is stopped after a bad CRC is appended to any frame
* currently being transmitted. The reception/transmission control logic
* (FIFO pointers, buffer descriptors, etc.) is reset. To bring the 
* interface back up, motFccStart() must be called.
*
* RETURNS: OK, always.
*/
LOCAL STATUS motFccStop(DRV_CTRL *pDrvCtrl)
{
int		retVal;		/* convenient holder for return value */
UINT8	command = 0;			/* command to issue to the CP */

    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccStop...\n"), 1, 2, 3, 4, 5, 6);

    /* mark the interface as down */
    END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));

    /* issue a graceful stop transmit command to the CP */
    command = M8260_CPCR_TX_GRSTOP;
    if (motFccCpcrCommand (pDrvCtrl, command) == ERROR)
	return ERROR;

    /* wait for the related interrupt */
    MOT_FCC_GRA_SEM_TAKE;

    /* mask chip interrupts */
    MOT_FCC_INT_DISABLE;	  

    /* disable system interrupt: reset relevant bit in SIMNR_L */
    SYS_FCC_INT_DISABLE (pDrvCtrl, retVal);
    if (retVal == ERROR)
	return ERROR;

    /* disconnect the interrupt handler */
    SYS_FCC_INT_DISCONNECT (pDrvCtrl, motFccInt, (int)pDrvCtrl, retVal);
    if (retVal == ERROR)
	return ERROR;

    /* call the BSP to disable the MII interface */
    SYS_FCC_ENET_DISABLE;

    /* free buffer descriptors */
    if (motFccBdFree (pDrvCtrl) != OK)
	return ERROR;

    MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccStop... Done \n"), 1, 2, 3, 4, 5, 6);
    return OK;
}


/*******************************************************************************
*
* motFccSendDummyFrame - send a dummy ethernet packet out for ARP
*
* This routine is run in netTask's context.
*
* RETURNS: N/A
*/
LOCAL void motFccSendDummyFrame(DRV_CTRL *pDrvCtrl)
{
int		intLevel;	/* current intr level */
int		len;		/* length of data to be sent */
char		*pBuf;		/* pointer to data to be sent */
FCC_BD		*pTbd;		/* pointer to the current ready TBD */
FCC_TBD_LIST	*pTbdList;	/* pointer to the TBD list*/

	END_TX_SEM_TAKE(&pDrvCtrl->endObj, WAIT_FOREVER);

	pTbd = &pDrvCtrl->tbdBase[pDrvCtrl->tbdIndex];
	pTbdList = &pDrvCtrl->pTbdList[pDrvCtrl->tbdIndex];
	pBuf = pDrvCtrl->pTxPollBuf;

	memset(pBuf,0xff,6);
	bcopy((char *)MOT_FCC_ADDR_GET(&pDrvCtrl->endObj),pBuf+6,6);

	len = 100;
	MOT_FCC_CACHE_FLUSH(pBuf,len);	/* flush the cache, if necessary */

	pTbd->bdLen = len;
	pTbd->bdAddr = (unsigned long)pBuf;
	pTbdList->pBuf = NULL;		/* not a Cluster pointer */
	pTbdList->info = 0;		/* so we know NOT to free in ISR */

	intLevel = intLock();
	pDrvCtrl->cleanTbdNum -= 1;			/* keep accurate count of clean BDs */
	if (pDrvCtrl->tbdIndex == (pDrvCtrl->tbdNum - 1)){
		pTbd->word1 =
			( M8260_FETH_TBD_R
			| M8260_FETH_TBD_L
			| M8260_FETH_TBD_TC
			| M8260_FETH_TBD_I
			| M8260_FETH_TBD_W
			| M8260_FETH_TBD_PAD
			);
	}else{
		pTbd->word1 =
			( M8260_FETH_TBD_R
			| M8260_FETH_TBD_L
			| M8260_FETH_TBD_TC
			| M8260_FETH_TBD_I
			| M8260_FETH_TBD_PAD
			);
	}
	/* move on to the next element */
	pDrvCtrl->tbdIndex = (pDrvCtrl->tbdIndex + 1) % pDrvCtrl->tbdNum;
	intUnlock (intLevel);

	END_TX_SEM_GIVE(&pDrvCtrl->endObj);
}

/*******************************************************************************
*
* motFccHandleLSCJob - task-level link status event processor
*
* This routine is run in netTask's context.
*
* RETURNS: N/A
*/
LOCAL void motFccHandleLSCJob(DRV_CTRL *pDrvCtrl)
{
int		intLevel;	/* current intr level */
UINT16		miiStat;
int		retVal,duplex;
UINT32		fccIramAddr,fpsmrVal;

    fccIramAddr = pDrvCtrl->fccIramAddr;

    MOT_FCC_LOG (MOT_FCC_DBG_ANY, "motFccHandleLSCJob: \n", 0, 0, 0, 0, 0, 0);

    ++pDrvCtrl->Stats->numLSCHandlerEntries;

    /* read MII status register once to unlatch link status bit */
    retVal = motFccMiiRead(pDrvCtrl,pDrvCtrl->phyInfo->phyAddr,1,&miiStat);
    /* read again to know it's current value */
    retVal = motFccMiiRead(pDrvCtrl,pDrvCtrl->phyInfo->phyAddr,1,&miiStat);

    if(miiStat & 4){	/* if link is now up */
	if(_func_motFccPhyDuplex){
	    /* get duplex mode from BSP */
	    retVal = (* _func_motFccPhyDuplex)(pDrvCtrl->phyInfo,&duplex);
	    if(retVal == OK){
		intLevel = int

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -