1. 程式人生 > >Linux無線驅動簡介及mac80211原始碼分析

Linux無線驅動簡介及mac80211原始碼分析

mac80211原始碼分析(原始出處

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計算,每個速率都會進行計算。計算結果有平滑效果,所以新的結果對於所選擇的速率有合理的影響。