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

📄 motcpmend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
        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;        pDrvCtrl->freeRtn[pDrvCtrl->ether.txBdNext] = (FUNCPTR) netClFree;    pDrvCtrl->freeData[pDrvCtrl->ether.txBdNext].arg1 =        pDrvCtrl->endObject.pNetPool;    pDrvCtrl->freeData[pDrvCtrl->ether.txBdNext].arg2 = pBuf;    /* incr BD count */        pDrvCtrl->ether.txBdNext = (pDrvCtrl->ether.txBdNext + 1) %        pDrvCtrl->ether.txBdNum;        /* Unlock interrupts */        intUnlock (oldLevel);    /* release semaphore */    END_TX_SEM_GIVE (&pDrvCtrl->endObject);    /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);    return (OK);    }/********************************************************************************* motCpmEndIoctl - network interface control routine** This routine implements the network interface control functions.* It handles EIOCSIFADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS,* EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 and EIOCGFBUF commands.** RETURNS: OK if successful, otherwise EINVAL.*/LOCAL int motCpmEndIoctl    (    END_CTRL *	pDrvCtrl,	/* pointer to END_CTRL structure */    int		cmd,		/* command to process */    caddr_t	data		/* pointer to data */     )    {    int         error   = 0;            /* error value */    long 	value;    END_OBJ *	pEndObj	= &pDrvCtrl->endObject;    MOTCPMLOGMSG(("motCpmEndIoctl with command = 0x%x \n", cmd, 0, 0, 0, 0, 0));    switch (cmd)        {	case EIOCSADDR:	    if (data == NULL)	    	error = EINVAL;	    bcopy ((char *)data, (char *)END_HADDR(pEndObj),			END_HADDR_LEN(pEndObj));	    break;        case EIOCGADDR:	    if (data == NULL)	    	error = EINVAL;	     else	     	bcopy ((char *)END_HADDR(pEndObj), (char *)data,		 	END_HADDR_LEN(pEndObj));	  	break;   	case EIOCSFLAGS:	    value = (long) data;	    if (value < 0)		{		value = -value;		value--;		END_FLAGS_CLR (pEndObj, value);		}	    else		END_FLAGS_SET (pEndObj, value);	    /* set promisc bit off flags */	    if (END_FLAGS_GET(pEndObj) & IFF_PROMISC)		pDrvCtrl->ether.pSccReg->psmr |= SCC_ETHER_PSMR_PRO;	    else		pDrvCtrl->ether.pSccReg->psmr &= ~SCC_ETHER_PSMR_PRO;	    break;	case EIOCGFLAGS:	    if (data == NULL)		error = EINVAL;	    else	    	*(int *)data = END_FLAGS_GET(pEndObj);	    break;	case EIOCPOLLSTART:	    error = motCpmEndPollStart (pDrvCtrl);	    break;	case EIOCPOLLSTOP:	    error = motCpmEndPollStop (pDrvCtrl);	    break;	case EIOCGMIB2:	    if (data == NULL)	    	error = EINVAL;	    else		bcopy((char *)&pDrvCtrl->endObject.mib2Tbl, (char *)data,			sizeof(pDrvCtrl->endObject.mib2Tbl));	    break;        case EIOCGFBUF:	    if (data == NULL)		error =  EINVAL;	    else		*(int *)data = LENGTH_MIN_FBUF;	    break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* motCpmEndMCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. ** 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 : OK or ERROR*/LOCAL STATUS motCpmEndMCastAddrAdd    (    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */    char *      pAddr		/* Address to add to the table. */    )    {    STATUS error;    MOTCPMLOGMSG(("motCpmEndMCastAddrAdd %x:%x:%x:%x:%x:%x \n", 		 pAddr[5], pAddr[4], pAddr[3], 		 pAddr[2], pAddr[1], pAddr[0]));    error = etherMultiAdd (&pDrvCtrl->endObject.multiList, pAddr);    if (error == ENETRESET)	{	pDrvCtrl->endObject.nMulti++;	/* Set the multicast address */	motCpmMCastFilterSet (pDrvCtrl, pAddr);	error = OK;	}    return ((error == OK) ? OK : ERROR);    }/********************************************************************************* motCpmEndMCastAddrDel - 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 motCpmEndMCastAddrDel    (    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */    char *      pAddr		/* Address to delete from the table. */    )    {    STATUS error;    MOTCPMLOGMSG(("motCpmEndMCastDel %x:%x:%x:%x:%x:%x \n", 		 pAddr[5], pAddr[4], pAddr[3], 		 pAddr[2], pAddr[1], pAddr[0]));    error = etherMultiDel (&pDrvCtrl->endObject.multiList, pAddr);    if (error == ENETRESET)	{	pDrvCtrl->endObject.nMulti--;	motCpmMCastConfig (pDrvCtrl);	error = OK;	}    return ((error == OK) ? OK : ERROR);    }/********************************************************************************* motCpmEndMCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>**/LOCAL STATUS motCpmEndMCastAddrGet    (    END_CTRL *  pDrvCtrl,	/* pointer to END_CTRL structure */    MULTI_TABLE *pTable		/* table to fill in with addresses */    )    {    MOTCPMLOGMSG(("motCpmEndMCastAddrGet \n", 0, 0, 0, 0, 0, 0));    return (etherMultiGet (&pDrvCtrl->endObject.multiList, pTable));    }/********************************************************************************* motCpmEndPollStart - start polling mode** This routine starts polling mode by disabling ethernet interrupts and* setting the polling flag in the END_CTRL stucture.** It is necessary to empty transmit queue before entering polling mode* because M_BLK_ID free routine used in interrupt mode could be unusable * in this mode (could use kernel calls). ** RETURNS: OK or ERROR if already in polling mode.*/LOCAL STATUS motCpmEndPollStart    (    END_CTRL    *pDrvCtrl	/* pointer to END_CTRL structure */    )    {    int 	intLevel;    int		txBdIndex;    SCC_BUF *	pTxBd;    MOTCPMLOGMSG(("motCpmEndPollStart \n", 0, 0, 0, 0, 0, 0));    /* Lock interrupts */    intLevel = intLock();    /* clean transmit queue */    txBdIndex = pDrvCtrl->txBdIndexC;    while (txBdIndex != pDrvCtrl->ether.txBdNext)	{	pTxBd = & pDrvCtrl->ether.txBdBase[txBdIndex];	/* Spin until frame buffer is sent */	while (pTxBd->statusMode & SCC_ETHER_TX_BD_R)	    ;	/* Check for transmit errors */	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);	    }	/* increment txBdIndex */	txBdIndex = (txBdIndex + 1) % pDrvCtrl->ether.txBdNum;	}        /* free all transmit buffer and update transmit queue */    motCpmCleanTxBdQueue (pDrvCtrl);    /* Now, transmit queue is empty. We can enter polling mode. */    /* mask off the receive and transmit interrupts */        pDrvCtrl->ether.pSccReg->sccm = 0;    /* Set the polling flag */    pDrvCtrl->polling = TRUE;    /* Unlock interrupts */    intUnlock (intLevel);    return (OK);    }/********************************************************************************* motCpmEndPollStop - stop polling mode** This routine stops polling mode by enabling ethernet interrupts and* resetting the polling flag in the END_CTRL structure.** RETURNS: OK always*/LOCAL STATUS motCpmEndPollStop    (    END_CTRL    *pDrvCtrl	/* pointer to END_CTRL structure */    )    {    int         intLevel;    MOTCPMLOGMSG(("motCpmEndPollStop \n", 0, 0, 0, 0, 0, 0));    /* lock interrupt  */    intLevel = intLock();    /* reset the SCC's interrupt status bit */    *CPM_CISR(pDrvCtrl->regBase) = pDrvCtrl->ether.intMask;    /* enable this SCC's interrupt */    *CPM_CIMR(pDrvCtrl->regBase) |= pDrvCtrl->ether.intMask;    /* reset the status bits */    pDrvCtrl->ether.pSccReg->scce = 0xffff;    /* enables the receive and transmit interrupts */    pDrvCtrl->ether.pSccReg->sccm = SCC_ETHER_SCCX_RXF | SCC_ETHER_SCCX_TXE |				    SCC_ETHER_SCCX_TXB;    /* reset the polling flag */    pDrvCtrl->polling = FALSE;    /* unlock interrupt  */    intUnlock (intLevel);    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))	{	return (EAGAIN);	}    /* fill the transmit frame descriptor */        pBuf = pDrvCtrl->txPoolBuf;        length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL);    pTxBd->dataPointer = (u_char *) pBuf;    /* padding mechanism in Rev A is buggy - do in software */

⌨️ 快捷键说明

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