This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

question about 3psw ethernet on DM8148?



Hi, 

    I need to hava 3psw ethernet work on bare board without operation system.

    now I set it to RGMII and auto-negotation mode. when i init the mac0 and phy, i can detect  the phy link status from mdio registers.

    when i set  value to  dma_tx0_hdp register, TX_INTSTAT_RAW register convert to 0x01. but actually the packet doesn't be sent out.

   does any one know the reason ?

 my source code as follows:

#define mdio_base 0x4A100800
#define mdio_ctl (*(volatile unsigned int*)(mdio_base + 0x04))
#define mdio_alive (*(volatile unsigned int*)(mdio_base + 0x08))
#define mdio_link (*(volatile unsigned int*)(mdio_base + 0x0C))
#define mdio_access0 (*(volatile unsigned int*)(mdio_base + 0x80))
#define mdio_physel0 (*(volatile unsigned int*)(mdio_base + 0x84))

#define cppi_base 0x4A102000 /* 8K */
#define cpsw_3g_base 0x4A100000
#define cpsw_subsys_base 0x4A100900

#define cpsw_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x04))
#define cpsw_soft_reset (*(volatile unsigned int*)(cpsw_3g_base + 0x08))
#define cpsw_stat_port_en (*(volatile unsigned int*)(cpsw_3g_base + 0x0c))
#define sl1_sa_lo (*(volatile unsigned int*)(cpsw_3g_base + 0x70))
#define sl1_sa_hi (*(volatile unsigned int*)(cpsw_3g_base + 0x74))
#define ale_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x608))
#define mac0_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x704))
#define mac0_soft_reset (*(volatile unsigned int*)(cpsw_3g_base + 0x70c))
#define cpts_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x504))
#define mac1_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x744))


#define dma_tx0_hdp (*(volatile unsigned int*)(cpsw_3g_base + 0x200))
#define dma_rx0_hdp (*(volatile unsigned int*)(cpsw_3g_base + 0x220))
#define dma_tx0_cdp (*(volatile unsigned int*)(cpsw_3g_base + 0x240))
#define dma_rx0_cdp (*(volatile unsigned int*)(cpsw_3g_base + 0x260))

#define tx_intstat_raw (*(volatile unsigned int*)(cpsw_3g_base + 0x180))
#define tx_intstat_masked (*(volatile unsigned int*)(cpsw_3g_base + 0x184))
#define tx_intmask_set (*(volatile unsigned int*)(cpsw_3g_base + 0x188))
#define tx_intmask_clear (*(volatile unsigned int*)(cpsw_3g_base + 0x18c))

#define rx_intstat_raw (*(volatile unsigned int*)(cpsw_3g_base + 0x1a0))
#define rx_intstat_masked (*(volatile unsigned int*)(cpsw_3g_base + 0x1a4))
#define rx_intmask_set (*(volatile unsigned int*)(cpsw_3g_base + 0x1a8))
#define rx_intmask_clear (*(volatile unsigned int*)(cpsw_3g_base + 0x1ac))

#define dma_intstat_raw (*(volatile unsigned int*)(cpsw_3g_base + 0x1b0))
#define dma_intstat_masked (*(volatile unsigned int*)(cpsw_3g_base + 0x1b4))
#define dma_intmask_set (*(volatile unsigned int*)(cpsw_3g_base + 0x1b8))
#define dma_intmask_clear (*(volatile unsigned int*)(cpsw_3g_base + 0x1bc))

#define mac0_sa_lo (*(volatile unsigned int*)(cpsw_3g_base + 0x70))
#define mac0_sa_hi (*(volatile unsigned int*)(cpsw_3g_base + 0x74))

#define p1_ts_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x64))
#define p2_ts_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0xa4))

#define tx_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x104))
#define rx_ctl (*(volatile unsigned int*)(cpsw_3g_base + 0x114))

#define mac0_emctl (*(volatile unsigned int*)(cpsw_3g_base + 0x720))
#define mac1_emctl (*(volatile unsigned int*)(cpsw_3g_base + 0x760))


#define gmii_sel (*(volatile unsigned int*)0x48140650)

#define tx_desc_base cppi_base
#define rx_desc_base (cppi_base + 0x1000)

unsigned char active_phy_addr = 0xFF;

void eth_delay(unsigned int time)
{
int i;
for(i = 0; i<time; i++)
;
}

void eth_mdio_enable(void)
{
mdio_ctl = (1<<30) | (1<<19) | (1<<18) |(2<<0); //clkdiv = 2
while(mdio_ctl & (1UL<<31)); // wait until active
}

int eth_mdio_phy_detect(void)
{
unsigned int phy_active_state;
int i;
phy_active_state = mdio_alive;
if(phy_active_state == 0)
return 1; // no active phy

else
{
for(i=0; i<32; i++)
if((phy_active_state & (1<<i)) == (1<<i))
{
active_phy_addr = i;
}
return 0;
}
}

unsigned short eth_mdio_phy_read(unsigned char phy, unsigned char reg)
{
unsigned short value;

mdio_access0 = 0 // Read Phy Id 1
| ( 1 << 31 ) // [31] Go
| ( 0 << 30 ) // [30] Read
| ( 0 << 29 ) // [29] Ack
| ( reg << 21 ) // [25-21] PHY register address
| ( phy << 16 ) // [20-16] PHY address
| ( 0 << 0 ); // [15-0] Data

while( mdio_access0 & 0x80000000 ); // Wait for Results

value = mdio_access0;
return value;
}

