u32 MHal_EMAC_CableConnection(void) { TITANIA_EMAC regs = (TITANIA_EMAC) REG_ADDR_BASE; u32 retValue = 0; u32 word_ETH_MAN = 0x00000000; u32 word_ETH_CTL = (regs->REG_EMAC_CTL_L) + (regs->REG_EMAC_CTL_H<<16); MHal_EMAC_Write_CTL(0x00000010 | word_ETH_CTL); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; MHal_EMAC_Write_MAN(0x60860000); while(MHal_EMAC_CheckINTDone()!=1); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; word_ETH_MAN = MHal_EMAC_Read_MAN(); if(word_ETH_MAN_old != word_ETH_MAN) { word_ETH_MAN_old = word_ETH_MAN; printk("EMAC: Link change = %x\n",word_ETH_MAN_old); } if(word_ETH_MAN & 0x00000004) { retValue = 1; } else { retValue = 0; } MHal_EMAC_Write_CTL(word_ETH_CTL); return(retValue); }
//------------------------------------------------------------------------------------------------- // Close the interface //------------------------------------------------------------------------------------------------- void MDrv_EMAC_close(struct eth_device *nic) { u32 uRegVal; //Disable Receiver and Transmitter // uRegVal = MHal_EMAC_Read_CTL(); //uRegVal &= ~(EMAC_TE | EMAC_RE); MHal_EMAC_Write_CTL(uRegVal); // Disable PHY interrupt // MHal_EMAC_disable_phyirq (); //Disable MAC interrupts // uRegVal = EMAC_INT_RCOM | EMAC_INT_RBNA | EMAC_INT_TUND | EMAC_INT_RTRY | EMAC_INT_TCOM | EMAC_INT_ROVR | EMAC_INT_HRESP; MHal_EMAC_Write_IDR(uRegVal); netif_stop_queue (nic); }
//------------------------------------------------------------------------------------------------- //Initialize and start the Receiver and Transmit subsystems //------------------------------------------------------------------------------------------------- static void MDrv_EMAC_start (const struct eth_device *nic) { struct emac_hw *hw = (struct emac_hw *) nic->priv; u32 uRegVal; #ifdef SOFTWARE_DESCRIPTOR u32 i; #endif // Initialize Receive Buffer Descriptors memset((u8*)(RBQP_BASE+RAM_ADDR_BASE),0x00,RBQP_SIZE); #ifdef SOFTWARE_DESCRIPTOR for(i=0; i<RBQP_LENG;i++) { if(i<(RBQP_LENG-1)) MHal_EMAC_WritRam32((RBQP_BASE+RAM_ADDR_BASE), i*16, (RX_BUFFER_BASE+0x600*i)); else MHal_EMAC_WritRam32((RBQP_BASE+RAM_ADDR_BASE), i*16, (RX_BUFFER_BASE+0x600*i+EMAC_DESC_WRAP)); } #else MHal_EMAC_WritRam32((RBQP_BASE+RAM_ADDR_BASE),(RBQP_SIZE-0x08),0x00000002); #endif Chip_Flush_Memory(); // set offset of read and write pointers in the receive circular buffer // uRegVal = MHal_EMAC_Read_BUFF(); uRegVal = (RX_BUFFER_BASE|RX_BUFFER_SEL); MHal_EMAC_Write_BUFF(uRegVal); MHal_EMAC_Write_RDPTR(0); MHal_EMAC_Write_WRPTR(0); // Program address of descriptor list in Rx Buffer Queue register // MHal_EMAC_Write_RBQP(RBQP_BASE); //Reset buffer index// hw->rxBuffIndex = 0; // Enable Receive and Transmit // uRegVal = MHal_EMAC_Read_CTL(); uRegVal |= (EMAC_RE | EMAC_TE); MHal_EMAC_Write_CTL(uRegVal); }
//------------------------------------------------------------------------------------------------- // Open the ethernet interface //------------------------------------------------------------------------------------------------- static int MDrv_EMAC_open (struct eth_device *nic, bd_t * bis) { // struct emac_hw *hw = (struct emac_hw *) nic->priv; u32 uRegVal; //ato EMAC_SYS->PMC_PCER = 1 << EMAC_ID_EMAC; //Re-enable Peripheral clock // uRegVal = MHal_EMAC_Read_CTL(); uRegVal |= EMAC_CSR; MHal_EMAC_Write_CTL(uRegVal); // Enable PHY interrupt // MHal_EMAC_enable_phyirq (); // Enable MAC interrupts // uRegVal = EMAC_INT_RCOM |EMAC_INT_RBNA | EMAC_INT_TUND | EMAC_INT_RTRY | EMAC_INT_TCOM | EMAC_INT_ROVR | EMAC_INT_HRESP; MHal_EMAC_Write_IER(uRegVal); MDrv_EMAC_start (nic); return 0; }
//------------------------------------------------------------------------------------------------- // EMAC Negotiation PHY //------------------------------------------------------------------------------------------------- u32 MHal_EMAC_NegotiationPHY(void) { // Set PHY -------------------------------------------------------------- u32 i; u32 word_PHY = 0x00000000; u32 retValue = 0; // IMPORTANT: Get real duplex by negotiation with peer. u32 word_ETH_CTL = MHal_EMAC_Read_CTL(); MHal_EMAC_Write_CTL(0x0000001C | word_ETH_CTL); MHalThisUVE.cntChkINTCounter=0; word_PHY = 0x50822100; MHal_EMAC_Write_MAN(word_PHY); while(MHal_EMAC_CheckINTDone()!=1); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; word_PHY = 0x509201E1; MHal_EMAC_Write_MAN(word_PHY); while(MHal_EMAC_CheckINTDone()!=1); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; word_PHY = 0x50821200; MHal_EMAC_Write_MAN(word_PHY); while(MHal_EMAC_CheckINTDone()!=1); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; // IMPORTANT: (20070906) There must be some delay (about 2 ~ 3 seconds) between writing 0x57821200 and 0x67FE0000. // Otherwise, the later EMAC_WritReg32(REG_ETH_MAN,word_PHY) has no effect. MHalThisBCE.duplex = 1; // Set default as Half-duplex if negotiation fails. retValue = 1; MHal_EMAC_CableConnection(); word_PHY = 0x60FE0000; // Read for 32th reg MHal_EMAC_Write_MAN(word_PHY); MHalThisUVE.cntChkINTCounter=0; while(MHal_EMAC_CheckINTDone()!=1); MHalThisUVE.flagISR_INT_DONE = 0x00; MHalThisUVE.cntChkINTCounter=0; MHalThisUVE.cntChkCableConnect = 0; for(i=0;i<100;i++) // (20071026_CHARLES) No check connection here, if no connect, also init here. { word_PHY = MHal_EMAC_Read_MAN(); word_PHY &= 0x0000FFFF; if(word_PHY & 0x00001000) { u32 test1 = (word_PHY & 0x0000001C) >> 2; if(test1 == 0x001 || test1 == 0x002) { MHalThisBCE.duplex = 1; retValue = 1; } else { MHalThisBCE.duplex = 2; retValue = 2; } // else //retValue = 1; break; } // if mdelay(1); MHalThisUVE.cntChkCableConnect++; if(MHalThisUVE.cntChkCableConnect==MAX_INT_COUNTER) break; } // for
//------------------------------------------------------------------------------------------------- // EMAC Hardware register set //------------------------------------------------------------------------------------------------- static int MDrv_EMAC_HW_init(const struct eth_device *nic) { u32 word_ETH_CTL = 0x00000000; u32 word_ETH_CFG = 0x00000800; u32 uJulian104Value=0; s32 uNegPhyVal = 0; // (20071026_CHARLES) Disable TX, RX and MDIO: (If RX still enabled, the RX buffer will be overwrited) MHal_EMAC_Write_CTL(word_ETH_CTL); // Init RX -------------------------------------------------------------- memset((u8*)(RAM_ADDR_BASE + RX_BUFFER_BASE),0x00,RX_BUFFER_SIZE); MHal_EMAC_Write_BUFF(RX_BUFFER_BASE|RX_BUFFER_SEL); MHal_EMAC_Write_RDPTR(0x00000000); MHal_EMAC_Write_WRPTR(0x00000000); // Initialize "Receive Buffer Queue Pointer" MHal_EMAC_Write_RBQP(RBQP_BASE); // Enable Interrupts ---------------------------------------------------- MHal_EMAC_Write_IER(0x0000FFFF); printf("MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n",ThisBCE.sa1[0],ThisBCE.sa1[1], ThisBCE.sa1[2],ThisBCE.sa1[3],ThisBCE.sa1[4],ThisBCE.sa1[5]); // Set MAC address ------------------------------------------------------ MHal_EMAC_Write_SA1_MAC_Address(ThisBCE.sa1[0],ThisBCE.sa1[1],ThisBCE.sa1[2],ThisBCE.sa1[3],ThisBCE.sa1[4],ThisBCE.sa1[5]); MHal_EMAC_Write_SA2_MAC_Address(ThisBCE.sa2[0],ThisBCE.sa2[1],ThisBCE.sa2[2],ThisBCE.sa2[3],ThisBCE.sa2[4],ThisBCE.sa2[5]); MHal_EMAC_Write_SA3_MAC_Address(ThisBCE.sa3[0],ThisBCE.sa3[1],ThisBCE.sa3[2],ThisBCE.sa3[3],ThisBCE.sa3[4],ThisBCE.sa3[5]); MHal_EMAC_Write_SA4_MAC_Address(ThisBCE.sa4[0],ThisBCE.sa4[1],ThisBCE.sa4[2],ThisBCE.sa4[3],ThisBCE.sa4[4],ThisBCE.sa4[5]); #ifdef SOFTWARE_DESCRIPTOR #ifdef CHECKSUM uJulian104Value=uJulian104Value|(CHECKSUM_ENABLE|SOFTWARE_DESCRIPTOR_ENABLE); #else uJulian104Value=uJulian104Value|SOFTWARE_DESCRIPTOR_ENABLE; #endif MHal_EMAC_Write_JULIAN_0104(uJulian104Value);//Disable interrupt delay #else #if defined(CONFIG_URANUS4) || defined(CONFIG_KRONUS) MHal_EMAC_Write_JULIAN_0100(0x0000F007); MHal_EMAC_Write_JULIAN_0104(0x00); #else uJulian104Value=0x00000000; MHal_EMAC_Write_JULIAN_0104(uJulian104Value); #endif #endif //#ifdef SOFTWARE_DESCRIPTOR // IMPORTANT: Run NegotiationPHY() before writing REG_ETH_CFG. ThisBCE.duplex = DUPLEX_FULL; ThisBCE.speed = SPEED_10; uNegPhyVal = MHal_EMAC_NegotiationPHY(); ThisUVE.flagMacTxPermit = 0x01; switch(uNegPhyVal) { case 1: ThisBCE.duplex = DUPLEX_HALF; ThisBCE.speed = SPEED_10; break; case 2: ThisBCE.duplex = DUPLEX_FULL; ThisBCE.speed = SPEED_10; word_ETH_CFG |= (EMAC_FD); break; case 3: ThisBCE.duplex = DUPLEX_HALF; ThisBCE.speed = SPEED_100; word_ETH_CFG |= (EMAC_SPD); break; case 4: ThisBCE.duplex = DUPLEX_FULL; ThisBCE.speed = SPEED_100; word_ETH_CFG |= (EMAC_SPD|EMAC_FD); break; case 5: ThisBCE.duplex = 1; ThisBCE.speed = SPEED_1000; word_ETH_CFG |= (EMAC_FD); break; default: printf("Status Error!\n"); break; } printf("word_ETH_CFG %x", word_ETH_CFG); MHal_EMAC_Write_CFG(word_ETH_CFG); // ETH_CTL Register ----------------------------------------------------- word_ETH_CTL = 0x0000010; // Enable MDIO if(ThisBCE.wes == 1) word_ETH_CTL |= 0x00000080; MHal_EMAC_Write_CTL(word_ETH_CTL); #ifdef SOFTWARE_DESCRIPTOR #if (SUPPORT_ALBANY) MHal_EMAC_Write_JULIAN_0100(0x0000F001); //MII #else MHal_EMAC_Write_JULIAN_0100(0x0000F007); //RMII #endif #else MHal_EMAC_Write_JULIAN_0100(0x00000107); #endif #ifdef CONFIG_ETHERNET_ALBANY MHal_EMAC_Write_JULIAN_0100(0x0000F001); #endif ThisUVE.flagPowerOn = 1; ThisUVE.initedEMAC = 1; return 1; }