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

📄 if_eex.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (intConnect ( (VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),                    eexInt, (int)pDrvCtrl) == ERROR)        return (ERROR);    /* Start the device */    if ( eexDeviceStart (unit) == ERROR )        return (ERROR);    eexDiag (unit);                             /* run diagnostics */    eexConfig (unit);                           /* configure chip */    eexIASetup (unit);                          /* set up address */    /* Carve up the shared memory region into the specific sections */    pDrvCtrl->rfdBase =            (TFD_OFFSET + (sizeof (TFRAME) * pDrvCtrl->nTFDs));    /* create the free tfd queue; nTFDs is non-zero */    for (ix = 0, currentFd = TFD_OFFSET;         ix < pDrvCtrl->nTFDs;         ix ++, pDrvCtrl->lastFd = currentFd, currentFd += sizeof (TFRAME))        {        /* Initialize the TFD to link to next TFD, point to adjacent TBD */        sysOutWord (port + WRPTR, currentFd);        sysOutWord (port + DXREG, 0);                           /* status */        sysOutWord (port + DXREG, CFD_C_XMIT);                  /* command */        sysOutWord (port + DXREG, currentFd + sizeof (TFRAME)); /* TFD link */#ifdef  EEX_AL_LOC        sysOutWord (port + DXREG, currentFd + sizeof (TFD));    /* TBD ptr */#else        sysOutWord (port + DXREG, currentFd + sizeof (TFD) +                                  FRAME_SIZE);                  /* TBD ptr */        sysOutWord (port + WRPTR, currentFd + sizeof (TFD) +                                  FRAME_SIZE);          /* point to TBD */#endif  /* EEX_AL_LOC */        /* Initialize the TBD following the above TFD */        sysOutWord (port + DXREG, 0);                   /* status */        sysOutWord (port + DXREG, 0xffff);              /* next TBD */#ifdef  EEX_AL_LOC        sysOutWord (port + DXREG,                       /* buffer address */                    currentFd + sizeof (TFD) + sizeof (TBD));#else        sysOutWord (port + DXREG,                       /* buffer address */                    currentFd + sizeof (TFD) + EH_SIZE);#endif  /* EEX_AL_LOC */        sysOutWord (port + DXREG, 0);                   /* buffer add. hi */        }    /* Fix the link field of the last TFD to point to the first */    sysOutWord (port + WRPTR, pDrvCtrl->lastFd + TF_LINK);    sysOutWord (port + DXREG, TFD_OFFSET);    pDrvCtrl->tfdQueue.head = TFD_OFFSET;       /* Initialize queues */    pDrvCtrl->tfdQueue.tail = pDrvCtrl->lastFd;    eexQInit ( (EEX_LIST *)&pDrvCtrl->txQueue);    /* to be sent queue */    eexQInit ( (EEX_LIST *)&pDrvCtrl->cblQueue);   /* actively sending queue */    eexQInit ( (EEX_LIST *)&pDrvCtrl->cleanQueue); /* queue of TFDs to clean */    /* create all the receive frame descriptors */    for (ix = 0, currentFd = pDrvCtrl->rfdBase;         ix < pDrvCtrl->nRFDs;         ix ++, pDrvCtrl->lastFd = currentFd, currentFd += sizeof (RFRAME))        {        /* Initialize the RFD to link to next RFD, point to following RBD */        sysOutWord (port + WRPTR, currentFd);        sysOutWord (port + DXREG, 0);                           /* status */        sysOutWord (port + DXREG, 0);                           /* command */        sysOutWord (port + DXREG, currentFd + sizeof (RFRAME)); /* RFD link */#ifdef  EEX_AL_LOC        sysOutWord (port + DXREG, currentFd + sizeof (RFD));    /* RBD ptr */#else        sysOutWord (port + DXREG, currentFd + sizeof (RFD) +                                  FRAME_SIZE);                  /* RBD ptr */        sysOutWord (port + WRPTR, currentFd + sizeof (RFD) +                                  FRAME_SIZE);          /* point to RBD */#endif  /* EEX_AL_LOC */        /* Initialize the RBD following the above RFD */        sysOutWord (port + DXREG, 0);                   /* act. count */        sysOutWord (port + DXREG, 0xffff);              /* next RBD */#ifdef  EEX_AL_LOC        sysOutWord (port + DXREG,                       /* buffer address */                    currentFd + sizeof (RFD) + sizeof (RBD));#else        sysOutWord (port + DXREG,                       /* buffer address */                    currentFd + sizeof (RFD) + EH_SIZE);#endif  /* EEX_AL_LOC */        sysOutWord (port + DXREG, 0);                   /* buffer add. hi */        sysOutWord (port + DXREG, RBD_M_EL + FRAME_SIZE); /* buffer size */        }    /* Fix the link field of the last RFD to point to the first */    sysOutWord (port + WRPTR, pDrvCtrl->lastFd + RF_LINK);    sysOutWord (port + DXREG, pDrvCtrl->rfdBase);    pDrvCtrl->rxQueue.head = pDrvCtrl->rfdBase; /* Initialize queue */    pDrvCtrl->rxQueue.tail = pDrvCtrl->lastFd;    pDrvCtrl->freeRfd = pDrvCtrl->rxQueue.head;    eex586IntAck (unit);                     /* clear any pended dev ints */    eex586IntEnable (unit);                  /* enable interrupts at system */    eexRxStartup (pDrvCtrl);                 /* start receive unit */    return (OK);    }/********************************************************************************* eexEnetAddrGet - get OEM Ethernet address from EtherExpress on-board EEPROM** The "OEM" (i.e. not necessarily assigned by Intel) Ethernet address for the* board is contained in words 2, 3, and 4 of the on-board EEPROM.  Note that* EEPROM addresses are WORD not byte addresses!* The byte swapping arises from the address being stored in big-endian byte* order, apparently in approximation of the transmitted order (but the bits* would have to be reversed for true transmitted bit order).*/static STATUS eexEnetAddrGet    (    DRV_CTRL *pDrvCtrl,    char addr[]    )    {    UINT16 eepromAddress;    char *dest = addr;    UINT16 t;    for (eepromAddress = EEX_EEPROM_EA_HIGH;         eepromAddress >= EEX_EEPROM_EA_LOW;         eepromAddress--)        {        t = eexReadEEPROM (pDrvCtrl, eepromAddress);        *dest++ = t >> 8;        *dest++ = t & 0xff;        }        return (OK);    }/********************************************************************************* eex586IntAck - acknowledge EtherExpress 16 interrupt** The board hardware conatains an interrupt latch which is cleared by clearing* the interrupt enable bit.  We presume we want the interrupts enabled so we* re-enable the interrupt.*/static void eex586IntAck    (    int unit    )    {    eex586IntDisable (unit);    eex586IntEnable (unit);    }/********************************************************************************* eex586IntDisable - disable EtherExpress 16 interrupt** Prevent the board's 82586 from interrupting the system.* As noted in IntAck above, the board has an interrupt latch which is cleared* "with the disable-enable interrupt bit".  We will assume that after the* moment of disabling, pending interrupts will be latched and honored when* the interrupt is re-enabled.  There is no evidence to support this* assumption, and it should be tested some day.*/static void eex586IntDisable    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    sysOutByte (pDrvCtrl->port + SEL_IRQ, pDrvCtrl->irqCode);    }/********************************************************************************* eex586IntEnable - enable EtherExpress 16 interrupt** Allow the board's 82586 to interrupt the system.*/static void eex586IntEnable    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    sysOutByte (pDrvCtrl->port + SEL_IRQ, pDrvCtrl->irqCode | IRQ_ENB);    }/********************************************************************************* eex586SetReset - reset the EtherExpress 16's  82586 chip** Set chip into reset state (and hold it there until released elsewhere).*/static void eex586SetReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    sysOutByte (pDrvCtrl->port + EE_CTRL, RESET_82586);    }/********************************************************************************* eex586ClearReset - remove the EtherExpress 16's 82586 chip from reset state** Clear the bit holding the chip's reset line enabled, allowing the chip* to follow its power-on initialization sequence.*/static void eex586ClearReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl;    pDrvCtrl = & drvCtrl [unit];    /* All other bits in this register should be zero when chip runs */    sysOutByte (pDrvCtrl->port + EE_CTRL, 0);    }/********************************************************************************* eex586ChanAtn - assert Channel Attention to the EtherExpress 16's  82586 chip** Channel Attention tells the 82586 to examine its System Control Block* for commands and acknowledgements.* This could really be a macro.*/static void eex586ChanAtn    (    DRV_CTRL *pDrvCtrl    )    {    /* The act of writing to the port does the job; data is irrelevant */    sysOutByte (pDrvCtrl->port + CA_CTRL, 0);    }/********************************************************************************* eexReadEEPROM - read one word from the on-board EEPROM** Note that a necessary side effect of accessing the EEPROM is to set the* RESET_82586 bit, because the 82586's bus signals must be disabled.* Note that EEPROM addresses are WORD not byte addresses!*/static UINT16 eexReadEEPROM    (    DRV_CTRL *pDrvCtrl,    UINT16 address    )    {    int port;    UCHAR eeCtrl;               /* maintains current port contents */    UINT16 value;    port = pDrvCtrl->port + EE_CTRL;    eeCtrl = sysInByte (port) & (EEPROM_CHIPSEL | RESET_82586);    sysOutByte (port, eeCtrl | EEPROM_CHIPSEL);    eexOutBitsEEPROM (port, 3, EEPROM_OP_READ);    eexOutBitsEEPROM (port, 6, address);    value = eexInBitsEEPROM (port, 16);    eeCtrl &= EEPROM_CHIPSEL;           /* be certain chip select is clear */    sysOutByte (port, eeCtrl);          /* also the data port */    eexDelayEEPROM();                   /* data setup time */    sysOutByte (port, eeCtrl | EEPROM_CLOCK);   /* clock with CS low? */    eexDelayEEPROM();    sysOutByte (port, eeCtrl);    eexDelayEEPROM();    return (value);    }/********************************************************************************* eexOutBitsEEPROM - send a bit string to the on-board EEPROM** Shifts the righmost 'count' bits out, LEFTMOST first.*/static void eexOutBitsEEPROM    (    int port,    int count,    UINT16 bits    )    {    UCHAR eeCtrl;               /* maintains current port contents */    bits <<= 16 - count;        /* left-justify the bit string */    eeCtrl = sysInByte (port) & (EEPROM_CHIPSEL | RESET_82586);    while (count--)        {        if (bits & 0x8000)            eeCtrl |= EEPROM_OUTPUT;        else            eeCtrl &= ~EEPROM_OUTPUT;        sysOutByte (port, eeCtrl);        eexDelayEEPROM();                       /* data setup time */        sysOutByte (port, eeCtrl | EEPROM_CLOCK);        eexDelayEEPROM();        sysOutByte (port, eeCtrl);        eexDelayEEPROM();        bits <<= 1;        }    sysOutByte (port, eeCtrl & ~EEPROM_OUTPUT); /* clear output bit */    }/********************************************************************************* eexInBitsEEPROM - receive a bit string from the on-board EEPROM**/static UINT16 eexInBitsEEPROM    (    int port,    int count    )    {    UCHAR eeCtrl;               /* maintains current port contents */    UINT16 value;               /* build result a bit at a time */    eeCtrl = sysInByte (port) & (EEPROM_CHIPSEL | RESET_82586);    value = 0;    while (count--)        {        value <<= 1;        sysOutByte (port, eeCtrl | EEPROM_CLOCK);        eexDelayEEPROM();        if (sysInByte (port) & EEPROM_INPUT)            value |= 1;        sysOutByte (port, eeCtrl);        eexDelayEEPROM();        }    return (value);    }/********************************************************************************* eexDelayEEPROM - delay for EEPROM to recognize clock change** Supposedly 4.0 microseconds for the Hyundai EEPROM.*/static void eexDelayEEPROM    (    )    {    taskDelay (1);              /* gross overkill! */    }/******************************************************************************//* END OF FILE */

⌨️ 快捷键说明

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