WARP Project Forums - Wireless Open-Access Research Platform

You are not logged in.

#1 2013-Aug-20 15:24:51

smitty1276
Member
Registered: 2013-Aug-20
Posts: 2

802.11 ethernet tx

Hello!  I apologize in advance for the fact that dealing with this low-level code and toolset is a bit out of my comfort zone, but I'm learning a lot and I appreciate any help you can give.  I suspect my question is quite simple. :-)

I'm looking at the 802.11 ref design and I am trying to understand what I would need to do to have it periodically transmit data to a host PC over ethernet.  Looking at the wlan_mac_ap project in Xilinx SDk, it looks like the nuts and bolts may be in place so I assume its just some setup and making the correct calls with the correct arguments.  Is this the case?  Can anyone point me towards some sample code or something I should read to understand what my next step should be?

Thanks!

Offline

 

#2 2013-Aug-20 17:40:57

chunter
Administrator
From: Mango Communications
Registered: 2006-Aug-24
Posts: 1212

Re: 802.11 ethernet tx

Hi,

I just posted a new release of the 802.11 Reference Design (v0.3 beta available here). Among the changes were replacing Ethernet FIFO calls with Ethernet DMA (which is much faster). Since you are looking to modify Ethernet stuff in the project, I highly recommend starting off with v0.3.

There are two things you need to do to enable the periodic Ethernet Tx behavior you want to build:

1. You'll probably want to use our wlan_mac_schedule_event function to have the framework periodically call a function that you create. As an example of how to do this, you can see how this function is used to generate periodic beacons with the call wlan_mac_schedule_event(BEACON_INTERVAL_US, (void*)beacon_transmit);. The "beacon_transmit()" function is called after BEACON_INTERVAL_US microseconds. At the bottom of the beacon_transmit function, the exact same call is made to schedule the next execution of the function. You can make your own function and schedule it just like beacon_transmit.

2. To send a packet over Ethernet, you'll want to use the wlan_eth_dma_send(u8* pkt_ptr, u32 length) function. All you have to do is give it a pointer to the Ethernet frame you want to send and the length of that packet. Note: the pointer needs to point to a valid Ethernet header followed by whatever payload you want to send if you want a PC not to throw away the packet. A good example of how this is done is the wlan_mpdu_eth_send(void* mpdu, u16 length) function, which takes a wireless frame (MPDU) and de-encapsulates it by sticking an Ethernet header on the front of it. At the bottom of that function, the wlan_eth_dma_send function is called. This function replaces the LL_FIFO calls in the v0.2 802.11 Reference Design for writing and sending packets.

With those two steps, you should be able to periodically sent Ethernet frames.

Offline

 

#3 2013-Aug-20 18:11:35

smitty1276
Member
Registered: 2013-Aug-20
Posts: 2

Re: 802.11 ethernet tx

Fantastic, that should get me on the path.  Thanks!  (though, I may have a follow-up or two tomorrow :-)).

Offline

 

#4 2014-Mar-05 16:32:04

abdul.jehangir
Member
Registered: 2014-Mar-05
Posts: 3

Re: 802.11 ethernet tx

Hi,
I'm using 802.11 reference design v0.71 and i'm trying to send an ethernet packet to a pc. I'm new to this system, i could be doing something wrong.

I wrote a function which makes an ethernet frame with IP frame as payload inside, and then calls wlan_eth_dma_send function to send the packet over the wire. Looking at wireshark on the computer at the other end, I can see the packet length is correct, but packet is all zeroes. your help would be very much appreciated. this is my function:

Code:

