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

📄 ei82596end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************* ei82596PollReceive - receive a packet in polled mode** RETURNS:*/LOCAL STATUS ei82596PollReceive    (    END_CTRL	*pDrvCtrl,    M_BLK_ID	pMblk    )    {    RFD 	*pRfd;    int		len;    while ((pRfd = ei82596RxQGet (pDrvCtrl)) != NULL)        {        len = (pRfd->count & ~0xc000);        if (((pRfd->status & (RFD_S_OK | RFD_S_COMPLETE)) !=             (RFD_S_OK | RFD_S_COMPLETE)) ||            (pMblk->mBlkHdr.mLen < len) ||            (!(pMblk->mBlkHdr.mFlags & M_EXT)))            {            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);            ei82596RxQPut (pDrvCtrl, pRfd);            continue;            }        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);        pMblk->mBlkHdr.mFlags 	|= M_PKTHDR;        pMblk->mBlkHdr.mLen	= len;        pMblk->mBlkPktHdr.len 	= pMblk->mBlkHdr.mLen;        bcopy ((char *)pRfd->enetHdr, (char *)pMblk->mBlkHdr.mData, len);        ei82596RxQPut (pDrvCtrl, pRfd);        DRV_LOG (DRV_DEBUG_POLL_RX, "R+ ", 0, 1, 2, 3, 4, 5);        return (OK);        }    return (EAGAIN);    }/********************************************************************************* ei82596DeviceStart - reset and start the device** This routine assumes interrupts from the device have been disabled, and* that the driver control structure has been initialized.*/LOCAL STATUS ei82596DeviceStart    (    END_CTRL 	*pDrvCtrl    )    {    void     *pTemp;    SCP      *pScp;                       /* system config ptr */    ISCP     *pIscp;                      /* intermediate system config ptr */    SCB      *pScb;                       /* system control block ptr */    int	     unit=pDrvCtrl->unit;    pDrvCtrl->txBlocked  = FALSE;    /* Get pointers */    pScp = pDrvCtrl->pScp;    pIscp = pDrvCtrl->pIscp;    pScb = pDrvCtrl->pScb;    /* perform board specific initializations */    sys596Init (pDrvCtrl->unit);    /* Issue the reset operation to the device */    sys596Port (unit, PORT_RESET, 0);    /* 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%d: device did not initialize\n", pDrvCtrl->unit);        return (ERROR);        }    return (OK);    }/********************************************************************************* ei82596Diag - format and issue a diagnostic command** Assumes that device interrupts are disabled.*/LOCAL STATUS ei82596Diag    (    END_CTRL 	*pDrvCtrl    )    {    bzero ((char *)pDrvCtrl->pCfd, sizeof (CFD));   /* zero command frame */    ei82596Action (pDrvCtrl, CFD_C_DIAG);     /* run diagnostics */    if (!(pDrvCtrl->pCfd->cfdStatus & CFD_S_OK))        {        printErr ("eiDiag: i82596 diagnostics failed. cfdStatus=0x%x\n",                  pDrvCtrl->pCfd->cfdStatus);        return (ERROR);        }    return (OK);   }/********************************************************************************* ei82596Config - format and issue a config command*/LOCAL void ei82596Config    (    END_CTRL 	*pDrvCtrl    )    {    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 =         DRV_FLAGS_ISSET (EI_PROMISC) ? 0x01 : 0x00;            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 =        DRV_FLAGS_ISSET (EI_MCAST) ? 0xdf : 0xff;        pDrvCtrl->pCfd->cfdConfig.ccByte20 = 0x00;    pDrvCtrl->pCfd->cfdConfig.ccByte21 = 0x3f;    ei82596Action (pDrvCtrl, CFD_C_CONFIG);   /* configure the chip */    }/********************************************************************************* eiIASetup - format and issue an interface address command*/LOCAL void ei82596IASetup    (    END_CTRL *	pDrvCtrl    )    {    bzero ((char *)pDrvCtrl->pCfd, sizeof (CFD));  /* zero command frame */    bcopy   (            (char *)END_HADDR(&pDrvCtrl->endObj),            (char *)pDrvCtrl->pCfd->cfdIASetup.ciAddress,            EADDR_LEN            );    ei82596Action (pDrvCtrl, CFD_C_IASETUP); /* setup the address */    }/********************************************************************************* ei82596RxStartup - start up the Receive Unit** Starts up the Receive Unit.  Assumes that the receive structures are set up.*/LOCAL void ei82596RxStartup    (    END_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 */    if (! DRV_FLAGS_ISSET (EI_POLLING))        SYS_INT_DISABLE( pDrvCtrl );    if ((pScb->scbStatus & SCB_S_RUMASK) != SCB_S_RUIDLE)        ei82596Command (pDrvCtrl, SCB_C_RUABORT); /* abort if not idle */    ei82596Command (pDrvCtrl, SCB_C_RUSTART);     /* start receive unit */    if (! DRV_FLAGS_ISSET (EI_POLLING))        SYS_INT_ENABLE( pDrvCtrl );    }/********************************************************************************* ei82596Action - execute the specified action with the CFD** 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.*/LOCAL void ei82596Action    (    END_CTRL	*pDrvCtrl,    UINT16	action    )    {    void	*pTemp;    CFD		*pCfd;    SCB		*pScb;    int		unit=pDrvCtrl->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);    LINK_WR (&pScb->pCB, pTemp);                /* point chip at CFD */    sys596ChanAtn (unit);               /* notify device of new command */    }    while (1)               /* wait for command acceptance and interrupt */        {        if ((pScb->scbCommand == 0) && (pScb->scbStatus & SCB_S_CNA))            break;        }    /* Acknowledge the event to the device */    pScb->scbCommand = (SCB_S_CX | SCB_S_CNA);    sys596ChanAtn (unit);    while (1)               /* wait for acknowledge acceptance */        {        if (pScb->scbCommand == 0)            break;        }    }/********************************************************************************* ei82596Command - deliver a command to the 82596 via SCB** This function causes the device to execute a command.  It should be called* with interrupts from the device disabled.  An error status is returned if* the command field does not return to zero, from a previous command, in a* reasonable amount of time.*/LOCAL STATUS ei82596Command    (    END_CTRL *pDrvCtrl,    UINT16    cmd    )    {    int loopy;    SCB * pScb;    pScb = pDrvCtrl->pScb;    for (loopy = 0x8000; loopy--;)        {        if (pScb->scbCommand == 0)                  /* wait for cmd zero */            break;        }    if (loopy > 0)        {        pScb->scbCommand = cmd;                     /* fill in command */        sys596ChanAtn (pDrvCtrl->unit);             /* channel attention */        return (OK);        }    else        {        logMsg("ei driver: command field frozen\n", 0, 0, 0, 0, 0, 0);        return (ERROR);        }    }/********************************************************************************* ei82596DeviceRestart - reset the chip and reinitialize the tx and rx queues**/LOCAL void ei82596DeviceRestart    (    END_CTRL *	pDrvCtrl    )    {    EI_LIST	tmpQueue;    EI_NODE    	*pNode;    BOOL        doMuxTxRestart;        /* Do we need to restart the mux? */    /* mark the interface -- down */    END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));    /* disable interrupts */    SYS_INT_DISABLE( pDrvCtrl );    doMuxTxRestart = pDrvCtrl->txBlocked;    /* reset the device */    if (ei82596DeviceStart (pDrvCtrl) == ERROR)        return;    /* discard the current cbl list, thread it to clean list */    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    ei82596QCat (&pDrvCtrl->cleanQueue, &pDrvCtrl->cblQueue);    ei82596QInit (&pDrvCtrl->cblQueue);    END_TX_SEM_GIVE (&pDrvCtrl->endObj);                /* reset watchdog timer counts */    pDrvCtrl->wdTxTimeout = 0;    pDrvCtrl->wdRxTimeout = 0;    /* stop the receiver, and command units */    ei82596Command (pDrvCtrl, SCB_C_RUABORT);    ei82596Command (pDrvCtrl, SCB_C_CUABORT);        if (ei82596Diag (pDrvCtrl) == ERROR)        return;    ei82596Config (pDrvCtrl);    ei82596IASetup (pDrvCtrl);    /* If we are not cleaning now, schedule one */    if (! pDrvCtrl->txCleaning)                  {        pDrvCtrl->txCleaning = TRUE;        netJobAdd ((FUNCPTR) ei82596TxCleanQ, (int) pDrvCtrl, 0, 0, 0, 0);        }    if (pDrvCtrl->txQueue.head != NULL)      /* anything to flush? */        ei82596TxQFlush (pDrvCtrl);          /* flush the tx q */    else        pDrvCtrl->txI

⌨️ 快捷键说明

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