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

📄 enetlib.c

📁 Ibmstb02500 miniboot 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   /* This time, I need to switch the bank register to bank 1,    */   /* so I can access the base address register                   */   out16( ENET_IO_ADDR + BANK_SELECT, 0x01 );   base_address_register = in16( ENET_IO_ADDR + BASE_REG );   if (base_address_register != 0x1801) {      if ( ENET_IO_ADDR != ( base_address_register >> 3 & 0x3E0 ) )  {         s1printf("Write Bank Select 0x%x, 0x1\n", ENET_IO_ADDR+BANK_SELECT);         s1printf("Read Base Reg 0x%x = 0x%x\n", ENET_IO_ADDR+BASE_REG, base_address_register);         s1printf("IOADDR %x doesn't match configuration (%x).\n",                 ENET_IO_ADDR, base_address_register >> 3 & 0x3E0 );         s1printf("Return(0) # 3\n");         return(0);      }#ifdef DEBUG_MSG_ISTHERE      s1printf("enetisThere: Write Bank Select 0x%x, 0x1\n", ENET_IO_ADDR+BANK_SELECT);      s1printf("enetisThere: Read Base Reg 0x%x = 0x%x\n", ENET_IO_ADDR+BASE_REG, base_address_register);      s1printf("enetisThere: IOADDR %x doesn't match configuration (%x).\n",                 ENET_IO_ADDR, base_address_register >> 3 & 0x3E0 );#endif      nsdelay(1000000);   }   /*  check if the revision register is something that I recognize. */   out16( ENET_IO_ADDR + BANK_SELECT, 0x03 );   revision_register  = in16( ENET_IO_ADDR + REV_REG );   if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] ) {        s1printf("Write Bank Select 0x%x, 0x3\n", ENET_IO_ADDR+BANK_SELECT);        s1printf("Read Rev 0x%x = 0x%x\n", ENET_IO_ADDR+REV_REG, revision_register);        s1printf("IO %x: Unrecognized revision register: %x\n",ENET_IO_ADDR, revision_register );        s1printf("Return(0) # 4\n");        return(0);   }#ifdef DEBUG_MSG_ISTHERE      s1printf("enetisThere: Write Bank Select 0x%x, 0x3\n", ENET_IO_ADDR+BANK_SELECT);      s1printf("enetisThere: Read Rev 0x%x = 0x%x\n", ENET_IO_ADDR+REV_REG, revision_register);      s1printf("enetisThere: IO %x: revision register: %x\n",ENET_IO_ADDR, revision_register );#endifnsdelay(1000000);   out16( ENET_IO_ADDR + BANK_SELECT, 0x01 );   for ( i = 0; i < 6; i += 2 ) {           unsigned int address;           address   = hwd_addr[ i + 1] << 8;   /* i for unswapped */           address  |= hwd_addr[ i ];           /* i + 1 for unswapped */           out16( ENET_IO_ADDR + ADDR0_REG + i, address );   }   return(1);}/*-----------------------------------------------------------------------------+| EnetTest.+-----------------------------------------------------------------------------*/int enetTest(){   char hw_addr[6];   if (enetisThere(NULL, NULL, (int *)hw_addr)==1) {#ifdef DEBUG_MSG_TEST   s1printf("enetTest successful...\n");#endif      return(0);   } else {#ifdef DEBUG_MSG_TEST   s1printf("enetTest unsuccessful...\n");#endif      return(-1);   }}/*-----------------------------------------------------------------------------+| enetInit.+-----------------------------------------------------------------------------*/int enetInit(unsigned long *srcaddr,    unsigned long *dstaddr, int *parmp){   static unsigned version_printed = 0;   /* registers */   unsigned short revision_register;   unsigned short memory_info_register;   unsigned long  temp;   unsigned long  msr;   const char *    version_string;   int   memory, i;#if 0   s1printf("\n\n");   s1printf("ENET Device is not available at this time\n");   s1printf("Please reset your board to continue...\n");   s1printf("\n\n - Processor Halted... \n");   ppcHalt();   return(0);  /*** WORKING ON IT *****/#endif#ifdef DEBUG_MSG_INIT   s1printf("enetInit Entered...\n");#endif   msr=ppcAndMsr(~ppcMsrEE);   (void)memcpy(dev.name, name, sizeof(name));#ifdef DEBUG_MSG_INIT    s1printf("device name = %s\n", dev.name);#endif    if (version_printed++ == 0) {#ifdef DEBUG_MSG_INIT            s1printf("version %s", version);#endif    }    /* fill in some of the fields */    dev.base_addr = ENET_IO_ADDR;    dev.irq       = ENET_INT;    (void)memcpy(dev.dev_addr, parmp, 6);    /* get the memory information */    out16( ENET_IO_ADDR + BANK_SELECT, 0x00 );    memory_info_register = in16( ENET_IO_ADDR + MIR_REG );    memory = memory_info_register & (unsigned int)0x00ff;    memory *= LAN91C111_MEMORY_MULTIPLIER;    out16( ENET_IO_ADDR + BANK_SELECT, 0x03 );    revision_register  = in16( ENET_IO_ADDR + REV_REG );    version_string = chip_ids[ ( revision_register  >> 4 ) & 0xF  ];    if ( !version_string ) {            /* I shouldn't get here because this call was done before.... */            return (1);    }    /* now, print out the card info, in a short format.. */#ifdef DEBUG_MSG_INIT    s1printf("%s rev:%d at %#3x IRQ:%d MEMSIZE:%db NOWAIT:%d\n",            version_string, revision_register & 0xF, ENET_IO_ADDR,            dev.irq, memory, dev.dma);#endif   /*--------------------------------------------------------------------------+   | Enable and configure the pocessor interrupts in level 1.   +--------------------------------------------------------------------------*/   temp = ppcMfuiccr();   ppcMtuiccr(temp & (~(0x80000000>>ENET_INT)));   temp = ppcMfuictr();   ppcMtuictr(temp & (~(0x80000000>>ENET_INT)));   temp = ppcMfuicpr();   ppcMtuicpr(temp & (~(0x80000000>>ENET_INT)));   ppcMtuicsr(0x80000000>>ENET_INT);   temp = ppcMfuicer();   ppcMtuicer(temp | (0x80000000>>ENET_INT));   ip_addr=srcaddr;   (void)ppcMtmsr(msr);#ifdef DEBUG_MSG_INIT   s1printf("smc_open\n");#endif   dev.tbusy      = 0;   dev.interrupt  = 0;   dev.start      = 1;   dev.phyaddr    = 0x00;  // YYD   /* Setup the default Register Modes */   dev.tcr_cur_mode = TCR_DEFAULT;   dev.rcr_cur_mode = RCR_DEFAULT;   dev.rpc_cur_mode = RPC_DEFAULT;   /* Set default parameters (files) */   dev.ctl_swfdup  =   0;   dev.ctl_ephloop =   0;   dev.ctl_miiop   =   0;   dev.ctl_autoneg =   1;   dev.ctl_rfduplx =   1;   dev.ctl_rspeed  =   1;   dev.ctl_afduplx =   1;   dev.ctl_aspeed  =   1;   dev.ctl_lnkfail =   1;   dev.ctl_forcol  =   0;   dev.ctl_filtcar =   0;   /* reset the hardware & configure the phy */   enet_reset();    // YYD, add mac address config here    out16( ENET_IO_ADDR + BANK_SELECT, 0x01 );    for ( i = 0; i < 6; i += 2 ) {        unsigned int address;                address   = hwd_addr[ i + 1] << 8;   /* i for unswapped */        address  |= hwd_addr[ i ];           /* i + 1 for unswapped */        out16( ENET_IO_ADDR + ADDR0_REG + i, address );    }#ifdef DEBUG_MSG_INIT    s1printf ("MAC Addr ( %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x )\n",        in16 (ENET_IO_ADDR + ADDR0_REG  )&0xff,        in16 (ENET_IO_ADDR + ADDR0_REG  )>>8,        in16 (ENET_IO_ADDR + ADDR0_REG+2)&0xff,        in16 (ENET_IO_ADDR + ADDR0_REG+2)>>8,        in16 (ENET_IO_ADDR + ADDR0_REG+4)&0xff,        in16 (ENET_IO_ADDR + ADDR0_REG+4)>>8);#endif    // YYD, end#ifdef DEBUG_MSG_INIT   s1printf("%s: enet_enable\n", dev.name);#endif    out16( ENET_IO_ADDR + BANK_SELECT, 0x00 );   /* see the header file for options in TCR/RCR DEFAULT*/   out16( ENET_IO_ADDR + TCR_REG, dev.tcr_cur_mode );   out16( ENET_IO_ADDR + RCR_REG, dev.rcr_cur_mode );#ifdef DEBUG_MSG_INIT   s1printf("RCR_REG %x\n", in16(ENET_IO_ADDR + RCR_REG));   s1printf("TCR_REG %x\n", in16(ENET_IO_ADDR + TCR_REG));#endif   /* now, enable interrupts */   out16( ENET_IO_ADDR + BANK_SELECT, 0x02 );   out16( ENET_IO_ADDR + INT_REG,  (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_MDINT)<<8 );#ifdef DEBUG_MSG_INIT   s1printf("IM_REG %x\n", in16(ENET_IO_ADDR + INT_REG));#endif   return(0);}/********************************************************************************* PHY_ClkMDIO - Set up FEAST to communicate with PHY**/static void phy_clkMDIO ( unsigned int MII_MGMTData ){    out16( ENET_IO_ADDR + BANK_SELECT, 0x03 );    out16(ENET_IO_ADDR + MII_REG, MII_MGMTData);    out16(ENET_IO_ADDR + MII_REG, MII_MGMTData | MII_MCLK);    nsdelay(200);    out16(ENET_IO_ADDR + MII_REG, MII_MGMTData);    nsdelay(200);}/********************************************************************************* phy_writereg - Write into the a PHY register** This routine writes a data into a given register of the PHY** RETURNS: N/A*/static void phy_writereg ( char PHYAddr, char RegAdd, unsigned int wData ){    int          i;    unsigned int MII_MGMTval;    /* Filter unused bits from input variables */    RegAdd     &= 0x1F;    PHYAddr    &= 0x1F;    out16( ENET_IO_ADDR + BANK_SELECT, 0x03 );    MII_MGMTval = in16(ENET_IO_ADDR + MII_REG) & (MII_MDALL ^ 0xFFFF);    /* Output Preamble (32 '1's) */    for ( i = 0; i < 32; i++)        phy_clkMDIO( MII_MGMTval | MII_MDOE | MII_MDO );    /* Output Start of Frame ('01') */    for ( i = 0; i < 2; i++)        phy_clkMDIO( MII_MGMTval | MII_MDOE | i );    /* Output OPCode ('01' for write or '10' for Read) */    for ( i = 1; i >= 0; i--)        phy_clkMDIO( MII_MGMTval | MII_MDOE |                               ( ( PHY_OPWrite >> i ) & 0x01 ) );    /* Output PHY Address */    for ( i = 4; i >= 0; i-- )        phy_clkMDIO( MII_MGMTval | MII_MDOE |                              ( (PHYAddr>>i) & 0x01 ) );    /* Output Register Address */    for (i=4;i>=0;i--)        phy_clkMDIO( MII_MGMTval | MII_MDOE |                               ( (RegAdd>>i) & 0x01 ) );    /* Write Operation */    /* Implement Turnaround ('10') */    for ( i = 1; i >= 0; i-- )        phy_clkMDIO( MII_MGMTval | MII_MDOE | ((2>>i) & 0x01));    /* Write Data */    for ( i = 15; i >= 0;i-- )        phy_clkMDIO( MII_MGMTval | MII_MDOE | ((wData>>i) & 0x01));    nsdelay(1000*1000);     // delay 1ms#ifdef DEBUG_MSG_PHYWRITE   s1printf("phy_writereg: phyaddr=%x phyreg=%x phydata=%x\n",                                 PHYAddr, RegAdd, wData);#endif}/********************************************************************************* phy_readreg - Read a Register from the PHY module** This routine reads a value of a given register of the PHY** RETURNS: the value read*/static unsigned int phy_readreg ( char PHYAddr, char RegAdd ){    int          i;    unsigned int MII_MGMTval;    unsigned int rtn;    unsigned int wData = 0;    /* Filter unused bits from input variables */    RegAdd     &= 0x1F;    PHYAddr    &= 0x1F;    out16( ENET_IO_ADDR + BANK_SELECT, 0x03 );    MII_MGMTval = in16(ENET_IO_ADDR + MII_REG) & (MII_MDALL ^ 0xFFFF);    /* Output Preamble (32 '1's) */    for ( i = 0; i < 32; i++)        phy_clkMDIO( MII_MGMTval | MII_MDOE | MII_MDO );    /* Output Start of Frame ('01') */    for ( i = 0; i < 2; i++)        phy_clkMDIO( MII_MGMTval | MII_MDOE | i );    /* Output OPCode ('01' for write or '10' for Read) */    for ( i = 1; i >= 0; i--)        phy_clkMDIO( MII_MGMTval | MII_MDOE |                               ( ( PHY_OPRead >> i ) & 0x01 ) );    /* Output PHY Address */    for ( i = 4; i >= 0; i-- )        phy_clkMDIO( MII_MGMTval | MII_MDOE |                              ( (PHYAddr>>i) & 0x01 ) );    /* Output Register Address */    for (i=4; i >= 0; i--)        phy_clkMDIO( MII_MGMTval | MII_MDOE |                               ( (RegAdd>>i) & 0x01 ) );    /* Read Operation */    /* Implement Turnaround ('Z0') */    out16(ENET_IO_ADDR + MII_REG, MII_MGMTval);    out16(ENET_IO_ADDR + MII_REG, MII_MGMTval |                            MII_MCLK |                            MII_MDOE |                            MII_MDO );    nsdelay(200);    out16(ENET_IO_ADDR + MII_REG, MII_MGMTval);    nsdelay(200);    /* Read Data */    wData = 0;    for ( i = 15; i >= 0; i-- ) {      out16(ENET_IO_ADDR + MII_REG, MII_MGMTval | MII_MCLK);

⌨️ 快捷键说明

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