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

📄 if_ex.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                                    (FUNCPTR) exRecvAndHang,                                    unit,                                    pMsg->mb_er.er_blks[0].bb_len,                                    pMsg->mb_rply,                                    0,                                    0                                    );                break;            case LLRTRANSMIT:#ifdef EX_DEBUG                if ((pDrvCtrl->flags & EX_XPENDING) == 0)                    panic ("exxmit: no xmit pending");#endif  /* EX_DEBUG */                pDrvCtrl->flags &= ~EX_XPENDING;                if (pMsg->mb_rply == LL_OK)                    ;                else if (pMsg->mb_rply & LLXM_1RTRY)                    {                    pDrvCtrl->idr.ac_if.if_collisions++;                    }                else if (pMsg->mb_rply & LLXM_RTRYS)                    {                    pDrvCtrl->idr.ac_if.if_collisions += 2;       /* guess */                    }                else if (pMsg->mb_rply & LLXM_ERROR)                    {                    pDrvCtrl->idr.ac_if.if_oerrors++;                    pDrvCtrl->idr.ac_if.if_opackets--;#ifdef EX_DEBUG                    logMsg ("ex%d: transmit error=%#x\n", unit, pMsg->mb_rply,                            0, 0, 0, 0);#endif                    }                if (pDrvCtrl->idr.ac_if.if_snd.ifq_head != NULL)#ifdef BSD43_DRIVER                    (void)netJobAdd ( (FUNCPTR)exStart, unit, 0, 0, 0, 0);#else                    (void)netJobAdd ( (FUNCPTR)exStart, (int)pDrvCtrl,                                       0, 0, 0, 0);#endif                break;            case LLNET_STSTCS:                pDrvCtrl->idr.ac_if.if_ierrors = pDrvCtrl->pStatArray->sa_crc;                pDrvCtrl->flags &= ~EX_STATPENDING;                break;            case LLNET_ADDRS:                /* Copy the enet addr from the message to our IDR */                bcopy   (                        (caddr_t) pMsg->mb_na.na_addrs,                        (caddr_t) pDrvCtrl->idr.ac_enaddr,                        sizeof (pDrvCtrl->idr.ac_enaddr)                        );                break;            case LLNET_RECV:            case LLNET_MODE:                break;            }        if (sysBus == MULTI_BUS)            pDrvCtrl->pDev->bus.multi.xd_porta = 7;  /* ack the interrupt */        pMsg->mb_length = MBDATALEN;        exGiveRequest (pMsg, pDrvCtrl->pDev);        pMsg = pDrvCtrl->pX2HNext = pDrvCtrl->pX2HNext->mb_next;        }    }/********************************************************************************* exMsgBlkGet - get a request buffer** Fill in standard values, advance pointer.*/LOCAL EX_MSG *exMsgBlkGet    (    DRV_CTRL *pDrvCtrl    )    {    EX_MSG *pMsg;    pMsg = pDrvCtrl->pH2XNext;#ifdef EX_DEBUG    if ((pMsg->mb_status & MH_OWNER) == MH_EXOS)        panic ("ex: EXOS owns message buffer");#endif  /* EX_DEBUG */    pMsg->mb_1rsrv  = 0;    pMsg->mb_length = MBDATALEN;    pDrvCtrl->pH2XNext = pDrvCtrl->pH2XNext->mb_next;    return (pMsg);    }/********************************************************************************* exRecvAndHang - receive packet and post another receive request*/LOCAL void exRecvAndHang    (    int unit,    int len,    int status    )    {    exRecv (unit, len, status);    exRxRqst (unit);    }/********************************************************************************* exRecv - process Ethernet receive completion** If input error just drop packet.* Otherwise purge input buffered data path and examine* packet to determine type.  If can't determine length* from type, then have to drop packet.  Otherwise decapsulate* packet based on type and pass to type-specific higher-level* input routine.*/LOCAL void exRecv    (    int unit,    int len,    int status    )    {    DRV_CTRL            *pDrvCtrl;    struct ether_header *eh;    MBUF                *pMbuf;    u_char              *pData;    pDrvCtrl = & drvCtrl [unit];    if (status != LL_OK)        {        pDrvCtrl->idr.ac_if.if_ierrors++;#ifdef EX_DEBUG        printErr ("ex%d: receive error=%b\n", unit, status, RECV_BITS);#endif        return;        }    /* get input packet length and ptr to packet */    len -= 4;                                       /* subtract FCS */    eh = (struct ether_header *)(pDrvCtrl->pReadBuf);    pDrvCtrl->idr.ac_if.if_ipackets++;    /* call input hook if any */    if ( etherInputHookRtn != NULL )        {        if ( (* etherInputHookRtn)(&pDrvCtrl->idr.ac_if, (char *) eh, len) )            return; /* input hook has already processed this packet */        }    /* Subtract header size from length */    len -= SIZEOF_ETHERHEADER;    /* Get pointer to packet data */    pData = ((u_char *) eh) + (SIZEOF_ETHERHEADER);    pMbuf = copy_to_mbufs (pData, len, 0, & pDrvCtrl->idr.ac_if);    if (pMbuf == NULL)                  /* no room at the inn */        {        pDrvCtrl->idr.ac_if.if_ierrors++;        return;        }#ifdef BSD43_DRIVER    do_protocol_with_type (ntohs(eh->ether_type), pMbuf, &pDrvCtrl->idr, len);#else    do_protocol (eh, pMbuf, &pDrvCtrl->idr, len);#endif    }/********************************************************************************* exRxRqst - send receive request to EXOS** Called by exIntr, with interrupts disabled in both cases.*/LOCAL void exRxRqst    (    int unit    )    {    DRV_CTRL        *pDrvCtrl;    EX_MSG          *pMsg;    pDrvCtrl = & drvCtrl [unit];    pMsg = exMsgBlkGet(pDrvCtrl);    pMsg->mb_rqst                  = LLRECEIVE;    pMsg->mb_er.er_nblock          = 1;    pMsg->mb_er.er_blks[0].bb_len  = EXMAXRBUF;#if     (CPU_FAMILY == SPARC)    {    ULONG blockAddr;    blockAddr = (ULONG) exHostAdrs ((char *) pDrvCtrl->pReadBuf);    pMsg->mb_er.er_blks[0].bb_addr[0] = blockAddr >> 16;    pMsg->mb_er.er_blks[0].bb_addr[1] = blockAddr & 0xffff;    }#else    *(char **)pMsg->mb_er.er_blks[0].bb_addr =                    exHostAdrs ((char *) pDrvCtrl->pReadBuf);#endif  /* CPU_FAMILY == SPARC */    exGiveRequest (pMsg, pDrvCtrl->pDev);    }#ifdef BSD43_DRIVER/********************************************************************************* exOutput - the output routine*/LOCAL int exOutput    (    IDR *pIDR,    MBUF *pMbuf,    SOCK *pDest    )    {    return (ether_output ((IFNET*)pIDR, pMbuf, pDest, (FUNCPTR) exStart, pIDR));    }#endif/********************************************************************************* exIoctl - process an ioctl request*/LOCAL int exIoctl    (    IDR *pIDR,    int cmd,    caddr_t data    )    {    int ret;    ret = 0;    switch (cmd)        {        case SIOCSIFADDR:           ((struct arpcom *)pIDR)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (pIDR, &IA_SIN (data)->sin_addr);            break;        case SIOCSIFFLAGS:            /* Flags are set outside this module. No additional work to do. */            break;        default:            ret = EINVAL;        }    return (ret);    }/********************************************************************************* exHostAdrs - get host address as required by EXOS board** This routine converts the specified local address into the form* that the EXOS board wants to see it, namely converted into* the proper vme address space and, in the VME version, with the* address modifier in the upper byte.** RETURNS: proper EXOS access address or ERROR.*/LOCAL char *exHostAdrs    (    char *localAdrs    )    {    char *busAdrs;    if (sysLocalToBusAdrs (exBusAdrsSpace, localAdrs, &busAdrs) != OK)        {#ifdef EX_DEBUG        printErr ("ex: no bus access to local address 0x%x (AM=0x%x)\n",                  localAdrs, exBusAdrsSpace);#endif        return ((char*)ERROR);        }    if (sysBus == VME_BUS && !exBit32)        {        /* EXOS 202 (VME version) requires AM code in upper byte */        busAdrs = (char *) ((int) busAdrs | (exBusAdrsSpace << 24));        }    return (busAdrs);    }/********************************************************************************* exGiveRequest - give request buffer to EXOS*/LOCAL void exGiveRequest    (    EX_MSG      *pMsg,            /* pointer to msg buffer to give to EXOS */    DEV_CTRL    *pDev             /* device address */    )    {    pMsg->mb_status |= MH_EXOS;   /* give request to EXOS */    if (sysBus == VME_BUS)        pDev->bus.vme.xd_portb = EX_NTRUPT;    else        pDev->bus.multi.xd_portb = EX_NTRUPT;    }/* END OF FILE */

⌨️ 快捷键说明

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