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

📄 motcpmend.c

📁 860最小系统的bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
*
* If it detects a transmission error, the restart command is issued.
*
* These routine should not call any kernel functions.
*
* RETURNS: OK or EAGAIN
*/

/*LOCAL STATUS motCpmEndPollSend*/
LOCAL STATUS motCpmEndSend/*wut 2004.7.22modify*/
    (
    END_CTRL    *pDrvCtrl,	/* pointer to END_CTRL structure */
    M_BLK_ID    pMblk	/* data to send */
    )
    {
    int		length;
    int              oldLevel;
    SCC_BUF *	pTxBd;
    u_char *	pad;
    char *	pBuf;
	
    if(send1==1)
    MOTCPMLOGMSG(("motCpmEndSend_START \n", 0, 0, 0, 0, 0, 0));



    END_TX_SEM_TAKE (&pDrvCtrl->endObject, WAIT_FOREVER);

    /* get a free transmit frame descriptor */

    pTxBd = & pDrvCtrl->ether.txBdBase[pDrvCtrl->ether.txBdNext];

    /* check if a transmit buffer descriptor is available */

    if ((pTxBd->statusMode & SCC_ETHER_TX_BD_R) ||
	(((pDrvCtrl->ether.txBdNext + 1) % pDrvCtrl->ether.txBdNum)
			== pDrvCtrl->txBdIndexC))
	{
	    END_TX_SEM_GIVE (&pDrvCtrl->endObject);
	    if(send3==1)
	    MOTCPMLOGMSG(("pTxBd->statusMode & SCC_ETHER_TX_BD_R \n", 0, 0, 0, 0, 0, 0));
	    motCpmCleanTxBdQueue (pDrvCtrl);
	    return (EAGAIN);
	}

    /* fill the transmit frame descriptor */
    
   pBuf = netClusterGet (pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId);
	
    if (pBuf == NULL)
        {
            END_TX_SEM_GIVE (&pDrvCtrl->endObject);
            if(send4==1)
            MOTCPMLOGMSG(("tran_pBuf == NULL \n", 0, 0, 0, 0, 0, 0));
	     netMblkClChainFree(pMblk); 	/*wutao*/
            return (ERROR);
        }

   length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL);
	
    pTxBd->dataPointer = (u_char *) pBuf;

    /* padding mechanism in Rev A is buggy - do in software */

    if (length < FRAME_MIN)
	{
	pad = pTxBd->dataPointer + length;
	for (; length != FRAME_MIN; length++, pad++)
	    *pad = 0x88;
	}

    pTxBd->dataLength = length;

    oldLevel = intLock ();	/* disable ints during update */

    if (pTxBd->statusMode & SCC_ETHER_TX_BD_W)
	pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
			    SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
			    SCC_ETHER_TX_BD_W | SCC_ETHER_TX_BD_R;
    else
	pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
			    SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
			    SCC_ETHER_TX_BD_R;

    /* incr BD count */

    pDrvCtrl->ether.txBdNext = (pDrvCtrl->ether.txBdNext + 1) %
				pDrvCtrl->ether.txBdNum;


    intUnlock (oldLevel);

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);

    /*
     * Spin until we've sent it.
     */

    if(send5==1)
            MOTCPMLOGMSG(("while no over \n", 0, 0, 0, 0, 0, 0));
	
    while (pTxBd->statusMode & SCC_ETHER_TX_BD_R)
	;

    if (pTxBd->statusMode & (SCC_ETHER_TX_BD_RL | SCC_ETHER_TX_BD_UN |
			    SCC_ETHER_TX_BD_CSL | SCC_ETHER_TX_BD_LC))
	{
	/* An error has occured, restart the transmitter */

	    
             	if(send6==1)
             	MOTCPMLOGMSG(("pDrvCtrl->txStop = TRUE \n", 0, 0, 0, 0, 0, 0));
				
 		motCpmTxRestart (pDrvCtrl);
		motCpmCleanTxBdQueue (pDrvCtrl);
		
	
	}

   
     	netClFree (pDrvCtrl->endObject.pNetPool, pBuf);

     	netMblkClChainFree(pMblk); 


    	pDrvCtrl->txBdIndexC = pDrvCtrl->ether.txBdNext;
	if(send7==1)
	MOTCPMLOGMSG(("tran_over \n", 0, 0, 0, 0, 0, 0));
	
	END_TX_SEM_GIVE (&pDrvCtrl->endObject);
	
    	return (OK);
    }

