Saturday, 12 October 2013

In this post I will put few points over frame encapsulation. We will see few points that we need to understand in frame encapsulation. We will also see how mac80211(which sits on top of ath9k/ath5k etc) encapsulates it. Top layers send the frame in 802.3 format. It is the job of the driver to strip the 802.3 header and insert the 802.11 header. This process of stripping the 802.3 header and inserting the 802.11 header is called encapsulation.

In this particular post I will cover ToDS, FromDS and address fields of the 802.11 header. The actual values that goes to in each field varies with mode (like station, AP, WDS etc). Following table enumerates each mode and possible values for each field. In mac80211, please refer the function, ieee80211_subif_start_xmit.Please note that this path is only 802.11 data frames.

Mode

Address 1

Address2

Address3

Address4

ToDS

FromDS

AP

Destination Address. Generally one of the associated stations.

BSSID.
In general this is the MAC address of the VAP.

Source Address.
In general one of the local MAC addresses of the AP or MAC address of machine sitting in the backend network of the AP.

N/A

0

1

Station

BSSID.
In general this is the MAC address of the AP.

Source Address.
(Station's MACaddress).

Destination Address.
In general one of the local addresses of the AP or MAC address of a machine sitting in the backend network of the AP.

N/A

1

0

WDS

Receiver address

Transmitter address

Destination Address.
In general one of the local addresses of the Receiver or MAC address of a machine sitting in the backend network of the Receiver.

Source Address.
In general one of the local addresses of the Source or MAC address of a machine sitting in the backend network of the Source.

1

1

Ad-hoc

Destination Address

Source address

BSSID

N/A

0

0

Following are few examples. You can verify them using any sniffer like Wireshark, Airopeek etc.

Setup1:
Assume we have a setup like STA<---->AP<---->PC.

In this setup AP is a bridge and STA is associated to the AP. PC is connected to AP with Ethernet interface. We will focus only on the communication between AP and Station.

A packet originated at PC an destined to STA, will have address1 filled with STA's MAC address, address 2 filled with BSSID(In general AP's MAC address) and address3 filled with PC's MAC address.

Setup2:
Assume we have a setup like STA<---->AP<---->PC.

In this setup AP is a Router and STA is associated to the AP. PC is connected to AP with Ethernet interface. Assume AP is the default gateway router for PC to reach STA. We will focus only on the communication between AP and Station.

A packet originated at PC an destined to STA, will have address1 filled
with STA's MAC address, address 2 filled with BSSID(In general AP's MAC
address) and address3 filled AP's MAC address.

Setup3:
Assume we have a setup like STA<---->AP<---->PC.

In this setup AP is a bridge and STA is associated to the AP. PC is connected to AP with Ethernet interface. We will focus only on the communication between AP and Station.

A packet originated at STA an destined to PC, will have address1
filled with BSSID(In general
AP's MAC address), address 2 filled with STA's MAC address, and address3 filled with PC's MAC address.

Wednesday, 2 October 2013

DMAing is one of the most important
parts to understand for any network driver developer. In my last post I have explored the descriptor details in Tx path. In this post, we
will try to explore few details of descriptors in Rx path. We will use ath9k as
the reference driver. This should be similar for ath5k, madwifi or any
other Atheros driver including Fusion and Aquila. Handling of Rx descriptors is slightly different from that of Tx descriptors.

Ath9K: EDMA and Non-EDMA

In Ath9k there are two paths for reception of frames from the hardware. The first one is the case where EDMA (Enhanced DMA) is supported and the other is where it is not supported. There are a couple of differences between the two. In case of EDMA, two queues are maintained by the hardware namely high priority queue and low priority queue. The second difference is in the way the memory is allocated for descriptors and buffers (skb). In case of non-EDMA, the allocation is more like that in the tx path. Rx descriptors are allocated followed by the allocation of buffers(skb). Both of them are DMA synced and the physical address of the buffer is populated in the corresponding descriptor. The following figures shows allocation of descriptors and their linkage with the frame buffers.

Rx descriptor allocation:

Rx Descriptors are generally allocated at the initialization of the driver. In Ath9k driver, please refer the function, ath_rx_init . There are two separate paths, one is for EDMA and the other is for Non-EDMA.

EDMA path allocations are handled in ath_rx_edma_init . In this function, you can see that the buffers are allocated using ath_rxbuf_alloc and dma-mapped using dma_map_single. Please observe that the size of the buffer is equal to rx_bufsize (the sum of rx status length and max buffer size).

Non-EDMA path allocations are handled in ath_rx_init itself. Its allocation is similar to that of Tx Descriptors.

Populate and pass descriptor to the hardware:

Once the descriptors are allocated, the next step is to pass them to the hardware. Generally it is not done as part of the initialization. Rather it is delayed further till reception of packets is enabled. Reception of packets generally is enabled when atleast one of the VAPs (created on top the device) is enabled. In Ath9k/mac80211 combination, this invocation path is ieee80211_do_open --> drv_start (ath9k_start) --> ath_complete_reset --> ath_startrecv.

Also, observe that calls are made to ath_rx_edma_buf_link (EDMA path, ath_edma_start_recv --> ath_rx_addbuffer_edma --> ath_rx_edma_buf_link ) and ath_rx_buf_link (Non-EDMA path) from ath_startrecv. In ath_rx_edma_buf_link and ath_rx_buf_link the descriptor's physical address is passed to the hardware.

Please observe in Non-EDMA path (ath_rx_buf_link)that, the physical address of the frame buffer is populated to the corresponding pointer of the descriptor (ds->ds_data = bf->bf_buf_addr;). This is not needed in EDMA path. Please refer the figures shown above.

Processing of frames:

When a frame is received, hardware populates the next available descriptor and raises an interrupt. Driver handles the interrupt and actual processing of the frames is done in a tasklet . The driver extracts the frame, dma-unmap it, processes it and sends it to the top layers. Once the frame is sent to the top layer, it also has to allocate a new frame buffer, dma-map it and pass to the hardware. Because it has taken out one frame buffer and passed it to the upper layers. The upper layers will free that frame once they are done with their processing.

In Ath9k driver, corresponding tasklet function is ath_rx_tasklet. Frames are extracted in ath_get_next_rx_buf and ath_edma_get_next_rx_buf functions respectively in Non-EDMA and EDMA paths respectively. Please also observe the creation of new frame buffer using ath_rxbuf_alloc and the new buffer is passed to the hardware using ath_rx_buf_link / ath_rx_edma_buf_link.