12.1 Mac80211 Subsystem
Before diving into the Linux kernel's wireless implementation, we need to face a reality: while wireless and wired networks look similar at the /etc/network/interfaces level, to the kernel, they are entirely different beasts.
You might think, it's just a network card, right? Load a driver, allocate a eth0 or wlan0, and send packets—what else is there?
If you really think that, writing drivers will be a painful experience.
A wireless network is not a "wire"—it's a chaotic medium of air. Two fundamental differences dictate its complexity: first, unlike Ethernet, you cannot talk and listen for collisions at the same time (half-duplex); you can only listen before you speak (CSMA/CA, Collision Avoidance). Second, this air is full of interference—microwaves, Bluetooth neighbors, and the router next door are all fighting for the channel.
Therefore, in the Linux kernel, a wireless network is not a simple variant of an Ethernet card. It has its own independent, massive subsystem—mac80211.
This is the protagonist of this chapter. But before fully unfolding this subsystem, let's go back to the chaotic era before its birth and see why we absolutely needed such a complex piece of machinery.
Legacy of the Old Era: The Price of "Just Making It Work"
Turn the clock back to 1997. IEEE released the first 802.11 specification. Wireless cards were rare back then, and it wasn't until around 2001, when laptops became widespread, that WiFi gradually became a standard feature.
The Linux community faced immense pressure at the time: Windows wireless drivers were already mature, while Linux had almost nothing. As Jeff Garzik, the kernel wireless maintainer at the time, put it: "They just wanted to make the hardware work."
Driven by this anxiety, the first generation of Linux wireless drivers was born. They had two characteristics:
- No unified architecture: Every driver was written from scratch, resulting in a massive amount of code duplication.
- Proliferation of FullMAC: To cut corners, driver developers offloaded most of the dirty work (like MLME at the management layer) to the hardware firmware.
It was like building a car without understanding how engines work, so you just bought a complete powertrain and stuffed it in. It runs, but you can't repair it, let alone optimize it.
But the wireless world changed. New protocol amendments sprang up like mushrooms after rain: 802.11a/b/g (physical layer speed boosts), 802.11e (QoS), 802.11i (security), 802.11n (MIMO high throughput)... By 2012, the 802.11 specification had ballooned to 2,793 pages.
The "let the hardware handle it" FullMAC approach simply couldn't keep up with this pace. The Linux community realized it had to take back control.
And so, mac80211 was born.
It was merged into Linux kernel 2.6.22 in July 2007, evolving from the d80211 stack (under the GPL) developed by a company called Devicescape. Its core idea was simple: put the generic soft MAC implementation into the kernel, and let drivers only deal with the hardware.
This was not just a technological advancement, but a shift in control—reclaimed from the closed-source firmware world back into the open-source kernel.
The Fundamental Difference at the MAC Layer: Why Can't We Just Reuse Ethernet?
In the mac80211 code, you will see many things never found in Ethernet drivers. This isn't for showing off; it's because the laws of physics have changed.
1. From "Collision Detection" to "Collision Avoidance"
Ethernet uses CSMA/CD (Carrier Sense Multiple Access / Collision Detection). This is intuitive: if I'm talking and hear someone else talking (detecting a collision), I stop, and everyone backs off randomly before trying again.
But in the wireless world, this trick doesn't work.
Imagine you are close to A, but far from B. A and B are talking at the same time. You can hear A, but not B (because the signal is weak). You think the channel is free and start talking—as a result, you become an interference source at B's end. This is the "hidden node problem." Wireless devices cannot listen to the channel while transmitting (because their own transmission power drowns out all other signals), so they simply cannot detect collisions.
Therefore, 802.11 adopted CSMA/CA (Collision Avoidance). The emphasis is on Avoidance. It must listen before transmitting and introduces an acknowledgment mechanism: I send to you, and you must reply with an ACK. If no ACK is received, I assume a collision occurred and retransmit.
This mechanism sounds simple, but it means the kernel must maintain retransmission queues, timers, and state machines—things we never have to worry about in Ethernet.
2. The Link is Unreliable
On twisted-pair cables, packet loss is a rare event. In the air, packet loss is the norm. Turn on a microwave, and your signal might drop by half.
The 802.11 specification mandates (except for broadcast and multicast): every received frame must be acknowledged with an ACK. If a sender transmits a frame and doesn't receive an ACK within a specified time, it must retransmit.
(Note: Starting from 802.11e, a QoSNoAck mode was introduced that allows skipping the ACK. However, in practice, to ensure reliability, this mode is rarely used.)
This means your wireless driver isn't just "moving data"—it is constantly performing handshakes.
FullMAC vs. SoftMAC: The Dividing Choice
Under the mac80211 framework, drivers are generally divided into two categories. We will repeatedly mention this distinction later in this chapter:
- FullMAC drivers: The hardware handles most MAC layer management functions (MLME) itself, such as scanning, authentication, and association. The kernel driver is very "thin," only responsible for sending and receiving data packets. These drivers are simple to write, but it's hard to leverage new features because much of the logic is locked in closed-source firmware.
- SoftMAC drivers (based on mac80211): The hardware is only responsible for transmitting and receiving raw waveforms (or doing minimal physical layer header processing). All MAC layer logic—frame construction, parsing, encryption, and retransmission—is handled by mac80211 in the kernel. This is the current mainstream direction in Linux.
The mac80211 subsystem is the stage prepared for SoftMAC drivers.
On this stage, the kernel is no longer a passive data mover; it must understand every detail of the 802.11 protocol. This brings complexity, but it also brings unparalleled flexibility and control—exactly what we are after.
Now that the stage is set, let's look at the scenery on it—how the 802.11 frame formats and topology structures are represented within this subsystem.