cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Participant
Participant
3,285 Views
Registered: ‎07-24-2017

Microblaze dual ethernet problem with LWIP

Jump to solution

Hello everyone, I have a custom board with 2 88e1512 Ethernet PHY's and XC7A100t-1 FPGA.
I am trying to work with two ethernet ports simultaneously using microblaze and LWIP.
Baby steps, I started with tcp echo_server example.

- I am using Vivado 2016.2, LWIP 141 v1.5
- I modified xaxiemacif_physpeed.c to work with 88e1512 PHY
- I modified xaxiemacif_dma.c as this:

**************************************************************
* original:
* /* initialize DMA */
* dmaconfig = XAxiDma_LookupConfig(XPAR_AXIDMA_0_DEVICE_ID);
*
* modified:
* volatile u16 dev_id;
* dev_id = xaxiemacif->axi_ethernet.Config.DeviceId;
* xil_printf("DEVICE_ID = %x \n\r", dev_id);
* dmaconfig = XAxiDma_LookupConfig(dev_id);
*
* As I have 2 DMAS for 2x AXI 1G/2.5G Ethernet Subsystem,
* original code is not proper.
**************************************************************

When I try to communicate with only one ethernet port,
I simply change XPAR_AXI_ETHERNET_0_BASE_ADDR
from XPAR_AXI_ETHERNET_1_BASE_ADDR at this part in main:

**************************************************************
* if (!xemac_add(echo_netif, &ipaddr, &netmask,
* &gw, mac_ethernet_address,
* XPAR_AXI_ETHERNET_0_BASEADDR)) {
* xil_printf("Error adding N/W interface\n\r");
* return -1;
* }
**************************************************************

this works properly, I can seperately communicate with both ethernet ports,
so in my opinion I don't have any problem with hardware configuration.

When I try to communicate with both ports, I can only reach the ethernet
port which is added last to the netif list. Here is my code:

