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

📄 if_eex.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.*/static void eexHandleRecvInt    (    DRV_CTRL *pDrvCtrl    )    {    EEX_SHORTLINK rfdOffset;    do        {        pDrvCtrl->rcvHandling = TRUE;             /* interlock with eexInt() */        while ( (rfdOffset = eexRxQGet (pDrvCtrl)) != NULL)            (void) eexReceive (pDrvCtrl, rfdOffset);        pDrvCtrl->rcvHandling = FALSE;            /* interlock with eexInt() */        }    while (eexRxQFull (pDrvCtrl));              /* make sure rx q still empty */    }/********************************************************************************* eexReceive - pass a received frame to the next layer up** Strips the Ethernet header and passes the packet to the appropriate* protocol.* Is responsible for proper disposition of frame buffer in all cases.*/static STATUS eexReceive    (    DRV_CTRL *pDrvCtrl,    EEX_SHORTLINK rfdOffset    )    {    struct ether_header * 	pEh;    u_char * 	pData;    int         len;#ifdef BSD43_DRIVER    UINT16      etherType;#endif    MBUF * 	m = NULL;    UINT16      status;    /* 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.     */    sysOutWord (pDrvCtrl->port + RDPTR, rfdOffset);    status = sysInWord (pDrvCtrl->port + DXREG);    if  (        ( status & ( RFD_S_OK | RFD_S_COMPLETE ) ) !=        ( RFD_S_OK | RFD_S_COMPLETE )        )        {        ++pDrvCtrl->idr.ac_if.if_ierrors;            /* bump error counter */#ifdef EEX_DEBUG1 /* dhe 10/20/94 */    logMsg ("case 1: status=%x,offset=%x\n", status, rfdOffset, 0, 0, 0, 0);#endif        eexRxQPut (pDrvCtrl, rfdOffset);             /* free the RFD */        return (ERROR);        }    /* get frame length */    sysOutWord (pDrvCtrl->port + RDPTR, rfdOffset + RF_ACT_COUNT);    len = sysInWord (pDrvCtrl->port + DXREG) & ACT_COUNT_MASK;#ifndef EEX_AL_LOC    len += EH_SIZE;#endif  /* EEX_AL_LOC */    sysOutWord (pDrvCtrl->port + RDPTR, rfdOffset + RF_BUFFER);    sysInWordString (pDrvCtrl->port + DXREG, (short *) buffer, (len + 1) / 2);    pEh = (struct ether_header *)buffer;    /* get ptr to ethernet header */    /* Bump input packet counter. */    ++pDrvCtrl->idr.ac_if.if_ipackets;    /* Service input hook */    if ( (etherInputHookRtn != NULL) )        {        if  ( (* etherInputHookRtn) (&pDrvCtrl->idr, (char *)pEh, len) )            {#ifdef EEX_DEBUG1 /* dhe 10/20/94 */    logMsg ("case 2: status=%x, offset=%x\n", status, rfdOffset, 0, 0, 0, 0);#endif            eexRxQPut (pDrvCtrl, rfdOffset);             /* free the RFD */            return (OK);            }        }    len -= EH_SIZE;    pData = (u_char *) buffer + EH_SIZE;#ifdef BSD43_DRIVER    etherType = ntohs (pEh->ether_type);#endif    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 statistic */#ifdef EEX_DEBUG1 /* dhe 10/20/94 */    logMsg ("case 3: status=%x, offset=%x\n", status, rfdOffset, 0, 0, 0, 0);#endif    eexRxQPut (pDrvCtrl, rfdOffset);             /* free the RFD */    return (OK);    }/********************************************************************************* eexDeviceStart - 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 eexDeviceStart    (    int unit                              /* physical unit number */    )    {    DRV_CTRL *pDrvCtrl;    /* Get pointers */    pDrvCtrl = & drvCtrl [unit];    /* Ensure the 82586 is in its reset state */    eex586SetReset (unit);    /* Initialize the SCP */    sysOutWord (pDrvCtrl->port + WRPTR, SCP_OFFSET);    sysOutWord (pDrvCtrl->port + DXREG, 0);     /* sysbus is 16-bit */    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, ISCP_OFFSET);    sysOutWord (pDrvCtrl->port + DXREG, 0);    /* Initialize the ISCP */    sysOutWord (pDrvCtrl->port + WRPTR, ISCP_OFFSET);    sysOutWord (pDrvCtrl->port + DXREG, 1);     /* Set ISCP busy bit */    sysOutWord (pDrvCtrl->port + DXREG, SCB_OFFSET);    sysOutWord (pDrvCtrl->port + DXREG, 0);     /* SCB is zero-based */    sysOutWord (pDrvCtrl->port + DXREG, 0);    /* Initialize the SCB */    /* WRPTR is at the SCB following ISCP initialization */    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    sysOutWord (pDrvCtrl->port + DXREG, 0);    /* Tell the device to read the SCP */    eex586ClearReset (unit);    eex586ChanAtn (pDrvCtrl);    /*     * The device will now read our SCP and ISCP. It will clear the busy     * flag in the ISCP.     */    taskDelay (50);    sysOutWord (pDrvCtrl->port + RDPTR, ISCP_OFFSET);    if ( sysInByte (pDrvCtrl->port + DXREG) == 1 )        {        printf ("\neex: device did not initialize\n");        return (ERROR);        }    return (OK);    }/********************************************************************************* eexDiag - format and issue a diagnostic command*/static void eexDiag    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    bzero ( (char *)pDrvCtrl->pCfd, sizeof (CFD));      /* zero command frame */    eexAction (unit, CFD_C_DIAG);                /* run diagnostics */    if (!(pDrvCtrl->pCfd->cfdStatus & CFD_S_OK))        printErr ("eexDiag: i82586 diagnostics failed.\n");    }/********************************************************************************* eexConfig - format and issue a config command*/static void eexConfig    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    bzero ( (char *)pDrvCtrl->pCfd, sizeof (CFD));      /* zero command frame */    /* Recommended i82586 User's Manual configuration values. */    pDrvCtrl->pCfd->cfdConfig.byteCount         = 12;    pDrvCtrl->pCfd->cfdConfig.fifoLimit         = 0x08;    pDrvCtrl->pCfd->cfdConfig.srdy_saveBad      = 0x40;#ifdef  EEX_AL_LOC    pDrvCtrl->pCfd->cfdConfig.addrLen_loopback  = 0x2e;#else    pDrvCtrl->pCfd->cfdConfig.addrLen_loopback  = 0x26;#endif  /* EEX_AL_LOC */    pDrvCtrl->pCfd->cfdConfig.backoff           = 0x00;    pDrvCtrl->pCfd->cfdConfig.interframe        = 0x60;    pDrvCtrl->pCfd->cfdConfig.slotTimeLow       = 0x00;    pDrvCtrl->pCfd->cfdConfig.slotTimeHi_retry  = 0xf2;    pDrvCtrl->pCfd->cfdConfig.promiscuous       = 0x00; /* promiscuous off */    pDrvCtrl->pCfd->cfdConfig.carrier_collision = 0x00;    pDrvCtrl->pCfd->cfdConfig.minFrame          = 0x40;    eexAction (unit, CFD_C_CONFIG);          /* configure the chip */    }/********************************************************************************* eexIASetup - format and issue an interface address command*/static void eexIASetup    (    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            );    eexAction (unit, CFD_C_IASETUP);         /* set up the address */    }/********************************************************************************* eexRxStartup - start up the Receive Unit** Starts up the Receive Unit.  Assumes that the receive structures are set up.*/static void eexRxStartup    (    DRV_CTRL *pDrvCtrl    )    {    if (sysInWord (pDrvCtrl->port + SCB_STATUS) & SCB_S_RUREADY)        /* already running */        return;    /* zero the status and EL bit of the current queue tail dhe 10/26/94 */    sysOutWord(pDrvCtrl->port + WRPTR, pDrvCtrl->rxQueue.tail);    sysOutWord(pDrvCtrl->port + DXREG, 0);    sysOutWord(pDrvCtrl->port + DXREG, 0);    /* set up head and tail to point to original list  dhe 10/26/94 */    pDrvCtrl->rxQueue.head = pDrvCtrl->rfdBase;    pDrvCtrl->rxQueue.tail = pDrvCtrl->lastFd;    /* Point receive area to list of free frames */    sysOutWord (pDrvCtrl->port + SCB_RFA, pDrvCtrl->freeRfd);        /*     * need to rebuild the rfd list here--copy code from initialization     * routine.  set queue.head and queue.tail.     */    eex586IntDisable (pDrvCtrl->idr.ac_if.if_unit);    if ( (sysInWord (pDrvCtrl->port + SCB_STATUS) & SCB_S_RUMASK)        != SCB_S_RUIDLE)        eexCommand (pDrvCtrl, SCB_C_RUABORT);            /* abort if not idle */    eexCommand (pDrvCtrl, SCB_C_RUSTART);              /* start receive unit */    eex586IntEnable (pDrvCtrl->idr.ac_if.if_unit);    }/********************************************************************************* eexAction - 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 eexAction    (    int    unit,    UINT16 action    )    {    CFD      *pCfd;    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    pCfd = pDrvCtrl->pCfd;      /* Building command in scratch area */    while (1)                   /* wait for idle command unit */        {        if ( (sysInWord (pDrvCtrl->port + SCB_STATUS) & 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 */    /* and the SCB */    sysOutWord (pDrvCtrl->port + SCB_COMMAND,                        SCB_S_CX |              /* ack any events */                        SCB_S_FR |                        SCB_S_CNA |                        SCB_S_RNR |                        SCB_C_CUSTART);         /* start command unit */    /* Point SCB to command area in board memory */    sysOutWord (pDrvCtrl->port + SCB_CBL, CFD_OFFSET);    /* Copy CFD to board memory */    sysOutWord (pDrvCtrl->port + WRPTR, CFD_OFFSET);    sysOutWordString (pDrvCtrl->port + DXREG, (short *) pCfd, sizeof (CFD) / 2);    eex586ChanAtn (pDrvCtrl);               /* notify device of new command */    }    while (1)               /* wait for command acceptance and interrupt */        {        if ( (sysInWord (pDrvCtrl->port + SCB_COMMAND) == 0)            && (sysInWord (pDrvCtrl->port + SCB_STATUS) & SCB_S_CNA))            break;        }    /* Copy updated CFD back to system memory */    sysOutWord (pDrvCtrl->port + RDPTR, CFD_OFFSET);    sysInWordString (pDrvCtrl->port + DXREG, (short *) pCfd, sizeof (CFD) / 2);    /* Acknowledge the event to the device */    sysOutWord(pDrvCtrl->port + SCB_COMMAND, SCB_S_CX | SCB_S_CNA);    eex586ChanAtn (pDrvCtrl);    while (1)               /* wait for acknowledge acceptance */        {        if (sysInWord (pDrvCtrl->port + SCB_COMMAND) == 0)            break;

⌨️ 快捷键说明

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