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

📄 sysgei82544end.c

📁 intel xscale 425的bsp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
** sysGei82546DynaTimerSetup - setup device internal timer value dynamically** This routine will be called every 2 seconds by default if GEI_END_SET_TIMER* flag is set. The available timers to adjust include RDTR(unit of ns),* RADV(unit of us), and ITR(unit of 256ns). Based on CPU's and/or tasks'* usage on system, user can tune the device's performance dynamically.* This routine would be called in the tNetTask context, and is only* available for 82540/82545/82546 MACs. Any timer value greater than* 0xffff won't be used to change corresponding timer register.** ERRNO: N/A** RETURNS: TRUE if timer value should change, or FALSE*/LOCAL BOOL sysGei82546DynaTimerSetup    (    ADAPTOR_INFO * pBoard     /* board information for the GEI driver */    )    {    /* user's specific code to decide what value should be used.     * For example, depending on     * 1: CPU usage on system and/or,     * 2: specific application task's usage and/or,     * 3: RX/TX packet processing per second, and/or     * 4: RX/TX interrupt counter per second, and/or     * 5: RX packet processing for each calling gei82543RxTxIntHandle(),     * users can choose optimal timer values from a predefined table to     * reduce interrupt rates. The statistic of 3,4,and 5 items above     * may be obtained from pBoard->devDrvStat.     *     * NOTE:     * ITR:  Interrupt throttling register (unit of 256ns)     *       inter-interrupt delay between chip's interrupts     *     * RADV: receive interrupt absolute delay timer register (unit of 1.024us)     *       a RX interrupt will absolutely occur at this defined value     *       after the first packet is received.     *     * RDTR: receive delay timer register (unit of 1.024us)     *       a RX interrupt will occur if device has not received a subsequent     *       packet within this defined value.     */    /* value > 0xffff would not be used for corresponding timer registers */    /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */    /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */    /* pBoard->devTimerUpdate.itrVal  = 0xffffffff; /@ unit of 256 ns */    /* pBoard->devTimerUpdate.watchDogIntVal = 2;   /@ 2 second default */    /* return TRUE; */    return FALSE;    }/*************************************************************************** sysGei82546InitTimerSetup - initially setup device internal timer value** The device's internal timers include RDTR(unit of ns),* RADV(unit of us), and ITR(unit of 256ns). The function is* called before device starts up, and it is only available for* 82540/82545/82546 MACs. Any timer value greater than 0xffff will* be discarded.** ERRNO: N/A** RETURNS: TRUE if timer value should change, or FALSE*/LOCAL BOOL sysGei82546InitTimerSetup    (    ADAPTOR_INFO * pBoard     /* board information for the GEI driver */    )    {    /* value > 0xffff would not change corresponding timer registers */    /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */    /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */    /* pBoard->devTimerUpdate.itrVal  = 0xffffffff; /@ unit of 256 ns  */    /* pBoard->devTimerUpdate.watchDogIntVal = 2;   /@ 2 second default */    /* return TRUE; */    return FALSE;    }/*************************************************************************** sys543eepromReadBits - read bits from EEPROM** This routine reads bit data from EEPROM** ERRNO: N/A** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadBits    (    int      unit,    int      bitsNum    )    {    int      count;    UINT32   ix;    volatile UINT16   val = 0;    UINT16   reqBit = 0;    GEI_RESOURCE * pRsrc;    pRsrc = &geiResources[unit];    if (pRsrc->boardType == PRO1000_546_BOARD)        reqBit = EECD_REQ_BIT;    for (ix = 0; ix < bitsNum; ix++)        {        /* raise the clk */        GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD,                                (EECD_CS_BIT | EECD_SK_BIT | reqBit));        /* wait 3000ns */        for (count = 0; count < 3; count++)             sys543Delay ();        val = ( val << 1) |          ((GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD) & EECD_DO_BIT)? 1 : 0);        /* lower the clk */        GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (EECD_CS_BIT | reqBit));        /* wait 3000 ns */        for (count = 0; count < 3; count++)             sys543Delay ();        }    return (val);    }/*************************************************************************** sys543eepromWriteBits - write bits out to EEPROM** This routine writes bits out to EEPROM** ERRNO: N/A** RETURNS: N/A*/LOCAL void sys543eepromWriteBits    (    int          unit,    UINT16       value,    UINT16       bitNum    )    {    int             count;    volatile UINT16 data;    UINT16          reqBit = 0;    GEI_RESOURCE * pRsrc;    pRsrc = &geiResources[unit];    if (pRsrc->boardType == PRO1000_546_BOARD)        reqBit = EECD_REQ_BIT;    if (bitNum == 0)        return;    while (bitNum--)        {        data = (value & (0x1 << bitNum )) ? EECD_DI_BIT : 0;        data |=  EECD_CS_BIT;        /* write the data */        GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit));        /* wait 2000ns */        for (count = 0; count < 2; count++)            sys543Delay ();        /* raise the clk */        GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | EECD_SK_BIT | reqBit));        /* wait 2000ns */        for (count = 0; count < 2; count++)            sys543Delay ();        /* lower the clk */        GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit));        /* wait 2000ns */        for (count = 0; count < 2; count++)            sys543Delay ();        }    }/*************************************************************************** sys543eepromReadWord - Read a word from EEPROM** This routine reads a word from the EEPROM** ERRNO: N/A** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadWord    (    int     unit,    UINT32  index    )    {    int     count;    UINT16  val;    UINT32  tmp;    GEI_RESOURCE * pRsrc;    pRsrc = &geiResources[unit];    if (pRsrc->boardType == PRO1000_546_BOARD)      {      int  ix = 0;      BOOL accessGet = FALSE;      tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);      tmp |= EECD_REQ_BIT;     /* request EEPROM access */      GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp);      do {         /* wait 3us */         for (count = 0; count < 3; count++)              sys543Delay ();         if ((tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD)) & EECD_GNT_BIT)             {             accessGet = TRUE;             break;             }         } while (ix++ < 500000);      if (!accessGet)        {        /* timeout in a second */        printf ("ERROR: timeout to grant access to gei unit %d EEPROM\n", unit);        return 0;        }      }    if (index >= geiResources[(unit)].eepromSize)        {        printf ("ERROR: gei unit %d Invalid index %d to EEPROM\n", unit, index);        return 0;        }    tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);    GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, EECD_CS_BIT);    /* wait 2000ns */    for (count = 0; count < 2; count++)         sys543Delay ();    /* write the opcode out */    sys543eepromWriteBits (unit, EEPROM_READ_OPCODE, EEPROM_CMD_BITS);    /* write the index out */    if (geiResources[(unit)].eepromSize == 64)        sys543eepromWriteBits (unit, index, 6);    else if (geiResources[(unit)].eepromSize == 256)        sys543eepromWriteBits (unit, index, 8);    else /* unsupported, but still try 64 words */       {        sys543eepromWriteBits (unit, index, 6);        printf ("ERROR: gei unit %d unsupported EEPROM size\n", unit);       }    tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);    /* read the data */    val = sys543eepromReadBits (unit, EEPROM_DATA_BITS);    /* clean up access to EEPROM */    if (pRsrc->boardType == PRO1000_546_BOARD)       tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT | EECD_REQ_BIT);    else       tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT);    GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp);    return val;    }/*************************************************************************** sys543EtherAddrGet - Get Ethernet address from EEPROM** This routine get an Ethernet address from EEPROM** ERRNO: N/A** RETURNS: OK or ERROR*/LOCAL STATUS sys543EtherAddrGet    (    int unit    )    {    UINT32 ix, count=0;    UINT16 val;    UCHAR  adr [ETHER_ADDRESS_SIZE];    for (ix = 0; ix < (ETHER_ADDRESS_SIZE / sizeof(UINT16)); ix++)        {        /* get word i from EEPROM */        val = sys543eepromReadWord (unit, (UINT16)(EEPROM_IA_ADDRESS + ix));        adr [count++] = (UCHAR)val;        adr [count++] = (UCHAR) (val >> 8);        }    /* check IA is UCAST  */    if (adr[0] & 0x1)        return (ERROR);    memcpy (&geiResources[unit].enetAddr[0], adr, ETHER_ADDRESS_SIZE);    return (OK);    }/**************************************************************************** sys543eepromCheckSum - calculate checksum** This routine perform EEPROM checksum.  The checksum is calculated* by summing all 16 bit words in the EEPROM but the carry bit is* ignored.  The result should be 0xBABA.** ERRNO: N/A** RETURNS: N/A*/LOCAL STATUS sys543eepromCheckSum    (    int unit    )    {    UINT16 checkSum = 0 ;    UINT32 ix;    for (ix = 0; ix < EEPROM_WORD_SIZE; ix++)        {        UINT16 val16;        val16 = sys543eepromReadWord(unit, ix);        /* printf("checksum word %d is 0x%x\n", ix, val16); debugging  */        checkSum += val16;        }    if (checkSum == (UINT16)EEPROM_SUM)        return OK;    else        return ERROR;    }/***************************************************************************** sys544PhyPreInit -- Init 82544's specific PHY regs before link setup** This routine initializes some 82544's PHY regs before set up link* Basically, it fixed short cable/backplane problem, Errata 21** RETURN: N/A*/LOCAL void sys544PhyPreInit    (    PHY_INFO * pPhyInfo     /* PHY's info structure pointer */    )    {    UINT16 regVal;          /* register value */    UINT16 phyId1;          /* phy Id 1 */    UINT16 phyId2;          /* phy ID 2 */    UINT32 retVal;          /* return value */    UINT32 phyOui = 0;      /* PHY's manufacture ID */    UINT32 phyMode;         /* PHY mode number */    UINT8  phyAddr;         /* PHY's bus number */    phyAddr = pPhyInfo->phyAddr;    MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal);    MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal);    phyOui =  phyId1 << 6 | phyId2 >> 10;    phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4;    if (phyOui == INTEL_82544PHY_OUI_ID && (phyMode == INTEL_82544PHY_MODEL))        {        regVal = 0x0004;        MII_WRITE (phyAddr, 29, 0x4, retVal);        MII_READ (phyAddr, 30, &regVal, retVal);        regVal |= 0x0200;        MII_WRITE (phyAddr, 30, regVal, retVal);        }    }/**************************************************************************** sys543PhySpecRegsInit - Initialize PHY specific registers** This routine initialize PHY specific registers** RETURN: N/A*/LOCAL void sys543PhySpecRegsInit    (    PHY_INFO * pPhyInfo,    /* PHY's info structure pointer */    UINT8      phyAddr      /* PHY's bus number */    )    {    UINT16 regVal;          /* register value */    UINT16 phyId1;          /* phy Id 1 */    UINT16 phyId2;          /* phy ID 2 */    UINT32 retVal;          /* return value */    UINT32 phyOui = 0;      /* PHY's manufacture ID */    UINT32 phyMode;         /* PHY mode number */    /* Intel Pro1000T adaptor uses Alaska transceiver */    /* read device ID to check Alaska chip available */    MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal);    MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal);    phyOui =  phyId1 << 6 | phyId2 >> 10;    phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4;    if (phyOui == MARVELL_OUI_ID && (phyMode == MARVELL_ALASKA_88E1000 ||                                     phyMode == MARVELL_ALASKA_88E1000S))        {         /* This is actually a Marvell Alaska 1000T transceiver */         /* disable PHY's interrupt */         MII_READ (phyAddr, ALASKA_INT_ENABLE_REG, &regVal, retVal);         regVal = 0;         MII_WRITE (phyAddr, ALASKA_INT_ENABLE_REG, regVal, retVal);         /* CRS assert on transmit */         MII_READ (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, &regVal, retVal);         regVal |= ALASKA_PSCR_ASSERT_CRS_ON_TX;         MII_WRITE (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, regVal, retVal);        /* set the clock rate when operate in 1000T mode */         MII_READ (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, &regVal, retVal);         regVal |= ALASKA_EPSCR_TX_CLK_25;         MII_WRITE (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, regVal, retVal);        }    else if (phyOui == INTEL_82544PHY_OUI_ID &&             (phyMode == INTEL_82544PHY_MODEL))        {        /* This is INTEL 82544GC/EI internal PHY */        /* disable PHY's interrupt */        MII_READ (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, &regVal, retVal);        regVal = 0;        MII_WRITE (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, regVal, retVal);        /* CRS assert on transmit */        MII_READ (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG,                  &regVal, retVal);        regVal |= INTEL_82544PHY_PSCR_ASSERT_CRS_ON_TX;        MII_WRITE (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG,                   regVal, retVal);

⌨️ 快捷键说明

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