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

📄 m8260sccend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
        intUnlock(s);        return(END_ERR_BLOCK);        }    /* fill the transmit frame descriptor */    pBuf = NULL;    pBuf = netClusterGet(pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId);    if (pBuf == NULL)        {        END_TX_SEM_GIVE (&pDrvCtrl->endObject);        netMblkClChainFree(pMblk);        return(ERROR);        }    length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL);    netMblkClChainFree(pMblk);     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;    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);    }/********************************************************************************* motSccEndIoctl - 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 motSccEndIoctl    (    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(("motSccEndIoctl with command = 0x%x \n", cmd, 0, 0, 0, 0, 0));    switch ((UINT32) cmd)        {        case EIOCSADDR:            if (data == NULL)                error = EINVAL;            else                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 = motSccEndPollStart (pDrvCtrl);            break;        case EIOCPOLLSTOP:            error = motSccEndPollStop (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;        }    MOTCPMLOGMSG(("motSccEndIoctl: DONE status %x \n",                   error, 0, 0, 0, 0, 0));    return(error);    }/********************************************************************************* motSccEndMCastAddrAdd - 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 motSccEndMCastAddrAdd    (    END_CTRL *  pDrvCtrl,   /* pointer to END_CTRL structure */    char *      pAddr       /* Address to add to the table. */    )    {    STATUS error;    MOTCPMLOGMSG(("motSccEndMCastAddrAdd %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 */        motSccMCastFilterSet (pDrvCtrl, pAddr);        error = OK;        }    return((error == OK) ? OK : ERROR);    }/********************************************************************************* motSccEndMCastAddrDel - 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 motSccEndMCastAddrDel    (    END_CTRL *  pDrvCtrl,   /* pointer to END_CTRL structure */    char *      pAddr       /* Address to delete from the table. */    )    {    STATUS error;    MOTCPMLOGMSG(("motSccEndMCastDel %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--;        motSccMCastConfig (pDrvCtrl);        error = OK;        }    return((error == OK) ? OK : ERROR);    }/********************************************************************************* motSccEndMCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>**/LOCAL STATUS motSccEndMCastAddrGet    (    END_CTRL *    pDrvCtrl, /* pointer to END_CTRL structure */    MULTI_TABLE * pTable    /* table to fill in with addresses */    )    {    MOTCPMLOGMSG(("motSccEndMCastAddrGet \n", 0, 0, 0, 0, 0, 0));    return (etherMultiGet (&pDrvCtrl->endObject.multiList, pTable));    }/********************************************************************************* motSccEndPollStart - 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 motSccEndPollStart    (    END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */    )    {    int         intLevel;    int         txBdIndex;    SCC_BUF *   pTxBd;    MOTCPMLOGMSG(("motSccEndPollStart \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;            motSccTxRestart (pDrvCtrl);            }        /* increment txBdIndex */        txBdIndex = (txBdIndex + 1) % pDrvCtrl->ether.txBdNum;        }    /* free all transmit buffer and update transmit queue */    motSccCleanTxBdQueue (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);    MOTCPMLOGMSG(("motSccEndPollStart OK\n", 0, 0, 0, 0, 0, 0));    return(OK);    }/********************************************************************************* motSccEndPollStop - 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 motSccEndPollStop    (    END_CTRL *  pDrvCtrl /* pointer to END_CTRL structure */    )    {    int         intLevel;    MOTCPMLOGMSG(("motSccEndPollStop \n", 0, 0, 0, 0, 0, 0));    /* lock interrupt  */    intLevel = intLock();    /* reset the SCC's interrupt status bit */    *M8260_SIPNR_L(pDrvCtrl->regBase) = pDrvCtrl->ether.intMask;    /* enable this SCC's interrupt */    *M8260_SIMR_L(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);    }/*******************************************************************************

⌨️ 快捷键说明

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