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

📄 if_eihk.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* is therefore 'ok' to return the RFD to the Rx queue.  A return value of ERROR* means that buffer loaning was employed, and so the RFD is still in use and* should not be returned to the Rx queue.  In this latter case, the RFD will* eventually be returned by the protocol, via a call to our eiLoanFree().*/static STATUS eiReceive    (    DRV_CTRL *pDrvCtrl,    RFD *pRfd    )    {    ETH_HDR * 	pEh;    u_char      *pData;    int         len;#ifdef BSD43_DRIVER    UINT16      etherType;#endif    MBUF        *m = NULL;    BOOL        rfdLoaned = FALSE;    /* Check packet for errors.  This should be completely unnecessary,     * but since Intel does not seem capable of explaining the exact     * functioning of the 'save bad frames' config bit, we will look for     * errors.     */    if  (        ( pRfd->status & ( RFD_S_OK | RFD_S_COMPLETE ) ) !=        ( RFD_S_OK | RFD_S_COMPLETE )        )        {        ++pDrvCtrl->idr.ac_if.if_ierrors;            /* bump error counter */        eiRxQPut (pDrvCtrl, pRfd);                   /* free the RFD */        return (ERROR);        }    /* Bump input packet counter. */    ++pDrvCtrl->idr.ac_if.if_ipackets;    len = ((pRfd->actualCnt     & ~0xc000) +           (pRfd->rbd.actualCnt & ~0xc000));    pEh = (ETH_HDR *)pRfd->enetHdr;   /* ptr to ethernet header */    /* Service input hook */    if ( (etherInputHookRtn != NULL) )        {        /* pull enetHdr down 2 bytes to be contiguous with enetData */        bcopyBytes((char *)pEh, ((char*)pEh+2), EH_SIZE);                if  ( (* etherInputHookRtn) (&pDrvCtrl->idr, ((char *)pEh+2), len) )            {            eiRxQPut (pDrvCtrl, pRfd);                  /* free the RFD */            return (OK);            }        }    len -= EH_SIZE;    pData = (u_char *) pRfd->enetData;#ifdef BSD43_DRIVER    etherType = ntohs (pEh->ether_type);#endif    /* we can loan out receive frames from 82596 receive queue if:     *     * 1) the threshold of loanable frames has not been exceeded     * 2) size of the input ethernet frame is large enough to be used with     *    clustering.     */    if ((pDrvCtrl->nLoanRfds > 0) && (USE_CLUSTER (len)) &&        ((m = build_cluster (pData, len, &pDrvCtrl->idr, MC_EI, &pRfd->refCnt,                 eiLoanFree, (int) pDrvCtrl, (int) pRfd, NULL)) != NULL))        {        pDrvCtrl->nLoanRfds --;             /* one less to loan */        rfdLoaned = TRUE;               /* we loaned a frame */        }    else        m = copy_to_mbufs (pData, len, 0, &pDrvCtrl->idr);    if (m != NULL)#ifdef BSD43_DRIVER        do_protocol_with_type (etherType, m, &pDrvCtrl->idr, len);#else        do_protocol (pEh, m, &pDrvCtrl->idr, len);#endif    else        pDrvCtrl->idr.ac_if.if_ierrors++; 	/* bump error counter */    return ((rfdLoaned) ? ERROR : OK);    }/********************************************************************************* eiLoanFree - return a loaned receive frame descriptor** This routine is called by the protocol code when it has completed use of* an RFD that we loaned to it.*/static void eiLoanFree    (    DRV_CTRL *pDrvCtrl,    RFD *pRfd    )    {    eiRxQPut (pDrvCtrl, pRfd);    pDrvCtrl->nLoanRfds ++;    }/********************************************************************************* eiDeviceStart - reset and start the device** This routine assumes interrupts from the device have been disabled, and* that the driver control structure has been initialized.*/static STATUS eiDeviceStart    (    int unit                              /* physical unit number */    )    {    void     *pTemp;    DRV_CTRL *pDrvCtrl;    SCP      *pScp;                       /* system config ptr */    ISCP     *pIscp;                      /* intermediate system config ptr */    SCB      *pScb;                       /* system control block ptr */    /* Get pointers */    pDrvCtrl = & drvCtrl [unit];    pScp = pDrvCtrl->pScp;    pIscp = pDrvCtrl->pIscp;    pScb = pDrvCtrl->pScb;    /* Issue the reset operation to the device */    sys596Port (unit, PORT_RESET, NULL);    /* Initialize the SCP */    pScp->scpRsv1 =    pScp->scpRsv2 =    pScp->scpRsv3 = 0;    pScp->scpSysbus = pDrvCtrl->sysbus;    pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pIscp);    LINK_WR (&pScp->pIscp, pTemp);              /* point SCP to ISCP */    /* Initialize the ISCP */    pIscp->iscpBusy = 1;    pIscp->iscpRsv1 = 0;    pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pScb);    LINK_WR (&pIscp->pScb, pTemp);              /* point ISCP to SCB */    /* Initialize the SCB */    bzero ((char *)pScb, sizeof (SCB));    /* Tell the device where the SCP is located */    pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pScp);    sys596Port (unit, PORT_NEWSCP, (UINT32) pTemp);    sys596ChanAtn (unit);    /*     * The device will now read our SCP and ISCP. It will clear the busy     * flag in the ISCP.     */    taskDelay (50);    if ( pIscp->iscpBusy == 1 )        {        printf ("\nei: device did not initialize\n");        return (ERROR);        }    return (OK);    }/********************************************************************************* eiDiag - format and issue a diagnostic command*/static void eiDiag    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    bzero ((char *)pDrvCtrl->pCfd, sizeof (CFD));       /* zero command frame */    eiAction (unit, CFD_C_DIAG);                /* run diagnostics */    if (!(pDrvCtrl->pCfd->cfdStatus & CFD_S_OK))        printErr ("eiDiag: i82596 diagnostics failed.\n");    }/********************************************************************************* eiConfig - format and issue a config command*/static void eiConfig    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    bzero ((char *)pDrvCtrl->pCfd, sizeof (CFD));       /* zero command frame */    /* Recommeded i82596 User's Manual configuration values.  Note that     * the original manual, #296443-001, was full of errors.  Errors in the     * description of the config bytes that I am aware of are noted below.     * It is possible there are further errors.  Intel has replaced the     * manual with #296853-001, which does correct some errors, but not all.     */    pDrvCtrl->pCfd->cfdConfig.ccByte8  = 0x8e;    pDrvCtrl->pCfd->cfdConfig.ccByte9  = 0xc8;    /* The manual is wrong about bit 7 in byte 10.     * A '0' allows reception of bad packets.     * A '1' causes rejection of bad packets.     */    pDrvCtrl->pCfd->cfdConfig.ccByte10 = 0xc0;    pDrvCtrl->pCfd->cfdConfig.ccByte11 = 0x2e;      /* loopback, NSAI */    pDrvCtrl->pCfd->cfdConfig.ccByte12 = 0x00;    pDrvCtrl->pCfd->cfdConfig.ccByte13 = 0x60;    pDrvCtrl->pCfd->cfdConfig.ccByte14 = 0x00;    pDrvCtrl->pCfd->cfdConfig.ccByte15 = 0xf2;    pDrvCtrl->pCfd->cfdConfig.ccByte16 = 0x00;      /* promiscuous off */    pDrvCtrl->pCfd->cfdConfig.ccByte17 = 0x00;    pDrvCtrl->pCfd->cfdConfig.ccByte18 = 0x40;    /* The manual is wrong about 2 bits in byte 19.     * Bit 5, multicast, a '1' disables.     * Bit 2, include CRC, a '1' disables.     */    pDrvCtrl->pCfd->cfdConfig.ccByte19 = 0xff;    pDrvCtrl->pCfd->cfdConfig.ccByte20 = 0x00;    pDrvCtrl->pCfd->cfdConfig.ccByte21 = 0x3f;    eiAction (unit, CFD_C_CONFIG);          /* configure the chip */    }/********************************************************************************* eiIASetup - format and issue an interface address command*/static void eiIASetup    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    bzero ((char *)pDrvCtrl->pCfd, sizeof (CFD));       /* zero command frame */    bcopy   (            (char *)pDrvCtrl->idr.ac_enaddr,            (char *)pDrvCtrl->pCfd->cfdIASetup.ciAddress,            6            );    eiAction (unit, CFD_C_IASETUP);         /* setup the address */    }/********************************************************************************* eiRxStartup - start up the Receive Unit** Starts up the Receive Unit.  Assumes that the receive structures are set up.*/static void eiRxStartup    (    DRV_CTRL *pDrvCtrl    )    {    SCB *pScb = pDrvCtrl->pScb;    void * pTemp;    if (pScb->scbStatus & SCB_S_RUREADY)        /* already running */        return;    pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pDrvCtrl->pFreeRfd);    LINK_WR (&pScb->pRF, pTemp);            /* point to free Rfd */    sys596IntDisable (pDrvCtrl->idr.ac_if.if_unit);    if ((pScb->scbStatus & SCB_S_RUMASK) != SCB_S_RUIDLE)        eiCommand (pDrvCtrl, SCB_C_RUABORT);            /* abort if not idle */    eiCommand (pDrvCtrl, SCB_C_RUSTART);              /* start receive unit */    sys596IntEnable (pDrvCtrl->idr.ac_if.if_unit);    }/********************************************************************************* eiAction - execute the specified action with the CFD pointed to in pDrvCtrl** Do the command contained in the CFD synchronously, so that we know* it's complete upon return.  This routine assumes that interrupts from the* device have been disabled.*/static void eiAction    (    int    unit,    UINT16 action    )    {    void     *pTemp;    CFD      *pCfd;    SCB      *pScb;    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    pCfd = pDrvCtrl->pCfd;    pScb = pDrvCtrl->pScb;    while (1)                   /* wait for idle command unit */        {        if ((pScb->scbStatus & SCB_S_CUMASK) == SCB_S_CUIDLE)            break;        }    { /* Prepare and issue the command to the device */    /* fill in CFD */    pCfd->cfdStatus  = 0;                       /* clear status */    pCfd->cfdCommand = CFD_C_EL | action;       /* fill in action */    LINK_WR (&pCfd->link, NULL);                /* terminate link */    /* and the SCB */    pScb->scbCommand =                        SCB_S_CX |              /* ack any events */                        SCB_S_FR |                        SCB_S_CNA |                        SCB_S_RNR |                        SCB_C_CUSTART;          /* start command unit */    pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pCfd);

⌨️ 快捷键说明

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