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

📄 motcpmend.c

📁 MPC850的bootrom。使用后可以直接启动boot程序
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    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);    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    (    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 */        (void) netJobAdd ((FUNCPTR) motCpmTxRestart, (int) pDrvCtrl, 			  0, 0, 0, 0);	pDrvCtrl->txStop = TRUE;	}    /* handle transmitter events - BD full condition -> ever happen ? */    if ((pDrvCtrl->ether.pSccReg->sccm & SCC_ETHER_SCCX_TXB) &&        (pDrvCtrl->ether.pSccReg->scce & SCC_ETHER_SCCX_TXB))	{	txbHandle = TRUE;	}    /* check for input busy condition */    if (pDrvCtrl->ether.pSccReg->scce & SCC_ETHER_SCCX_BSY)        pDrvCtrl->ether.pSccReg->scce = SCC_ETHER_SCCX_BSY;     /* acknowledge all other interrupts - ignore events */    pDrvCtrl->ether.pSccReg->scce = (pDrvCtrl->ether.pSccReg->scce &				    ~(SCC_ETHER_SCCX_RXF |				      SCC_ETHER_SCCX_TXE |				      SCC_ETHER_SCCX_TXB |				      SCC_ETHER_SCCX_BSY));    /*      * clean the transmit buffer descriptor queue if we have      * received a transmit interrupt and if we are not already     * cleaning this transmit queue.     */    if ((pDrvCtrl->txStop || txbHandle) && !pDrvCtrl->txCleaning)        {    	motCpmCleanTxBdQueue (pDrvCtrl);        if (pDrvCtrl->txBlocked)            {            pDrvCtrl->txBlocked = FALSE;            (void) netJobAdd ((FUNCPTR) muxTxRestart,                              (int)&pDrvCtrl->endObject,                              0, 0, 0, 0);            }        }    /* acknowledge interrupts */    if (rxHandle)        pDrvCtrl->ether.pSccReg->scce = SCC_ETHER_SCCX_RXF;     if (pDrvCtrl->txStop)        pDrvCtrl->ether.pSccReg->scce = SCC_ETHER_SCCX_TXE;     if (txbHandle)        pDrvCtrl->ether.pSccReg->scce = SCC_ETHER_SCCX_TXB;     *CPM_CISR(pDrvCtrl->regBase) = pDrvCtrl->ether.intMask;    }/********************************************************************************* motCpmMCastFilterSet - set the group addres filter for a multicast addresse.** To add an address in the processor group address hash filter, we use* the SET GROUP ADDRESS command. This command can be executed at any * time, regadless of whether the Ethernet channel is enabled.** RETURNS : N/A **/LOCAL void motCpmMCastFilterSet    (    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */    char *      pAddress        /* Address to delete from the table. */    )    {    MOTCPMLOGMSG(("motCpmMCastFilterSet \n", 0, 0, 0, 0, 0, 0));    /* add multicast address */    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_h =					(pAddress[5] << 8) + pAddress[4];    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_m =					(pAddress[3] << 8) + pAddress[2];    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_l =					(pAddress[1] << 8) + pAddress[0];    /* issue the set group address command to the CP */    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    *CPM_CPCR(pDrvCtrl->regBase) = ((pDrvCtrl->ether.sccNum - 1) << 6) |				       CPM_CR_SCC_SET_GROUP |				       CPM_CR_FLG;    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    }/********************************************************************************* motCpmMCastConfig - reconfigure the interface under us.** Reconfigure the interface changing the multicast interface list.** In order to delete an address from the hash tabke, the Ethernet channel* should be disabled, the hash table registers should be cleared, and * the SET GROUP ADDRESS command must be executed for the remaining * desired addresses. This is required because the hash table may have mapped* multiple addresses to the same hash table bit.** RETURNS : N/A */LOCAL void motCpmMCastConfig    (    END_CTRL *  pDrvCtrl	/* pointer to END_CTRL structure */    )    {    ETHER_MULTI *	pCurr;    MOTCPMLOGMSG(("motCpmMCastConfig \n",0,0,0,0,0,0));    /* disable the ethernet channel */    motCpmReset (pDrvCtrl);    /* clear hash table group registers */    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr1     = 0x0000;    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr2     = 0x0000;    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr3     = 0x0000;    ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr4     = 0x0000;    /* restore remaining addresses */    for (pCurr = END_MULTI_LST_FIRST(&pDrvCtrl->endObject); pCurr != NULL;			pCurr = (ETHER_MULTI *)lstNext(&pCurr->node))	{	/* add multicast address */	motCpmMCastFilterSet (pDrvCtrl, pCurr->addr);	}    /* restart the ethernet channel */    motCpmRestart (pDrvCtrl);    }/********************************************************************************* motCpmRestart - network interface restart routine** This routine restarts the device.  This includes enabling interrupts, * starting the transmitter and receiver, and calling the bsp-specific* LAN enable routine to do any target specific enabling.** This routine follows the instructions in MC68EN360/MPC821 Users's Manual :* "Disabling the SCCs on the Fly"** The complement of this routine is motCpmReset().  Once a unit is reset by* motCpmReset(), it may be re-initialized to a running state by this routine.** RETURNS: N/A*/LOCAL STATUS motCpmRestart    (    END_CTRL * 	pDrvCtrl	/* pointer to END_CTRL structure */    )    {    /* enable Ethernet interrupts */    *CPM_CIMR(pDrvCtrl->regBase) |= pDrvCtrl->ether.intMask;    /* call the BSP to do any other initialization (e.g., connecting clocks) */    SYS_ENET_ENABLE;    /* enable the transmitter */    pDrvCtrl->ether.pSccReg->gsmrl |= SCC_GSMRL_ENT;    /* issue the restart transmitter command to the CP */    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    *CPM_CPCR(pDrvCtrl->regBase) = ((pDrvCtrl->ether.sccNum - 1) << 6) |				      CPM_CR_SCC_RESTART |				      CPM_CR_FLG;    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    /* issue the enter hunt mode command to the CP */    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    *CPM_CPCR(pDrvCtrl->regBase) = ((pDrvCtrl->ether.sccNum - 1) << 6) |				      CPM_CR_SCC_HUNT |				      CPM_CR_FLG;    while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);    /* enable the receiver */    pDrvCtrl->ether.pSccReg->gsmrl |= SCC_GSMRL_ENR;    return (OK);    }/********************************************************************************* motCpmReset - network interface reset routine** This routine resets the device.  This includes disabling interrupts, * stopping the transmitter and receiver, and calling the bsp-specific* LAN disable routine to do any target specific disabling.** This routine follows the instructions in MC68EN360/MPC821 Users's Manual :* "Disabling the SCCs on the Fly"** The complements of this routine are motCpmEndStart() and motCpmRestart().  * Once a unit is reset in this routine, it may be re-started with parameters* reinitialized with motCpmEndStart() or re-started with current parameteres * with  motCpmRestart().** RETURNS: N/A*/LOCAL void motCpmReset    (    END_CTRL * 	pDrvCtrl	/* pointer to END_CTRL structure */    )    {    int counter = 0xffff;    /* disable the SCC interrupts */    *CPM_CIMR(pDrvCtrl->regBase) &= ~pDrvCtrl->ether.intMask;    /* issue the CP graceful stop command to the transmitter if necessary */    if (pDrvCtrl->ether.pSccReg->gsmrl & SCC_GSMRL_ENT)	{        while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);        *CPM_CPCR(pDrvCtrl->regBase) = ((pDrvCtrl->ether.sccNum - 1) << 6) |                                          CPM_CR_SCC_GRSTOP | CPM_CR_FLG;        while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);        /* wait for graceful stop to register */        while ((counter--) && (!(pDrvCtrl->ether.pSccReg->

⌨️ 快捷键说明

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