From 5de990c9e2b93155d22cf480724b5ef8c3f5ef4e Mon Sep 17 00:00:00 2001 From: mengtianfang Date: Mon, 27 Oct 2014 16:47:07 +0800 Subject: [PATCH] Add the gmac on 1A support 1.Modify Targets/Bonito2g1a/conf/Bonito.2g1a 2.Modify Targets/Bonito2g1a/include/ls1a.h Change-Id: I643f6b23c8a9380041e1e48d09d32ccf27bfdd2e Target:LS2G1A --- Targets/Bonito2g1a/conf/Bonito.2g1a | 10 +- Targets/Bonito2g1a/include/ls1a.h | 2 +- sys/dev/gmac/if_gmac.c | 9 +- sys/dev/gmac/synopGMAC_Dev.c | 98 +++--- sys/dev/gmac/synopGMAC_network_interface.c | 342 +++++++++++++-------- sys/dev/gmac/synopGMAC_plat.c | 35 +++ sys/dev/gmac/synopGMAC_plat.h | 43 ++- 7 files changed, 349 insertions(+), 190 deletions(-) diff --git a/Targets/Bonito2g1a/conf/Bonito.2g1a b/Targets/Bonito2g1a/conf/Bonito.2g1a index 78a19d56..92b5a5e3 100644 --- a/Targets/Bonito2g1a/conf/Bonito.2g1a +++ b/Targets/Bonito2g1a/conf/Bonito.2g1a @@ -26,7 +26,7 @@ option DEVBD2E option MIPS option INET option LOONGSON_2G1A -option ENABLE_SATA #Enable SATA ,when enable IDE can also use, when commended only IDE can use +option ENABLE_SATA #Enable SATA ,when enable IDE can also use, when commended only IDE can use option BOOT_PARAM select mod_flash_amd # AMD flash device programming @@ -175,13 +175,6 @@ rtl* at pci? dev ? function ? #usb* at usbbus ? #ohci1 at pci? dev ? function ? -#select mod_usb -#select mod_usb_storage -#select mod_usb_uhci -#select mod_usb_ohci -#select mod_usb_kbd - - #### IDE controllers pciide* at pci ? dev ? function ? flags 0x0000 #atp* at pci? dev ? function ? #sata atp8620 @@ -204,6 +197,7 @@ ide_cd* at pciide? channel ? drive ? flags 0x0001 syn0 at localbus0 syn1 at localbus0 +syn2 at localbus0 select gmac #ide_cd* at pciide? channel ? drive ? flags 0x0001 diff --git a/Targets/Bonito2g1a/include/ls1a.h b/Targets/Bonito2g1a/include/ls1a.h index abde56eb..c35ff9c8 100644 --- a/Targets/Bonito2g1a/include/ls1a.h +++ b/Targets/Bonito2g1a/include/ls1a.h @@ -71,7 +71,7 @@ /* GMAC regs */ #define LS1A_GMAC0_REG_BASE (LS1A_IO_REG_BASE + 0x00e10000) -#define LS1A_GMAC1_REG_BASE (LS1A_IO_REG_BASE + 0x00e18000) +#define LS1A_GMAC1_REG_BASE (LS1A_IO_REG_BASE + 0x00e20000) /* HDA regs */ #define LS1A_HDA_REG_BASE (LS1A_IO_REG_BASE + 0x00e20000) diff --git a/sys/dev/gmac/if_gmac.c b/sys/dev/gmac/if_gmac.c index f0097242..7fdb5929 100644 --- a/sys/dev/gmac/if_gmac.c +++ b/sys/dev/gmac/if_gmac.c @@ -7,7 +7,9 @@ #include "synopGMAC_plat.h" - +#if defined(LOONGSON_2G1A) +#include "target/ls1a.h" +#endif static int syn_match(parent, match, aux) @@ -31,7 +33,10 @@ syn_attach(parent, self, aux) { struct device *sc = self; #if defined(LOONGSON_2G5536)||defined(LOONGSON_2G1A) -synopGMAC_init_network_interface(sc->dv_xname,sc->dv_unit?0x90000d0000000000LL:0x90000c0000000000LL); + if (sc->dv_unit != 2) + synopGMAC_init_network_interface(sc->dv_xname,sc->dv_unit?0x90000d0000000000LL:0x90000c0000000000LL); + if (sc->dv_unit == 2) + synopGMAC_init_network_interface(sc->dv_xname, LS1A_GMAC0_REG_BASE); #else synopGMAC_init_network_interface(sc->dv_xname, sc); #endif diff --git a/sys/dev/gmac/synopGMAC_Dev.c b/sys/dev/gmac/synopGMAC_Dev.c index 0ca5c7a6..91f3583e 100755 --- a/sys/dev/gmac/synopGMAC_Dev.c +++ b/sys/dev/gmac/synopGMAC_Dev.c @@ -10,6 +10,9 @@ * Synopsys 01/Aug/2007 Created */ #include "synopGMAC_Dev.h" +#if defined(LOONGSON_2G1A) +#include "target/ls1a.h" +#endif /** * Function to set the MDC clock for mdio transactiona @@ -55,31 +58,32 @@ u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev) */ s32 synopGMAC_read_phy_reg(u64 RegBase,u32 PhyBase, u32 RegOffset, u16 * data ) { -u32 addr; -u32 loop_variable; -addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiCsrClk3; //sw: add GmiiCsrClk -addr = addr | GmiiBusy ; //Gmii busy bit + u32 addr; + u32 loop_variable; + addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiCsrClk3; + //sw: add GmiiCsrClk + addr = addr | GmiiBusy ; //Gmii busy bit -synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); //write the address from where the data to be read in GmiiGmiiAddr register of synopGMAC ip + synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); //write the address from where the data to be read in GmiiGmiiAddr register of synopGMAC ip - for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time - if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ - break; - } - plat_delay(DEFAULT_DELAY_VARIABLE); - } - if(loop_variable < DEFAULT_LOOP_VARIABLE) - * data = (u16)(synopGMACReadReg(RegBase,GmacGmiiData) & 0xFFFF); - else{ - TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); - return -ESYNOPGMACPHYERR; - } + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time + if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + if(loop_variable < DEFAULT_LOOP_VARIABLE) + * data = (u16)(synopGMACReadReg(RegBase,GmacGmiiData) & 0xFFFF); + else{ + TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } //sw #if SYNOP_REG_DEBUG printf("read phy reg: addr = 0x%016x\tdata = 0x%x\n",RegOffset + Regbase, data); #endif -return -ESYNOPGMACNOERR; + return -ESYNOPGMACNOERR; } /** @@ -93,30 +97,29 @@ return -ESYNOPGMACNOERR; */ s32 synopGMAC_write_phy_reg(u64 RegBase, u32 PhyBase, u32 RegOffset, u16 data) { -u32 addr; -u32 loop_variable; + u32 addr; + u32 loop_variable; -synopGMACWriteReg(RegBase,GmacGmiiData,data); // write the data in to GmacGmiiData register of synopGMAC ip + synopGMACWriteReg(RegBase,GmacGmiiData,data); // write the data in to GmacGmiiData register of synopGMAC ip -addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiWrite | GmiiCsrClk3; //sw: add GmiiCsrclk + addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiWrite | GmiiCsrClk3; //sw: add GmiiCsrclk -addr = addr | GmiiBusy ; //set Gmii clk to 20-35 Mhz and Gmii busy bit - -synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); - for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ - if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ - break; - } - plat_delay(DEFAULT_DELAY_VARIABLE); - } + addr = addr | GmiiBusy ; //set Gmii clk to 20-35 Mhz and Gmii busy bit - if(loop_variable < DEFAULT_LOOP_VARIABLE){ - return -ESYNOPGMACNOERR; + synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ + if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + + if(loop_variable < DEFAULT_LOOP_VARIABLE){ + return -ESYNOPGMACNOERR; + } else { + TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; } - else{ - TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); - return -ESYNOPGMACPHYERR; - } #if SYNOP_REG_DEBUG printf("write phy reg: offset = 0x%x\tdata = 0x%x",RegOffset,data); #endif @@ -134,16 +137,16 @@ synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); #if UNUSED s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback) { -s32 status = -ESYNOPGMACNOERR; -u16 *temp; + s32 status = -ESYNOPGMACNOERR; + u16 *temp; status = synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, PHY_CONTROL_REG,temp); -if(loopback) - *temp |= 0x4000; -else - *temp = *temp; + if(loopback) + *temp |= 0x4000; + else + *temp = *temp; status = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, PHY_CONTROL_REG, *temp); -return status; + return status; } #endif @@ -1399,7 +1402,14 @@ s32 synopGMAC_attach (synopGMACdevice * gmacdev, u64 macBase, u64 dmaBase, u32 p /*Populate the mac and dma base addresses*/ gmacdev->MacBase = macBase; gmacdev->DmaBase = dmaBase; +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (macBase == LS1A_GMAC0_REG_BASE + MACBASE) + gmacdev->PhyBase = 1; + else + gmacdev->PhyBase = phyBase; +#else gmacdev->PhyBase = phyBase; +#endif /* Program/flash in the station/IP's Mac address */ synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, mac_addr); diff --git a/sys/dev/gmac/synopGMAC_network_interface.c b/sys/dev/gmac/synopGMAC_network_interface.c index ba6ff299..521ac91f 100755 --- a/sys/dev/gmac/synopGMAC_network_interface.c +++ b/sys/dev/gmac/synopGMAC_network_interface.c @@ -36,6 +36,10 @@ #include "target/eeprom.h" #endif +#if defined(LOONGSON_2G1A) +#include "target/ls1a.h" +#endif + //sw: ioctl in linux to be fixed #define SIOCDEVPRIVATE 0x89f0 @@ -505,30 +509,46 @@ s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 DmaDesc *first_desc = NULL; //DmaDesc *second_desc = NULL; - //dma_addr_t dma_addr; + dma_addr_t dma_addr; gmacdev->TxDescCount = 0; TR("Total size of memory required for Tx Descriptors in Ring Mode = 0x%08x\n",((sizeof(DmaDesc) * no_of_desc))); // first_desc = plat_alloc_consistent_dmaable_memory (pcidev, sizeof(DmaDesc) * no_of_desc,&dma_addr); - first_desc = (DmaDesc *)plat_alloc_memory(sizeof(DmaDesc) * no_of_desc+15); //sw: 128 aligned +#if defined(LOONGSON_2G5536) ||defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) + first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory (sizeof(DmaDesc) * no_of_desc, &dma_addr); + else + first_desc = (DmaDesc *)plat_alloc_memory(sizeof(DmaDesc) * no_of_desc+15); //sw: 128 aligned +#else + first_desc = (DmaDesc *)plat_alloc_memory(sizeof(DmaDesc) * no_of_desc+15); +#endif if(first_desc == NULL){ TR("Error in Tx Descriptors memory allocation\n"); return -ESYNOPGMACNOMEM; } - first_desc = ((u32)first_desc) & ~15; +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) +#endif + first_desc = ((u32)first_desc) & ~15; // memset((u32)first_desc,0, sizeof(DmaDesc) * no_of_desc); gmacdev->TxDescCount = no_of_desc; gmacdev->TxDesc = first_desc; - bf1 = (DmaDesc *)CACHED_TO_UNCACHED((unsigned long)(gmacdev->TxDesc)); - //gmacdev->TxDescDma = (unsigned long)vtophys((unsigned long)bf1); +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + gmacdev->TxDescDma = dma_addr; + } else { + bf1 = (DmaDesc *)CACHED_TO_UNCACHED((unsigned long)(gmacdev->TxDesc)); + //gmacdev->TxDescDma = (unsigned long)vtophys((unsigned long)bf1); + gmacdev->TxDescDma = (unsigned long)UNCACHED_TO_PHYS((unsigned long)bf1); + } +#else + bf1 = (DmaDesc *)CACHED_TO_UNCACHED((unsigned long)(gmacdev->TxDesc)); gmacdev->TxDescDma = (unsigned long)UNCACHED_TO_PHYS((unsigned long)bf1); -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) - - gmacdev->TxDescDma &= 0x0fffffff; - gmacdev->TxDescDma |= 0x00000000; + gmacdev->TxDescDma &= 0x0fffffff; + gmacdev->TxDescDma |= 0x00000000; #endif //gmacdev->TxDesc = bf1; @@ -593,33 +613,47 @@ s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 DmaDesc * bf1; DmaDesc *first_desc = NULL; //DmaDesc *second_desc = NULL; - //dma_addr_t dma_addr; + dma_addr_t dma_addr; gmacdev->RxDescCount = 0; TR("total size of memory required for Rx Descriptors in Ring Mode = 0x%08x\n",((sizeof(DmaDesc) * no_of_desc))); - // first_desc = plat_alloc_consistent_dmaable_memory (pcidev, sizeof(DmaDesc) * no_of_desc, &dma_addr); - first_desc = plat_alloc_memory (sizeof(DmaDesc) * no_of_desc+15); //sw: 2word aligned +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) + first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory (sizeof(DmaDesc) * no_of_desc, &dma_addr); + else + first_desc = (DmaDesc *)plat_alloc_memory (sizeof(DmaDesc) * no_of_desc+15);//sw: 2word aligned +#else + first_desc = (DmaDesc *)plat_alloc_memory (sizeof(DmaDesc) * no_of_desc+15); +#endif if(first_desc == NULL){ TR("Error in Rx Descriptor Memory allocation in Ring mode\n"); return -ESYNOPGMACNOMEM; } - first_desc = (DmaDesc *)((u32)first_desc & ~15); +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) +#endif + first_desc = (DmaDesc *)((u32)first_desc & ~15); gmacdev->RxDescCount = no_of_desc; gmacdev->RxDesc = first_desc; // gmacdev->RxDescDma = dma_addr; +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + gmacdev->RxDescDma = dma_addr; + } else { + bf1 = (DmaDesc *)CACHED_TO_UNCACHED((unsigned long)(gmacdev->RxDesc)); + gmacdev->RxDescDma = (unsigned long)UNCACHED_TO_PHYS((unsigned long)bf1); + } +#else bf1 = (DmaDesc *)CACHED_TO_UNCACHED((unsigned long)(gmacdev->RxDesc)); - //gmacdev->RxDescDma = (unsigned long)vtophys((unsigned long)bf1); gmacdev->RxDescDma = (unsigned long)UNCACHED_TO_PHYS((unsigned long)bf1); - //gmacdev->RxDesc = bf1; -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) gmacdev->RxDescDma |= 0x00000000; #endif // gmacdev->RxDescDma = (dma_addr_t) first_desc; - for(i =0; i < gmacdev -> RxDescCount; i++){ + for(i = 0; i < gmacdev -> RxDescCount; i++){ synopGMAC_rx_desc_init_ring(gmacdev->RxDesc + i, i == gmacdev->RxDescCount-1); #if SYNOP_TOP_DEBUG TR("%02d %08x \n",i, (unsigned int)(gmacdev->RxDesc + i)); @@ -974,6 +1008,11 @@ void synop_handle_received_data(struct synopGMACNetworkAdapter* tp) ; #endif +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + dma_addr1 = plat_dma_map_single(gmacdev,data1,RX_BUF_SIZE,SYNC_R); + } +#endif len = synopGMAC_get_rx_desc_frame_length(status) - 4; //Not interested in Ethernet CRC bytes bcopy((char *)data1, mtod(skb, char *), len); @@ -1015,6 +1054,10 @@ void synop_handle_received_data(struct synopGMACNetworkAdapter* tp) ether_input(ifp, eh, skb); memset((u32)data1,0,RX_BUF_SIZE); +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) + pci_sync_cache(NULL, (vm_offset_t)data1, RX_BUF_SIZE, SYNC_W); +#endif adapter->synopGMACNetStats.rx_packets++; adapter->synopGMACNetStats.rx_bytes += len; } @@ -1026,8 +1069,12 @@ void synop_handle_received_data(struct synopGMACNetworkAdapter* tp) adapter->synopGMACNetStats.rx_length_errors += synopGMAC_is_rx_frame_length_errors(status); } +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) { + dma_addr1 = (unsigned long)CACHED_TO_PHYS((unsigned long)(data1)); + } +#else dma_addr1 = (unsigned long)CACHED_TO_PHYS((unsigned long)(data1)); -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) dma_addr1 |= 0x00000000; #endif desc_index = synopGMAC_set_rx_qptr(gmacdev,dma_addr1, RX_BUF_SIZE, (u32)data1,0,0,0); @@ -1095,11 +1142,11 @@ int synopGMAC_intr_handler(struct synopGMACNetworkAdapter * tp) if(dma_status_reg == 0) return 0; - //if(dma_status_reg & 0x04) //sw: dbg - // printf("Tx Desc Unavailable! 0x%x \n",dma_status_reg); - - if(dma_status_reg == 0x660004) //sw: dbg - return 0; +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) +#endif + if(dma_status_reg == 0x660004) //sw: dbg + return 0; //sw: check phy status // synopGMAC_linux_cable_unplug_function(tp); @@ -1246,10 +1293,14 @@ int synopGMAC_intr_handler(struct synopGMACNetworkAdapter * tp) break; // return -ESYNOPGMACNOMEM; } - - //dma_addr = (u32)skb; + +#if defined(LOONGSON_2G1A) || defined(LOONGSON_2G5536) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) + dma_addr = plat_dma_map_single(gmacdev,skb,RX_BUF_SIZE,SYNC_R); + else + dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(skb)); +#else dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(skb)); -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) dma_addr |= 0x00000000; #endif status = synopGMAC_set_rx_qptr(gmacdev,dma_addr,RX_BUF_SIZE, (u32)skb,0,0,0); @@ -1298,8 +1349,8 @@ int synopGMAC_intr_handler(struct synopGMACNetworkAdapter * tp) #endif // dumpreg(regbase); #if 1 - if(GMAC_Power_down == 0){ // If Mac is not in powerdown - synop_handle_transmit_over(adapter); + if(GMAC_Power_down == 0){ // If Mac is not in powerdown + synop_handle_transmit_over(adapter); } #endif } @@ -1314,13 +1365,13 @@ int synopGMAC_intr_handler(struct synopGMACNetworkAdapter * tp) TR("%s::Transmitter stopped sending the packets\n",__FUNCTION__); printf("%s::Transmitter stopped sending the packets\n",__FUNCTION__); #if 1 - if(GMAC_Power_down == 0){ // If Mac is not in powerdown - synopGMAC_disable_dma_tx(gmacdev); - synopGMAC_take_desc_ownership_tx(gmacdev); - - synopGMAC_enable_dma_tx(gmacdev); -// netif_wake_queue(netdev); - TR("%s::Transmission Resumed\n",__FUNCTION__); + if(GMAC_Power_down == 0){ // If Mac is not in powerdown + synopGMAC_disable_dma_tx(gmacdev); + synopGMAC_take_desc_ownership_tx(gmacdev); + + synopGMAC_enable_dma_tx(gmacdev); +// netif_wake_queue(netdev); + TR("%s::Transmission Resumed\n",__FUNCTION__); } #endif } @@ -1388,9 +1439,10 @@ unsigned long synopGMAC_linux_open(struct synopGMACNetworkAdapter *tp) #endif /*Attach the device to MAC struct This will configure all the required base addresses such as Mac base, configuration base, phy base address(out of 32 possible phys )*/ - // synopGMAC_attach(synopGMACadapter->synopGMACdev,(u32) synopGMACMappedAddr + MACBASE,(u32) synopGMACMappedAddr + DMABASE, DEFAULT_PHY_BASE); - //synopGMAC_attach(adapter->synopGMACdev,(u64) synopGMACMappedAddr + MACBASE,(u64) synopGMACMappedAddr + DMABASE, DEFAULT_PHY_BASE,PInetdev->dev_addr); -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) + synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, PInetdev->dev_addr); +#else synopGMAC_set_mac_addr(adapter->synopGMACdev, GmacAddr0High, GmacAddr0Low, PInetdev->dev_addr); #endif /*Lets read the version of ip in to device structure*/ @@ -1484,23 +1536,25 @@ unsigned long synopGMAC_linux_open(struct synopGMACNetworkAdapter *tp) break; // return -ESYNOPGMACNOMEM; } - +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + dma_addr = plat_dma_map_single(gmacdev,skb,RX_BUF_SIZE,SYNC_R); + } else { + skb1 = (u32)CACHED_TO_UNCACHED((unsigned long)(skb)); + dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(skb1)); + } +#else skb1 = (u32)CACHED_TO_UNCACHED((unsigned long)(skb)); - //dma_addr = (unsigned long)vtophys((unsigned long)(skb1)); dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(skb1)); - -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) - dma_addr &= 0x0fffffff; + dma_addr &= 0x0fffffff; dma_addr |= 0x00000000; #endif // TR("rx_buf_PTR:%x, skb1:%x, dma_addr%x\n",skb, skb1, dma_addr); -// dbgdesc = gmacdev->RxNextDesc + 12; - //status = synopGMAC_set_rx_qptr_init(gmacdev,dma_addr,RX_BUF_SIZE, (u32)skb,0,0,0); status = synopGMAC_set_rx_qptr(gmacdev,dma_addr,RX_BUF_SIZE, (u32)skb,0,0,0); - //pci_sync_cache(0, (vm_offset_t)skb, len, SYNC_W); - //printf("==rx sync cache\n"); + //pci_sync_cache(0, (vm_offset_t)skb, len, SYNC_W); + //printf("==rx sync cache\n"); //status = 0; if(status < 0) @@ -1550,17 +1604,17 @@ unsigned long synopGMAC_linux_open(struct synopGMACNetworkAdapter *tp) #if SYNOP_PHY_LOOPBACK { - gmacdev->LinkState = LINKUP; - gmacdev->DuplexMode = FULLDUPLEX; - gmacdev->Speed = SPEED1000; + gmacdev->LinkState = LINKUP; + gmacdev->DuplexMode = FULLDUPLEX; + gmacdev->Speed = SPEED1000; } #endif plat_delay(DEFAULT_LOOP_VARIABLE); synopGMAC_check_phy_init(gmacdev); synopGMAC_mac_init(gmacdev); - PInetdev->sc_ih = pci_intr_establish(0, 0, IPL_NET, synopGMAC_intr_handler, adapter, 0); - TR("register poll interrupt: gmac 0\n"); + PInetdev->sc_ih = pci_intr_establish(0, 0, IPL_NET, synopGMAC_intr_handler, adapter, 0); + TR("register poll interrupt: gmac 0\n"); return retval; @@ -1703,19 +1757,22 @@ s32 synopGMAC_linux_xmit_frames(struct ifnet* ifp) } #endif - while(ifp->if_snd.ifq_head != NULL){ - if(!synopGMAC_is_desc_owned_by_dma(gmacdev->TxNextDesc)) - { + while(ifp->if_snd.ifq_head != NULL){ + if(!synopGMAC_is_desc_owned_by_dma(gmacdev->TxNextDesc)) + { - bf1 = (u32)plat_alloc_memory(TX_BUF_SIZE); - if(bf1 == 0) - { + bf1 = (u32)plat_alloc_memory(TX_BUF_SIZE); + if(bf1 == 0) + { #if SYNOP_TX_DEBUG - printf("===error in alloc bf1\n"); + printf("===error in alloc bf1\n"); #endif - return -1; - } + return -1; + } #ifdef FIX_CACHE_ADDR_UNALIGNED /*fixed by tangyt 2011-03-20*/ +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) +#endif while(bf1 & 0x10) { plat_free_memory((void *)(bf1)); @@ -1729,100 +1786,112 @@ s32 synopGMAC_linux_xmit_frames(struct ifnet* ifp) } } #endif - memset((char *)bf1,0,TX_BUF_SIZE); + memset((char *)bf1,0,TX_BUF_SIZE); - IF_DEQUEUE(&ifp->if_snd, skb); + IF_DEQUEUE(&ifp->if_snd, skb); - /*Now we have skb ready and OS invoked this function. Lets make our DMA know about this*/ + /*Now we have skb ready and OS invoked this function. Lets make our DMA know about this*/ - len = skb->m_pkthdr.len; + len = skb->m_pkthdr.len; - //sw: i don't know weather it's right - m_copydata(skb, 0, len,(char *)bf1); + //sw: i don't know weather it's right + m_copydata(skb, 0, len,(char *)bf1); +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + dma_addr = plat_dma_map_single(gmacdev,bf1,len,SYNC_W); + } +#endif /* if(len < 64) len = 64; */ #if SYNOP_TX_DEBUG - printf("==tx pkg len: %d",len); + printf("==tx pkg len: %d",len); +#endif + //sw: dbg +#if defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) #endif - //sw: dbg eh = mtod(skb, struct ether_header *); #if SYNOP_TX_DEBUG - dumppkghd(eh,0); + dumppkghd(eh,0); - for(i = 0;i < len;i++) - { - ptr = (u32)bf1; - printf(" %02x",*(ptr+i)); - } - printf("\n"); + for(i = 0;i < len;i++) + { + ptr = (u32)bf1; + printf(" %02x",*(ptr+i)); + } + printf("\n"); #endif #if defined(LOONGSON_2G5536)||defined(LOONGSON_2G1A) - m_freem(skb); + m_freem(skb); #else - plat_free_memory(skb); + plat_free_memory(skb); #endif - bf2 = (u32)CACHED_TO_UNCACHED((unsigned long)bf1); - //dma_addr = (unsigned long)vtophys((unsigned long)(bf2)); +#if defined(LOONGSON_2G5536) || defined(LOONGSON_2G1A) + if (gmacdev->MacBase != LS1A_GMAC0_REG_BASE + MACBASE) { + bf2 = (u32)CACHED_TO_UNCACHED((unsigned long)bf1); dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(bf2)); - -#if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) - dma_addr &= 0x0fffffff; - dma_addr |= 0x00000000; + } +#else + bf2 = (u32)CACHED_TO_UNCACHED((unsigned long)bf1); + //dma_addr = (unsigned long)vtophys((unsigned long)(bf2)); + dma_addr = (unsigned long)UNCACHED_TO_PHYS((unsigned long)(bf2)); + dma_addr &= 0x0fffffff; + dma_addr |= 0x00000000; #endif - // status = synopGMAC_set_tx_qptr(gmacdev, dma_addr, TX_BUF_SIZE, bf1,0,0,0,offload_needed); + //status = synopGMAC_set_tx_qptr(gmacdev, dma_addr, TX_BUF_SIZE, bf1,0,0,0,offload_needed); - status = synopGMAC_set_tx_qptr(gmacdev, dma_addr, len, bf1,0,0,0,offload_needed,&index,dpr); + status = synopGMAC_set_tx_qptr(gmacdev, dma_addr, len, bf1,0,0,0,offload_needed,&index,dpr); // printf("synopGMAC_set_tx_qptr: index = %d, dma_addr = %08x, len = %02x, buf1 = %08x\n", index, dma_addr, len, bf1); - //printf("===%x: next txDesc belongs to DMA don't set it\n",gmacdev->TxNextDesc); -// dumpdesc(gmacdev); // by xqch to dump all desc -// dumpreg(regbase); //by xqch to dumpall dma reg + //printf("===%x: next txDesc belongs to DMA don't set it\n",gmacdev->TxNextDesc); +// dumpdesc(gmacdev); // by xqch to dump all desc +// dumpreg(regbase); //by xqch to dumpall dma reg #if SYNOP_TX_DEBUG - printf("status = %d \n",status); + printf("status = %d \n",status); #endif - if(status < 0){ + if(status < 0){ #if SYNOP_TX_DEBUG - TR("%s No More Free Tx Descriptors\n",__FUNCTION__); + TR("%s No More Free Tx Descriptors\n",__FUNCTION__); #endif - // dev_kfree_skb (skb); //with this, system used to freeze.. ?? - return -EBUSY; - } + //dev_kfree_skb (skb); //with this, system used to freeze.. ?? + return -EBUSY; } + } #if defined(LOONGSON_2G5536)||defined(LOONGSON_2G1A) - else{ + else{ #endif #if SYNOP_TX_DEBUG #if (!defined(LOONGSON_2G5536))&&(!defined(LOONGSON_2G1A)) - else + else #endif - printf("===%x: next txDesc belongs to DMA don't set it\n",gmacdev->TxNextDesc); + printf("===%x: next txDesc belongs to DMA don't set it\n",gmacdev->TxNextDesc); #endif #if defined(LOONGSON_2G5536)||defined(LOONGSON_2G1A) - return; - } -#endif + return; } +#endif + } // ls2h_flush_cache2(); /*Now force the DMA to start transmission*/ #if SYNOP_TX_DEBUG - { - u32 data; - data = synopGMACReadReg(gmacdev->DmaBase, 0x48); - printf("TX DMA DESC ADDR = 0x%x\n",data); - } + { + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, 0x48); + printf("TX DMA DESC ADDR = 0x%x\n",data); + } #endif /* synopGMAC_tx_enable(gmacdev); @@ -1845,8 +1914,8 @@ s32 synopGMAC_linux_xmit_frames(struct ifnet* ifp) */ struct net_device_stats * synopGMAC_linux_get_stats(struct synopGMACNetworkAdapter *tp) { -TR("%s called \n",__FUNCTION__); -return( &(((struct synopGMACNetworkAdapter *)(tp))->synopGMACNetStats) ); + TR("%s called \n",__FUNCTION__); + return( &(((struct synopGMACNetworkAdapter *)(tp))->synopGMACNetStats) ); } /** @@ -1955,18 +2024,47 @@ void set_phy_manu(synopGMACdevice * gmacdev) } #endif +#if defined(LOONGSON_2G1A) +static int rtl88e1111_config_init(synopGMACdevice *gmacdev) +{ + int retval, err; + u16 data; + + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,&data); + data = data | 0x82; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,data); + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,&data); + data = data | 0x8000; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data); + + if (err < 0) + return err; + return 0; +} +#endif +#if defined(LOONGSON_2G1A) +int init_phy(synopGMACdevice *gmacdev) +#else int init_phy(struct synopGMACdevice *gmacdev) +#endif { int retval; - - //retval = bcm54xx_config_init(gmacdev); - - retval = rtl8211_config_init(gmacdev); -// synopGMAC_phy_loopback(gmacdev, SYNOP_PHY_LOOPBACK); - //if(retval != 0) +#if defined(LOONGSON_2G1A) || defined(LOONGSON_2G5536) + u16 data; + if (gmacdev->MacBase == LS1A_GMAC0_REG_BASE + MACBASE) { + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,2,&data); + if(data == 0x141) + rtl88e1111_config_init(gmacdev); + return 0; + } else { + retval = rtl8211_config_init(gmacdev); return retval; -// return 0; + } +#else + retval = rtl8211_config_init(gmacdev); + return retval; +#endif } @@ -2594,13 +2692,13 @@ s32 synopGMAC_init_network_interface(char* xname,u64 synopGMACMappedAddr) u16 data; struct synopGMACNetworkAdapter * synopGMACadapter; - static int syn_num; - { - if(0x90000c0000000000LL == synopGMACMappedAddr) - parseenv(0,mac_addr0); - else - parseenv(1,mac_addr0); - } + static int syn_num; + + if(0x90000c0000000000LL == synopGMACMappedAddr) + parseenv(0,mac_addr0); + else + parseenv(1,mac_addr0); + #else s32 synopGMAC_init_network_interface(char* xname, struct device *sc ) { diff --git a/sys/dev/gmac/synopGMAC_plat.c b/sys/dev/gmac/synopGMAC_plat.c index 718438ec..aa5db8ba 100755 --- a/sys/dev/gmac/synopGMAC_plat.c +++ b/sys/dev/gmac/synopGMAC_plat.c @@ -18,6 +18,19 @@ * @param[in] bytes in bytes to allocate */ + +#if defined(LOONGSON_2G1A) +dma_addr_t __attribute__((weak)) gmac_dmamap(unsigned long va,size_t size) +{ + unsigned long dma_adr; + if(va >= 0x84000000 && va <= 0x8fffffff) + dma_adr = va - 0x74000000; + else + printf("error!!! the address is out of the rang that 1F can map ,you can change the pci_map\n"); + return dma_adr; +} +#endif + void *plat_alloc_memory(u32 bytes) { return (void*)malloc((size_t)bytes, M_DEVBUF, M_DONTWAIT); @@ -29,6 +42,19 @@ void *plat_alloc_memory(u32 bytes) * @param[in] bytes in bytes to allocate */ +#if defined(LOONGSON_2G1A) +void *plat_alloc_consistent_dmaable_memory(u32 size, u32 *addr) +{ + void *buf; + buf = (void*)malloc((size_t)size, M_DEVBUF, M_DONTWAIT); + CPU_IOFlushDCache( buf,size, SYNC_W); + + *addr =gmac_dmamap(buf,size); + buf = (unsigned char *)CACHED_TO_UNCACHED(buf); + return buf; +} +#endif + //sw to-be clean /* void *plat_alloc_consistent_dmaable_memory(struct pci_dev *pcidev, u32 size, u32 *addr) @@ -64,6 +90,15 @@ void plat_free_memory(void *buffer) return ; } +#if defined(LOONGSON_2G1A) +dma_addr_t plat_dma_map_single(void *hwdev, void *ptr, + size_t size, int direction) +{ + unsigned long addr = (unsigned long) ptr; + CPU_IOFlushDCache(addr,size, direction); + return gmac_dmamap(addr,size); +} +#endif /** * This is a wrapper function for platform dependent delay diff --git a/sys/dev/gmac/synopGMAC_plat.h b/sys/dev/gmac/synopGMAC_plat.h index 0a9a2a9d..574e9878 100755 --- a/sys/dev/gmac/synopGMAC_plat.h +++ b/sys/dev/gmac/synopGMAC_plat.h @@ -23,6 +23,13 @@ */ #include "GMAC_Pmon.h" + +#if defined(LOONGSON_2G1A) +#include "target/ls1a.h" +#define MACBASE 0x0000 +#define DMABASE 0x1000 +#endif + //#include "synopGMAC_Host.h" //sw: copy the type define into here @@ -145,12 +152,17 @@ void plat_delay(u32); static u32 synopGMACReadReg(u64 RegBase, u32 RegOffset) { - u64 addr; - u32 data; + u64 addr; + u32 data; - addr = RegBase + (u64)RegOffset; + addr = RegBase + (u64)RegOffset; +#if defined(LOONGSON_2G1A) + if (RegBase == LS1A_GMAC0_REG_BASE + MACBASE || RegBase == LS1A_GMAC0_REG_BASE + DMABASE) + data = *(volatile u32 *)addr; + else +#endif - __asm __volatile( + __asm __volatile( ".set\tnoreorder\n\t" ".set\tmips3\n\t" "ld $8,%1\n\t" @@ -163,9 +175,9 @@ static u32 synopGMACReadReg(u64 RegBase, u32 RegOffset) :"memory","$8","$9" ); #if SYNOP_REG_DEBUG - TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data ); + TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data ); #endif - return data; + return data; } @@ -180,15 +192,20 @@ static u32 synopGMACReadReg(u64 RegBase, u32 RegOffset) static void synopGMACWriteReg(u64 RegBase, u32 RegOffset, u32 RegData ) { - u64 addr; + u64 addr; - addr = RegBase + (u64)RegOffset; + addr = RegBase + (u64)RegOffset; #if SYNOP_REG_DEBUG - TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData ); + TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData); #endif - //writel(RegData,(void *)addr); - //printf("GMAC addr = 0x%lx \n",addr); - __asm __volatile( + //writel(RegData,(void *)addr); + //printf("GMAC addr = 0x%lx \n",addr); +#if defined(LOONGSON_2G1A) + if (RegBase == LS1A_GMAC0_REG_BASE + MACBASE || RegBase == LS1A_GMAC0_REG_BASE + DMABASE) + *(volatile u32 *)addr = RegData; + else +#endif + __asm __volatile( ".set\tnoreorder\n\t" ".set\tmips3\n\t" "lw $9,%0\n\t" @@ -198,7 +215,7 @@ static void synopGMACWriteReg(u64 RegBase, u32 RegOffset, u32 RegData ) :"m"(RegData),"m"(addr) :"memory","$8","$9" ); - return; + return; } /**