/******************************************************************************
*
* motCpmEndPollSend - transmit a packet in polled mode
*
* This routine is called by a user to try and send a packet on the
* device. It sends a packet directly on the network from the caller without
* going through the normal processes of queuing a pacet on an output queue
* and the waiting for the device to decide to transmit it.
*
* If it detects a transmission error, the restart command is issued.
*
* These routine should not call any kernel functions.
*
* RETURNS: OK or EAGAIN
*/

   LOCAL STATUS motCpmEndPollSend

    (
    END_CTRL    *pDrvCtrl,	/* pointer to END_CTRL structure */
    M_BLK_ID    pMblk	/* data to send */
    )
    {
    int		length;
    SCC_BUF *	pTxBd;
    u_char *	pad;
    char *	pBuf;

    MOTCPMLOGMSG(("motCpmEndPollSend \n", 0, 0, 0, 0, 0, 0));

    if (pDrvCtrl->txStop)
	return (ERROR);

    /* get a free transmit frame descriptor */

    pTxBd = & pDrvCtrl->ether.txBdBase[pDrvCtrl->ether.txBdNext];

    /* check if a transmit buffer descriptor is available */

    if ((pTxBd->statusMode & SCC_ETHER_TX_BD_R) ||
	(((pDrvCtrl->ether.txBdNext + 1) % pDrvCtrl->ether.txBdNum)
			== pDrvCtrl->txBdIndexC))
	{
	motCpmCleanTxBdQueue (pDrvCtrl);
	return (EAGAIN);
	}

    /* fill the transmit frame descriptor */
    
    pBuf = netClusterGet (pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId);
    if (pBuf == NULL)
        {
        return (ERROR);
        }

    length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL);

    pTxBd->dataPointer = (u_char *) pBuf;

    /* padding mechanism in Rev A is buggy - do in software */

    if (length < FRAME_MIN)
	{
	pad = pTxBd->dataPointer + length;
	for (; length != FRAME_MIN; length++, pad++)
	    *pad = 0x88;
	}

    pTxBd->dataLength = length;

    if (pTxBd->statusMode & SCC_ETHER_TX_BD_W)
	pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
			    SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
			    SCC_ETHER_TX_BD_W | SCC_ETHER_TX_BD_R;
    else
	pTxBd->statusMode = SCC_ETHER_TX_BD_I | SCC_ETHER_TX_BD_PAD |
			    SCC_ETHER_TX_BD_L | SCC_ETHER_TX_BD_TC  |
			    SCC_ETHER_TX_BD_R;

    /* incr BD count */

    pDrvCtrl->ether.txBdNext = (pDrvCtrl->ether.txBdNext + 1) %
				pDrvCtrl->ether.txBdNum;

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);

    /*
     * Spin until we've sent it.
     */

    while (pTxBd->statusMode & SCC_ETHER_TX_BD_R)
	;

    if (pTxBd->statusMode & (SCC_ETHER_TX_BD_RL | SCC_ETHER_TX_BD_UN |
			    SCC_ETHER_TX_BD_CSL | SCC_ETHER_TX_BD_LC))
	{
	/* An error has occured, restart the transmitter */

	pDrvCtrl->txStop = TRUE;

	motCpmTxRestart (pDrvCtrl);
	}

    /* 
     * we are allow to do this because transmit queue is empty when we
     * start polling mode.
     */

    netClFree (pDrvCtrl->endObject.pNetPool, pBuf);

     netMblkClChainFree(pMblk); 

    pDrvCtrl->txBdIndexC = pDrvCtrl->ether.txBdNext;

    return (OK);
    }


/*******************************************************************************
*
* motCpmEndPollReceive - receive a packet in polled mode
*
* This routine is called by a user to try and get a packet from the
* device. It returns EAGAIN if no packet is available. The caller must
* supply a M_BLK_ID with enough space to contain the receiving packet. If
* enough buffer is not available then EAGAIN is returned.
*
* These routine should not call any kernel functions.
*
* RETURNS: OK or EAGAIN
*/

