Browse Source

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
master
mengtianfang 10 years ago
parent
commit
5de990c9e2
  1. 10
      Targets/Bonito2g1a/conf/Bonito.2g1a
  2. 2
      Targets/Bonito2g1a/include/ls1a.h
  3. 9
      sys/dev/gmac/if_gmac.c
  4. 96
      sys/dev/gmac/synopGMAC_Dev.c
  5. 334
      sys/dev/gmac/synopGMAC_network_interface.c
  6. 35
      sys/dev/gmac/synopGMAC_plat.c
  7. 43
      sys/dev/gmac/synopGMAC_plat.h

10
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

2
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)

9
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

96
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
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);
}
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;
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);

334
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;
#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)vtophys((unsigned long)bf1);
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);
@ -1247,9 +1294,13 @@ int synopGMAC_intr_handler(struct synopGMACNetworkAdapter * tp)
// 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);
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__);
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
#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)vtophys((unsigned long)(bf2));
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 )
{

35
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

43
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;
}
/**

Loading…
Cancel
Save