mac80211源碼分析(原始出處)
reference:Linux無線驅動簡介http://blog.csdn.net/dickjtk/article/details/11862815
1、概述
-
mac80211:是一個Linux內核子系統,是驅動開發者可用於爲SoftMAC無線設備寫驅動的框架。mac80211在內核空間實現STA模式,在用戶空間實現AP模式(hostapd)。
-
cfg80211:用於對無線設備進行配置管理,與FullMAC,mac80211和nl80211一起工作。
-
nl80211:用於對無線設備進行配置管理,它是一個基本Netlink的用戶態協議。
-
MLME:即MAC(Media Access Control) Layer Management Entity,它管理物理層MAC狀態機。
-
SoftMAC:其MLME由軟件實現,mac80211爲SoftMAC實現提供了一個API。即:SoftMAC設備允許對硬件執行更好地控制,允許用軟件實現對802.11的幀管理,包括解析和產生802.11無線幀。目前大多數802.11設備爲SoftMAC,而FullMAC設備較少。
-
FullMAC:其MLME由硬件管理,當寫FullMAC無線驅動時,不需要使用mac80211。
-
wpa_supplicant:是用戶空間一個應用程序,主要發起MLME命令,然後處理相關結果。
-
hostpad:是用戶空間一個應用程序,主要實現station接入認證管理。
-
cfg80211是Linux802.11配置API。cfg80211用於代碼wext(Wireless-Extensions),nl80211用於配置一個cfg80211設備,且用於kernel與userspace間的通信。wext現處理維護狀態,沒有新的功能被增加,只是修改bug。如果需要通過wext操作,則需要定義ONFIG_CFG80211_WEXT。
-
cfg80211and nl80211:基於消息機制,使用netlink接口
-
wext:基於ioctl機制(madwifi wext 等已經在linxu內核中被移除linux 2.6.26)
-
structieee80211_hw:表示硬件信息和狀態
-
ieee80211_alloc_hw:每個driver調用ieee80211_alloc_hw分配ieee80211_hw,且以ieee80211_ops爲參數
-
ieee80211_register_hw:每個driver調用ieee80211_register_hw創建wlan0和wmaster0,並進行各種初始化。
-
structieee80211_ops:每個driver實現它的成員函數,且它的成員函數都以structieee80211_hw做爲第一個參數。在structieee80211_ops中定義了24個方法,以下7個方法必須實現:tx,start,stop,add_interface,remove_interface,config和configure_filter。
2、體系結構
圖2-1系統框架
3、代碼結構
-
ieee80211_i.h(主要數據結構)
-
main.c(主函數入口)
-
iface.c(虛擬接口處理)
-
key.c,key.h(密鑰管理)
-
sta_info.c,sta_info.h(用戶管理)
-
pm.c(功率管理)
-
rate.c,rate.h(速率控制函數)
-
rc80211*(速率控制算法)
-
rx.c(幀接收路徑代碼)
-
tx.c(幀發送路徑代碼)
-
scan.c(軟件掃描代碼)
-
mlme.c(station/managed模式MLME)
-
ibss.c(IBSSMLME)
-
cfg.c,cfg.h,wext.c(配置入口代碼)
-
aes*,tkip*,wep*,michael*,wpa*(WPA/RSN/WEP代碼)
-
wme.c,wme.h(QoS代碼)
-
util.c(公共函數)
4、數據結構
ieee80211_local/ieee80211_hw
-
每個數據結構代表一個無線設備(ieee80211_hw嵌入到ieee80211_local)
-
ieee80211_hw是ieee80211_local在驅動中的可見部分
-
包含無線設備的所有操作信息
sta_info/ieee80211_sta
-
代表每一個station
-
可能是mesh,IBSS,AP,WDS
-
ieee80211_sta是驅動可見部分
ieee80211_conf
-
硬件配置
-
當前信道是最重要的字段
-
硬件特殊參數
ieee80211_bss_conf
-
BSS配置
-
多BSSes類型(IBSS/AP/managed)
-
包含比如基礎速率位圖
-
perBSS parameters in case hardware supports creating/associating withmultiple BSSes
ieee80211_key/ieee80211_key_conf
-
代表加密/解密密鑰
-
ieee80211_key_conf提供給驅動用於硬件加速
-
ieee80211_key包含book-keeping和軟件解密狀態
ieee80211_tx_info
-
大部分複雜數據結構
-
skb內部控制緩衝區(cb)
-
經歷三個階段:1、由mac80211初始化;2、由驅動使用;3、由發送狀態通告使用
ieee80211_rx_status
-
包含接收幀狀態
-
驅動通過接收幀傳給mac80211
ieee80211_sub_if_data/ieee80211_vif
-
包含每個虛擬接口信息
-
ieee80211_vifis passed to driver for those virtual interfaces the driver knowsabout (no monitor,VLAN)
-
包含的sub-structures取決於模式
5、主要流程
配置
-
所有發起來自用戶空間(wext或者nl80211)
-
managed和IBSS模式:觸發狀態機(基於workqueue)
-
有些操作或多或少直接通過驅動傳遞(比如信道設置)
接收路徑
-
通過函數ieee80211_rx()接收幀
-
調用ieee80211_rx_monitor()拷貝幀傳遞給所有監聽接口
-
調用invoke_rx_handlers()處理幀
-
如果是數據幀,轉換成802.3幀格式,傳遞給上層協議棧
-
如果是管理幀/控制幀,傳遞給MLME
接收處理鉤子(invoke_rx_handlers)
-
ieee80211_rx_h_passive_scan
-
ieee80211_rx_h_check
-
ieee80211_rx_h_decrypt
-
ieee80211_rx_h_check_more_data
-
ieee80211_rx_h_sta_process
-
ieee80211_rx_h_defragment
-
ieee80211_rx_h_ps_poll
-
ieee80211_rx_h_michael_mic_verify
-
ieee80211_rx_h_remove_qos_control
-
ieee80211_rx_h_amsdu
-
ieee80211_rx_h_mesh_fwding
-
ieee80211_rx_h_data
-
ieee80211_rx_h_ctrl
-
ieee80211_rx_h_action
-
ieee80211_rx_h_mgmt
發送路徑
-
幀傳遞給ieee80211_subif_start_xmit()
-
把幀轉換成802.11格式,丟棄發給未認證工作站的單播包,除了來自本地的EAPOL幀
-
如果是MONITOR接口,在幀頭部增加radiotap信息
-
調用invoke_tx_handlers()處理幀
-
調用drv_tx(),把幀傳遞給驅動
發送處理鉤子(invoke_tx_handlers)
-
ieee80211_tx_h_dynamic_ps
-
ieee80211_tx_h_check_assoc
-
ieee80211_tx_h_ps_buf
-
ieee80211_tx_h_select_key
-
ieee80211_tx_h_sta
-
ieee80211_tx_h_rate_ctrl
-
ieee80211_tx_h_michael_mic_add
-
ieee80211_tx_h_sequence
-
ieee80211_tx_h_fragment
-
ieee80211_tx_h_stats
-
ieee80211_tx_h_encrypt
-
ieee80211_tx_h_calculate_duration
mangement/MLME
-
狀態機運行依賴於用戶請求
-
標準方法如下:
-
proberequest/response
-
authrequest/response
-
assocrequest/response
-
notificationrequest/response
IBSS
-
嘗試尋找IBSS
-
加入IBSS或者創建IBSS
-
如果沒有配對,則週期性地嘗試尋找IBSS並加入
創建接口路徑
-
創建接口由用戶空間通過nl80211發起
-
分配網絡設備空間(包含sdata對象空間)
-
初始化網絡設備
-
初始化sdata對象(包括設備類型,接口類型,設備操作函數等等)
-
註冊網絡設備
-
把sdata對象加入local->interfaces
刪除接口路徑
-
刪除接口由用戶空間通過nl80211發起
-
把sdata對象從local->interfaces移除
-
移除網絡設備
創建station路徑
-
創建station由用戶空間通過nl80211發起
-
分配sta_info對象空間
-
初始化sta_info對象(包括偵聽間隔,支持速率集等等)
-
初始化sta_info對象的速率控制對象
-
把sta_info對象加入local->sta_pending_list
-
調用local->ops->sta_add通知驅動創建station
-
把sta_info對象加入local->sta_list
刪除station路徑
-
刪除station由用戶空間通過nl80211發起
-
刪除sta_info對象的key對象
-
把sta_info對象從local->sta_pending_list移除
-
調用local->ops->sta_remove通知驅動移除station
-
刪除sta_info對象的速率控制對象
-
把sta_info對象從local->sta_list移除
掃描請求路徑
-
掃描請求由用戶空間通過nl80211發起
-
如果支持硬件掃描,調用local->ops->hw_scan()執行硬件掃描
-
否則,調用ieee80211_start_sw_scan()執行軟件掃描
-
延時喚醒ieee80211_scan_work()
掃描狀態機路徑
-
如果存在硬件掃描請求,調用drv_hw_scan()進行掃描,如果失敗,調用ieee80211_scan_completed()完成掃描
-
如果存在掃描請求,同時未進行掃描,調用__ieee80211_start_scan()進行軟件掃描,如果失敗,調用ieee80211_scan_completed()完成掃描
-
根據next_scan_state調用相應的處理函數
-
如果next_delay==0,則繼續根據next_scan_state調用相應的處理函數
-
延時喚醒ieee80211_scan_work()
6、切換點
配置
-
wirelessextensions (wext)
-
cfg80211(通過nl80211和用戶空間通信)
wext
-
設置SSID,BSSID和其他關聯參數
-
設置RTS/fragmentationthresholds
-
managed/IBSS模式的加密密鑰
cfg80211
-
掃描
-
用戶管理(AP)
-
mesh管理
-
虛擬接口管理
-
AP模式加密密鑰
從mac80211到速率控制
-
速率控制不是驅動的一部分
-
每個驅動有自己的速率控制選擇算法
-
速率控制填充ieee80211_tx_info速率信息
-
速率控制獲取發送狀態
從mac80211到驅動
-
驅動方法(ieee80211_ops)
-
mac80211有一些輸出函數
-
參考include/net/mac80211.h
7、主要函數
ieee80211_alloc_hw()
-
分配wiphy對象空間(保證私有數據和硬件私有數據32字節對齊,wiphy包含ieee80211_local和驅動私有數據)
-
初始化wiphy對象(包括重傳次數,RTS門限等等)
-
初始化ieee80211_local(包括重傳次數,工作隊列,接口鏈表等等)
-
初始化sta_pending_list鏈表
-
初始化sta_list鏈表
ieee80211_register_hw()
-
分配int_scan_req數據結構
-
初始化支持接口類型(包括MONITOR接口)
-
註冊wiphy
-
初始化WEP
-
初始化速率控制算法
-
註冊STA接口(默認wlan0)
ieee80211_rx()
-
拷貝skb,同時在skb頭部增加radiotap信息,傳遞給所有監聽接口
-
如果是數據幀,根據MAC地址查找station
-
如果station沒有找到,把skb傳遞給所有接口處理
-
數據幀:轉換成802.3幀格式,傳遞給網絡協議棧
-
管理幀/控制幀:傳遞給MLME
ieee80211_xmit()
-
如果skb來自監聽接口,移除skb頭部的radiotap信息
-
進行skb預處理(包括設置QoS優先級,設置分段標誌,ACK應答標誌等等)
-
選擇加密密鑰
-
選擇速率(ESP8089採用硬件速率控制,所以mac80211速率控制無效)
-
加密(mac80211採用硬件加速,所以mac80211加密無效)
-
通過local->ops->tx()把skb傳遞給驅動
8、速率控制
Minstrel是mac80211從MadWifi移植過來的速率控制算法,支持多速率重傳和提供最好速率。
工作原理
我們定義衡量吞吐量(發包數)的成功,用發送的比特數。
這個措施將獲取無線接口的最大速率編號來調整傳輸速度。而且,這表示在優先使用11Mpbs速率的情況將不使用1Mbps速率。這個模塊將記錄所有已發送包的成功結果。通過這個數據,模塊就有充分的信息去決定哪個包最成功。但是,需要一個可變參數。去強制模塊檢查最理想的速率。所以,一些百分比的包使用非正常速率進行發送。
重傳序列
一些器件自己已經創建多速率重傳序列。比如Atheros11abg芯片組有四個段。每一段指導硬件採用某些速率來發送當前包,和固定的重傳次數。當包發送成功,剩餘重傳序列被忽略。重傳次數的選擇是根據期望在26ms內發包出去,或者失敗。重傳序列是通過兩個合理的規則計算的,如果包是一個普通發送包(90%的包)那麼重傳數是bestthroughput,nextbest throughput,bestprobability,lowestbaserate。如果是採樣包(10%的包)那麼重傳數是randomlookaround,bestthroughput,bestprobability,lowestbaserate。表格如下:
重傳數是經過調整的,所以重傳序列部分發送時間小於26ms。表格修改如下:
EWMA
EWMA(ExponentialWeighted MovingAverage)是Minstrel速率算法的核心。每秒鐘實現10次EWMA計算,每個速率都會進行計算。計算結果有平滑效果,所以新的結果對於所選擇的速率有合理的影響。