int main()
{
	int Status;
	init_platform();
	Status = XGpio_Initialize(&uart_enable_gpio, UART_ENABLES);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	Status = XGpio_SelfTest(&uart_enable_gpio);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	XGpio_DiscreteWrite(&uart_enable_gpio, 1, 0x00);

	xil_printf("APP STARTED\n\r");
	struct ip_addr ipaddr_0, netmask_0, gw_0;
	struct ip_addr ipaddr_1, netmask_1, gw_1;
	/* the mac address of the board. this should be unique per board */
	unsigned char mac_ethernet_address_0[] =
	{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

	unsigned char mac_ethernet_address_1[] =
	{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x03 };

	echo_netif_0 = &server_netif_0;
	echo_netif_1 = &server_netif_1;

	/* initliaze IP addresses to be used */
	IP4_ADDR(&ipaddr_0,  192, 168,   1, 142);
	IP4_ADDR(&netmask_0, 255, 255, 255,  0);
	IP4_ADDR(&gw_0,      192, 168,   1,  1);

	IP4_ADDR(&ipaddr_1,  192, 168,   2, 143);
	IP4_ADDR(&netmask_1, 255, 255, 255,  0);
	IP4_ADDR(&gw_1,      192, 168,   2,  1);

	print_app_header();

	lwip_init();

  	/* Add network interface to the netif_list, and set it as default */
	if (!xemac_add(echo_netif_0, &ipaddr_0, &netmask_0,
						&gw_0, mac_ethernet_address_0,
						XPAR_AXI_ETHERNET_0_BASEADDR)) {
		xil_printf("Error adding N/W interface\n\r");
		return -1;
	}


	if (!xemac_add(echo_netif_1, &ipaddr_1, &netmask_1,
						&gw_1, mac_ethernet_address_1,
						XPAR_AXI_ETHERNET_1_BASEADDR)) {
		xil_printf("Error adding N/W interface\n\r");
		return -1;
	}

	echo_netif_0 -> name[0] = 'a';
	netif_set_up(echo_netif_0);
	netif_set_default(echo_netif_0);
	echo_netif_1 -> name[0] = 'b';
	netif_set_up(echo_netif_1);
	netif_set_default(echo_netif_1);

	/* now enable interrupts */
	platform_enable_interrupts();

	print_ip_settings(&ipaddr_0, &netmask_0, &gw_0);

	print_ip_settings(&ipaddr_1, &netmask_1, &gw_1);

	/* start the application (web server, rxtest, txtest, etc..) */
	start_application();

	/* receive and process packets */
	while (1) {
		if (TcpFastTmrFlag) {
			tcp_fasttmr();
			TcpFastTmrFlag = 0;
		}
		if (TcpSlowTmrFlag) {
			tcp_slowtmr();
			TcpSlowTmrFlag = 0;
		}
		xemacif_input(echo_netif_0);
		xemacif_input(echo_netif_1);
		transfer_data();
	}
  
	/* never reached */
	cleanup_platform();

	return 0;
}

With this code I can reach netif_1(XPAR_AXI_ETHERNET_1_BASEADDR, 192.168.2.143).

 

When I changed the order of the xemac_add functions as this:

		if (!xemac_add(echo_netif_1, &ipaddr_1, &netmask_1,
							&gw_1, mac_ethernet_address_1,
							XPAR_AXI_ETHERNET_1_BASEADDR)) {
			xil_printf("Error adding N/W interface\n\r");
			return -1;
		}
		if (!xemac_add(echo_netif_0, &ipaddr_0, &netmask_0,
							&gw_0, mac_ethernet_address_0,
							XPAR_AXI_ETHERNET_0_BASEADDR)) {
			xil_printf("Error adding N/W interface\n\r");
			return -1;
		}

I can reach netif_0(XPAR_AXI_ETHERNET_0_BASEADDR, 192.168.1.142)

I have read similar problems have been solved by giving different sub-net masks to
the ports but that didn't do the trick for me. I am adding the Block design structure
to provide you a more comprehensive grasp of the project.

ethernets.JPGThank you for your attention already,

20801700

 

Tags (2)
1 Solution

Accepted Solutions
Highlighted
Participant
Participant
3,148 Views
Registered: ‎07-24-2017

Hello guys, long time no see!! I solved it, it was DMA operations.

Apparently lwIP is indeed capable of working with multiple ethernet ports, however Xilinx guys did not put too much effort on it. in my case xaxiemacif_dma.c has its own xemac and xaxiemacif as xemac_fast and xaxiemacif_fast, and it copies your xemac's info into those when init_axi_dma(struct xemac_s *xemac) function is called. When you call it the second time with a different xemac, the info and interrupt assignments for the first one is simply overwritten because there is actually only one active xemac (named as xemac_fast) and one xaxiemacif(named as xaxiemacif_fast). I duplicated these structs and interrupt callback functions, added a simple initialization counter and it worked like magic, with the echo.c I got from Srikanth(thanks again!!!). Well I am adding the modified file here, I modified it for two connections with NO-SYS and FAST_INTERRUPT, but I do not recommend using it as-is since I did not change the operation in any other configurations.

 

Have a nice day

 

20801700

View solution in original post

9 Replies
Highlighted
Moderator
Moderator
3,239 Views
Registered: ‎10-30-2017

Hi @20801700,

 

Please check my post in following thread.

https://forums.xilinx.com/t5/Embedded-Processor-System-Design/zynq-zc7020-lwip-client-server/m-p/824558#M22874

 

Best Regards,
Srikanth
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.

 

 

0 Kudos
Highlighted
Participant
Participant
3,219 Views
Registered: ‎07-24-2017

Hi Srikanth,

Thank you for your help but it seems my problem lies in a deeper level. When I a watch LWIP debug prints on my console, I observe that the active port frequently receives and prints the messages like this (I am not sending these messages, I am not connected with tcp yet, it is my pc checking its connections):

 

IP header:
+-------------------------------+
| 4 | 5 |  0x00 |        36     | (v, hl, tos, len)
+-------------------------------+
|    11298      |000|       0   | (id, flags, offset)
+-------------------------------+
|  128  |   17  |    0x8A2E     | (ttl, proto, chksum)
+-------------------------------+
|  192  |  168  |    1  |   41  | (src)
+-------------------------------+
|  192  |  168  |    1  |  255  | (dest)
+-------------------------------+
ip_input: p->len 36 p->tot_len 36
ip_input: iphdr->dest 0xFF01A8C0 netif->ip_addr 0x8E01A8C0 (0x1A8C0, 0x1A8C0, 0xFF000000)
ip_input: packet accepted on interface ae

 And it enters accept_callback function when I connect with tcp at the given port. However the inactive port neither receives any messages nor enters accept_callback function when I try to connect. So the code doesn't call recv_callback_2 function. Thank you for the modification though, it will be handy when I am able to communicate from both ethernet ports.

 

Best regards,

20801700

0 Kudos
Highlighted
Moderator
Moderator
3,156 Views
Registered: ‎08-25-2009

Hi @20801700,

 

We tried one design with AXI Ethernet + GEM a long time back using LWIP for dual Ethernet simultaneously . But I’m not sure what the limitations with two AXI Ethernet designs would be. The application will have to be modified like what you did.

Have you tried with using different subnet in IP address and see if that works?

"Don't forget to reply, kudo and accept as solution."
0 Kudos
Highlighted
Participant
Participant
3,150 Views
Registered: ‎07-24-2017

Hi nanz

Thanks for your reply (sincerely), I am working with different subnet IP's. The scary thing is that I could not find any example design with this configuration. Even these guys : http://www.fpgadeveloper.com/2016/01/running-a-lwip-echo-server-on-a-multi-port-ethernet-design.html drive their MACs separately as I did in the first place, I suspect the DMA usage, but I don't have clear data to back my suspicion yet, when I catch the problem I will post my findings, please don't hesitate to share if anything comes on your mind, I am new with lwIP and microblaze so I might have done simple mistakes

0 Kudos
Highlighted
Participant
Participant
3,149 Views
Registered: ‎07-24-2017

Hello guys, long time no see!! I solved it, it was DMA operations.

Apparently lwIP is indeed capable of working with multiple ethernet ports, however Xilinx guys did not put too much effort on it. in my case xaxiemacif_dma.c has its own xemac and xaxiemacif as xemac_fast and xaxiemacif_fast, and it copies your xemac's info into those when init_axi_dma(struct xemac_s *xemac) function is called. When you call it the second time with a different xemac, the info and interrupt assignments for the first one is simply overwritten because there is actually only one active xemac (named as xemac_fast) and one xaxiemacif(named as xaxiemacif_fast). I duplicated these structs and interrupt callback functions, added a simple initialization counter and it worked like magic, with the echo.c I got from Srikanth(thanks again!!!). Well I am adding the modified file here, I modified it for two connections with NO-SYS and FAST_INTERRUPT, but I do not recommend using it as-is since I did not change the operation in any other configurations.

 

Have a nice day

 

20801700

View solution in original post

Highlighted
Participant
Participant
1,979 Views
Registered: ‎01-02-2019

Hi @20801700,

Did you get any solution on this ?

Actually i am trying to send ethernet packets on 8 ports , i have used FIFO insted of DMA in vivado. I am also facing similar issue.

If you have any solution can you please post it.

Thank you.

0 Kudos
Highlighted
Visitor
Visitor
921 Views
Registered: ‎03-14-2020

Hello, We have interfaced 88E1512 ethernet (in RGMII mode) with Artix 7(XC7A200T-1FBG676I) FPGA.

We have implemented the design using block design in Vivado 2015.2, generated the bitstream and exported the bitstream to the SDK 2015.2.

In the SDK we have selected the LWIP template. After this, we have programmed FPGA and then executed the code. But the echo server is not working. It's showing following messages on the console

-----lwIP TCP echo server ------
TCP packets sent to port 6001 will be echoed back
auto-negotiated link speed: 912

As per datasheet of 88E1512 (page 39, table 33), Register 20 is used to select mode of operation by mode[2:0]. But datasheet says that MODE[2:0] is set to 111 by default for 88E1512/88E1514. Therefore it must be programmed with the RGMII mode of operation i.e. 000. So how can we update/change this register in the LWIP driver template?

You have changed your LWIP for 88E1512, can you please let us know how did you change it.  How did you modify xaxiemacif_physpeed.c to work with 88e1512 PHY? Can you please share the xaxiemacif_physpeed.c file.

Thanks is advance.

0 Kudos
Highlighted
Visitor
Visitor
854 Views
Registered: ‎03-14-2020

Hello all,

  Finally, our ethernet worked. As we are using 88E1512, and its model no is 1D0 so we had to add this in “xaxiemacif_physpeed.c” file, similarly we had added one function  for 88E1512 by following below link

https://github.com/fpgadeveloper/zedboard-qgige-axieth

After these modifications, our design worked and we were able to ping successfully.

Tags (1)
Highlighted
Explorer
Explorer
47 Views
Registered: ‎01-04-2013

Hello @Participant

I'm using 88e1512,xc7k325T,microblaze,lwip141,and I want to use speed of  1000Mbps,but I don't know how to modify the file xaxiemacif_physpeed.c,can you send me the file

My email is 305211061@qq.com.

Additionally,I create a TCP server of the lwip,and I want to send 2M bytes data(which are from ADC) to a TCP client which is created on windows,but the send speed is only 200K bytes per second even though I increase the buf so much like below

Dingtalk_20201014165346.jpg

 

 

Thanks

Best wishes.

0 Kudos