📄 enetlib.c
字号:
/* 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 + -