LOCAL STATUS motCpmEndPollReceive
    (
    END_CTRL    *pDrvCtrl,	/* pointer to END_CTRL structure */
    M_BLK_ID    pMblk
    )
    {
    SCC_BUF *	pRxBd = & pDrvCtrl->ether.rxBdBase[pDrvCtrl->ether.rxBdNext];
    int		length;
    int		status = EAGAIN;

    MOTCPMLOGMSG(("motCpmEndPollReceive \n", 0, 0, 0, 0, 0, 0));

    /* if we have not received packets, leave immediatly */

    if (pRxBd->statusMode & SCC_ETHER_RX_BD_E)
	return (EAGAIN);

    /* check packets for errors */

    if (((pRxBd->statusMode & (SCC_ETHER_RX_BD_F  | SCC_ETHER_RX_BD_L))
			   == (SCC_ETHER_RX_BD_F  | SCC_ETHER_RX_BD_L))
       && !(pRxBd->statusMode & (SCC_ETHER_RX_BD_CL |
				SCC_ETHER_RX_BD_OV | SCC_ETHER_RX_BD_CR |
				SCC_ETHER_RX_BD_SH | SCC_ETHER_RX_BD_NO |
				SCC_ETHER_RX_BD_LG)))
	{
	/* adjust length to data only */

	length = pRxBd->dataLength;

	if ((length - SIZEOF_ETHERHEADER) <= 0)
	    {
	    /* bump input error packet counter */

	    END_ERR_ADD (&pDrvCtrl->endObject, MIB2_IN_ERRS, +1);
	    goto cleanRxBd;
	    }

	/* 
	 * Upper layer provides the buffer.
         * If buffer is not large enough, we return.
	 */

	/* copy data */

        if ((pMblk->mBlkHdr.mLen < length) ||
            (!(pMblk->mBlkHdr.mFlags & M_EXT)))
            {
            goto cleanRxBd;
            }
        
	bcopy ((char *) pRxBd->dataPointer, (char *)pMblk->mBlkHdr.mData,
               length);
	pMblk->mBlkHdr.mLen = length;
	pMblk->mBlkPktHdr.len = length;
	pMblk->mBlkHdr.mFlags |= M_PKTHDR;

	/* bump input packet counter */

	END_ERR_ADD (&pDrvCtrl->endObject, MIB2_IN_UCAST, +1);

	status = OK;
	}
    else
	{
	/* bump input error packet counter */

	END_ERR_ADD (&pDrvCtrl->endObject, MIB2_IN_ERRS, +1);
	}

cleanRxBd:
    motCpmCleanRxBd (pDrvCtrl, pRxBd);	/* reset buffer descriptor as empty */

    return (status);
    }

/*******************************************************************************
*
* motCpmIntr - network interface interrupt handler
*
* This routine gets called at interrupt level. It handles work that 
* requires minimal processing. Interrupt processing that is more 
* extensive gets handled at task level. The network task, netTask(), is 
* provided for this function. Routines get added to the netTask() work 
* queue via the netJobAdd() command.
*
* RETURNS: N/A
*/

LOCAL void motCpmIntr/*wut*/
    (
    END_CTRL *	pDrvCtrl	/* pointer to END_CTRL structure */
    )
    {
    BOOL rxHandle = FALSE;
    BOOL txbHandle = FALSE;
    
    /* check for spurious interrupt -> initialized ? */

    if (!pDrvCtrl->endObject.attached)
	{
        pDrvCtrl->ether.pSccReg->scce = 0xffff;

        *CPM_CISR(pDrvCtrl->regBase) = pDrvCtrl->ether.intMask;
	return;
	}

    /* handle receive events */

    if ((pDrvCtrl->ether.pSccReg->sccm & SCC_ETHER_SCCX_RXF) &&
        (pDrvCtrl->ether.pSccReg->scce & SCC_ETHER_SCCX_RXF))
	{
        (void) netJobAdd ((FUNCPTR) motCpmHandleInt, (int) pDrvCtrl, 
			  0, 0, 0, 0); 

	/* turn off receive interrupts for now - motCpmHandleIt turns back on */

        pDrvCtrl->ether.pSccReg->sccm &= ~SCC_ETHER_SCCX_RXF;
	rxHandle = TRUE;
        }

    /* check for output errors */

    if (pDrvCtrl->ether.pSccReg->scce & SCC_ETHER_SCCX_TXE)
	{
	/* clean the transmit buffer descriptor queue */
	/* NOTE: HBC error not supported -> always RESTART Tx here */
	
	if(send11==1)
	MOTCPMLOGMSG(("netJobAdd (FUNCPTR) motCpmTxRestart\n", 0, 0, 0, 0, 0, 0));

	 if ( !pDrvCtrl->txCleaning)
	 motCpmCleanTxBdQueue (pDrvCtrl);
	 
	 pDrvCtrl->ether.pSccReg->scce = SCC_ETHER_SCCX_TXE;
        
        (void) netJobAdd ((FUNCPTR) motCpmTxRestart, (int) pDrvCtrl, 
			 

⌨️ 快捷键说明

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