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

📄 if_enp.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    DRV_CTRL   *pDrvCtrl;#ifdef ENP_DEBUG    printf ( "\nenp: attach: unit=%d, addr=%x, ivec=%d, ilevel=%d, Am=%d\n",             unit, addr, ivec, ilevel, enpAddrAm );#endif    /* Safety check unit number */    if (unit < 0 || unit >= MAX_UNITS)        {        errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT);        return (ERROR);        }    /* Get pointer to our driver control structure */    pDrvCtrl = & drvCtrl [unit];    /* Check for multiple invocation per unit */    if (pDrvCtrl->attached)        return (OK);    /* Publish the interface data record */#ifdef BSD43_DRIVER    ether_attach    ( & pDrvCtrl->idr.ac_if, unit, "enp", (FUNCPTR) NULL,                      (FUNCPTR) enpIoctl, (FUNCPTR) enpOutput,                      (FUNCPTR) enpReset);#else    ether_attach (                  &pDrvCtrl->idr.ac_if, unit,                  "enp",                  (FUNCPTR)NULL,                 (FUNCPTR)enpIoctl,                  (FUNCPTR)ether_output,                 (FUNCPTR)enpReset                 );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)enpTxStartup;#endif#ifdef BSD43_DRIVER    /* Create the transmit semaphore. */    pDrvCtrl->TxSem = semMCreate    (                                    SEM_Q_PRIORITY |                                    SEM_DELETE_SAFE |                                    SEM_INVERSION_SAFE                                    );    if (pDrvCtrl->TxSem == NULL)        {#ifdef ENP_DEBUG        printf ("enp: error creating transmitter semaphore\n");#endif        return (ERROR);        }#endif    /* Determine local address and AM codes to access the controller */    if (sysBusToLocalAdrs (enpAddrAm, addr, &enpBase) == ERROR)        {        errnoSet (EFAULT);        return (ERROR);        }#ifdef ENP_DEBUG    printf ( "enp: attach: local addr=%x\n", enpBase );#endif    pEnpDev = (ENPDEVICE *) enpBase;    enpBase += 0x1000;  /* memory is offset from board base address */    /* Connect the interrupt handler */    (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (ivec),                       (VOIDFUNCPTR)enpIntr, unit);    /* wait for kernel reset to finish */    delay = 15 * sysClkRateGet ();    while (1)        {        /* Test for response on the buss */        if  (            vxMemProbe  (                        (char *) & pEnpDev->enp_status,                        O_RDONLY,                        sizeof (short),                        (char *) & status                        )            == OK            )            {            /* Check status word */            if ( (ntohs (status) & STS_READY) != 0 )                break;            }        /* Check for timeout */        if (--delay <= 0)            {            (void) errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT);            return (ERROR);            }        taskDelay (sysClkRateGet() / 30);       /* 1/30th of a second */        }    /* start link level firmware */    pEnpDev->enp_intvector = htons (ivec);    temp = htonl ((u_long) enpBase);    WRITELONG (&pEnpDev->enp_base, temp);#if  CPU_FAMILY==I960    pEnpDev->enp_mode = htons (0x0080);#endif /* CPU_FAMILY==I960 */    pEnpDev->enp_go = htons (GOVAL);    CACHE_PIPE_FLUSH ();    /* wait for the link level firmware to finish initialization */    delay = 15 * sysClkRateGet ();    while ((ntohs (pEnpDev->enp_state) & S_ENPRUN) == 0)        {        if (--delay <= 0)            {            (void) errnoSet (S_ioLib_DEVICE_ERROR);            return (ERROR);            }        taskDelay (sysClkRateGet() / 30);       /* 1/30th of a second */        }    pDrvCtrl->enpAddr     = pEnpDev;    pDrvCtrl->enpIntLevel = ilevel;    pDrvCtrl->enpIntVec   = ivec;    enpgetaddr (unit);    (void) sysIntEnable (ilevel);    /* Raise the interface flags */    pDrvCtrl->idr.ac_if.if_flags |= IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_MULTICAST;    /* Set our success indicator */    pDrvCtrl->attached = TRUE;    return (OK);    }/********************************************************************************* enpReset - reset the interface*/LOCAL STATUS enpReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    ENPDEVICE *pEnpDev;#ifdef ENP_DEBUG    printf ( "enp: reset: unit=%d\n", unit );#endif    /* Safety check unit number */    if (unit < 0 || unit >= MAX_UNITS)        {        errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT);        return (ERROR);        }    pDrvCtrl = & drvCtrl[unit];    pEnpDev = pDrvCtrl->enpAddr;    pDrvCtrl->idr.ac_if.if_flags = 0;    RESET_ENP (pEnpDev);    /* reset the status word that enpattach watches to know when enp is reset;     * this is necessary because the enp doesn't clear this status immediately     * on reset.  Re-initializing the enp after a reset (i.e. in VxWorks     * init after boot rom reset) could get fooled if we rely on enp to clear     * the READY bit in this status.     */    pEnpDev->enp_status = 0;    CACHE_PIPE_FLUSH ();    return (OK);    }/********************************************************************************* enpIntr - the driver's interrupt handler** The ENP board will only interrupt us to notify us that there are packets* to be processed.  The processing of each packet is done by netTask.  This* routine simply queues our job for netTask.*/LOCAL void enpIntr    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    /* Safety check unit number */    if (unit < 0 || unit >= MAX_UNITS)        return;    pDrvCtrl = & drvCtrl [unit];    sysBusIntAck (pDrvCtrl->enpIntLevel);    if (!pDrvCtrl->taskLevelActive)        {        /* indicate that enpHandleInt is q'd */        pDrvCtrl->taskLevelActive = TRUE;        (void) netJobAdd ((FUNCPTR)enpRxEvent, unit, 0,0,0,0);        /* see comment in enpHandleInt */        }    }/********************************************************************************* enpRxEvent - handler for receive events*/LOCAL void enpRxEvent    (    int unit    )    {    DRV_CTRL  *pDrvCtrl;    ENPDEVICE *pDev;    pDrvCtrl = & drvCtrl [unit];    pDev = pDrvCtrl->enpAddr;    splx (0);       /* Give up the spl semaphore taken for us by netTask. */    /* the following loop attempts to pull multiple buffers off of the     * input queue;  the boolean "taskLevelActive" is used to inform     * the interrupt level code that we're already processing input     * buffers, so there's no need to do a netJobAdd, thereby decreasing     * the possibility of a net task ring buffer overflow.     */    do        {        pDrvCtrl->taskLevelActive = TRUE;        while (!enpringempty ((RING*) &pDev->enp_tohost))            {            if ( enpRxPktProcess (unit) == ERROR )                {                pDrvCtrl->taskLevelActive = FALSE;                splimp ();      /* Take the spl semaphore for netTask */                return;                }            }        pDrvCtrl->taskLevelActive = FALSE;        /* check once more after resetting taskLevelActive to avoid race */        }    while (!enpringempty ((RING*) &pDev->enp_tohost));    splimp ();      /* Take the spl semaphore for netTask */    }/********************************************************************************* enpRxPktProcess - process the next received packet** Copy packets from a BCB into an mbuf and hand it to the next higher layer.*/LOCAL STATUS enpRxPktProcess    (    int unit    )    {    int             len;    int             temp;    DRV_CTRL        *pDrvCtrl;    ENET_HDR        *pEnetHdr;    MBUF            *pMbuf;    BCB             *pBCB;    ENPDEVICE       *pDev;    unsigned char   *pData;    /* Get control pointers */    pDrvCtrl = & drvCtrl [unit];    pDev = pDrvCtrl->enpAddr;    /* Check ifnet flags. Return if incorrect. */    if  (        (pDrvCtrl->idr.ac_if.if_flags & (IFF_UP | IFF_RUNNING)) !=        (IFF_UP | IFF_RUNNING)        )        return (ERROR);    /* Get pointer to next packet */    pBCB = (BCB*) enpringget ((RING*) &pDev->enp_tohost);    if (pBCB == NULL)                     /* unlikely error */        return (ERROR);    /* Bump the incoming packet statistic */    pDrvCtrl->idr.ac_if.if_ipackets++;    /* Get length of packet */    len = ntohs (pBCB->b_msglen);    /* Get pointer to packet */    READLONG ((& pBCB->b_addr), &temp);    pEnetHdr = (ENET_HDR *) ntohl (temp);    /* call input hook if any */    if (etherInputHookRtn != NULL)        {        if  (            (*etherInputHookRtn) (& pDrvCtrl->idr.ac_if, (char *) pEnetHdr, len)            == 1            )            {            (void) enpringput ((RING *)&pDev->enp_enpfree, pBCB);            return (OK);            }        }    /* Adjust length; subtract size of header */    len -= ENET_HDR_REAL_SIZ;    /* Get pointer to data section of the packet */    pData = ((unsigned char *) pEnetHdr) + ENET_HDR_REAL_SIZ;    /* copy data from enp to mbuf a word at a time */#if (CPU == MC68000) || (CPU == MC68010) || (CPU == CPU32)    pMbuf = bcopy_to_mbufs (pData, len, 0, (IFNET *) &pDrvCtrl->idr.ac_if, 1);#else    pMbuf = bcopy_to_mbufs (pData, len, 0, (IFNET *) &pDrvCtrl->idr.ac_if, 2);#endif  /* (CPU == MC68000) || (CPU == MC68010) || (CPU == CPU32) */    if (pMbuf != NULL)#ifdef BSD43_DRIVER        do_protocol_with_type   (                                ntohs (pEnetHdr->type),                                pMbuf,                                & pDrvCtrl->idr,                                len                                );#else        do_protocol (pEnetHdr, pMbuf, &pDrvCtrl->idr, len);#endif    else        ++pDrvCtrl->idr.ac_if.if_ierrors;       /* bump error stat */    (void) enpringput ((RING *)&pDev->enp_enpfree, pBCB);

⌨️ 快捷键说明

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