int eth_send(void* payload, u16 payload_size) {
	int status;
	u32 ip = 0x0100007f;
	u32 eth_tx_length = sizeof(ethernet_header) + sizeof(ipv4_header) + payload_size;
	u8* eth_tx_ptr = wlan_mac_high_malloc(eth_tx_length);

	// make ethernet header
	ethernet_header* eth_hdr = (ethernet_header*)eth_tx_ptr;
	eth_hdr->address_destination[0] = 0x68;
	eth_hdr->address_destination[1] = 0x5b;
	eth_hdr->address_destination[2] = 0x35;
	eth_hdr->address_destination[3] = 0x87;
	eth_hdr->address_destination[4] = 0xfd;
	eth_hdr->address_destination[5] = 0xd6;

// copy source address
	memcpy((void*) eth_hdr->address_source, (void*) wlan_mac_high_get_eth_mac_addr(), 6);
	eth_hdr->type = ETH_TYPE_IP;
	//end of ethernet header

	// ipv4 header
	ipv4_header* ip_hdr = (ipv4_header*)(eth_tx_ptr + sizeof(ethernet_header));
	ip_hdr->ver_ihl = 0x45;
	ip_hdr->tos = 0x00;
	ip_hdr->length = 0x3400; //length of payload is fixed, thats why its hardcoded for now.
	ip_hdr->id = 0x0100;
	ip_hdr->flags_fragOffset = 0x0000;
	ip_hdr->ttl = 0x40;
	ip_hdr->prot = 0x00;
	ip_hdr->checksum = 0xc77c; //length of payload is fixed, thats why its hardcoded for now.

	memcpy((void*) ip_hdr->ip_dest, (void*) &ip, 4);
	memcpy((void*) ip_hdr->ip_src, (void*) &ip, 4);

	//copy payload
	memcpy((void*)(eth_tx_ptr + sizeof(ethernet_header) + sizeof(ipv4_header)), (void*) payload, payload_size);

	u8 i = 0;
	xil_printf("\npacket size: %d\n", eth_tx_length);
	while (i < eth_tx_length) {
		xil_printf("%02x-", *(eth_tx_ptr + i));
		i++;
	} // Printing the packet on console, i can confirm the packet is there in memory with correct content

#ifdef FMC_PKT_EN
	status = wlan_fmc_pkt_eth_send(eth_tx_ptr, eth_tx_length);
	if(status != 0) {xil_printf("Error in wlan_fmc_pkt_eth_send! Err = %d\n", status); return -1;}
#else
	status = wlan_eth_dma_send(eth_tx_ptr, eth_tx_length); //zeroes are received on the other end, but the packet length is correct.
	if(status != 0) {xil_printf("Error in wlan_mac_send_eth! Err = %d\n", status); return -1;}  
#endif

	return 0;
}

Offline

 

#5 2014-Mar-05 20:27:17

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: 802.11 ethernet tx

I think you've run into a subtle but important MicroBlaze architecture quirk.

The 802.11 ref design uses LMB (local memory bus) memory blocks for instruction and data space (ILMB, DLMB). The CPU_High heap is stored in the DLMB. Thus, the pointer you're receiving from malloc() is inside the DLMB.

The ETH_A Ethernet MAC uses the axi_dma peripheral to move Tx and Rx packets between memory and the Ethernet MAC. The axi_dma accesses packets in memory by mastering the axi_shared interconnect. However the DLMB memory block is not on the axi_shared interconnect. The LMBs are only accessible by the MicroBlaze processor itself. When the axi_dma issues a read request for the DLMB address the interconnect quietly does nothing, hence the zeros in your transmitted packet.

To send packets via ETH_A you must make the packet payload available in a memory area accessible by masters on the axi_shared interconnect. The DRAM and wireless Tx/Rx packet buffers are good options.

The safest way to grab some DRAM would be to request a queue entry from the Tx queue system, use its pre-allocated payload buffer to construct your custom packet, provide this pointer to the wlan_eth_dma_send() call, then return the queue entry to the free pool.

For example:

Code:

u8* my_pkt_ptr;
u32 my_pkt_len;
dl_list queue_entry_list;
packet_bd* queue_entry;

//Get a list of queue entries with one entry (single-entry lists are still lists)
queue_checkout(&queue_entry_list, 1);

if(checkout.length == 1){ 

  //Extract the queue entry from the list
  queue_entry =  (packet_bd*)(checkout.first);

  //Get a pointer to the queue entry's pre-allocated buffer space
  my_pkt_ptr = queue_entry->buf_ptr

  /* Fill in my_pkt_ptr and my_pkt_len here */

  //Send the packet over ETH_A
  status = wlan_eth_dma_send(my_pkt_ptr, my_pkt_len);

  //Return the list of queue entries to the free pool
  queue_checkin(&checkout);
}

Offline

 

#6 2014-Mar-05 21:35:11

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: 802.11 ethernet tx

For completeness, if you wanted to use a spare wireless Tx pkt buffer instead, you could point my_pkt_ptr to TX_PKT_BUF_TO_ADDR(BUF_INDEX), where BUF_INDEX is [2,3,...14]. The reference code uses Tx pkt buffers [0,1,15] for data ping/pong and ACKs. The rest are unused by default. The wireless packet buffers will be faster than DRAM.

Offline

 

#7 2014-Mar-06 00:19:43

abdul.jehangir
Member
Registered: 2014-Mar-05
Posts: 3

Re: 802.11 ethernet tx

Thanks alot. I was able to send the correct data through ethernet now! Really appreciate your quick response.

Offline

 

Board footer