mac80211 子系統 (高階)¶
本書這一部分包含的資訊僅對 mac80211 與驅動程式的高階互動感興趣,以利用更多的硬體功能並提高效能。
LED 支援¶
Mac80211 支援各種 LED 閃爍方式。在任何可能的情況下,裝置 LED 都應作為 LED 類裝置公開,並連線到適當的觸發器,然後由 mac80211 適當觸發。
-
struct ieee80211_tpt_blink¶
吞吐量閃爍描述
定義:
struct ieee80211_tpt_blink {
int throughput;
int blink_time;
};
成員
吞吐量吞吐量,單位為 Kbit/秒
閃爍時間閃爍時間,單位為毫秒 (完整週期,即一個關閉週期 + 一個開啟週期)
-
enum ieee80211_tpt_led_trigger_flags¶
吞吐量觸發標誌
常量
IEEE80211_TPT_LEDTRIG_FL_RADIO啟用無線電閃爍
IEEE80211_TPT_LEDTRIG_FL_WORK啟用工作時閃爍
IEEE80211_TPT_LEDTRIG_FL_CONNECTED當至少一個介面以某種方式連線時啟用閃爍,包括作為 AP
-
const char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw)¶
獲取 TX LED 的名稱
引數
struct ieee80211_hw *hw要獲取 LED 觸發器名稱的硬體
描述
mac80211 為每個無線硬體建立一個傳輸 LED 觸發器,如果您的驅動程式註冊了一個 LED 裝置,則可以使用該觸發器來驅動 LED。此函式返回觸發器的名稱 (或 NULL,如果未配置 LED),以便您可以自動連結 LED 裝置。
返回
LED 觸發器的名稱。 NULL,如果未配置 LED。
-
const char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)¶
獲取 RX LED 的名稱
引數
struct ieee80211_hw *hw要獲取 LED 觸發器名稱的硬體
描述
mac80211 為每個無線硬體建立一個接收 LED 觸發器,如果您的驅動程式註冊了一個 LED 裝置,則可以使用該觸發器來驅動 LED。此函式返回觸發器的名稱 (或 NULL,如果未配置 LED),以便您可以自動連結 LED 裝置。
返回
LED 觸發器的名稱。 NULL,如果未配置 LED。
-
const char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)¶
獲取關聯 LED 的名稱
引數
struct ieee80211_hw *hw要獲取 LED 觸發器名稱的硬體
描述
mac80211 為每個無線硬體建立一個關聯 LED 觸發器,如果您的驅動程式註冊了一個 LED 裝置,則可以使用該觸發器來驅動 LED。此函式返回觸發器的名稱 (或 NULL,如果未配置 LED),以便您可以自動連結 LED 裝置。
返回
LED 觸發器的名稱。 NULL,如果未配置 LED。
-
const char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)¶
獲取無線電 LED 的名稱
引數
struct ieee80211_hw *hw要獲取 LED 觸發器名稱的硬體
描述
mac80211 為每個無線硬體建立一個無線電更改 LED 觸發器,如果您的驅動程式註冊了一個 LED 裝置,則可以使用該觸發器來驅動 LED。此函式返回觸發器的名稱 (或 NULL,如果未配置 LED),以便您可以自動連結 LED 裝置。
返回
LED 觸發器的名稱。 NULL,如果未配置 LED。
-
const char *ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len)¶
建立吞吐量 LED 觸發器
引數
struct ieee80211_hw *hw要為其建立觸發器的硬體
unsigned int flags觸發標誌,請參閱
enum ieee80211_tpt_led_trigger_flagsconst struct ieee80211_tpt_blink *blink_table閃爍表 -- 需要按吞吐量排序
unsigned int blink_table_len閃爍表的大小
返回
NULL (如果出錯或未配置 LED 觸發器) 或新觸發器的名稱。
注意
必須在 ieee80211_register_hw() 之前呼叫此函式。
硬體加密加速¶
mac80211 能夠利用許多硬體加速設計來進行加密和解密操作。
為給定裝置的 struct ieee80211_ops 中的 set_key() 回撥用於啟用加密和解密的硬體加速。回撥採用一個 sta 引數,該引數對於預設金鑰或僅用於傳輸的金鑰將為 NULL,或者指向對等方的電臺資訊的指標,以用於單獨的金鑰。當為接入點配置 VLAN 時,可以使用具有相同金鑰索引的多個傳輸金鑰。
傳輸時,TX 控制資料將使用驅動程式透過修改由 key 引數指向的 struct ieee80211_key_conf (傳遞給 set_key() 函式) 選擇的 hw_key_idx。
如果金鑰現在正在使用,則 SET_KEY 命令的 set_key() 呼叫應返回 0;如果無法新增金鑰,則返回 -EOPNOTSUPP 或 -ENOSPC;如果返回 0,則必須將 hw_key_idx 分配給硬體金鑰索引。您可以自由使用完整的 u8 範圍。
請注意,如果設定了 IEEE80211_HW_SW_CRYPTO_CONTROL 標誌,如果啟用硬體加密失敗,mac80211 將不會自動回退到軟體加密。set_key() 呼叫也可能返回值 1,以允許在軟體中完成此特定金鑰/演算法。
當 cmd 為 DISABLE_KEY 時,它必須成功。
請注意,即使已將金鑰上傳到硬體,也可以不解密幀。堆疊不會根據是否已上傳金鑰做出任何決定,而是根據接收標誌做出決定。
key 引數指向的 struct ieee80211_key_conf 結構保證在另一次 set_key() 呼叫將其刪除之前有效,但它只能用作區分金鑰的 Cookie。
在 TKIP 中,某些硬體需要提供一個第 1 階段金鑰,用於 RX 解密加速 (即 iwlwifi)。這些驅動程式應提供 update_tkip_key 處理程式。update_tkip_key() 呼叫使用新的第 1 階段金鑰更新驅動程式。每當 iv16 迴繞時 (每 65536 個數據包),就會發生這種情況。set_key() 呼叫對於每個金鑰僅發生一次 (除非 AP 重新金鑰);它不會包含有效的第 1 階段金鑰。有效的第 1 階段金鑰僅由 update_tkip_key 提供。觸發 mac80211 呼叫此處理程式的原因是軟體解密和 iv16 的迴繞。
set_default_unicast_key() 呼叫更新為 WEP 加密型別配置到硬體的預設 WEP 金鑰索引。這是支援資料包解除安裝的裝置 (例如,ARP 響應) 所必需的。
當 Mac80211 驅動程式能夠按照以下要求替換正在使用的 PTK 金鑰時,應設定 NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 標誌:1) 它們不會將使用舊金鑰解密的幀傳遞給 mac80211
-
enum ieee80211_key_flags¶
金鑰標誌
常量
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT對於 CCMP/GCMP 金鑰,驅動程式應設定此標誌,以指示它僅需要管理幀 (MFP) 的 IV 生成。
IEEE80211_KEY_FLAG_GENERATE_IV驅動程式應設定此標誌,以指示它需要此特定金鑰的 IV 生成。設定此標誌並不一定意味著 SKB 將具有足夠的尾部空間用於 ICV 或 MIC。
IEEE80211_KEY_FLAG_GENERATE_MMIC如果 TKIP 金鑰需要在軟體中生成 Michael MIC,驅動程式應設定此標誌。
IEEE80211_KEY_FLAG_PAIRWISE由 mac80211 設定,此標誌指示金鑰是成對金鑰而不是共享金鑰。
IEEE80211_KEY_FLAG_SW_MGMT_TX如果 CCMP/GCMP 金鑰需要在軟體中完成管理幀 (MFP) 的 CCMP/GCMP 加密,驅動程式應設定此標誌。
IEEE80211_KEY_FLAG_PUT_IV_SPACE如果應為 IV 準備空間,但不應生成 IV 本身,驅動程式應設定此標誌。不要與同一金鑰上的 IEEE80211_KEY_FLAG_GENERATE_IV 一起設定。設定此標誌並不一定意味著 SKB 將具有足夠的尾部空間用於 ICV 或 MIC。
IEEE80211_KEY_FLAG_RX_MGMT此金鑰將用於解密收到的管理幀。該標誌可以幫助那些硬體加密實現無法正確處理管理幀的驅動程式,方法是允許它們不將金鑰上傳到硬體並回退到軟體加密。請注意,此標誌僅處理 RX,如果您的加密引擎無法處理 TX,您還可以設定
IEEE80211_KEY_FLAG_SW_MGMT_TX標誌以在 SW 中加密此類幀。IEEE80211_KEY_FLAG_RESERVE_TAILROOM對於金鑰,驅動程式應設定此標誌,以指示必須始終為 ICV 或 MIC 保留足夠的尾部空間,即使啟用了 HW 加密也是如此。
IEEE80211_KEY_FLAG_PUT_MIC_SPACE如果 TKIP 金鑰僅需要 MIC 空間,驅動程式應設定此標誌。不要與同一金鑰上的 IEEE80211_KEY_FLAG_GENERATE_MMIC 一起設定。
IEEE80211_KEY_FLAG_NO_AUTO_TX金鑰需要顯式 Tx 啟用。
IEEE80211_KEY_FLAG_GENERATE_MMIE對於 AES_CMAC 或 AES_GMAC 金鑰,驅動程式應設定此標誌,以指示它僅需要序列號生成
IEEE80211_KEY_FLAG_SPP_AMSDUSPP A-MSDU 可以與此金鑰一起使用 (由 mac80211 從 sta->spp_amsdu 標誌設定)
描述
這些標誌用於驅動程式和 mac80211 之間關於金鑰的通訊,使用 struct ieee80211_key_conf 的 flags 引數。
-
struct ieee80211_key_conf¶
金鑰資訊
定義:
struct ieee80211_key_conf {
atomic64_t tx_pn;
u32 cipher;
u8 icv_len;
u8 iv_len;
u8 hw_key_idx;
s8 keyidx;
u16 flags;
s8 link_id;
u8 keylen;
u8 key[];
};
成員
tx_pn用於 TX 金鑰的 PN,如果驅動程式需要自行進行軟體 PN 分配 (例如,由於 TSO),也可以由驅動程式使用
密碼金鑰的密碼套件選擇器。
icv_len此金鑰型別的 ICV 長度
iv_len此金鑰型別的 IV 長度
hw_key_idx要由驅動程式設定,這是驅動程式希望在傳輸幀並需要在硬體中加密時給出的金鑰索引。
keyidx金鑰索引 (0-7)
標誌金鑰標誌,請參閱
enum ieee80211_key_flags。link_id鏈路 ID,對於非 MLO 為 0,對於成對金鑰為 -1
keylen金鑰材料長度
金鑰金鑰材料。對於 ALG_TKIP,金鑰編碼為 256 位 (32 位元組) 資料塊:- 臨時加密金鑰 (128 位) - 臨時身份驗證器 Tx MIC 金鑰 (64 位) - 臨時身份驗證器 Rx MIC 金鑰 (64 位)
描述
此金鑰資訊由 mac80211 透過 struct ieee80211_ops 中的 set_key() 回撥提供給驅動程式。
-
enum set_key_cmd¶
金鑰命令
常量
SET_KEY設定金鑰
DISABLE_KEY必須停用金鑰
描述
與 struct ieee80211_ops 中的 set_key() 回撥一起使用,這指示金鑰是被刪除還是被新增。
-
void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf, u32 iv32, u16 *p1k)¶
獲取 IV32 的 TKIP 第 1 階段金鑰
引數
struct ieee80211_key_conf *keyconf與設定金鑰一起傳遞的引數
u32 iv32要為其獲取 P1K 的 IV32
u16 *p1k將向其寫入金鑰的緩衝區,作為 5 個 u16 值
描述
此函式返回給定 IV32 的 TKIP 第 1 階段金鑰。
-
void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf, struct sk_buff *skb, u16 *p1k)¶
獲取 TKIP 第 1 階段金鑰
引數
struct ieee80211_key_conf *keyconf與設定金鑰一起傳遞的引數
struct sk_buff *skb要從中獲取 IV32 值的資料包,該值將使用此 P1K 加密
u16 *p1k將向其寫入金鑰的緩衝區,作為 5 個 u16 值
描述
此函式返回從給定資料包中獲取的 IV32 的 TKIP 第 1 階段金鑰。
-
void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, struct sk_buff *skb, u8 *p2k)¶
獲取 TKIP 第 2 階段金鑰
引數
struct ieee80211_key_conf *keyconf與設定金鑰一起傳遞的引數
struct sk_buff *skb要從中獲取 IV32/IV16 值的資料包,該值將使用此金鑰加密
u8 *p2k將向其寫入金鑰的緩衝區,16 位元組
描述
此函式計算資料包中 IV 值的 TKIP RC4 金鑰。
省電支援¶
mac80211 支援各種省電實現。
首先,它可以支援自行處理所有省電的硬體;此類硬體應簡單地設定 IEEE80211_HW_SUPPORTS_PS 硬體標誌。在這種情況下,它將被告知所需的省電模式,其中 IEEE80211_CONF_PS 標誌取決於關聯狀態。硬體必須在必要時傳送 nullfunc 幀,即在進入和離開省電模式時。硬體需要檢視信標中的 AID,並在找到定向到它的流量時向 AP 發出它已喚醒的訊號。
啟用的 IEEE80211_CONF_PS 標誌意味著啟用了 IEEE 802.11-2007 第 11.2 節中定義的省電模式。這不應與硬體喚醒和睡眠狀態混淆。驅動程式負責在向硬體發出命令之前喚醒硬體,並在適當的時間將其恢復睡眠狀態。
啟用 PS 後,硬體需要喚醒以接收信標,並在信標後接收緩衝的多播/廣播幀。此外,必須可以傳送幀並接收確認幀。
其他硬體設計無法自行傳送 nullfunc 幀,還需要軟體支援來解析 TIM 點陣圖。mac80211 透過組合 IEEE80211_HW_SUPPORTS_PS 和 IEEE80211_HW_PS_NULLFUNC_STACK 標誌來支援這一點。當然,仍然需要硬體來傳遞信標。硬體仍然需要處理為多播流量喚醒;如果它不能,驅動程式必須儘可能地處理它;mac80211 太慢而無法做到這一點。
動態省電是正常省電的擴充套件,其中硬體在傳送幀後保持喚醒使用者指定的時間段,以便無需緩衝回覆幀,因此不會延遲到下一次喚醒。這是在存在資料流量時獲得足夠好的延遲,並且在空閒期間仍然顯著節省電量的一種折衷方案。
動態省電只需透過 mac80211 基於流量啟用和停用 PS 來支援。驅動程式只需要設定 IEEE80211_HW_SUPPORTS_PS 標誌,mac80211 將自動處理一切。此外,具有動態 PS 功能支援的硬體可以設定 IEEE80211_HW_SUPPORTS_DYNAMIC_PS 標誌,以指示它可以自行支援動態 PS 模式。驅動程式需要檢視 dynamic_ps_timeout 硬體配置值,並在設定 IEEE80211_CONF_PS 時使用該值。在這種情況下,mac80211 將停用堆疊中的動態 PS 功能,並且只要使用者啟用了省電,就會保持 IEEE80211_CONF_PS 啟用。
驅動程式透過啟用 IEEE80211_VIF_SUPPORTS_UAPSD 標誌來通知 U-APSD 客戶端支援。該模式透過 conf_tx() 操作中的 uapsd 引數進行配置。硬體需要傳送 QoS Nullfunc 幀,並保持喚醒狀態直到服務期結束。要利用 U-APSD,voip AC 的動態省電將被停用,並且來自該 AC 的所有幀都將在啟用省電的情況下傳輸。
注意:IEEE80211_HW_PS_NULLFUNC_STACK 尚不支援 U-APSD 客戶端模式。
信標過濾器支援¶
某些硬體具有信標過濾器支援,以減少主機 CPU 喚醒,這將降低系統功耗。它通常的工作方式是韌體建立信標的校驗和,但省略所有不斷變化的元素 (TSF、TIM 等)。每當校驗和更改時,信標都會轉發到主機,否則它將被丟棄。這樣,主機將僅接收其中某些相關資訊 (例如 ERP 保護或 WMM 設定) 已更改的信標。
信標過濾器支援透過 IEEE80211_VIF_BEACON_FILTER 介面功能進行廣播。每當啟用省電時,驅動程式都需要啟用信標過濾器支援,即設定 IEEE80211_CONF_PS。啟用省電後,堆疊將不檢查信標丟失,並且驅動程式需要透過 ieee80211_beacon_loss() 通知信標丟失。
在韌體通知驅動程式信標丟失事件之前的時間 (或錯過的信標數量) (這反過來會導致驅動程式呼叫 ieee80211_beacon_loss()) 應該是可配置的,並且將來將由 mac80211 和漫遊演算法控制。
由於可能存在軟體堆疊中沒有任何內容關心的不斷變化的資訊元素,因此在將來,我們將讓 mac80211 告訴驅動程式哪些資訊元素是有趣的,因為我們希望看到其中的更改。這將包括
資訊元素 ID 列表
供應商資訊元素的 OUI 列表
理想情況下,硬體將過濾掉任何未請求元素中發生更改的信標,但如果它無法支援這一點,則可能會以犧牲一些效率為代價,僅過濾掉一個子集。例如,如果裝置不支援檢查 OUI,它應該傳遞所有供應商資訊元素中的所有更改。
請注意,為簡化起見,更改還包括資訊元素從信標中出現或消失。
某些硬體支援“忽略列表”來代替。只需確保忽略列表中沒有任何請求的內容,並在忽略列表中包含常用更改的資訊元素 ID,例如 11 (BSS 負載) 和具有未知內容的各種供應商分配的 IE (128、129、133-136、149、150、155、156、173、176、178、179、219);為了向前相容,它還可以包括一些當前未使用的 ID。
除了這些功能之外,硬體還應該支援通知主機信標 RSSI 的更改。這與在沒有流量流動時實施漫遊相關 (當流量流動時,我們會看到收到的資料包的 RSSI)。這可以包括在 RSSI 顯著變化或低於或高於可配置閾值時通知主機。將來,這些閾值也將由 mac80211 (從使用者空間獲取它們) 配置,以根據漫遊演算法的要求實施它們。
如果硬體無法實現這一點,驅動程式應要求它定期將信標幀傳遞給主機,以便軟體可以進行訊號強度閾值檢查。
-
void ieee80211_beacon_loss(struct ieee80211_vif *vif)¶
通知硬體未接收到信標
引數
struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標。
描述
當使用 IEEE80211_VIF_BEACON_FILTER 啟用信標過濾並設定 IEEE80211_CONF_PS 時,只要硬體未使用此函式接收到信標,驅動程式就需要通知。
多個佇列和 QoS 支援¶
待定
-
struct ieee80211_tx_queue_params¶
傳輸佇列配置
定義:
struct ieee80211_tx_queue_params {
u16 txop;
u16 cw_min;
u16 cw_max;
u8 aifs;
bool acm;
bool uapsd;
bool mu_edca;
struct ieee80211_he_mu_edca_param_ac_rec mu_edca_param_rec;
};
成員
txop最大突發時間,單位為 32 微秒,0 表示停用
cw_min最小競爭視窗 [範圍 1..32767 中形式為 2^n-1 的值]
cw_max最大競爭視窗 [如 cw_min]
aifs仲裁幀間間距 [0..255]
acm訪問類別是否需要強制准入控制
uapsd是否為佇列啟用 U-APSD 模式
mu_edca是否配置了 MU EDCA
mu_edca_param_recHE 的 MU EDCA 引數記錄
描述
QoS 傳輸佇列配置需要此結構中提供的資訊。Cf. IEEE 802.11 7.3.2.29。
接入點模式支援¶
待定
應在此處討論 if_conf 的某些部分
在此處或在 hw 加密章節中插入有關帶有 hw 加密的 VLAN 介面的說明。
對省電客戶端的支援¶
為了實現 AP 和 P2P GO 模式,mac80211 支援客戶端節能,包括“傳統”PS(PS-Poll/null data)和 uAPSD。目前不支援 sAPSD。
mac80211 有一個假設,即客戶端不會同時使用 PS-Poll 進行輪詢和使用 uAPSD 進行觸發。兩者都受支援,並且可以由同一客戶端使用,但不能由同一客戶端同時使用。這簡化了驅動程式程式碼。
首先要記住的是,有一個用於完整驅動程式實現的標誌:IEEE80211_HW_AP_LINK_PS。如果設定了此標誌,mac80211 會期望驅動程式處理大多數節能客戶端的狀態機,並且會忽略傳入幀中的 PM 位。然後,驅動程式使用 ieee80211_sta_ps_transition() 來通知 mac80211 站點的節能轉換。在此模式下,mac80211 也不處理 PS-Poll/uAPSD。
在沒有 IEEE80211_HW_AP_LINK_PS 的模式下,mac80211 將檢查傳入幀中的 PM 位以進行客戶端節能轉換。當站點進入睡眠狀態時,我們將停止向其傳輸資料。但是,存在競爭條件:在硬體佇列上有資料緩衝時,站點可能會進入睡眠狀態。如果裝置支援此功能,它將拒絕幀,並且驅動程式應將帶有 IEEE80211_TX_STAT_TX_FILTERED 標誌的幀返回給 mac80211,這將導致 mac80211 在站點喚醒時重試該幀。驅動程式還會透過呼叫其 sta_notify 回撥來收到節能轉換的通知。
當站點處於睡眠狀態時,它有三個選擇:它可以喚醒、可以使用 PS-Poll 進行輪詢,或者可以啟動 uAPSD 服務週期。喚醒是透過簡單地將所有緩衝的(和過濾的)幀傳輸到站點來實現的。這是最簡單的情況。當站點發送 PS-Poll 或 uAPSD 觸發幀時,mac80211 將透過 allow_buffered_frames 回撥通知驅動程式;此回撥是可選的。然後,mac80211 將像往常一樣傳輸幀,並在每個幀上設定 IEEE80211_TX_CTL_NO_PS_BUFFER。服務週期中的最後一個幀(或對 PS-Poll 的唯一響應)也設定了 IEEE80211_TX_STATUS_EOSP,以指示它結束了服務週期;由於此幀必須具有 TX 狀態報告,因此它還會設定 IEEE80211_TX_CTL_REQ_TX_STATUS。當報告此幀的 TX 狀態時,服務週期將被標記為已結束,並且對等方可以啟動新的服務週期。
此外,mac80211 還可以傳輸帶有 IEEE80211_TX_CTL_NO_PS_BUFFER 的不可緩衝 MMPDU。
在某些裝置(如 iwlwifi)上,當有幀在佇列中等待站點並且站點喚醒或輪詢時,可能會出現另一個競爭條件;已經排隊的幀最終可能會首先被傳輸,從而導致 EOSP 的重新排序和/或錯誤處理。原因是允許將幀傳輸到特定站點的行為是與裝置的帶外通訊。為了解決此問題,如果站點進入睡眠狀態時有幀被緩衝,驅動程式可以呼叫 ieee80211_sta_block_awake()。當所有這些幀都被過濾(參見上文)時,它必須再次呼叫該函式以指示該站點不再被阻止。
如果驅動程式以任何方式緩衝驅動程式中的幀以進行聚合,則當收到站點進入睡眠狀態的通知時,它必須使用 ieee80211_sta_set_buffered() 呼叫來通知 mac80211 哪些 TID 有幀緩衝。請注意,當站點喚醒時,此資訊會被重置(因此需要在收到站點進入睡眠狀態的通知時呼叫它)。然後,當任何原因啟動服務週期時,將呼叫 release_buffered_frames,其中包含要釋放的幀數以及要從中釋放幀的 TID。在這種情況下,驅動程式負責在釋放的幀中設定 EOSP(對於 uAPSD)和 MORE_DATA 位。為了提供幫助,more_data 引數被傳遞以告知驅動程式其他 TID 上是否有更多資料——從其釋放幀的 TID 被忽略,因為 mac80211 不知道這些 TID 的緩衝區包含多少幀。
如果驅動程式還實現了 GO 模式,其中不存在週期可能會縮短服務週期(或中止 PS-Poll 響應),則它必須過濾這些響應幀,除非這些幀被緩衝在驅動程式中——這些幀必須保持緩衝以避免重新排序。因為在這種情況下可能沒有幀被釋放,所以驅動程式必須呼叫 ieee80211_sta_eosp() 以指示 mac80211 服務週期無論如何都已結束。
最後,如果從 mac80211 釋放了來自多個 TID 的幀,但驅動程式可能會重新排序它們,則它必須清除並設定相應的標誌(只有最後一個幀可能具有 IEEE80211_TX_STATUS_EOSP),並且還需要注意幀中的 EOSP 和 MORE_DATA 位。驅動程式也可以在這種情況下使用 ieee80211_sta_eosp()。
請注意,如果驅動程式緩衝了除 QoS 資料幀之外的其他幀,則必須注意永遠不要將非 QoS 資料幀作為服務週期中的最後一個幀傳送,如果需要,在非 QoS 資料幀之後新增 QoS 空資料幀。
-
enum ieee80211_frame_release_type¶
幀釋放原因
常量
IEEE80211_FRAME_RELEASE_PSPOLL為 PS-Poll 釋放的幀
IEEE80211_FRAME_RELEASE_UAPSD由於在啟用觸發器的 AC 上接收到幀而釋放的幀
-
int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)¶
已連線站點的 PS 轉換
引數
struct ieee80211_sta *sta當前已連線的站點
bool start啟動或停止 PS
描述
當以 AP 模式執行且設定了 IEEE80211_HW_AP_LINK_PS 標誌時,請使用此函式來通知 mac80211 已連線的站點進入/離開 PS 模式。
不得在 IRQ 上下文中或啟用軟中斷的情況下呼叫此函式。
必須同步針對單個硬體的此函式的呼叫。
返回
成功時返回 0。當請求的 PS 模式已設定時,返回 -EINVAL。
-
int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta, bool start)¶
已連線站點的 PS 轉換(在程序上下文中)
引數
struct ieee80211_sta *sta當前已連線的站點
bool start啟動或停止 PS
描述
與 ieee80211_sta_ps_transition() 類似,但可以在程序上下文中呼叫(內部停用下半部)。併發呼叫限制仍然適用。
返回
-
void ieee80211_sta_set_buffered(struct ieee80211_sta *sta, u8 tid, bool buffered)¶
通知 mac80211 驅動程式緩衝的幀
引數
struct ieee80211_sta *sta睡眠站點的
struct ieee80211_sta指標u8 tid具有緩衝幀的 TID
bool buffered指示是否為此 TID 緩衝了幀
描述
如果驅動程式緩衝了節能站點的幀,而不是將它們傳遞迴 mac80211 以進行重傳,則可能仍然需要透過 TIM 位告知該站點存在緩衝幀。
此函式告知 mac80211 在驅動程式中是否緩衝了給定 TID 的幀;然後,mac80211 可以使用此資料來設定 TIM 位(注意:這可能會回撥到驅動程式的 set_tim 呼叫中!請注意鎖定!)
如果所有幀都已釋放到站點(由於 PS-poll 或 uAPSD),則驅動程式需要通知 mac80211 不再有幀被緩衝。但是,當站點喚醒時,mac80211 假定所有緩衝的幀都將被傳輸並清除此資料,驅動程式需要確保它們在睡眠轉換(sta_notify(),帶有 STA_NOTIFY_SLEEP)時通知 mac80211 所有緩衝的幀。
請注意,從技術上講,mac80211 只需要知道每個 AC(而不是每個 TID)的此資訊,但是由於驅動程式緩衝不可避免地會按 TID 發生(因為它與聚合相關),因此使 mac80211 將 TID 對映到所需的 AC 更容易,而不是在所有使用此 API 的驅動程式中進行跟蹤。
-
struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id)¶
信標生成函式
引數
struct ieee80211_hw *hw從
ieee80211_alloc_hw()獲取的指標。struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標。unsigned int link_id信標所屬的連結 ID(對於未與 AP MLD 關聯的 AP STA,則為 0)。
描述
請參閱 ieee80211_beacon_get_tim()。
返回
請參閱 ieee80211_beacon_get_tim()。
-
struct sk_buff *ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif)¶
訪問緩衝的廣播和多播幀
引數
struct ieee80211_hw *hw從
ieee80211_alloc_hw()獲取的指標。struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標。
描述
用於訪問緩衝的廣播和多播幀的函式。如果硬體/韌體未在節能時實現廣播/多播幀的緩衝,則 802.11 程式碼會將它們緩衝在主機記憶體中。底層驅動程式使用此函式獲取下一個緩衝幀。在大多數情況下,這在生成信標幀時使用。
返回
指向下一個緩衝 skb 的指標,如果沒有更多緩衝幀可用,則為 NULL。
注意
僅在使用 ieee80211_beacon_get() 生成 DTIM 信標幀後才返回緩衝幀,因此底層驅動程式必須首先呼叫 ieee80211_beacon_get()。如果先前生成的信標不是 DTIM,則 ieee80211_get_buffered_bc() 返回 NULL,因此底層驅動程式不需要單獨檢查 DTIM 信標,並且應該能夠對所有信標使用通用程式碼。
-
void ieee80211_sta_block_awake(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, bool block)¶
阻止站點喚醒
引數
struct ieee80211_hw *hw硬體
struct ieee80211_sta *pubsta站點
bool block是否阻止或取消阻止
描述
某些裝置要求在可以將輪詢響應或站點喚醒後的幀傳遞到佇列中之前,必須重新整理特定站點的所有幀。請注意,此類幀必須被驅動程式拒絕為已過濾,並帶有適當的狀態標誌。
此函式允許以無競爭的方式實現此模式。
為此,驅動程式必須跟蹤仍為特定站點排隊的幀數。如果站點進入睡眠狀態時此數字不為零,則驅動程式必須呼叫此函式以強制 mac80211 認為該站點處於睡眠狀態,而不管該站點的實際狀態如何。一旦未完成幀的數量達到零,驅動程式必須再次呼叫此函式以取消阻止該站點。這將導致 mac80211 能夠傳送 ps-poll 響應,並且如果該站點在此期間進行了查詢,則也將傳送幀。此外,無論站點在被阻止時是否實際喚醒,驅動程式都會收到該站點在取消阻止後一段時間喚醒的通知。
-
void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)¶
通知 mac80211 SP 結束
引數
struct ieee80211_sta *pubsta站點
描述
當裝置以一種無法在 TX 狀態下告知 mac80211 EOSP 的方式傳輸幀時,它必須清除 IEEE80211_TX_STATUS_EOSP 位並改為呼叫此函式。這適用於 PS-Poll 以及 uAPSD。
請注意,就像使用 _tx_status() 和 _rx() 一樣,驅動程式不得混合呼叫 irqsafe/non-irqsafe 版本,此函式也不得與這些版本混合使用。使用所有 irqsafe 或所有 non-irqsafe,不要混合使用!
- 注意:此函式的 _irqsafe 版本不存在,目前沒有
驅動程式需要它。如果您需要 _irqsafe 版本,請勿呼叫此函式,檢視 git 歷史記錄並恢復 _irqsafe 版本!
支援多個虛擬介面¶
待定
注意:具有相同 MAC 地址的 WDS 幾乎總是可以的
在此處插入有關具有不同 MAC 地址的多個虛擬介面的註釋,請注意 mac80211 支援哪些配置,新增有關使用它支援硬體加密的註釋。
-
void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data)¶
迭代活動介面
引數
struct ieee80211_hw *hw應該在其上迭代介面的硬體結構
u32 iter_flags迭代標誌,請參閱
enum ieee80211_interface_iteration_flagsvoid (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif)要呼叫的迭代器函式
void *data迭代器函式的第一個引數
描述
此函式迭代與給定硬體關聯的當前活動的介面,併為它們呼叫回撥。當迭代器函式可以休眠時,可以使用原子迭代器函式 ieee80211_iterate_active_interfaces_atomic。在 add_interface() 期間不會迭代新介面。
-
void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data)¶
迭代活動介面
引數
struct ieee80211_hw *hw應該在其上迭代介面的硬體結構
u32 iter_flags迭代標誌,請參閱
enum ieee80211_interface_iteration_flagsvoid (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif)要呼叫的迭代器函式,無法休眠
void *data迭代器函式的第一個引數
描述
此函式迭代與給定硬體關聯的當前活動的介面,併為它們呼叫回撥。此函式要求迭代器回撥函式是原子的,如果不希望這樣,請改用 ieee80211_iterate_active_interfaces。在 add_interface() 期間不會迭代新介面。
站點處理¶
TODO
-
struct ieee80211_sta¶
站點表條目
定義:
struct ieee80211_sta {
u8 addr[ETH_ALEN] ;
u16 aid;
u16 max_rx_aggregation_subframes;
bool wme;
u8 uapsd_queues;
u8 max_sp;
struct ieee80211_sta_rates __rcu *rates;
bool tdls;
bool tdls_initiator;
bool mfp;
bool mlo;
bool spp_amsdu;
u8 max_amsdu_subframes;
u16 eml_cap;
struct ieee80211_sta_aggregates *cur;
bool support_p2p_ps;
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1];
u16 valid_links;
struct ieee80211_link_sta deflink;
struct ieee80211_link_sta __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
u8 drv_priv[] ;
};
成員
addrMAC 地址
aid如果我是 AP,則分配給站點的 AID
max_rx_aggregation_subframes此站點允許傳輸給我們的單個 AMPDU 中的最大幀數。可以由驅動程式修改。
wme指示 STA 是否支援 QoS/WME(如果本地裝置支援,否則始終為 false)
uapsd_queues為 uapsd 配置的佇列的點陣圖。僅當支援 wme 時才有效。位的順序類似於 IEEE80211_WMM_IE_STA_QOSINFO_AC_*。
max_sp最大服務週期。僅當支援 wme 時才有效。
rates速率控制選擇表
tdls指示 STA 是否為 TDLS 對等方
tdls_initiator指示 STA 是否為 TDLS 連結的發起方。僅當 STA 首先是 TDLS 對等方時才有效。
mfp指示 STA 是否使用管理幀保護。
mlo指示 STA 是否為 MLO 站點。
spp_amsdu指示 STA 是否使用 SPP A-MSDU。
max_amsdu_subframes指示單個 A-MSDU 中的 MSDU 最大數量。取自擴充套件功能元素。0 表示無限制。
eml_cap此 MLO 站點的 EML 功能
cur當前有效資料,是從活動連結聚合的。對於非 MLO STA,它將指向 deflink 資料。對於 MLO STA,必須呼叫 ieee80211_sta_recalc_aggregates() 才能更新它。
support_p2p_ps指示 STA 是否支援 P2P PS 機制。
txq每個 TID 資料 TX 佇列;請注意,最後一個條目 (
IEEE80211_NUM_TIDS) 用於非資料幀valid_links有效連結的點陣圖,對於非 MLO,則為 0
deflink這儲存預設連結 STA 資訊,對於非 MLO STA,所有連結特定的 STA 資訊都透過 deflink 或透過指向 deflink 地址的 link[0] 訪問。對於 MLO Link STA,第一個新增的連結 STA 將指向 deflink。
link對 Link Sta 條目的引用。對於 Non MLO STA,除了第一個連結(即 link[0])之外,所有連結預設都將被分配為 NULL,並且將透過 deflink 或 link[0] 訪問連結資訊。對於 MLO STA,正在新增的第一個連結 STA 將其連結指標指向 deflink 地址,其餘連結將被分配,並且該地址將被分配給 link[link_id],其中 link_id 是由 AP 分配的 ID。
drv_priv用於驅動程式使用的資料區域,將始終與 sizeof(void *) 對齊,大小在硬體資訊中確定。
描述
站點表條目表示我們可能與之通訊的站點。由於站點在 mac80211 中是 RCU 管理的,因此您訪問的任何 ieee80211_sta 指標都必須受到 rcu_read_lock() 的顯式或隱式保護,或者您必須注意在呼叫 sta_remove 回撥(已刪除它)後不要使用此類指標。這也表示 MLO 關聯情況下的 MLD STA,並儲存指向各種連結 STA 的指標
-
enum sta_notify_cmd¶
sta 通知命令
常量
STA_NOTIFY_SLEEP站點現在正在睡眠
STA_NOTIFY_AWAKE睡眠站點已喚醒
描述
與 struct ieee80211_ops 中的 sta_notify() 回撥一起使用,指示關聯的站點是否進行了電源狀態轉換。
-
struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr)¶
查詢站點
引數
struct ieee80211_vif *vif在其上查詢站點的虛擬介面
const u8 *addr站點的地址
返回
如果找到,則為站點。否則為 NULL。
注意
此函式必須在 RCU 鎖下呼叫,並且結果指標也僅在 RCU 鎖下有效。
-
struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, const u8 *addr, const u8 *localaddr)¶
在硬體上查詢站點
引數
struct ieee80211_hw *hw從
ieee80211_alloc_hw()獲取的指標const u8 *addr遠端站點地址
const u8 *localaddr本地地址 (vif->sdata->vif.addr)。對於“任意”地址,使用 NULL。
返回
如果找到,則為站點。否則為 NULL。
注意
此函式必須在 RCU 鎖下呼叫,並且結果指標也僅在 RCU 鎖下有效。
注意
- 您可以為 localaddr 傳遞 NULL,但這樣您只能獲得
與遠端地址“addr”匹配的第一個 STA。我們可以有多個 STA 與多個邏輯站相關聯(例如,考慮一個站點在同一 AP 硬體上連線到另一個 BSSID,而無需先斷開連線)。在這種情況下,當 localaddr 為 NULL 時,此方法的結果不可靠。
描述
如果可能,請不要使用 localaddr 為 NULL 的此函式。
硬體掃描解除安裝¶
待定
-
void ieee80211_scan_completed(struct ieee80211_hw *hw, struct cfg80211_scan_info *info)¶
硬體掃描完成
引數
struct ieee80211_hw *hw完成掃描的硬體
struct cfg80211_scan_info *info有關已完成掃描的資訊
描述
當使用硬體掃描解除安裝時(即,已分配 hw_scan() 回撥),驅動程式需要呼叫此函式以通知 mac80211 掃描已完成。可以從任何上下文呼叫此函式,包括硬中斷上下文。
聚合¶
TX A-MPDU 聚合¶
TX 端的聚合需要設定硬體標誌 IEEE80211_HW_AMPDU_AGGREGATION。然後,驅動程式將收到帶有標誌的包,指示 A-MPDU 聚合。驅動程式或裝置負責實際聚合幀,以及決定聚合多少幀和哪些幀。
當 TX 聚合由某些子系統啟動時(通常速率控制演算法是合適的),透過呼叫 ieee80211_start_tx_ba_session() 函式,驅動程式將透過其 ampdu_action 函式收到通知,並帶有 IEEE80211_AMPDU_TX_START 操作。
作為對此的響應,稍後需要驅動程式呼叫 ieee80211_start_tx_ba_cb_irqsafe() 函式,該函式將在對等方也響應後真正啟動聚合會話。如果對等方響應為否定,則會話將立即再次停止。請注意,聚合會話可能在驅動程式指示其已完成設定之前停止,在這種情況下,它不得指示設定完成。
另請注意,由於我們還需要等待來自對等方的響應,因此驅動程式會透過 ampdu_action 回撥的 IEEE80211_AMPDU_TX_OPERATIONAL 操作來通知握手完成。
類似地,當聚合會話被對等方或呼叫 ieee80211_stop_tx_ba_session() 的某些內容停止時,將使用操作 IEEE80211_AMPDU_TX_STOP 呼叫驅動程式的 ampdu_action 函式。在這種情況下,呼叫不得失敗,並且驅動程式稍後必須呼叫 ieee80211_stop_tx_ba_cb_irqsafe()。請注意,sta 可能會在 BA 拆卸完成之前被銷燬。
RX A-MPDU 聚合¶
RX 端的聚合僅需要實現 ampdu_action 回撥,該回調用於啟動/停止 RX 聚合的任何塊確認會話。
當 RX 聚合由對等方啟動時,會透過 ampdu_action 函式收到通知,並帶有 IEEE80211_AMPDU_RX_START 操作,並且可以拒絕該請求,在這種情況下,會向對等方傳送否定響應,如果接受該請求,則傳送肯定響應。
在會話處於活動狀態時,裝置/驅動程式需要取消聚合幀,並將它們逐個傳遞給 mac80211,這將處理重新排序緩衝區。
當聚合會話再次被對等方或我們自己停止時,將使用操作 IEEE80211_AMPDU_RX_STOP 呼叫驅動程式的 ampdu_action 函式。在這種情況下,呼叫不得失敗。
-
enum ieee80211_ampdu_mlme_action¶
A-MPDU 操作
常量
IEEE80211_AMPDU_RX_START啟動 RX 聚合
IEEE80211_AMPDU_RX_STOP停止 RX 聚合
IEEE80211_AMPDU_TX_START啟動 TX 聚合,驅動程式必須呼叫
ieee80211_start_tx_ba_cb_irqsafe()或呼叫ieee80211_start_tx_ba_cb_irqsafe(),狀態為IEEE80211_AMPDU_TX_START_DELAY_ADDBA,以在呼叫 ieee80211_start_tx_ba_cb_irqsafe 後延遲 addba,或者僅返回特殊狀態IEEE80211_AMPDU_TX_START_IMMEDIATE。IEEE80211_AMPDU_TX_STOP_CONT停止 TX 聚合,但繼續傳輸排隊的包,現在未聚合。在傳輸所有包後,驅動程式必須呼叫
ieee80211_stop_tx_ba_cb_irqsafe()。IEEE80211_AMPDU_TX_STOP_FLUSH停止 TX 聚合並重新整理所有包,當刪除站點時呼叫。在這種情況下,無需或沒有理由呼叫
ieee80211_stop_tx_ba_cb_irqsafe(),因為 mac80211 假定會話已消失並刪除站點。IEEE80211_AMPDU_TX_STOP_FLUSH_CONT當停止 TX 聚合但驅動程式尚未呼叫
ieee80211_stop_tx_ba_cb_irqsafe()時,以及現在連線已斷開且站點將被刪除時呼叫。驅動程式應清理並刪除剩餘的包。IEEE80211_AMPDU_TX_OPERATIONALTX 聚合已變為可操作
描述
這些標誌與 struct ieee80211_ops 中的 ampdu_action() 回撥一起使用,以指示所需的操作。
請注意,驅動程式必須能夠處理 TX 聚合會話的停止,即使在他們透過呼叫 ieee80211_start_tx_ba_cb_irqsafe 來確認啟動它之前,因為對等方可能會收到 addBA 幀並立即傳送 delBA!
空間複用省電 (SMPS)¶
SMPS(空間複用省電)是一種在 802.11n 實現中節省電能的機制。有關該機制和基本原理的詳細資訊,請參閱 802.11(由 802.11n-2009 修訂)“11.2.3 SM 省電”。
mac80211 實現能夠傳送操作幀以更新 AP 關於站點的 SMPS 模式,並將指示驅動程式進入特定模式。它還將在關聯握手期間宣佈請求的 SMPS 模式。需要對此功能的硬體支援,並且可以透過硬體標誌指示。
預設模式將為“自動”,nl80211/cfg80211 將其定義為(常規)省電模式下的動態 SMPS,否則 SMPS 將關閉。
為了支援此功能,驅動程式必須設定適當的硬體支援標誌,並將 SMPS 標誌處理到 config() 操作。然後,在此機制下,將指示它在關聯到 HT AP 時進入請求的 SMPS 模式。
-
enum ieee80211_smps_mode¶
空間複用省電模式
常量
IEEE80211_SMPS_AUTOMATIC自動
IEEE80211_SMPS_OFF關閉
IEEE80211_SMPS_STATIC靜態
IEEE80211_SMPS_DYNAMIC動態
IEEE80211_SMPS_NUM_MODES內部,請勿使用
-
void ieee80211_request_smps(struct ieee80211_vif *vif, unsigned int link_id, enum ieee80211_smps_mode smps_mode)¶
請求 SM PS 轉換
引數
struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標。unsigned int link_idMLO 的連結 ID,或 0
enum ieee80211_smps_mode smps_mode新的 SM PS 模式
描述
這允許驅動程式在託管模式下請求 SM PS 轉換。當驅動程式比堆疊具有更多關於可能干擾的資訊時,例如透過藍牙,這非常有用。
待定
本書的這一部分描述了速率控制演算法介面以及它如何與 mac80211 和驅動程式相關。
速率控制 API¶
待定
-
enum ieee80211_rate_control_changed¶
指示更改內容的標誌
常量
IEEE80211_RC_BW_CHANGED可用於傳輸到此站點的頻寬已更改。實際頻寬位於站點資訊中 -- 對於 HT20/40,IEEE80211_HT_CAP_SUP_WIDTH_20_40 標誌會更改,對於 HT 和 VHT,頻寬欄位會更改。
IEEE80211_RC_SMPS_CHANGED站點的 SMPS 狀態已更改。
IEEE80211_RC_SUPP_RATES_CHANGED由於發現有關對等方的更多資訊,此對等方的支援速率集已更改(在 IBSS 模式下)。
IEEE80211_RC_NSS_CHANGEDN_SS(空間流的數量)已由對等方更改
-
int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid, u16 timeout)¶
啟動 tx 塊確認會話。
引數
struct ieee80211_sta *sta要為其啟動 BA 會話的站點
u16 tid要在其上進行 BA 的 TID。
u16 timeout會話超時值(以 TU 為單位)
返回
如果已傳送 addBA 請求,則成功,否則失敗
描述
雖然 mac80211/低階驅動程式/使用者空間應用程式可以估計在特定 RA/TID 上啟動聚合的需要,但會話級別將由 mac80211 管理。
-
void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid)¶
低階驅動程式已準備好聚合。
引數
struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標const u8 *raBA 會話接收者的接收方地址。
u16 tid要在其上進行 BA 的 TID。
描述
一旦低階驅動程式完成 BA 會話的準備工作,就必須呼叫此函式。可以從任何上下文呼叫它。
-
int ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, u16 tid)¶
停止塊確認會話。
引數
struct ieee80211_sta *sta要停止其 BA 會話的站點
u16 tid要停止 BA 的 TID。
返回
如果 TID 無效,或者沒有活動的聚合,則返回負錯誤
描述
雖然 mac80211/低階驅動程式/使用者空間應用程式可以估計在特定 RA/TID 上停止聚合的需要,但會話級別將由 mac80211 管理。
-
void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, u16 tid)¶
低階驅動程式已準備好停止聚合。
引數
struct ieee80211_vif *vif來自 add_interface 回撥的
struct ieee80211_vif指標const u8 *raBA 會話接收者的接收方地址。
u16 tid要在其上進行 BA 的所需 TID。
描述
一旦低階驅動程式完成 BA 會話拆卸的準備工作,就必須呼叫此函式。可以從任何上下文呼叫它。
-
struct ieee80211_tx_rate_control¶
來自/用於 RC 演算法的速率控制資訊
定義:
struct ieee80211_tx_rate_control {
struct ieee80211_hw *hw;
struct ieee80211_supported_band *sband;
struct ieee80211_bss_conf *bss_conf;
struct sk_buff *skb;
struct ieee80211_tx_rate reported_rate;
bool rts, short_preamble;
u32 rate_idx_mask;
u8 *rate_idx_mcs_mask;
bool bss;
};
成員
hw為其呼叫演算法的硬體。
sband正在其上傳送此幀的頻段。
bss_conf當前 BSS 配置
skb將要傳送的 skb,需要在其中填寫控制資訊
reported_rate速率控制演算法可以填寫此項以指示應向用戶空間報告哪個速率作為當前速率,並用於網狀網路中的速率計算。
rts是否將對此幀使用 RTS,因為它長於 RTS 閾值
short_preamble如果所選速率支援短前導碼傳輸,mac80211 是否會請求短前導碼傳輸
rate_idx_mask使用者請求的(舊版)速率掩碼
rate_idx_mcs_mask使用者請求的 MCS 速率掩碼(如果未使用,則為 NULL)
bss此幀是否以 AP 或 IBSS 模式傳送
待定
本書的這一部分描述了 mac80211 內部結構。
金鑰處理¶
金鑰處理基礎知識¶
mac80211 中的金鑰處理基於每個介面 (sub_if_data) 金鑰和每個站點金鑰完成。由於每個站點都屬於一個介面,因此每個站點金鑰也屬於該介面。
硬體加速是以最大努力的方式為軟體中實現的演算法完成的,對於每個金鑰,都會要求硬體啟用該金鑰以進行解除安裝,但如果硬體無法執行此操作,則只會保留該金鑰以進行軟體加密(除非它是用於軟體中未實現的演算法)。目前除了檢視 debugfs 之外,沒有辦法知道金鑰是在 SW 還是 HW 中處理的。
所有金鑰管理都在內部由互斥鎖保護。在 mac80211 的所有其他部分中,金鑰引用就像 STA 結構引用一樣,受到 RCU 的保護。但是請注意,有些事情是不受保護的,即硬體加速函式中的 key->sta 解引用。這意味著 sta_info_destroy() 必須刪除金鑰,該金鑰等待 RCU 寬限期。
更多待定¶
待定
接收處理¶
待定
傳輸處理¶
待定
站點資訊處理¶
程式設計資訊¶
-
enum ieee80211_sta_info_flags¶
站點標誌
常量
WLAN_STA_AUTH站點已透過身份驗證。
WLAN_STA_ASSOC站點已關聯。
WLAN_STA_PS_STA站點處於省電模式
WLAN_STA_AUTHORIZED站點已授權傳送/接收流量。始終檢查此位,因此對於未使用虛擬埠控制的所有站點都需要啟用此位。
WLAN_STA_SHORT_PREAMBLE站點能夠接收短前導碼幀。
WLAN_STA_WDS站點是我們 WDS 對等方之一。
WLAN_STA_CLEAR_PS_FILT當向此站點發送下一個幀時,清除硬體中的 PS 過濾器(使用 IEEE80211_TX_CTL_CLEAR_PS_FILT 控制標誌)。
WLAN_STA_MFP管理幀保護用於此 STA。
WLAN_STA_BLOCK_BA用於在掛起/恢復和站點移除期間拒絕 ADDBA 請求(TX 和 RX)。
WLAN_STA_PS_DRIVER驅動程式需要邏輯上將此站點保持在省電模式,以重新整理可能仍在佇列中的幀
WLAN_STA_PSPOLL當驅動程式將站點保持在省電模式時,站點發送了 PS-poll,在驅動程式解除阻塞時回覆。
WLAN_STA_TDLS_PEER站點是 TDLS 對等方。
WLAN_STA_TDLS_PEER_AUTH此 TDLS 對等方已授權傳送直接資料包。這意味著已啟用連結。
WLAN_STA_TDLS_INITIATOR我們是與此站點的 TDLS 連結的發起者。
WLAN_STA_TDLS_CHAN_SWITCH此 TDLS 對等方支援 TDLS 通道切換
WLAN_STA_TDLS_OFF_CHANNEL本地 STA 當前與此 TDLS 對等方斷開通道
WLAN_STA_TDLS_WIDER_BW此 TDLS 對等方支援在 BSS 基本通道上使用更寬的 bw。
WLAN_STA_UAPSD當驅動程式將站點保持在省電模式時,站點請求了計劃外的 SP,在驅動程式解除阻塞站點時回覆。
WLAN_STA_SP站點處於服務期,因此不要嘗試回覆其他 uAPSD 觸發幀或 PS-Poll。
WLAN_STA_4ADDR_EVENT已為此幀傳送了 4 地址事件。
WLAN_STA_INSERTED此站點已插入到雜湊表中。
WLAN_STA_RATE_CONTROL已為此站點初始化速率控制。
WLAN_STA_TOFFSET_KNOWN為此站點計算的 toffset 有效。
WLAN_STA_MPSP_OWNER本地 STA 是網狀網路對等方服務期的所有者。
WLAN_STA_MPSP_RECIPIENT本地 STA 是 MPSP 的接收者。
WLAN_STA_PS_DELIVER站點已喚醒,但在傳送掛起的幀之前,我們仍在阻止 TX
WLAN_STA_USES_ENCRYPTION此站點配置為加密,因此稍後會刪除所有沒有金鑰的資料包。
WLAN_STA_DECAP_OFFLOAD此站點使用 rx 解封裝解除安裝
NUM_WLAN_STA_FLAGS已定義的標誌數
描述
這些標誌與 struct sta_info 的 flags 成員一起使用,但僅間接與 set_sta_flag() 及其朋友一起使用。
-
struct sta_info¶
STA 資訊
定義:
struct sta_info {
struct list_head list, free_list;
struct rcu_head rcu_head;
struct rhlist_head hash_node;
u8 addr[ETH_ALEN];
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS];
u8 ptk_idx;
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
spinlock_t rate_ctrl_lock;
spinlock_t lock;
struct ieee80211_fast_tx __rcu *fast_tx;
struct ieee80211_fast_rx __rcu *fast_rx;
#ifdef CONFIG_MAC80211_MESH;
struct mesh_sta *mesh;
#endif;
struct work_struct drv_deliver_wk;
u16 listen_interval;
bool dead;
bool removed;
bool uploaded;
enum ieee80211_sta_state sta_state;
unsigned long _flags;
spinlock_t ps_lock;
struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
unsigned long driver_buffered_tids;
unsigned long txq_buffered_tids;
u64 assoc_at;
long last_connected;
__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
struct airtime_info airtime[IEEE80211_NUM_ACS];
u16 airtime_weight;
struct sta_ampdu_mlme ampdu_mlme;
#ifdef CONFIG_MAC80211_DEBUGFS;
struct dentry *debugfs_dir;
#endif;
u8 reserved_tid;
s8 amsdu_mesh_control;
struct cfg80211_chan_def tdls_chandef;
struct ieee80211_fragment_cache frags;
struct ieee80211_sta_aggregates cur;
struct link_sta_info deflink;
struct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
struct ieee80211_sta sta;
};
成員
list全域性連結串列條目
free_list用於跟蹤要釋放的站點的列表條目
rcu_head用於釋放此站點結構的 RCU 頭
hash_node用於 rhashtable 的雜湊節點
addr站點的 MAC 地址 - 從公共部分複製,以便雜湊表僅使用單個快取行
local指向全域性資訊的指標
sdata此站點所屬的虛擬介面
ptk與此站點協商的對等方金鑰(如果有)
ptk_idx上次安裝的對等方金鑰索引
rate_ctrl速率控制演算法引用
rate_ctrl_priv每個 STA 的速率控制私有指標
rate_ctrl_lock用於保護速率控制資料的自旋鎖(演算法內部的資料,因此序列化對演算法的呼叫)
lock用於鎖定所有需要鎖定的欄位,請參閱標頭檔案中的註釋。
fast_txTX 快速路徑資訊
fast_rxRX 快速路徑資訊
mesh網狀網路 STA 資訊
drv_deliver_wk用於在驅動程式 PS 解除阻塞後傳送幀
listen_interval此站點的偵聽間隔,當我們充當 AP 時
dead當 sta 取消連結時設定為 true
removed當 sta 從 sta_list 中刪除時設定為 true
uploaded當 sta 上傳到驅動程式時設定為 true
sta_state複製有關站點狀態的資訊(用於除錯)
_flagsSTA 標誌,請參閱
enum ieee80211_sta_info_flags,請勿直接使用ps_lock用於省電(當 mac80211 是 AP 時)相關的鎖定
ps_tx_buf當站點離開省電狀態或輪詢時,要傳輸到此站點的幀緩衝區(每個 AC)
tx_filtered由於 STA 已進入省電狀態,我們已嘗試傳輸但被硬體過濾的幀緩衝區(每個 AC),當站點離開省電狀態或輪詢幀時,這些幀也會傳遞到站點
driver_buffered_tids驅動程式已緩衝資料的 TID 點陣圖
txq_buffered_tidsmac80211 已緩衝 txq 資料的 TID 點陣圖
assoc_at上次關聯的時鐘啟動時間(以納秒為單位)
last_connected站點連線的時間(以秒為單位)
last_seq_ctrl來自此 STA 的上次接收的 seq/frag 編號(每個 TID 加一表示非 QoS 幀)
tid_seq用於傳送到此 STA 的每個 TID 的序列號
airtime每個 AC 的 struct airtime_info,描述此站點的空口時間統計資訊
airtime_weight用於空口時間公平性計算目的的站點權重
ampdu_mlmeA-MPDU 狀態機狀態
debugfs_dir除錯檔案系統目錄 dentry
reserved_tid保留的 TID(如果有,否則為 IEEE80211_TID_UNRESERVED)
amsdu_mesh_control跟蹤對等方使用的網狀網路 A-MSDU 格式
-1:未知
0:非網狀網路 A-MSDU 長度欄位
1:大端網狀網路 A-MSDU 長度欄位
2:小端網狀網路 A-MSDU 長度欄位
tdls_chandefTDLS 對等方可以具有與 BSS 相容的更寬的 chandef。
frags片段快取
cur用於聚合資料的儲存
struct ieee80211_sta指向此處或 deflink.agg。deflink這是預設的連結 STA 資訊,對於非 MLO STA,所有連結特定的 STA 資訊都透過 deflink 或透過指向 deflink 地址的 link[0] 訪問。對於 MLO 連結 STA,第一個新增的連結 STA 將指向 deflink。
link對 Link Sta 條目的引用。對於 Non MLO STA,除了第一個連結(即 link[0])之外,所有連結預設都將被分配為 NULL,並且將透過 deflink 或 link[0] 訪問連結資訊。對於 MLO STA,正在新增的第一個連結 STA 將其連結指標指向 deflink 地址,其餘連結將被分配,並且該地址將被分配給 link[link_id],其中 link_id 是由 AP 分配的 ID。
sta我們與驅動程式共享的站點資訊
描述
此結構收集有關 mac80211 正在與其通訊的站點的資訊。
STA 資訊生存期規則¶
STA 資訊結構 (struct sta_info) 在雜湊表中管理,以便更快地查詢,並在列表中管理,以便進行迭代。它們使用 RCU 進行管理,即對列表和雜湊表的訪問受到 RCU 的保護。
在透過 sta_info_alloc() 分配 STA 資訊結構時,呼叫者擁有該結構。然後,它必須使用 sta_info_insert() 或 sta_info_insert_rcu() 將其插入到雜湊表中;只有在後一種情況下(這會獲取 rcu 讀取節,但不得從中呼叫),指標在呼叫後仍然有效。請注意,呼叫者在插入之前可能無法對 STA 資訊執行太多操作;特別是,它可能不會啟動任何網狀網路對等方連結管理或新增加密金鑰。
當插入失敗時 (sta_info_insert()) 返回非零值),該結構將已被 sta_info_insert() 釋放!
當您與對等方建立連結時,mac80211 會新增站點條目。這意味著對於我們支援的不同型別的介面,意義有所不同。對於常規站點,這意味著我們在收到來自 AP 的關聯響應時新增 AP sta。對於 IBSS,這發生在瞭解同一 IBSS 上的對等方時。對於 WDS,我們在裝置開啟時立即新增對等方的 sta。當使用 AP 模式時,我們在使用者空間透過 nl80211 請求後,為每個站點新增站點。
為了刪除 STA 資訊結構,可以使用各種 sta_info_destroy_*() 呼叫。
STA 條目沒有所有權的概念;每個結構都由全域性雜湊表/列表擁有,直到它被刪除。結構的所有使用者都需要受到 RCU 保護,以便在他們完成使用該結構之前不會釋放該結構。
聚合函式¶
-
struct tid_ampdu_tx¶
TID 聚合資訊 (Tx)。
定義:
struct tid_ampdu_tx {
struct rcu_head rcu_head;
struct timer_list session_timer;
struct timer_list addba_resp_timer;
struct sk_buff_head pending;
struct sta_info *sta;
unsigned long state;
unsigned long last_tx;
u16 timeout;
u8 dialog_token;
u8 stop_initiator;
bool tx_stop;
u16 buf_size;
u16 ssn;
u16 failed_bar_ssn;
bool bar_pending;
bool amsdu;
u8 tid;
};
成員
rcu_head用於釋放結構的 rcu 頭
session_timer檢查我們是否保持在 TID 上 Tx-ing(按超時值)
addba_resp_timer用於對等方對 addba 請求的響應的計時器
pending掛起的幀佇列 -- 使用 sta 的自旋鎖進行保護
stastation we are attached to
statesession state (see above)
last_txjiffies of last tx activity
timeoutsession timeout value to be filled in ADDBA requests
dialog_tokendialog token for aggregation session
stop_initiatorinitiator of a session stop
tx_stopTX DelBA frame when stopping
buf_sizereorder buffer size at receiver
ssnstarting sequence number of the session
failed_bar_ssnssn of the last failed BAR tx attempt
bar_pendingBAR needs to be re-sent
amsdusupport A-MSDU within A-MDPU
tidTID number
描述
This structure’s lifetime is managed by RCU, assignments to the array holding it must hold the aggregation mutex.
The TX path can access it under RCU lock-free if, and only if, the state has the flag HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path must also acquire the spinlock and re-check the state, see comments in the tx code touching it.
-
struct tid_ampdu_rx¶
TID aggregation information (Rx).
定義:
struct tid_ampdu_rx {
struct rcu_head rcu_head;
spinlock_t reorder_lock;
u64 reorder_buf_filtered;
struct sk_buff_head *reorder_buf;
unsigned long *reorder_time;
struct sta_info *sta;
struct timer_list session_timer;
struct timer_list reorder_timer;
unsigned long last_rx;
u16 head_seq_num;
u16 stored_mpdu_num;
u16 ssn;
u16 buf_size;
u16 timeout;
u8 tid;
u8 auto_seq:1,removed:1, started:1;
};
成員
rcu_headRCU head used for freeing this struct
reorder_lockserializes access to reorder buffer, see below.
reorder_buf_filteredbitmap indicating where there are filtered frames in the reorder buffer that should be ignored when releasing frames
reorder_bufbuffer to reorder incoming aggregated MPDUs. An MPDU may be an A-MSDU with individually reported subframes.
reorder_timejiffies when skb was added
stastation we are attached to
session_timercheck if peer keeps Tx-ing on the TID (by timeout value)
reorder_timerreleases expired frames from the reorder buffer.
last_rxjiffies of last rx activity
head_seq_numhead sequence number in reordering buffer.
stored_mpdu_numnumber of MPDUs in reordering buffer
ssnStarting Sequence Number expected to be aggregated.
buf_sizebuffer size for incoming A-MPDUs
timeoutreset timer value (in TUs).
tidTID number
auto_seqused for offloaded BA sessions to automatically pick head_seq_and and ssn.
removedthis session is removed (but might have been found due to RCU)
startedthis session has started (head ssn or higher was received)
描述
This structure’s lifetime is managed by RCU, assignments to the array holding it must hold the aggregation mutex.
The reorder_lock is used to protect the members of this struct, except for timeout, buf_size and dialog_token, which are constant across the lifetime of the struct (the dialog token being used only for debugging).
-
struct sta_ampdu_mlme¶
STA aggregation information.
定義:
struct sta_ampdu_mlme {
struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS];
u8 tid_rx_token[IEEE80211_NUM_TIDS];
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
unsigned long tid_rx_manage_offl[BITS_TO_LONGS(2 * IEEE80211_NUM_TIDS)];
unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
struct wiphy_work work;
struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
struct tid_ampdu_tx *tid_start_tx[IEEE80211_NUM_TIDS];
unsigned long last_addba_req_time[IEEE80211_NUM_TIDS];
u8 addba_req_num[IEEE80211_NUM_TIDS];
u8 dialog_token_allocator;
};
成員
tid_rxaggregation info for Rx per TID -- RCU protected
tid_rx_tokendialog tokens for valid aggregation sessions
tid_rx_timer_expiredbitmap indicating on which TIDs the RX timer expired until the work for it runs
tid_rx_stop_requestedbitmap indicating which BA sessions per TID the driver requested to close until the work for it runs
tid_rx_manage_offlbitmap indicating which BA sessions were requested to be treated as started/stopped due to offloading
agg_session_validbitmap indicating which TID has a rx BA session open on
unexpected_aggbitmap indicating which TID already sent a delBA due to unexpected aggregation related frames outside a session
workwork struct for starting/stopping aggregation
tid_txaggregation info for Tx per TID
tid_start_txsessions where start was requested, not just protected by wiphy mutex but also sta->lock
last_addba_req_timetimestamp of the last addBA request.
addba_req_numnumber of times addBA request has been sent.
dialog_token_allocatordialog token enumerator for each new session;
Synchronisation Functions¶
待定
Locking, lots of RCU