void eth_mdio_phy_write(unsigned char phy, unsigned char reg, unsigned short data)
{

mdio_access0 = 0 // Read Phy Id 1
| ( 1 << 31 ) // [31] Go
| ( 1 << 30 ) // [30] Write
| ( 0 << 29 ) // [29] Ack
| ( reg << 21 ) // [25-21] PHY register address
| ( phy << 16 ) // [20-16] PHY address
| ( data << 0 ); // [15-0] Data

while( mdio_access0 & 0x80000000 ); // Wait for Results
}

int get_link_speed(unsigned char phy)
{
int ret = 1;
if((eth_mdio_phy_read(phy, 1) & 0x04) == 0x04)
{
ret = 0;
}
return ret;
}
typedef volatile struct _emac_desc
{
unsigned int *next;
unsigned char* buf;
unsigned int buf_off_len;
unsigned int pkt_flag_len;
}emac_desc;

volatile emac_desc* rx_des;
volatile emac_desc* tx_des;

#define SOP 1<<31
#define EOP 1<<30
#define OWNER 1<<29

#define TX_DATA_LEN 1024
#define RX_DATA_LEN 1024
unsigned char tx_data[TX_DATA_LEN];
unsigned char rx_data[RX_DATA_LEN];

#define ENABLE_ALE (1UL<<31)
#define ALE_BYPASS (1<<4)

#include <string.h> // memset()

extern void Ethernet_PinMux_Setup();
extern void RMII_PinMux_Setup();

unsigned short readdata;

int emac_init()
{

Ethernet_PinMux_Setup();
RMII_PinMux_Setup();

mac0_ctl = 0xa1; // enable G/MII, full-duplex mode
mac0_emctl = 0x03;
mac1_ctl = 0xa1;
mac1_emctl = 0x03;

gmii_sel = 0x02; // select rgmii

cpsw_soft_reset = 1;
while( cpsw_soft_reset != 0 );

ale_ctl = 0x80000000;
eth_delay(10000);
ale_ctl = 0x40000000;
eth_delay(10000);
ale_ctl = 0x00000010;
eth_delay(10000);

mdio_ctl = 0x40000020; // Enable MII interface ( MDIOCLK < 12.5MHz )
eth_delay(10000);

cpts_ctl = 0;

cpsw_stat_port_en = 0; // disable statistics

if(eth_mdio_phy_detect() !=0)
return 1;

readdata = eth_mdio_phy_read(active_phy_addr, 0);
eth_mdio_phy_write(active_phy_addr , 0, 0x1300 ); // auto-negotiation, full duplex

eth_delay( 100000 );
readdata = eth_mdio_phy_read(active_phy_addr, 0);

readdata = eth_mdio_phy_read(active_phy_addr, 1);

/* Wait for link */
if(get_link_speed(active_phy_addr) != 0)
return 2;

mac0_sa_lo = 0x01;
mac0_sa_hi = (0x02<<24) | (0x03<<16) | (0x04<<8) | 0x05;

tx_intmask_clear = 0xFF; // mask all interrupt
rx_intmask_clear = 0xFF;
dma_intmask_clear = 0x03;

tx_des = (emac_desc*)tx_desc_base;
memset((void*)tx_des, 0, sizeof(emac_desc));
rx_des = (emac_desc*)rx_desc_base;
memset((void*)rx_des, 0, sizeof(emac_desc));

memset(rx_data, 0, RX_DATA_LEN);

tx_ctl |= 0x01; // enable tx dma
rx_ctl |= 0x01; // enable rx dma

rx_des = (emac_desc*)rx_desc_base;
rx_des->next = 0;
rx_des->buf = rx_data;
rx_des->buf_off_len = RX_DATA_LEN & 0xFFFF;
rx_des->pkt_flag_len = SOP | EOP | OWNER | (RX_DATA_LEN & 0x3FF);

dma_rx0_hdp = (unsigned int)rx_des;

return 0;
}

// arp request packet

unsigned char arpsendbuf[42]={

0xff,0xff,0xff,0xff,0xff,0xff, 
0x00,0x01,0x02,0x03,0x04,0x05, 
0x08,0x06,

0x00,0x01, 
0x08,0x00, 
0x06, 
0x04, 
0x00,0x01, 

0x00,0x01,0x02,0x03,0x04,0x05, 
192, 168, 1, 50, 
0x00,0x00,0x00,
192, 168, 1, 2
};

int emac_tx_packet(unsigned char* datas, int length)
{
unsigned int status;
if(get_link_speed(active_phy_addr) == 1)
{
return 1;
}
tx_des = (emac_desc*)tx_desc_base;
tx_des->next = 0;
tx_des->buf = datas;
tx_des->buf_off_len = length;
tx_des->pkt_flag_len = SOP | EOP | OWNER | length;

dma_tx0_hdp = (unsigned int)tx_des;

while(1)
{
if((get_link_speed(0)) == 1)
return 1;
if((tx_intstat_raw & 0x01) == 1)
break;
}
status = dma_tx0_cdp;
dma_tx0_cdp = status;

return 0;
}

int emac_rx_packet()
{
unsigned int status;

status = dma_rx0_cdp;
dma_rx0_cdp = status;
eth_delay(100000);

return 0;
}

void eth_test(void)
{
int i;
if(emac_init() != 0)
return;
for(i=0; i<10; i++)
emac_tx_packet(arpsendbuf, 42);

}