There is so many structures in the Linux wireless driver mac80211. Things like struct net_device
, struct ieee80211_hw
, struct ieee80211_vif
and struct ieee80211_local
and so on. So many structures that I don't understand what information they contain and when them were initialized.
How can I learn about them and the whole architecture of wireless drivers?
You may want to check out Johannes Berg's (mac80211 maintainer) slides here: http://wireless.kernel.org/en/developers/Documentation/mac80211?action=AttachFile&do=get&target=mac80211.pdf
They may be somewhat outdated but should give you a place to start.
A high level description of the Linux WiFi kernel stack:
- It's important to understand there are 2 paths in which userspace communicates with the kernel when we're talking about WiFi:
- Data path: the data being received is passed from the wireless driver to the netdev core (usually using
netif_rx()
). From there the net core will pass it through the TCP/IP stack code and will queue it on the relevant sockets from which the userspace process will read it. On the Tx path packets will be sent from the netdev core to the wireless driver using thendo_start_xmit()
callback. The driver registers (like other netdevices such as an ethernet driver) a set of operations callbacks by using thestruct net_device_ops
. - Control path: This path is how userspace controls the WiFi interface/device and performs operations like scan / authentication / association. The userspace interface is based on netlink and called
nl80211
(seeinclude/uapi/linux/nl80211.h
). You can send commands and get events in response.
- Data path: the data being received is passed from the wireless driver to the netdev core (usually using
- When you send an
nl80211
command it gets initially handled bycfg80211
kernel module (it's code is undernet/wireless
and the handlers are innet/wireless/nl80211.c
).cfg80211
will usually call a lower level driver. In case of Full MAC hardware the specific HW driver is right below cfg80211. The driver belowcfg80211
registers a set of ops withcfg80211
by usingcfg80211_ops struct
. For example see brcmfmac driver (drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
) - For Soft MAC hardware there's
mac80211
which is a kernel module implementing the 802.11 MAC layer. In this casecfg80211
will talk tomac80211
which will in turn use the hardware specific lower level driver. An example of this is iwlwifi (For Intel chips). mac80211
registers itself withcfg80211
by using thecfg80211_ops
(seenet/mac80211/cfg.c
). The specific HW driver registers itself withmac80211
by using theieee80211_ops struct
(for exampledrivers/net/wireless/iwlwifi/mvm/mac80211.c
).- Initialization of a new NIC you've connected occurs from the bottom up the stack. The HW specific driver will call mac80211's
ieee80211_allow_hw()
usually after probing the HW.ieee80211_alloc_hw()
gets the size of private data struct used by the HW driver. It in turns callscfg80211 wiphy_new()
which does the actual allocation of space sufficient for the wiphy struct, theieee80211_local struct
(which is used bymac80211
) and the HW driver private data (the layering is seen inieee80211_alloc_hw
code).ieee80211_hw
is an embedded struct withinieee80211_local
which is "visible" to the the HW driver. All of these (wiphy
,ieee80211_local
,ieee80211_hw
) represent a single physical device connected. - On top of a single physical device (also referred to as phy) you can set up multiple virtual interfaces. These are essentially what you know as wlan0 or wlan1 which you control with
ifconfig
. Each such virtual interface is represented by anieee80211_vif
. This struct also contains at the end private structs accessed by the HW driver. Multiple interfaces can be used to run something like a station on wlan0 and an AP on wlan1 (this is possible depending on the HW capabilities).
来源:https://stackoverflow.com/questions/7157181/how-to-learn-the-structure-of-linux-wireless-drivers-mac80211