浅谈 Linux 内核无线子系统(4)

以 triggering scan 为例,扫描请求从 cfg80211 到 mac80211 是通过 mac80211 在 cfg80211 中注册的回调函数来实现的。

const struct cfg80211_ops mac80211_config_ops = { ... .scan = ieee80211_scan, ... };

在 mac80211 中, ieee80211_scan 将会具体去实现扫描发现网络的具体细节。

=>ieee80211_scan_state_send_probe =>ieee80211_send_probe_req =>ieee80211_tx_skb_tid_band =>ieee80211_xmit =>ieee80211_tx =>ieee80211_tx_frags =>drv_txj 6 数据包又是如何被接收?

我们接下来反过来看看数据接收的过程,现在我们不再比较数据路径与管理路径的不同了。相信读者同样能明白。
当一个数据包在空中被无线设备捕捉到后,硬件将会向内核发出一个中断(大部分 PCI 接口的设备这样做),或则通过轮询机制判断是否有数据到来(如,使用了 USB 接口)。
前者,中断将会引发中断处理程序的执行,后者促使特定的接收函数将被调用。

一般设备驱动层的回调函数不会做太多关于接收数据包的操作,仅仅做数据校验,为 mac80211 填充接收描述符,然后把数据包推给 mac80211 , 由 mac80211 来做之后的工作(直接或间接将数据包放入接收队列)。
数据进入 mac80211 后,将会调用 ieee80211_rx 或者其他变种接收函数。在这里数据路径和管理路径也将分开进行。
如果收到的帧是数据,它将被转换成 802.3 数据帧(通过 __ieee80211_data_to8023 实现),然后该数据帧将通过 netif_receive_skb 交付到网络协议栈。在协议栈中,各层网络协议将会对数据进行解析,识别协议首部。
如果接收到的是控制帧,数据将会由 ieee80211_sta_rx_queued_mgmt 处理。部分控制帧在 mac80211 层就终止,另外一些将会通过 cfg80211 发送到用户空间下的管理程序。
例如,身份认证控制帧被 cfg80211_rx_mlme_mgmt 处理,然后通过 nl80211_send_rx_auth 发送到用户空间下的 wpa_supplicant ; 相应的关联响应控制帧被 cfg80211_rx_assoc_resp 处理,并由 nl80211_send_rx_assoc 发送到用户空间。

7 总结一下

一般 WiFi 驱动包含如下三个部分:配置、发送回调、接收回调。再以 USB WiFi 适配器为例,当内核探测到设备被插入时,会调用 probe 函数。这可能发生在注册配置好的 ieee80211_ops 时。
首先, ieee80211_alloc_hw 分配一个 ieee80211_hw 结构体,代表着相应 WiFi 设备。另外,如下的数据结构也会被分配:

wiphy 结构:主要用来描述 WiFi 硬件参数(如, MAC 地址、接口模式与组合、支持的波特率以及其他一些硬件功能)。

ieee80211_local 结构:这是一个设备驱动层可见的结构,并且被 mac80211 大量使用。ieee80211_ops 的映射绑定将链接到 ieee80211_local 中。 前者作为后者的一个成员。在 ieee80211_hw 中可以通过 container_of 或者 hw_to_local 这个专用 API 得到 ieee80211_local 。

设备驱动使用到的在 ieee80211_hw 中的私有结构 void *priv 。

注意:硬件设备的注册由 ieee80211_register_hw 完成,前提是事先已经插入注册了 mac80211 模块,好比在 STA 模式中,要先用 wpa_supplicant 控制设备连接上了某个热点才能进行通信一样。
最后希望这篇总结能让相关人员在探索源代码时具有整体把握。

参考原文:https://www.linux.com/blog/linux-wireless-networking-short-walk

参考资料:https://wireless.wiki.kernel.org/en/developers/documentation/glossary

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/14982.html