Table of Contents

Joshua Oreman: 802.11 wireless development

gPXE 802.11 API design notes

The below are my thoughts about a week into the coding season. They may change without warning. This is not meant to be a complete API guide; there are comments in the header files for that. Update: As of Week 5 these have been updated for accuracy, if not completeness.

802.11 drivers should “feel” like regular NIC drivers. They'll need to handle more things, because wireless networking is more complex than wired, but the programming interface should be similar. 802.11 has a lot of MAC-layer processing, though, so there needs to be a shim between the driver layer and the ll_protocol push/pull. I chose to implement this by creating a net80211_device, and having the 802.11 MAC layer set up a normal net_device to wrap it.

The operations for a net80211_device are the same as those of a net_device, with one addition: config(). The config call is used to ask the driver to update any hardware-level settings for wireless-specific issues like channel, transmission rate, association settings (what network are we connected to?), and physical-layer issues like ERP parameters. (When associating with an 802.11g network, we might get something in the association response packet that tells us how to configure our timings and such; the card needs to hear about that.)

On initialization (the driver probe() routine), each wireless driver provides some information about the capabilities and quirks of its hardware in order to register its net80211_device. This information is stored in a net80211_hw_info structure, and its contents are mostly self-explanatory. The MAC layer uses it to know what to advertise when associating with a network, how to interpret the card's status, and how to set up the wrapping net_device (proper MAC address).

Network management

When the 802.11 netdev is first open, after driver initialization is complete, an auto-association process is started that does all of the following in sequence. They can be done separately from that based on user commands.

First, it's necessary to find out what network you want to associate with. To that end, net80211_probe_start() will start scanning for networks, and process received data whenever net80211_probe_step() is called. The handler should call net80211_probe_finish_all() or net80211_probe_finish_best() to retrieve a list of all networks, or the best-signal network, that were returned by the probe and matched the SSID filter supplied, if any. The probe call will attempt a passive search (scanning for beacons), but can be configured to search actively (sending probe requests) for networks on the 2.4GHz band by setting the netX/active-scan gPXE setting. The net80211_probe_finish_* calls return net80211_wlan structures listing the detected network parameters; either a list or a single structure. The returned structure(s) need to be freed by calling net80211_free_wlan() or net80211_free_wlanlist() after they have been used for association.

The actual association is performed by passing that net80211_wlan structure in sequence to net80211_prepare_assoc(), net80211_send_auth(), net80211_send_assoc(), and crypto handshaking:

To be continued…