mac80211 子系統(基礎)

在實現 mac80211 驅動程式時,您應該閱讀並理解本書此部分中包含的資訊。在某些章節中,會註明高階用法,如果不需要,可以跳過這些內容。

本書的這一部分僅涵蓋站點和監控模式功能,實現其他模式所需的其他資訊將在本書的第二部分中介紹。

基本硬體處理

待定

本章將包含有關獲取 hw 結構並將其註冊到 mac80211 的資訊。

由於需要在註冊 hw 結構之前分配速率/模式,因此本章還將包含有關設定速率/模式結構的資訊。

此外,還應在此處討論回撥和一般程式設計模型,包括 ieee80211_ops 的定義,這將經常被引用。

最後,應該參考本書的其他部分來討論硬體功能。

enum ieee80211_hw_flags

硬體標誌

常量

IEEE80211_HW_HAS_RATE_CONTROL

硬體或韌體包括速率控制,並且不能由堆疊控制。因此,不應例項化速率控制演算法,並且報告給使用者空間的 TX 速率將從 TX 狀態獲取,而不是從速率控制演算法獲取。請注意,這需要驅動程式實現一些回撥,以便它具有正確的資訊,它需要具有 set_rts_threshold 回撥,並且必須檢視 BSS 配置 use_cts_prot 以進行 G/N 保護,use_short_slot 以進行 2.4 GHz 中的時隙定時,以及 use_short_preamble 以進行 CCK 幀的前導碼。

IEEE80211_HW_RX_INCLUDES_FCS

指示傳遞給堆疊的接收幀在末尾包含 FCS。

IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING

某些無線 LAN 晶片組在硬體/韌體中緩衝省電站的廣播/多播幀,而另一些則依賴於主機系統進行此類緩衝。此選項用於配置 IEEE 802.11 上層,以便在有省電站時緩衝廣播和多播幀,以便驅動程式可以使用 ieee80211_get_buffered_bc() 獲取它們。

IEEE80211_HW_SIGNAL_UNSPEC

硬體可以提供訊號值,但我們不知道它的單位。我們期望的值介於 0 和 max_signal 之間。如果可能,請提供 dB 或 dBm。

IEEE80211_HW_SIGNAL_DBM

硬體以 dBm(分貝差,以一毫瓦為基準)給出訊號值。這是首選方法,因為它在不同的裝置之間是標準化的。不需要設定 max_signal

IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC

此裝置需要在關聯之前從信標獲取資料(即 dtim_period)。

IEEE80211_HW_SPECTRUM_MGMT

硬體支援 802.11h 中定義的頻譜管理:測量、通道切換、靜默、TPC

IEEE80211_HW_AMPDU_AGGREGATION

硬體支援 11n A-MPDU 聚合。

IEEE80211_HW_SUPPORTS_PS

硬體具有省電支援(即可以進入睡眠狀態)。

IEEE80211_HW_PS_NULLFUNC_STACK

硬體需要在堆疊中進行 nullfunc 幀處理,這意味著堆疊支援動態 PS。

IEEE80211_HW_SUPPORTS_DYNAMIC_PS

硬體支援動態 PS。

IEEE80211_HW_MFP_CAPABLE

硬體支援管理幀保護(MFP,IEEE 802.11w)。

IEEE80211_HW_WANT_MONITOR_VIF

當監控介面是唯一活動的介面時,驅動程式希望收到虛擬監控介面的通知。

IEEE80211_HW_NO_VIRTUAL_MONITOR

驅動程式希望收到任何監控介面以及其配置的通道的通知。這對於在不同通道上支援多個監控介面很有用。

IEEE80211_HW_NO_AUTO_VIF

驅動程式希望不建立 wlanX。預計使用者空間會根據需要建立 vif(因此可以根據需要命名它們)。

IEEE80211_HW_SW_CRYPTO_CONTROL

驅動程式想要控制哪些加密演算法可以在軟體中完成 - 因此如果硬體加密失敗,不要自動嘗試回退到它,而是僅當驅動程式返回 1 時才這樣做。這也會強制驅動程式公佈其支援的密碼套件。

IEEE80211_HW_SUPPORT_FAST_XMIT

驅動程式/硬體支援快速傳輸,目前僅需要計算幀的持續時間的能力。

IEEE80211_HW_REPORTS_TX_ACK_STATUS

硬體可以向堆疊提供 Tx 幀的 ack 狀態報告。

IEEE80211_HW_CONNECTION_MONITOR

硬體執行自己的連線監控,包括定期向 AP 傳送保持活動訊號以及在信標丟失時探測 AP。

IEEE80211_HW_QUEUE_CONTROL

驅動程式想要控制每個介面的佇列對映,以便為不同的虛擬介面使用不同的佇列(不僅僅是每個 AC 一個)。有關更多詳細資訊,請參閱有關 HW 佇列控制的文件部分。

IEEE80211_HW_SUPPORTS_PER_STA_GTK

該裝置的加密引擎支援 IBSS RSN 或快速轉換期間使用的每個站點的 GTK。如果該裝置不支援每個站點的 GTK,但可以要求不解密組定址幀,則仍然可以使用 IBSS RSN 支援,但將使用軟體加密。僅在這種情況下才公佈 wiphy 標誌。

IEEE80211_HW_AP_LINK_PS

在 AP 模式下執行時,該裝置自主管理連線站點的 PS 狀態。設定此標誌後,mac80211 將不會根據傳入幀的 PM 位觸發連線站點的 PS 模式。使用 ieee80211_start_ps()/ieee8021_end_ps() 手動配置連線站點的 PS 模式。

IEEE80211_HW_TX_AMPDU_SETUP_IN_HW

該裝置嚴格在 HW 中處理 TX A-MPDU 會話設定。mac80211 不應嘗試在軟體中執行此操作。

IEEE80211_HW_SUPPORTS_RC_TABLE

驅動程式支援使用速率控制演算法提供的速率選擇表。

IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF

對任何 P2P 介面使用 P2P 裝置地址。即使支援多個介面,也會遵守此設定。

IEEE80211_HW_TIMING_BEACON_ONLY

僅使用來自信標幀的同步定時,以允許獲取 DTIM 信標的 TBTT。

IEEE80211_HW_SUPPORTS_HT_CCK_RATES

硬體支援混合 HT/CCK 速率,並且可以處理聚合會話中的 CCK 速率(例如,透過不對此類幀使用聚合)。

IEEE80211_HW_CHANCTX_STA_CSA

在使用通道上下文時,支援基於 802.11h 的通道切換 (CSA) 以進行單個活動通道。如果未啟用支援,則預設操作是在獲取 CSA 幀時斷開連線。

IEEE80211_HW_SUPPORTS_CLONED_SKBS

驅動程式永遠不會在不首先複製的情況下修改 TX skb 的有效負載或尾部空間。

IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS

HW 支援在一個命令中掃描所有頻段,mac80211 不必為每個頻段執行單獨的掃描。

IEEE80211_HW_TDLS_WIDER_BW

對於基通道上的 TDLS 鏈路,裝置/驅動程式支援比 BSS 頻寬更寬的頻寬。

IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU

驅動程式支援在 A-MPDU 中接收 A-MSDU。

IEEE80211_HW_BEACON_TX_STATUS

裝置/驅動程式為傳送的信標提供 TX 狀態。

IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR

硬體(或驅動程式)要求每個站點都有唯一的地址,即每個站點條目只能透過其 MAC 地址來識別;例如,這可以防止同一站點同時連線到兩個虛擬 AP 介面。

IEEE80211_HW_SUPPORTS_REORDERING_BUFFER

硬體(或驅動程式)在內部管理重新排序緩衝區,保證 mac80211 按順序接收幀,並且不需要管理自己的重新排序緩衝區或 BA 會話超時。

IEEE80211_HW_USES_RSS

該裝置使用 RSS,因此需要並行 RX,這意味著使用每個 CPU 的站點統計資訊。

IEEE80211_HW_TX_AMSDU

硬體(或驅動程式)支援軟體聚合的 A-MSDU 幀。需要軟體 tx 佇列和快速傳輸支援。當不使用 minstrel/minstrel_ht 速率控制時,驅動程式必須透過在 struct ieee80211_sta 中設定 max_rc_amsdu_len 來限制最大 A-MSDU 大小,具體取決於當前 tx 速率。

IEEE80211_HW_TX_FRAG_LIST

硬體(或驅動程式)支援傳送 frag_list skb,這是零複製軟體 A-MSDU 所需的。

IEEE80211_HW_REPORTS_LOW_ACK

驅動程式(或韌體)基於其自己的演算法透過 ieee80211_report_low_ack() 報告低 ack 事件。對於此類驅動程式,將不會觸發 mac80211 資料包丟失機制,並且驅動程式完全依賴於韌體事件進行站點踢出。

IEEE80211_HW_SUPPORTS_TX_FRAG

硬體本身進行分片。堆疊不會進行分片。還應設定 set_frag_threshold 的回撥。

IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA

硬體支援在 TDLS 鏈路上緩衝 STA。

IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP

驅動程式(或韌體)不支援 AP 探測的 QoS NDP - 這很可能是驅動程式錯誤。

IEEE80211_HW_BUFF_MMPDU_TXQ

使用 TXQ 處理可緩衝的 MMPDU,當然這需要驅動程式首先使用 TXQ。

IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW

(硬體)速率控制支援 VHT 擴充套件 NSS BW (dot11VHTExtendedNSSBWCapable)。如果所選的速率控制演算法設定了 RATE_CTRL_CAPA_VHT_EXT_NSS_BW,則將設定此標誌,但如果速率控制是內建的,則必須由驅動程式設定。另請參閱該標誌的文件。

IEEE80211_HW_STA_MMPDU_TXQ

將額外的每個站點的非 TID TXQ 用於站點介面上的所有 MMPDU。當然,這需要驅動程式首先使用 TXQ。

IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN

驅動程式在 tx 狀態資訊中不報告準確的 A-MPDU 長度

IEEE80211_HW_SUPPORTS_MULTI_BSSID

硬體支援多 BSSID

IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID

硬體僅支援 HE AP 的多 BSSID。如果設定了 IEEE80211_HW_SUPPORTS_MULTI_BSSID,則適用。

IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT

卡和驅動程式僅聚合具有相同 keyid 的 MPDU,允許 mac80211 在使用擴充套件金鑰 ID 重新金鑰時保持 Tx A-MPDU 會話處於活動狀態。

IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD

硬體支援 tx 封裝解除安裝

IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD

硬體支援 rx 解封裝解除安裝

IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP

硬體支援併發 rx 解封裝解除安裝和傳遞用於監控介面的原始 802.11 幀。如果支援此功能,則驅動程式必須將用於實際使用的 802.3 幀和設定了 RX_FLAG_ONLY_MONITOR 的 802.11 幀傳遞給堆疊以進行監控。

IEEE80211_HW_DETECTS_COLOR_COLLISION

HW/驅動程式支援 BSS 顏色衝突檢測,不需要在軟體中進行檢測。

IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX

硬體/驅動程式處理在所有鏈路上傳送多播幀,mac80211 不應執行此操作。

IEEE80211_HW_DISALLOW_PUNCTURING

HW 需要停用 EHT 中的打孔,而是以較低的頻寬連線

IEEE80211_HW_DISALLOW_PUNCTURING_5GHZ

HW 需要停用 5 GHz EHT 中的打孔,而是以較低的頻寬連線

IEEE80211_HW_HANDLES_QUIET_CSA

HW/驅動程式處理 CSA 的靜默,因此無需停止佇列。這實際上應該由實現 MLO 的驅動程式設定,因此當一個鏈路切換時,可以在其他鏈路上繼續操作。

IEEE80211_HW_STRICT

嚴格執行規範規定的某些內容,否則會為了互操作性而被忽略/解決。這是一個 HW 標誌,因此驅動程式可以根據自己的控制選擇加入,例如在測試中。

NUM_IEEE80211_HW_FLAGS

硬體標誌的數量,用於調整陣列大小

描述

這些標誌用於向堆疊指示硬體功能。通常,此處的標誌應以最簡單的硬體不需要設定任何特定標誌的方式來完成其含義。但是,此規則存在一些例外情況,因此建議您仔細檢查這些標誌。

struct ieee80211_hw

硬體資訊和狀態

定義:

struct ieee80211_hw {
    struct ieee80211_conf conf;
    struct wiphy *wiphy;
    const char *rate_control_algorithm;
    void *priv;
    unsigned long flags[BITS_TO_LONGS(NUM_IEEE80211_HW_FLAGS)];
    unsigned int extra_tx_headroom;
    unsigned int extra_beacon_tailroom;
    int vif_data_size;
    int sta_data_size;
    int chanctx_data_size;
    int txq_data_size;
    u16 queues;
    u16 max_listen_interval;
    s8 max_signal;
    u8 max_rates;
    u8 max_report_rates;
    u8 max_rate_tries;
    u16 max_rx_aggregation_subframes;
    u16 max_tx_aggregation_subframes;
    u8 max_tx_fragments;
    u8 offchannel_tx_hw_queue;
    u8 radiotap_mcs_details;
    u16 radiotap_vht_details;
    struct {
        int units_pos;
        s16 accuracy;
    } radiotap_timestamp;
    netdev_features_t netdev_features;
    u8 uapsd_queues;
    u8 uapsd_max_sp_len;
    u8 max_nan_de_entries;
    u8 tx_sk_pacing_shift;
    u8 weight_multiplier;
    u32 max_mtu;
    const s8 *tx_power_levels;
    u8 max_txpwr_levels_idx;
};

成員

conf

struct ieee80211_conf,裝置配置,請勿使用。

wiphy

這指向為此 802.11 PHY 分配的 struct wiphy。您必須使用 SET_IEEE80211_DEV()SET_IEEE80211_PERM_ADDR() 填寫此結構的 perm_addrdev 成員。此外,所有支援的頻段(帶有通道、位元率)都將在此處註冊。

rate_control_algorithm

此硬體的速率控制演算法。如果未設定(NULL),將使用預設演算法。必須在呼叫 ieee80211_register_hw() 之前設定。

priv

指向與此結構一起為驅動程式使用分配的私有區域的指標。

flags

硬體標誌,請參閱 enum ieee80211_hw_flags

extra_tx_headroom

要在每個傳輸 skb 中保留的頭部空間,供驅動程式使用(例如,用於傳輸標頭)。

extra_beacon_tailroom

要在每個信標 tx skb 中保留的尾部空間。驅動程式可以使用它來新增額外的 IE。

vif_data_size

struct ieee80211_vif 中 drv_priv 資料區域的大小(以位元組為單位)。

sta_data_size

struct ieee80211_sta 中 drv_priv 資料區域的大小(以位元組為單位)。

chanctx_data_size

struct ieee80211_chanctx_conf 中 drv_priv 資料區域的大小(以位元組為單位)。

txq_data_size

struct ieee80211_txq 中 drv_priv 資料區域的大小(以位元組為單位)。

queues

可用於資料包的硬體傳輸佇列的數量。WMM/QoS 至少需要四個,這些佇列需要具有可配置的訪問引數。

max_listen_interval

HW 支援的最大偵聽間隔(以信標間隔為單位)

max_signal

RX 資訊中訊號(rssi)的最大值,僅在 IEEE80211_HW_SIGNAL_UNSPECIEEE80211_HW_SIGNAL_DB 時使用

max_rates

hw 可以處理的最大備用速率重試階段數。

max_report_rates

hw 可以報告的最大備用速率重試階段數。

max_rate_tries

每個階段的最大嘗試次數

max_rx_aggregation_subframes

要用於 A-MPDU 塊 ack 接收器聚合的最大緩衝區大小(子幀數)。這僅在裝置對子幀數有限制時才相關,如果它依賴 mac80211 進行重新排序,則不應設定它。

max_tx_aggregation_subframes

HT/HE 裝置將傳輸的聚合中的最大子幀數。在 HT AddBA 中,我們將公佈一個常量值 64,因為如果視窗大小較小,某些舊 AP 會崩潰(一個示例是使用 FW v1.0.07 build 002 Jun 18 2012 的 LinkSys WRT120N)。對於 AddBA 到支援 HE 的對等方,將使用此值。

max_tx_fragments

每個 (A)-MSDU 的最大 tx 緩衝區數,frag_list 中每個 skb 的 1 + skb_shinfo(skb)->nr_frags 的總和。

offchannel_tx_hw_queue

用於異通道 TX 的 HW 佇列 ID(如果設定了 IEEE80211_HW_QUEUE_CONTROL

radiotap_mcs_details

列出 HW 可以報告哪些 MCS 資訊,預設情況下設定為 _MCS、_GI 和 _BW,但不包括 _FMT。使用 IEEE80211_RADIOTAP_MCS_HAVE_* 值,今天僅支援新增 _BW。

radiotap_vht_details

列出 HW 報告哪些 VHT MCS 資訊,預設為 _GI | _BANDWIDTH。使用 IEEE80211_RADIOTAP_VHT_KNOWN_* 值。

radiotap_timestamp

Radiotap 時間戳欄位的資訊;如果 units_pos 成員設定為非負值,則將新增時間戳欄位並從 struct ieee80211_rx_status device_timestamp 填充。

radiotap_timestamp.units_pos

必須設定為 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_* 和 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_* 值的組合。

radiotap_timestamp.accuracy

如果為非負值,則填充 radiotap 欄位中的精度,並且將設定精度已知標誌。

netdev_features

要在此 HW 建立的每個 netdev 中設定的 netdev 功能。請注意,並非所有功能都可用於 mac80211,其他功能將在 HW 註冊期間被拒絕。

uapsd_queues

此點陣圖包含在(重新)關聯幀中,以指示每個訪問類別是否啟用了 uAPSD 觸發器和傳輸。使用 IEEE80211_WMM_IE_STA_QOSINFO_AC_* 設定此點陣圖。每個位對應於不同的 AC。特定位中的值“1”表示相應的 AC 同時啟用了觸發器和傳輸。“0”表示既未啟用觸發器也未啟用傳輸。

uapsd_max_sp_len

WMM AP 可以在 WMM STA 觸發的任何服務週期內傳送給 WMM STA 的最大總緩衝幀數。使用 IEEE80211_WMM_IE_STA_QOSINFO_SP_* 獲取正確的值。

max_nan_de_entries

裝置支援的最大 NAN DE 函式數。

tx_sk_pacing_shift

遇到來自它們的幀時,要在 TCP 套接字上設定的步調移位。通常不應更改預設值,除非驅動程式有充分的理由需要更多緩衝區。

weight_multiplier

在重新填充每個 TXQ 的赤字時使用的特定於驅動程式的空時權重乘數。

max_mtu

可以設定的最大 mtu。

tx_power_levels

wifi 硬體支援的功率級別列表。功率級別可以指定為整數或分數。索引 0 處的功率級別應為最大正功率級別。

max_txpwr_levels_idx

“tx_power_levels”列表的最大有效索引。

描述

此結構包含 802.11 PHY 的配置和硬體資訊。

void SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev)

為 802.11 硬體設定裝置

引數

struct ieee80211_hw *hw

要為其設定裝置的 struct ieee80211_hw

struct device *dev

此 802.11 裝置的 struct device

void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, const u8 *addr)

為 802.11 硬體設定永久 MAC 地址

引數

struct ieee80211_hw *hw

要為其設定 MAC 地址的 struct ieee80211_hw

const u8 *addr

要設定的地址

struct ieee80211_ops

從 mac80211 到驅動程式的回撥

定義:

struct ieee80211_ops {
    void (*tx)(struct ieee80211_hw *hw,struct ieee80211_tx_control *control, struct sk_buff *skb);
    int (*start)(struct ieee80211_hw *hw);
    void (*stop)(struct ieee80211_hw *hw, bool suspend);
#ifdef CONFIG_PM;
    int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
    int (*resume)(struct ieee80211_hw *hw);
    void (*set_wakeup)(struct ieee80211_hw *hw, bool enabled);
#endif;
    int (*add_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*change_interface)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, enum nl80211_iftype new_type, bool p2p);
    void (*remove_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*config)(struct ieee80211_hw *hw, u32 changed);
    void (*bss_info_changed)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *info, u64 changed);
    void (*vif_cfg_changed)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, u64 changed);
    void (*link_info_changed)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *info, u64 changed);
    int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf);
    void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf);
    u64 (*prepare_multicast)(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list);
    void (*configure_filter)(struct ieee80211_hw *hw,unsigned int changed_flags,unsigned int *total_flags, u64 multicast);
    void (*config_iface_filter)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,unsigned int filter_flags, unsigned int changed_flags);
    int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set);
    int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key);
    void (*update_tkip_key)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_key_conf *conf,struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
    void (*set_rekey_data)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_gtk_rekey_data *data);
    void (*set_default_unicast_key)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx);
    int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req);
    void (*cancel_hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*sched_scan_start)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_sched_scan_request *req, struct ieee80211_scan_ies *ies);
    int (*sched_scan_stop)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    void (*sw_scan_start)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, const u8 *mac_addr);
    void (*sw_scan_complete)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*get_stats)(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats);
    void (*get_key_seq)(struct ieee80211_hw *hw,struct ieee80211_key_conf *key, struct ieee80211_key_seq *seq);
    int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
    int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
    int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta);
#ifdef CONFIG_MAC80211_DEBUGFS;
    void (*vif_add_debugfs)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    void (*link_add_debugfs)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *link_conf, struct dentry *dir);
    void (*sta_add_debugfs)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, struct dentry *dir);
    void (*link_sta_add_debugfs)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_link_sta *link_sta, struct dentry *dir);
#endif;
    void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd, struct ieee80211_sta *sta);
    int (*sta_set_txpwr)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct ieee80211_sta *sta,enum ieee80211_sta_state old_state, enum ieee80211_sta_state new_state);
    void (*sta_pre_rcu_remove)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    void (*link_sta_rc_update)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_link_sta *link_sta, u32 changed);
    void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    void (*sta_statistics)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, struct station_info *sinfo);
    int (*conf_tx)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,unsigned int link_id, u16 ac, const struct ieee80211_tx_queue_params *params);
    u64 (*get_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    void (*set_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf);
    void (*offset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, s64 offset);
    void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*tx_last_beacon)(struct ieee80211_hw *hw);
    int (*ampdu_action)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params);
    int (*get_survey)(struct ieee80211_hw *hw, int idx, struct survey_info *survey);
    void (*rfkill_poll)(struct ieee80211_hw *hw);
    void (*set_coverage_class)(struct ieee80211_hw *hw, s16 coverage_class);
#ifdef CONFIG_NL80211_TESTMODE;
    int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len);
    int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb,struct netlink_callback *cb, void *data, int len);
#endif;
    void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop);
    void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    void (*channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch);
    int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
    int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
    int (*remain_on_channel)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_channel *chan,int duration, enum ieee80211_roc_type type);
    int (*cancel_remain_on_channel)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
    void (*get_ringparam)(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
    bool (*tx_frames_pending)(struct ieee80211_hw *hw);
    int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask);
    void (*event_callback)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, const struct ieee80211_event *event);
    void (*allow_buffered_frames)(struct ieee80211_hw *hw,struct ieee80211_sta *sta,u16 tids, int num_frames,enum ieee80211_frame_release_type reason, bool more_data);
    void (*release_buffered_frames)(struct ieee80211_hw *hw,struct ieee80211_sta *sta,u16 tids, int num_frames,enum ieee80211_frame_release_type reason, bool more_data);
    int (*get_et_sset_count)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int sset);
    void (*get_et_stats)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ethtool_stats *stats, u64 *data);
    void (*get_et_strings)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, u32 sset, u8 *data);
    void (*mgd_prepare_tx)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_prep_tx_info *info);
    void (*mgd_complete_tx)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_prep_tx_info *info);
    void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, unsigned int link_id);
    int (*add_chanctx)(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx);
    void (*remove_chanctx)(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx);
    void (*change_chanctx)(struct ieee80211_hw *hw,struct ieee80211_chanctx_conf *ctx, u32 changed);
    int (*assign_vif_chanctx)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx);
    void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx);
    int (*switch_vif_chanctx)(struct ieee80211_hw *hw,struct ieee80211_vif_chanctx_switch *vifs,int n_vifs, enum ieee80211_chanctx_switch_mode mode);
    void (*reconfig_complete)(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type);
#if IS_ENABLED(CONFIG_IPV6);
    void (*ipv6_addr_change)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct inet6_dev *idev);
#endif;
    void (*channel_switch_beacon)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef);
    int (*pre_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch);
    int (*post_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf);
    void (*abort_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf);
    void (*channel_switch_rx_beacon)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch);
    int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    u32 (*get_expected_throughput)(struct ieee80211_hw *hw, struct ieee80211_sta *sta);
    int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, int *dbm);
    int (*tdls_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, u8 oper_class,struct cfg80211_chan_def *chandef, struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie);
    void (*tdls_cancel_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta);
    void (*tdls_recv_channel_switch)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_tdls_ch_sw_params *params);
    void (*wake_tx_queue)(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
    void (*sync_rx_queues)(struct ieee80211_hw *hw);
    int (*start_nan)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_nan_conf *conf);
    int (*stop_nan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    int (*nan_change_conf)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_nan_conf *conf, u32 changes);
    int (*add_nan_func)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, const struct cfg80211_nan_func *nan_func);
    void (*del_nan_func)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, u8 instance_id);
    bool (*can_aggregate_in_amsdu)(struct ieee80211_hw *hw,struct sk_buff *head, struct sk_buff *skb);
    int (*get_ftm_responder_stats)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_ftm_responder_stats *ftm_stats);
    int (*start_pmsr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_pmsr_request *request);
    void (*abort_pmsr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_pmsr_request *request);
    int (*set_tid_config)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, struct cfg80211_tid_config *tid_conf);
    int (*reset_tid_config)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta, u8 tids);
    void (*update_vif_offload)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
    void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enabled);
    int (*set_sar_specs)(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar);
    void (*sta_set_decap_offload)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enabled);
    void (*add_twt_setup)(struct ieee80211_hw *hw,struct ieee80211_sta *sta, struct ieee80211_twt_setup *twt);
    void (*twt_teardown_request)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 flowid);
    int (*set_radar_background)(struct ieee80211_hw *hw, struct cfg80211_chan_def *chandef);
    int (*net_fill_forward_path)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta,struct net_device_path_ctx *ctx, struct net_device_path *path);
    bool (*can_activate_links)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, u16 active_links);
    int (*change_vif_links)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,u16 old_links, u16 new_links, struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]);
    int (*change_sta_links)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, u16 old_links, u16 new_links);
    int (*set_hw_timestamp)(struct ieee80211_hw *hw,struct ieee80211_vif *vif, struct cfg80211_set_hw_timestamp *hwts);
    int (*net_setup_tc)(struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct net_device *dev,enum tc_setup_type type, void *type_data);
    enum ieee80211_neg_ttlm_res(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_neg_ttlm *ttlm);
    void (*prep_add_interface)(struct ieee80211_hw *hw, enum nl80211_iftype type);
};

成員

tx

802.11 模組為每個傳輸的幀呼叫的處理程式。skb 包含從 IEEE 802.11 標頭開始的緩衝區。底層驅動程式應根據 TX 控制資料中的配置傳送幀。此處理程式最好永遠不要失敗並適當地停止佇列。必須是原子的。

start

在連線到硬體的第一個 netdevice 啟用之前呼叫。這應該開啟硬體,並且必須開啟幀接收(對於可能啟用的監控介面)。返回負錯誤程式碼,這些程式碼可能會在使用者空間中看到,或者返回零。當裝置啟動時,它不應具有 MAC 地址,以避免在新增非監控裝置之前確認幀。必須實現並且可以休眠。

stop

在連線到硬體的最後一個 netdevice 停用後呼叫。這應該關閉硬體(至少必須關閉幀接收)。如果在新增介面後該介面被拒絕,則可能會立即呼叫此函式。如果您在 mac80211 工作佇列上添加了任何工作,則應確保在此回撥中取消它。必須實現並且可以休眠。

suspend

掛起裝置;mac80211 本身將在掛起之前停止傳輸和執行任何其他配置,然後要求裝置掛起。僅在配置 WoWLAN 時才會呼叫此函式,否則裝置將被完全取消配置並在恢復時重新配置。驅動程式還可以施加特殊條件,在其想要使用“正常”掛起(取消配置)的情況下,例如,如果它僅在裝置關聯時才支援 WoWLAN。在這種情況下,它必須從此函式返回 1。

resume

如果配置了 WoWLAN,則表示 mac80211 現在正在恢復其操作,在此之後,裝置必須再次完全正常執行。如果此函式返回錯誤,則唯一的出路也是登出該裝置。如果它返回 1,則 mac80211 還將在恢復時進行常規的完整重新啟動。

set_wakeup

當修改 WoWLAN 配置時,啟用或停用喚醒。原因是 device_set_wakeup_enable() 應該在配置更改時呼叫,而不僅僅是在 suspend() 中呼叫。

add_interface

在連線到硬體的 netdevice 啟用時呼叫。由於不會為監控模式裝置呼叫此函式,因此必須實現 startstop。驅動程式應執行裝置啟用之前所需的任何初始化。conf 引數中給出了介面的初始配置。回撥可以透過返回負錯誤程式碼(這將在使用者空間中看到)來拒絕新增介面。必須實現並且可以休眠。

change_interface

在 netdevice 更改型別時呼叫。此回撥是可選的,但僅當支援此回撥時,才能在介面啟動時切換介面型別。回撥可以休眠。請注意,在切換介面時,介面迭代回撥將找不到它。

remove_interface

通知驅動程式介面即將關閉。如果它是最後一個介面並且沒有監控介面,則在此之後呼叫 stop 回撥。刪除所有介面後,必須清除硬體中的 MAC 地址,以便裝置不再確認資料包,但是 conf 結構的 mac_addr 成員設定為即將離開的裝置的 MAC 地址。因此,必須實現此回撥。它可以休眠。

config

配置請求的處理程式。IEEE 802.11 程式碼呼叫此函式以更改硬體配置,例如通道。此函式永遠不應失敗,但如果失敗,則返回負錯誤程式碼。回撥可以休眠。

bss_info_changed

用於處理與BSS引數相關的配置請求,這些引數可能在BSS的生命週期內發生變化,並可能影響底層驅動程式(例如,關聯/解除關聯狀態、erp引數)。除非是為了關聯指示,否則在未設定任何BSS的情況下不應使用此函式。changed引數指示呼叫時哪些bss引數已更改。回撥可以休眠。

vif_cfg_changed

用於處理與介面(MLD)引數相關的配置請求,這些引數來自struct ieee80211_vif_cfg,並在介面的生命週期內發生變化(例如,關聯狀態、IP地址等)。changed引數指示哪個值已更改。回撥可以休眠。

link_info_changed

用於處理與鏈路引數相關的配置請求,這些引數來自struct ieee80211_bss_conf,且與單個鏈路相關。例如,傳統/HT/VHT/...速率資訊。changed引數指示哪個值已更改,link_id引數指示鏈路ID。請注意,對於非MLO連線,link_id將為0。回撥可以休眠。

start_ap

啟動AP介面上的操作,這在設定bss_conf中的所有資訊並且可以檢索信標後呼叫。在呼叫此函式之前,會繫結一個通道上下文。請注意,如果驅動程式使用軟體掃描或ROC,則當AP僅因掃描/ROC而“暫停”時(由透過bss_info_changed禁/啟用信標指示),不會呼叫此函式(和stop_ap)。

stop_ap

停止AP介面上的操作。

prepare_multicast

準備多播過濾器配置。此回撥是可選的,其返回值將傳遞給configure_filter()。此回撥必須是原子的。

configure_filter

配置裝置的RX過濾器。有關更多資訊,請參見“幀過濾”部分。必須實現此回撥,並且可以休眠。

config_iface_filter

配置介面的RX過濾器。此回撥是可選的,用於配置應將哪些幀傳遞給mac80211。filter_flags是FIF_*標誌的組合。changed_flags是一個位掩碼,指示哪些標誌已更改。回撥可以休眠。

set_tim

設定TIM位。當必須為給定的STA設定或清除TIM位時,mac80211會呼叫此函式。必須是原子的。

set_key

參見“硬體加密加速”部分。僅在add_interface和remove_interface呼叫之間(即,在給定的虛擬介面啟用時)呼叫此回撥。如果無法新增金鑰,則返回負錯誤程式碼。回撥可以休眠。

update_tkip_key

參見“硬體加密加速”部分。將在Rx上下文中呼叫此回撥。為設定IEEE80211_KEY_FLAG_TKIP_REQ_RX_P1_KEY的驅動程式呼叫。回撥必須是原子的。

set_rekey_data

如果裝置支援GTK重新金鑰,例如在主機掛起時,它可以分配此回撥以檢索執行GTK重新金鑰所需的資料,這是KEK、KCK和重放計數器。重新金鑰完成後,應(例如在恢復期間)使用ieee80211_gtk_rekey_notify()通知使用者空間新的重放計數器。

set_default_unicast_key

設定預設(單播)金鑰索引,這對於WEP在裝置自主傳送資料包時(例如,用於ARP解除安裝)很有用。索引可以是0-3,或者對於取消設定,可以是-1。

hw_scan

要求硬體服務掃描請求,無需在堆疊中啟動掃描狀態機。掃描必須遵循監管代理在wiphy的註冊頻段中完成的通道配置。硬體(或驅動程式)需要確保停用省電模式。req ie/ie_len成員由mac80211重寫以包含SSID之後的所有IE,以便驅動程式根本不需要檢視它們,只需在SSID之後傳送它們即可——mac80211包括(擴充套件的)支援速率和HT資訊(如果適用)。掃描完成後,必須呼叫ieee80211_scan_completed();請注意,當由於任何錯誤而無法完成掃描時,也必須呼叫它,除非此回撥返回負錯誤程式碼。此回撥也允許返回特殊返回值1,這表示現在不希望進行硬體掃描,而應進行軟體掃描。希望使用此功能的驅動程式必須確保其(硬體)掃描功能不會被宣傳為比mac80211的軟體掃描更強大。回撥可以休眠。

cancel_hw_scan

要求底層取消活動的硬體掃描。驅動程式應要求硬體取消掃描(如果可能),但僅在驅動程式呼叫ieee80211_scan_completed()後才能完成掃描。此回撥是wowlan所必需的,以防止在底層驅動程式已掛起後將新的scan_work排隊。回撥可以休眠。

sched_scan_start

要求硬體以特定間隔重複開始掃描。驅動程式必須在找到結果時呼叫ieee80211_sched_scan_results()函式。此過程將持續到呼叫sched_scan_stop為止。

sched_scan_stop

告訴硬體停止正在進行的計劃掃描。在這種情況下,不得呼叫ieee80211_sched_scan_stopped()。

sw_scan_start

在軟體掃描開始之前呼叫的通知函式。如果驅動程式不需要此通知,則可以為NULL。mac_addr引數允許支援NL80211_SCAN_FLAG_RANDOM_ADDR,如果驅動程式可以使用此引數,則可以設定NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR標誌。回撥可以休眠。

sw_scan_complete

在軟體掃描完成後呼叫的通知函式。如果驅動程式不需要此通知,則可以為NULL。回撥可以休眠。

get_stats

返回底層統計資訊。如果統計資訊可用,則返回零。回撥可以休眠。

get_key_seq

如果您的裝置在硬體中實現加密並執行IV/PN分配,則應提供此回撥以從硬體讀取給定金鑰的IV/PN。回撥必須是原子的。

set_frag_threshold

分片閾值配置。如果裝置本身進行分片,則分配此函式。請注意,為防止堆疊進行分片,還應設定IEEE80211_HW_SUPPORTS_TX_FRAG。回撥可以休眠。

set_rts_threshold

RTS閾值配置(如果裝置需要)回撥可以休眠。

sta_add

通知底層驅動程式有關新增關聯的站點、AP、IBSS/WDS/網格對等方等。此回撥可以休眠。

sta_remove

通知底層驅動程式有關刪除關聯的站點、AP、IBSS/WDS/網格對等方等。請注意,在回撥返回後,使用該指標是不安全的,即使是RCU保護的;不能保證在此處返回和釋放站點之間的RCU寬限期。如果需要,請參見sta_pre_rcu_remove。此回撥可以休眠。

vif_add_debugfs

驅動程式可以使用此回撥來新增帶有其檔案的debugfs vif目錄。此回撥應在CONFIG_MAC80211_DEBUGFS條件下。此回撥可以休眠。

link_add_debugfs

當連結新增到mac80211 vif時,驅動程式可以使用此回撥來新增debugfs檔案。此回撥應在CONFIG_MAC80211_DEBUGFS條件下。此回撥可以休眠。對於非MLO,將針對預設的bss_conf呼叫一次回撥,使用vif的目錄而不是單獨的子目錄。

sta_add_debugfs

當站點新增到mac80211的站點列表時,驅動程式可以使用此回撥來新增debugfs檔案。此回撥應在CONFIG_MAC80211_DEBUGFS條件下。此回撥可以休眠。

link_sta_add_debugfs

當連結新增到mac80211站點時,驅動程式可以使用此回撥來新增debugfs檔案。此回撥應在CONFIG_MAC80211_DEBUGFS條件下。此回撥可以休眠。對於非MLO,將針對deflink呼叫一次回撥,使用站點的目錄而不是單獨的子目錄。

sta_notify

通知底層驅動程式有關關聯站點、AP、IBSS/WDS/網格對等方等的電源狀態轉換。對於在AP模式下執行的VIF,設定IEEE80211_HW_AP_LINK_PS標誌後,不會呼叫此回撥。必須是原子的。

sta_set_txpwr

配置站點傳輸功率。此回撥設定站點的傳輸功率。此回撥可以休眠。

sta_state

通知底層驅動程式有關站點(可以是AP、客戶端、IBSS/WDS/網格對等方等)的狀態轉換。此回撥與sta_add/sta_remove互斥。對於向下轉換,它不得失敗,但對於狀態列表的向上轉換,它可能會失敗。另請注意,在回撥返回後,使用該指標是不安全的,即使是RCU保護的 - 不能保證在此處返回和釋放站點之間的RCU寬限期。如果需要,請參見sta_pre_rcu_remove。此回撥可以休眠。

sta_pre_rcu_remove

在RCU同步之前通知驅動程式有關站點刪除的資訊。如果驅動程式需要使用RCU保護站點指標,這將很有用,然後它可以使用此呼叫來清除指標,而不是等待sta_state中的RCU寬限期。回撥可以休眠。

link_sta_rc_update

通知驅動程式可以用於傳輸到站點的位元率的更改。更改透過來自enum ieee80211_rate_control_changed的位來宣傳,這些值反映在站點資料中。僅當驅動程式使用硬體速率控制(IEEE80211_HW_HAS_RATE_CONTROL)時才應使用此回撥,否則將直接通知速率控制演算法。必須是原子的。

sta_rate_tbl_update

通知驅動程式速率表已更改。這僅在配置的速率控制演算法實際使用新的速率表API時使用,因此是可選的。必須是原子的。

sta_statistics

獲取此站點的統計資訊。例如,對於信標過濾,mac80211保留的統計資訊可能不準確,因此讓驅動程式預先填充統計資訊。驅動程式可以填充大多數值(透過設定填充的點陣圖來指示),但並非所有值都有意義 - 請參見原始碼以瞭解哪些值是可能的。驅動程式未填充的統計資訊將由mac80211填充。回撥可以休眠。

conf_tx

為硬體TX佇列配置TX佇列引數(EDCF(aifs、cw_min、cw_max)、突發)。失敗時返回負錯誤程式碼。回撥可以休眠。

get_tsf

從韌體/硬體獲取當前的TSF計時器值。目前,這僅用於IBSS模式BSSID合併和除錯。不是必需的函式。回撥可以休眠。

set_tsf

將TSF計時器設定為韌體/硬體中的指定值。目前,這僅用於IBSS模式除錯。不是必需的函式。回撥可以休眠。

offset_tsf

按韌體/硬體中的指定值偏移TSF計時器。首選set_tsf,因為它避免了呼叫set_tsf()和硬體被程式設計之間的時間延遲,這將顯示為TSF延遲。不是必需的函式。回撥可以休眠。

reset_tsf

重置TSF計時器並允許韌體/硬體與IBSS中的其他STA同步。這僅在IBSS模式下使用。如果韌體/硬體完全負責TSF同步,則此函式是可選的。回撥可以休眠。

tx_last_beacon

確定最後一個IBSS信標是否由我們傳送。這僅在IBSS模式下需要,此函式的結果用於確定是否回覆探測請求。如果此裝置傳送了最後一個信標,則返回非零值。回撥可以休眠。

ampdu_action

執行特定的A-MPDU操作。RA/TID組合確定我們要為其執行ampdu操作的目標和TID。該操作透過ieee80211_ampdu_mlme_action定義。當操作設定為IEEE80211_AMPDU_TX_OPERATIONAL時,驅動程式既不能傳送包含比buf_size更多子幀的聚合,也不能以丟失的幀將超過緩衝區大小的方式傳送聚合。如果只是限制聚合大小,則使用buf_size為8是可能的

  • TX: 1.....7

  • RX:  2....7 (丟失幀#1)

  • TX:        8..1...

這是無效的,因為#1現在已被重新傳輸,遠遠超過8的緩衝區大小。重新傳輸#1的正確方法是

  • TX:        1  

  • TX:        18 

  • TX:        81

即使189也是錯誤的,因為1可能再次丟失。

失敗時返回負錯誤程式碼。如果會話可以立即開始,驅動程式可以為IEEE80211_AMPDU_TX_START返回IEEE80211_AMPDU_TX_START_IMMEDIATE

回撥可以休眠。

get_survey

返回每個通道的調查資訊

rfkill_poll

輪詢rfkill硬體狀態。如果需要此功能,還需要在註冊之前將wiphy->rfkill_poll設定為true,並且需要在回撥中呼叫wiphy_rfkill_set_hw_state()。回撥可以休眠。

set_coverage_class

按照IEEE 802.11-2007第17.3.8.6節中的規定,為給定的覆蓋範圍類別設定時隙時間,並相應地修改ACK超時;覆蓋範圍類別等於-1以啟用ACK超時估算演算法(dynack)。要停用dynack,請為覆蓋範圍類別設定有效值。此回撥不是必需的,可以休眠。

testmode_cmd

實現cfg80211測試模式命令。傳遞的vif可以為NULL。回撥可以休眠。

testmode_dump

實現cfg80211測試模式轉儲。回撥可以休眠。

flush

從硬體佇列中重新整理所有掛起的幀,確保硬體佇列為空。queues引數是要重新整理的佇列的點陣圖,如果不同的虛擬介面使用不同的硬體佇列,這將很有用;它也可以指示所有佇列。如果引數drop設定為true,則可能會刪除掛起的幀。請注意,vif可以為NULL。回撥可以休眠。

flush_sta

重新整理或刪除給定站點的硬體佇列中的所有掛起幀,因為它即將被刪除。回撥可以休眠。

channel_switch

需要(或想要)解除安裝從AP接收的CSA的通道切換操作的驅動程式可以實現此回撥。然後,他們必須呼叫ieee80211_chswitch_done()以指示通道切換完成。

set_antenna

在裝置上設定天線配置(tx_ant、rx_ant)。引數是允許用於TX/RX的天線的點陣圖。驅動程式可能會拒絕他們不支援的TX/RX掩碼組合,方法是返回-EINVAL(另請參見nl80211.h NL80211_ATTR_WIPHY_ANTENNA_TX)。

get_antenna

從裝置獲取當前天線配置(tx_ant、rx_ant)。

remain_on_channel

在給定通道上啟動離線道週期,必須回撥ieee80211_ready_on_channel()才能在該通道上執行。請注意,正常的通道流量不會停止,因為這適用於硬體解除安裝。在離線道通道上傳輸的幀會正常傳輸,除了IEEE80211_TX_CTL_TX_OFFCHAN標誌。當持續時間(始終為非零)到期時,驅動程式必須呼叫ieee80211_remain_on_channel_expired()。請注意,可以在裝置處於IDLE狀態時呼叫此回撥,並且必須在這種情況下接受此回撥。此回撥可以休眠。

cancel_remain_on_channel

請求在到期之前中止正在進行的離線道週期。此回撥可以休眠。

set_ringparam

設定tx和rx環大小。

get_ringparam

獲取tx和rx環的當前和最大大小。

tx_frames_pending

在進入省電模式之前,檢查硬體佇列中是否有任何掛起的幀。

set_bitrate_mask

設定用於速率控制選擇的速率掩碼,以傳輸幀。目前僅處理傳統速率。回撥可以休眠。

event_callback

通知驅動程式有關mac80211中的任何事件。有關不同型別,請參見enum ieee80211_event_type。回撥必須是原子的。

allow_buffered_frames

準備裝置以允許給定數量的幀傳送到給定站點。在此呼叫之後,mac80211將透過通常的TX路徑傳送幀。已釋放幀的TX資訊也將設定IEEE80211_TX_CTL_NO_PS_BUFFER標誌,最後一個還將設定IEEE80211_TX_STATUS_EOSP。如果釋放了來自多個TID的幀,並且驅動程式可能會在TID之間重新排序它們,則它必須在最後一個幀上設定IEEE80211_TX_STATUS_EOSP標誌,並在所有其他幀上清除它,並且還必須正確處理QoS標頭中的EOSP位。或者,它也可以呼叫ieee80211_sta_eosp()函式。tids引數是點陣圖,並告知驅動程式幀將位於哪些TID上;它最多將設定兩個位。此回撥必須是原子的。

release_buffered_frames

根據給定的引數釋放緩衝的幀。在驅動程式緩衝一些睡眠站點幀的情況下,mac80211將使用此回撥來告訴驅動程式釋放一些幀,用於PS-poll或uAPSD。請注意,如果more_data引數為false,則驅動程式必須檢查給定TID上是否有更多幀,並且如果有超過正在釋放的幀,則它仍然必須在幀中設定more-data位。如果more_data引數為true,那麼當然必須始終設定more-data位。tids引數告知驅動程式要從哪些TID釋放幀,對於PS-poll,它將始終只有一個位設定。在這種情況下,用於PS-poll發起的釋放,num_frames引數將始終為1,因此可以共享程式碼。在這種情況下,驅動程式還必須在TX狀態上設定IEEE80211_TX_STATUS_EOSP標誌(並且必須報告TX狀態),以便正確結束PS-poll週期。這用於避免為重試的PS-poll幀傳送多個響應。在這種情況下,用於uAPSD,num_frames引數可能大於1,但驅動程式可能會發送較少的幀(但它必須至少傳送一個)。在這種情況下,它還負責在幀的QoS標頭中設定EOSP標誌。此外,當服務週期結束時,驅動程式必須在SP中的最後一個幀上設定IEEE80211_TX_STATUS_EOSP。或者,它可以呼叫函式ieee80211_sta_eosp()以通知mac80211 SP結束。此回撥必須是原子的。

get_et_sset_count

Ethtool API用於獲取字串集計數。請注意,此回撥不儲存wiphy互斥鎖,因為它有望返回靜態值。

get_et_stats

Ethtool API用於獲取一組u64統計資訊。

get_et_strings

Ethtool API用於獲取一組字串以描述統計資訊和可能其他支援型別的ethtool資料集。請注意,此回撥不儲存wiphy互斥鎖,因為它有望返回靜態值。

mgd_prepare_tx

準備用於關聯的管理幀,然後才能關聯。在多通道場景中,虛擬介面在關聯之前繫結到通道,但由於尚未關聯,因此不必一定被賦予空口時間,特別是由於與P2P GO的任何傳輸都需要與GO的省電狀態同步。mac80211將在傳輸該幀之前呼叫此函式,以便驅動程式為其提供通道時間進行傳輸、獲取響應並能夠與GO同步。將在每次傳輸之前呼叫回撥,並且在返回時,mac80211將立即傳輸幀。其他資訊在struct ieee80211_prep_tx_info資料中傳遞。如果持續時間大於零,則mac80211提示驅動程式請求操作的持續時間。回撥是可選的,並且可以(應該!)休眠。

mgd_complete_tx

通知驅動程式先前使用mgd_prepare_tx宣告的已傳輸幀的響應幀已收到,資料填充類似於mgd_prepare_tx,但未使用持續時間。

mgd_protect_tdls_discover

保護TDLS發現會話。在傳送TDLS發現請求後,我們希望在AP的通道上收到回覆。我們必須停留在通道上(沒有PSM、掃描等),因為TDLS設定響應是由AP未緩衝的直接資料包。mac80211將在傳輸TDLS發現請求之前呼叫此函式。建議的保護週期至少為2 *(DTIM週期)。回撥是可選的,並且可以休眠。

add_chanctx

通知裝置驅動程式有關新通道上下文建立的資訊。此回撥可以休眠。

remove_chanctx

通知裝置驅動程式有關通道上下文銷燬的資訊。此回撥可以休眠。

change_chanctx

通知裝置驅動程式有關通道上下文更改的資訊,這些更改可能發生在具有不同設定的同一通道上下文中組合不同的虛擬介面時。此回撥可以休眠。

assign_vif_chanctx

通知裝置驅動程式有關繫結到vif的通道上下文的資訊。可能的用途是用於硬體佇列重新對映。此回撥可以休眠。

unassign_vif_chanctx

通知裝置驅動程式有關從vif取消繫結的通道上下文的資訊。此回撥可以休眠。

switch_vif_chanctx

根據ieee80211_chanctx_switch_mode中定義的模式,將大量vif從一個chanctx切換到另一個,如傳遞給驅動程式的ieee80211_vif_chanctx_switch列表中所指定的。此回撥可以休眠。

reconfig_complete

在呼叫ieee80211_restart_hw()和恢復期間(在重新配置完成後)呼叫。這可以幫助驅動程式實現重新配置步驟(並指示mac80211已準備好接收幀)。此回撥可以休眠。

ipv6_addr_change

給定介面上的IPv6地址分配已更改。目前,這僅針對託管或P2P客戶端介面呼叫。此回撥是可選的;它不得休眠。

channel_switch_beacon

啟動到新通道的通道切換。信標被修改為包括CSA或ECSA IE,然後再呼叫此函式。這些IE中的相應計數字段必須遞減,並且當它們達到1時,驅動程式必須呼叫ieee80211_csa_finish()。使用ieee80211_beacon_get()的驅動程式會使mac80211遞減csa計數器,但必須在使用ieee80211_beacon_counter_is_complete()檢查其是否為1之後傳輸信標,然後呼叫ieee80211_csa_finish()。如果CSA計數以零或1開頭,則不會呼叫此函式,因為無論如何都沒有時間在切換之前發出信標。

pre_channel_switch

這是一個可選的回撥,在啟動通道切換過程之前(即,當STA獲得CSA或使用者空間發起的通道切換時)呼叫,允許驅動程式為通道切換做準備。

post_channel_switch

這是一個可選的回撥,在通道切換過程完成後呼叫,允許驅動程式返回到正常配置。

abort_channel_switch

這是一個可選的回撥,當通道切換過程被中止時呼叫,允許驅動程式返回到正常配置。

channel_switch_rx_beacon

這是一個可選的回撥,在通道切換過程正在進行並且收到了帶有CSA IE的額外信標時呼叫,允許驅動程式跟蹤計數中的更改。

join_ibss

加入IBSS(在IBSS介面上);這在設定bss_conf中的所有資訊並且可以檢索信標後呼叫。在呼叫此函式之前,會繫結一個通道上下文。

leave_ibss

再次離開IBSS。

get_expected_throughput

提取到指定站點的預期吞吐量。返回的值以Kbps表示。如果RC演算法沒有提供適當的資料,則返回0。

get_txpower

根據配置和硬體限制獲取當前最大傳輸功率(以dBm為單位)。

tdls_channel_switch

與TDLS對等方啟動通道切換。驅動程式負責持續啟動通道切換操作並返回到基本通道以與AP通訊。驅動程式接收通道切換請求模板以及作為呼叫一部分的模板中切換定時IE的位置。該模板僅在呼叫中有效,並且驅動程式可以選擇複製skb以供進一步重用。

tdls_cancel_channel_switch

停止與TDLS對等方進行通道切換。呼叫完成時,兩個對等方都必須位於基本通道上。

tdls_recv_channel_switch

已從遠端對等方收到與TDLS通道切換相關的幀(請求或響應)。驅動程式獲取從傳入幀解析的引數,並且可以使用它們來繼續正在進行的通道切換操作。此外,還提供了一個通道切換響應模板,以及模板中切換定時IE的位置。skb只能在函式呼叫中使用。

wake_tx_queue

當新資料包新增到佇列時呼叫。

sync_rx_queues

處理RSS佇列中的所有掛起幀。這是一種同步,如果驅動程式在其RSS佇列中具有在當前採取的控制路徑操作(例如,解除關聯)之前接收但尚未處理的掛起幀,則需要此同步。

start_nan

加入現有NAN叢集,或建立一個新的NAN叢集。

stop_nan

離開NAN叢集。

nan_change_conf

更改NAN配置。cfg80211_nan_conf中的資料包含完整的新配置,並且更改指定相對於上次NAN配置更改了哪些引數。驅動程式獲取完整配置和已更改的引數,因為某些裝置可能需要完整配置,而其他裝置只需要已更改的引數。

add_nan_func

新增NAN函式。成功時返回0。不得在此呼叫的範圍之外引用cfg80211_nan_func中的資料。

del_nan_func

刪除NAN函式。驅動程式必須在刪除時呼叫帶有NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST原因程式碼的ieee80211_nan_func_terminated()。

can_aggregate_in_amsdu

呼叫以確定硬體是否支援在同一A-MSDU中聚合兩個特定幀。skb之間的關係應該是對稱和可傳遞的。請注意,雖然skb始終是真實幀,但head可能是也可能不是A-MSDU。

get_ftm_responder_stats

檢索FTM響應器統計資訊(如果可用)。統計資訊應該是累積的,目前沒有提供重置的方法。

start_pmsr

啟動對等測量(例如,FTM)(此呼叫可以休眠)

abort_pmsr

中止對等測量(此呼叫可以休眠)

set_tid_config

應用特定於TID的配置。此回撥可以休眠。

reset_tid_config

重置對等方的特定於TID的配置。此回撥可以休眠。

update_vif_offload

更新虛擬介面解除安裝標誌。此回撥可以休眠。

sta_set_4addr

呼叫以通知驅動程式站點何時開始/停止使用4地址模式

set_sar_specs

更新SAR(TX功率)設定。

sta_set_decap_offload

呼叫以通知驅動程式何時允許站點使用rx解封裝解除安裝

add_twt_setup

使用從對等方接收的TWT協議引數更新硬體。此回撥允許硬體檢查是否支援請求的引數以及是否有足夠的空間用於新協議。硬體應在twt結構的req_type欄位中設定協議結果。

twt_teardown_request

使用從對等方接收的TWT拆除請求更新硬體。

set_radar_background

配置可用於某些硬體上的雷達/CAC檢測的專用離線道鏈。此鏈不能用於傳輸或接收幀,並且它繫結到正在執行的wdev。後臺雷達/CAC檢測允許避免CAC停機,在選定的雷達通道上進行CAC檢測期間切換到不同的通道。呼叫者應將chandef指標設定為NULL,以停用後臺CAC/雷達檢測。

net_fill_forward_path

從.ndo_fill_forward_path呼叫以解析硬體流解除安裝的路徑

can_activate_links

檢查驅動程式是否支援特定的active_links點陣圖。

change_vif_links

更改介面上的有效連結,請注意,雖然刪除舊連結資訊仍然有效(link_conf指標),但在函式返回後可能會立即消失。如果從/到非MLO情況,則舊的或新的連結點陣圖可能為0。old陣列包含指向已刪除的舊bss_conf結構的指標,以防需要它們。此回撥可以休眠。

change_sta_links

更改站點的有效連結,類似於change_vif_links。此回撥可以休眠。請注意,站點也可以插入或刪除有效的連結,即,傳遞給sta_add/sta_state,其中sta->valid_links不為零。實際上,不能從具有valid_links更改為不具有它們。

set_hw_timestamp

啟用/停用TM/FTM幀的硬體時間戳。這不會在硬體重置時由mac80211恢復,因此驅動程式需要注意這一點。

net_setup_tc

從.ndo_setup_tc呼叫以準備來自vif的流的硬體流解除安裝。請注意,驅動程式不得假定vif driver_data此時有效,因為可以在netdev拆卸期間呼叫回撥。

can_neg_ttlm

對於管理介面,請求驅動程式確定是否可以接受請求的 TID 到鏈路的對映。 如果不接受,驅動程式可以建議首選對映,並使用建議的 TID 到鏈路對映修改 ttlm 引數。

prep_add_interface

準備新增介面。 驅動程式可以使用此回撥來準備新增新介面,例如,分配所需的資源等。此回撥不保證將新增指定型別的介面,因此實現此回撥的驅動程式需要處理此類情況。 型別是完整的 enum nl80211_iftype

描述

此結構包含驅動程式可以處理的各種回撥,或者在某些情況下必須處理的回撥,例如,將硬體配置到新通道或傳輸幀。

注意

如果未實現 vif_cfg_changedlink_info_changed,則會呼叫此回撥。

未實現。

struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops)

分配新的硬體裝置

引數

size_t priv_data_len

私有資料的長度

const struct ieee80211_ops *ops

此裝置的回撥

描述

每個硬體裝置必須呼叫此函式一次。 呼叫其他函式時,必須使用返回的指標來引用此裝置。 mac80211 為驅動程式分配一個私有資料區域,該區域由 struct ieee80211_hw 中的 priv 指向,此區域的大小作為 priv_data_len 給出。

返回

指向新硬體裝置的指標,如果出錯,則為 NULL

int ieee80211_register_hw(struct ieee80211_hw *hw)

註冊硬體裝置

引數

struct ieee80211_hw *hw

要註冊的裝置,由 ieee80211_alloc_hw() 返回

描述

必須在 mac80211 中的任何其他函式之前呼叫此函式。 請注意,在註冊硬體之前,您需要填寫包含的 wiphy 的資訊。

返回

成功時為 0。 否則為錯誤程式碼。

void ieee80211_unregister_hw(struct ieee80211_hw *hw)

登出硬體裝置

引數

struct ieee80211_hw *hw

要登出的硬體

描述

此函式指示 mac80211 釋放已分配的資源並從網路子系統登出網路裝置。

void ieee80211_free_hw(struct ieee80211_hw *hw)

釋放硬體描述符

引數

struct ieee80211_hw *hw

要釋放的硬體

描述

此函式會釋放所有已分配的內容,包括驅動程式的私有資料。 在呼叫此函式之前,必須呼叫 ieee80211_unregister_hw()

PHY 配置

待定

本章應描述 PHY 處理,包括啟動/停止回撥和使用的各種結構。

enum ieee80211_conf_flags

配置標誌

常量

IEEE80211_CONF_MONITOR

存在監視器介面 - 使用此介面來確定是否計算資料包的時間戳,請勿代替篩選器標誌!

IEEE80211_CONF_PS

啟用 802.11 省電模式(僅限管理模式)。 這是 IEEE 802.11-2007 第 11.2 節定義的省電模式,這意味著硬體仍然會喚醒以接收信標,能夠傳輸幀並接收可能的確認幀。 不要與硬體特定的喚醒/睡眠狀態混淆,驅動程式對此負責。 有關更多資訊,請參閱“省電支援”部分。

IEEE80211_CONF_IDLE

裝置正在執行,但處於空閒狀態; 如果設定了該標誌,驅動程式應準備好處理配置請求,但可能會盡可能地關閉裝置。 通常,當介面設定為 UP 但未關聯或掃描時,將設定此標誌,但當監視器介面處於活動狀態時,也可以取消設定此標誌。

IEEE80211_CONF_OFFCHANNEL

裝置當前不在其主操作通道上。

描述

定義 PHY 配置選項的標誌

struct ieee80211_conf

裝置配置

定義:

struct ieee80211_conf {
    u32 flags;
    int power_level, dynamic_ps_timeout;
    u16 listen_interval;
    u8 ps_dtim_period;
    u8 long_frame_max_tx_count, short_frame_max_tx_count;
    struct cfg80211_chan_def chandef;
    bool radar_enabled;
    enum ieee80211_smps_mode smps_mode;
};

成員

flags

上面定義的配置標誌

power_level

請求的傳輸功率(以 dBm 為單位),僅向後相容的值設定為所有介面的最小值

dynamic_ps_timeout

動態省電超時(以毫秒為單位),請參閱下面的省電文件。 僅當設定了 CONF_PS 標誌時,此變數才有效。

listen_interval

偵聽間隔,以信標間隔為單位

ps_dtim_period

我們連線到的 AP 的 DTIM 週期,用於省電。 在收到信標並且已知 DTIM 週期之前,不會啟用省電。

long_frame_max_tx_count

“長”幀(未受 RTS 保護的幀)的最大傳輸次數,在 802.11 中稱為“dot11LongRetryLimit”,但實際上是指傳輸次數而不是重試次數

short_frame_max_tx_count

“短”幀的最大傳輸次數,在 802.11 中稱為“dot11ShortRetryLimit”,但實際上是指傳輸次數而不是重試次數

chandef

要調諧到的通道定義

radar_enabled

是否啟用雷達檢測

smps_mode

空間多路複用省電模式; 請注意,當裝置未配置為 HT 通道時,使用 IEEE80211_SMPS_STATIC。 請注意,這僅在不使用通道上下文時有效,否則每個通道上下文都列出了鏈的數量。

描述

此結構指示驅動程式應如何配置硬體。

虛擬介面

待定

本章應描述與驅動程式相關的虛擬介面基礎知識(VLAN、MGMT 等不是)。 它應解釋 add_iface/remove_iface 回撥以及介面配置回撥的用法。

與 AP 模式相關的事項應在此處討論。

與支援多個介面相關的事項應在相應的章節中討論,此處應有一條重要提示,建議首先只允許在 STA 模式下使用單個介面!

struct ieee80211_vif

每個介面的資料

定義:

struct ieee80211_vif {
    enum nl80211_iftype type;
    struct ieee80211_vif_cfg cfg;
    struct ieee80211_bss_conf bss_conf;
    struct ieee80211_bss_conf __rcu *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
    u16 valid_links, active_links, dormant_links, suspended_links;
    struct ieee80211_neg_ttlm neg_ttlm;
    u8 addr[ETH_ALEN] ;
    bool addr_valid;
    bool p2p;
    u8 cab_queue;
    u8 hw_queue[IEEE80211_NUM_ACS];
    struct ieee80211_txq *txq;
    netdev_features_t netdev_features;
    u32 driver_flags;
    u32 offload_flags;
#ifdef CONFIG_MAC80211_DEBUGFS;
    struct dentry *debugfs_dir;
#endif;
    bool probe_req_reg;
    bool rx_mcast_action_reg;
    u8 drv_priv[] ;
};

成員

type

此虛擬介面的型別

cfg

vif 配置,請參閱 struct ieee80211_vif_cfg

bss_conf

此介面的 BSS 配置,無論是我們自己的還是我們關聯到的 BSS

link_conf

對於 MLD,每個鏈路的 BSS 配置,按鏈路 ID 索引

valid_links

有效鏈路的點陣圖,對於非 MLO,則為 0。

active_links

活動鏈路的點陣圖,對於非 MLO,則為 0。 驅動程式不應直接更改此點陣圖,而應使用為此目的設計的 API 呼叫。

dormant_links

由於分別通告或協商的 TTLM 而被停用/暫停的有效鏈路子集。 對於非 MLO,則為 0。

suspended_links

dormant_links 的子集,表示由於協商的 TTLM 而暫停的鏈路,將來可以透過解除 TTLM 協商來啟用這些鏈路。 對於非 MLO,則為 0。

neg_ttlm

協商的 TID 到鏈路對映資訊。 請參閱 struct ieee80211_neg_ttlm

addr

此介面的地址

addr_valid

指示地址是否正在使用。 對於被動監視器介面,設定為 false,在所有其他情況下設定為 true。

p2p

指示此 AP 或 STA 介面是否為 p2p 介面,即 GO 或 p2p-sta

cab_queue

信標後內容(實際上是 DTIM 信標)佇列,僅限 AP 模式

hw_queue

每個 AC 的硬體佇列

txq

多播資料 TX 佇列

netdev_features

此 vif 的硬體支援的 tx netdev 功能。 mac80211 將其初始化為 hw->netdev_features,驅動程式可以遮蔽掉特定的 tx 功能。 mac80211 將處理遮蔽解除安裝的軟體修復(GSO、CSUM)

driver_flags

驅動程式為此介面擁有的標誌/功能,這些需要在新增介面時設定(或清除),或者,如果驅動程式支援,則在執行時更改介面型別,mac80211 永遠不會觸及此欄位

offload_flags

802.3 -> 802.11 封裝解除安裝標誌,請參閱 enum ieee80211_offload_flags

debugfs_dir

debugfs 目錄項,驅動程式可以使用它來建立自己的每個介面的除錯檔案。 請注意,對於虛擬監視器介面(如果已請求),它將為 NULL。

probe_req_reg

應將探測請求報告給此介面的 mac80211。

rx_mcast_action_reg

應將多播操作幀報告給此介面的 mac80211。

drv_priv

供驅動程式使用的資料區域,將始終與 sizeof(void *) 對齊。

描述

此結構中的資料在虛擬介面的生命週期內持續存在,供驅動程式使用。

接收和傳輸處理

此處應包含哪些內容

待定

這應描述 mac80211/驅動程式中的接收和傳輸路徑以及傳輸狀態處理。

幀格式

作為一般規則,當幀在 mac80211 和驅動程式之間傳遞時,它們以 IEEE 802.11 標頭開頭,幷包含透過無線方式傳送的相同八位位元組,但 FCS 應由硬體計算。

但是,對於高階功能,此規則有各種例外情況

第一個例外是硬體加密和解密解除安裝,其中 IV/ICV 可能在硬體中生成,也可能不在硬體中生成。

其次,當硬體處理分片時,從 mac80211 傳遞到驅動程式的幀是 MSDU,而不是 MPDU。

資料包對齊

驅動程式始終需要將與雙位元組邊界對齊的資料包傳遞到堆疊。

此外,如果可能,它們應以保證包含的 IP 標頭與四位元組邊界對齊的方式對齊有效負載資料。 對於常規幀,這僅僅意味著將有效負載與四位元組邊界對齊(因為要麼直接包含 IP 標頭,要麼在其前面有長度可被四整除的 IV/RFC1042 標頭)。 如果有效負載資料未正確對齊,並且該架構不支援有效的未對齊操作,則 mac80211 將對齊資料。

但是,對於 A-MSDU 幀,有效負載資料地址必須產生兩個模四,因為 A-MSDU 幀中有 14 位元組的 802.3 標頭,這些標頭會將 IP 標頭進一步推回到四的倍數。 值得慶幸的是,這次的規範足夠健全,可以要求將每個 A-MSDU 子幀填充到四的倍數的長度。

不支援 Atheros 硬體新增的填充,它位於 802.11 標頭和有效負載之間; 在這種情況下,驅動程式需要移動 802.11 標頭,使其直接位於有效負載的前面。

從中斷呼叫到 mac80211

只有 ieee80211_tx_status_irqsafe()ieee80211_rx_irqsafe() 可以在硬體中斷上下文中呼叫。 底層驅動程式不得在硬體中斷上下文中呼叫任何其他函式。 如果需要這樣的呼叫,底層驅動程式應首先確認中斷,然後在之後執行 IEEE 802.11 程式碼呼叫,例如,從計劃的工作佇列甚至任務佇列函式。

注意:如果驅動程式選擇使用 _irqsafe() 函式,則它也不能

使用非 IRQ 安全函式!

函式/定義

enum mac80211_tx_info_flags

描述傳輸資訊/狀態的標誌

常量

IEEE80211_TX_CTL_REQ_TX_STATUS

需要此幀的 TX 狀態回撥。

IEEE80211_TX_CTL_ASSIGN_SEQ

驅動程式必須為此幀分配一個序列號,注意不要覆蓋片段號,並且僅當設定了 IEEE80211_TX_CTL_FIRST_FRAGMENT 標誌時才增加序列號。 mac80211 將正確地為 QoS 資料幀分配序列號,但無法為非 QoS 資料幀和管理幀正確地執行此操作,因為信標也需要來自該計數器的序列號,並且 mac80211 無法保證正確的排序。 如果設定了此標誌,驅動程式應指示硬體為幀分配序列號或自己分配一個序列號。 對比 IEEE 802.11-2007 7.1.3.4.1 第 3 段。 對於信標,此標誌將始終設定,對於沒有序列號欄位的幀,此標誌將始終清除。

IEEE80211_TX_CTL_NO_ACK

告訴底層不要等待確認

IEEE80211_TX_CTL_CLEAR_PS_FILT

清除目標站的省電篩選器

IEEE80211_TX_CTL_FIRST_FRAGMENT

這是幀的第一個片段

IEEE80211_TX_CTL_SEND_AFTER_DTIM

在 DTIM 信標之後傳送此幀

IEEE80211_TX_CTL_AMPDU

此幀應作為 A-MPDU 的一部分發送

IEEE80211_TX_CTL_INJECTED

幀已注入,mac80211 內部。

IEEE80211_TX_STAT_TX_FILTERED

由於目標 STA 處於省電模式,因此未傳輸該幀。 請注意,為了避免競爭情況,篩選器必須由硬體或韌體在收到指示站進入睡眠狀態的幀時設定(必須在裝置上完成以篩選已在佇列中的幀),並且只有在 mac80211 透過設定 IEEE80211_TX_CTL_CLEAR_PS_FILT 給出 OK 後才能取消設定(請參閱上文),因為只有這樣才能保證硬體佇列中沒有更多幀。

IEEE80211_TX_STAT_ACK

幀已確認

IEEE80211_TX_STAT_AMPDU

幀已聚合,因此狀態適用於整個聚合。

IEEE80211_TX_STAT_AMPDU_NO_BACK

未返回塊確認,因此請考慮使用塊確認請求 (BAR)。

IEEE80211_TX_CTL_RATE_CTRL_PROBE

mac80211 內部,可以由速率控制演算法設定以指示探測速率,對於分片幀將被清除(最後一個片段除外)

IEEE80211_TX_INTFL_OFFCHAN_TX_OK

mac80211 內部。 用於指示在佇列因異通道操作而停止時可以傳輸幀。

IEEE80211_TX_CTL_HW_80211_ENCAP

此幀使用硬體封裝(標頭轉換)

IEEE80211_TX_INTFL_RETRIED

完全在 mac80211 內部,用於指示幀已因 PS 而重試

IEEE80211_TX_INTFL_DONT_ENCRYPT

完全在 mac80211 內部,用於指示不應加密幀

IEEE80211_TX_CTL_NO_PS_BUFFER

此幀是對輪詢幀(PS-Poll 或 uAPSD)或不可緩衝的 MMPDU 的響應,即使站處於省電模式,也必須傳送。

IEEE80211_TX_CTL_MORE_FRAMES

在當前幀之後,將有更多幀傳遞到傳輸函式,驅動程式可以使用它僅在取消設定或佇列已滿時才啟動 DMA 佇列。

IEEE80211_TX_INTFL_RETRANSMISSION

此幀在 TX 狀態後重新傳輸,因為目標已休眠,不得再次修改(沒有 seqno 分配、加密等)

IEEE80211_TX_INTFL_MLME_CONN_TX

此幀由 MLME 程式碼傳輸以進行連線建立,這表示其狀態應啟動 MLME 狀態機。

IEEE80211_TX_INTFL_NL80211_FRAME_TX

幀是透過 nl80211 MLME 命令請求的(mac80211 內部,用於確定是否將 TX 狀態傳送到使用者空間)

IEEE80211_TX_CTL_LDPC

告訴驅動程式為此幀使用 LDPC

IEEE80211_TX_CTL_STBC

為此幀啟用空時塊編碼 (STBC) 並選擇它可以使用的最大流數。

IEEE80211_TX_CTL_TX_OFFCHAN

將此資料包標記為在異通道通道上進行傳輸,如果在硬體中完成了保留在通道上的解除安裝 - 正常資料包仍然流動,並期望裝置正確處理。

IEEE80211_TX_INTFL_TKIP_MIC_FAILURE

將此資料包標記為用於 TKIP 測試。 它將使用不正確的 Michael MIC 金鑰傳送出去,以允許測試 TKIP 對策。

IEEE80211_TX_CTL_NO_CCK_RATE

此幀將以非 CCK 速率傳送。 此標誌實際上用於管理幀,尤其是用於未以 2GHz 頻段的 CCK 速率傳送的 P2P 幀。

IEEE80211_TX_STATUS_EOSP

此資料包標記服務週期的結束,當報告其狀態時,服務週期結束。 對於 mac80211 傳輸的 SP 中的幀,已設定該標誌; 對於驅動程式幀,驅動程式可以設定此標誌。 它也用於對 PS-Poll 響應執行相同的操作。

IEEE80211_TX_CTL_USE_MINRATE

此幀將以最低速率傳送。 當 nullfunc 用於連線監視目的時,此標誌用於以最低速率傳送 nullfunc 幀。

IEEE80211_TX_CTL_DONTFRAG

即使資料包將按大小分片,也不要分片該資料包(這是可選的,僅用於監視器注入)。

IEEE80211_TX_STAT_NOACK_TRANSMITTED

已成功傳輸標記有 IEEE80211_TX_CTL_NO_ACK 的幀,沒有任何錯誤(如特定於驅動程式/HW 的問題)。 對於未使用 IEEE80211_TX_CTL_NO_ACK 請求無確認行為的幀,不得設定此標誌。

描述

這些標誌與 ieee80211_tx_infoflags 成員一起使用。

注意

如果您必須向列舉中新增新標誌,請不要

在必要時忘記更新 IEEE80211_TX_TEMPORARY_FLAGS

enum mac80211_tx_control_flags

描述傳輸控制的標誌

常量

IEEE80211_TX_CTRL_PORT_CTRL_PROTO

此幀是埠控制協議幀(例如 EAP)

IEEE80211_TX_CTRL_PS_RESPONSE

此幀是對輪詢幀(PS-Poll 或 uAPSD)的響應。

IEEE80211_TX_CTRL_RATE_INJECT

此幀使用速率資訊注入

IEEE80211_TX_CTRL_AMSDU

此幀是 A-MSDU 幀

IEEE80211_TX_CTRL_FAST_XMIT

此幀正在透過 fast_xmit 路徑

IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP

此幀跳過網格路徑查詢

IEEE80211_TX_INTCFL_NEED_TXPROCESSING

完全在 mac80211 內部,用於指示掛起的幀在傳送之前需要 TX 處理。

IEEE80211_TX_CTRL_NO_SEQNO

不要覆蓋已分配給此幀的序列號。

IEEE80211_TX_CTRL_DONT_REORDER

相對於其他設定了此標誌的幀,不應重新排序此幀,無論其 QoS TID 或其他優先順序欄位值如何。

IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX

第一個 MLO TX,主要在內部用於序列號分配

IEEE80211_TX_CTRL_DONT_USE_RATE_MASK

不要對此幀使用速率掩碼,該幀是由於掃描或異通道 TX 而傳輸的,而不是在介面上的正常操作中傳輸的。

IEEE80211_TX_CTRL_MLO_LINK

如果不是 IEEE80211_LINK_UNSPECIFIED,則應在特定鏈路上傳送此幀。 這實際上只與不存在資料的幀相關,並且也不用於 802.3 格式的幀。 請注意,即使幀位於特定鏈路上,如果它用於 MLD,則地址轉換仍然可能適用。

描述

這些標誌用於 tx_info->control.flags。

enum mac80211_rate_control_flags

由速率控制演算法設定的每個速率的標誌。

常量

IEEE80211_TX_RC_USE_RTS_CTS

將 RTS/CTS 交換用於此速率。

IEEE80211_TX_RC_USE_CTS_PROTECT

需要 CTS 到自身的保護。 如果當前 BSS 需要 ERP 保護,則設定此標誌。

IEEE80211_TX_RC_USE_SHORT_PREAMBLE

使用短前導碼。

IEEE80211_TX_RC_MCS

HT 速率。

IEEE80211_TX_RC_GREEN_FIELD

指示是否應在 Greenfield 模式下使用此速率。

IEEE80211_TX_RC_40_MHZ_WIDTH

指示通道寬度是否應為 40 MHz。

IEEE80211_TX_RC_DUP_DATA

如果當前通道型別為 NL80211_CHAN_HT40MINUS 或 NL80211_CHAN_HT40PLUS,則應在兩個相鄰的 20 MHz 通道上傳送幀。

IEEE80211_TX_RC_SHORT_GI

短保護間隔應用於此速率。

IEEE80211_TX_RC_VHT_MCS

VHT MCS 速率,在這種情況下,idx 欄位分為較高的 4 位 (Nss) 和較低的 4 位 (MCS 編號)

IEEE80211_TX_RC_80_MHZ_WIDTH

指示 80 MHz 傳輸

IEEE80211_TX_RC_160_MHZ_WIDTH

指示 160 MHz 傳輸(尚不支援 80+80)

描述

這些標誌由速率控制演算法在 tx 期間為每個速率設定,位於 struct ieee80211_tx_rateflags 成員中。

struct ieee80211_tx_rate

速率選擇/狀態

定義:

struct ieee80211_tx_rate {
    s8 idx;
    u16 count:5, flags:11;
};

成員

idx

嘗試使用的速率索引

count

在此速率下進行的嘗試次數,然後再轉到下一個速率

flags

速率控制標誌(enum mac80211_rate_control_flags

描述

idx 的值為 -1 表示速率無效,如果在重試速率陣列中使用,則表示不應再嘗試任何速率。

用於傳輸狀態報告時,驅動程式應始終報告速率及其使用的標誌。

struct ieee80211_tx_info 在控制資訊中包含這些結構的陣列,它將由速率控制演算法根據應傳送的內容填充。 例如,如果此陣列包含以下資訊,格式為 { , }:

{ 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }

這意味著應以速率 3 最多傳輸兩次該幀,以速率 2 最多傳輸兩次,如果未收到確認,則以速率 1 最多傳輸四次。 假設在第五次嘗試後對等方確認了該幀,則狀態資訊應包含

{ 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ...

因為它以速率 3 傳輸了兩次,以速率 2 傳輸了兩次,並且以速率 1 傳輸了一次,之後我們收到了確認。

struct ieee80211_tx_info

skb 傳輸資訊

定義:

struct ieee80211_tx_info {
    u32 flags;
    u32 band:3,status_data_idr:1,status_data:13,hw_queue:4, tx_time_est:10;
    union {
        struct {
            union {
                struct {
                    struct ieee80211_tx_rate rates[ IEEE80211_TX_MAX_RATES];
                    s8 rts_cts_rate_idx;
                    u8 use_rts:1;
                    u8 use_cts_prot:1;
                    u8 short_preamble:1;
                    u8 skip_table:1;
                    u8 antennas:2;
                };
                unsigned long jiffies;
            };
            struct ieee80211_vif *vif;
            struct ieee80211_key_conf *hw_key;
            u32 flags;
            codel_time_t enqueue_time;
        } control;
        struct {
            u64 cookie;
        } ack;
        struct {
            struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
            s32 ack_signal;
            u8 ampdu_ack_len;
            u8 ampdu_len;
            u8 antenna;
            u8 pad;
            u16 tx_time;
            u8 flags;
            u8 pad2;
            void *status_driver_data[16 / sizeof(void *)];
        } status;
        struct {
            struct ieee80211_tx_rate driver_rates[ IEEE80211_TX_MAX_RATES];
            u8 pad[4];
            void *rate_driver_data[ IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)];
        };
        void *driver_data[ IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
    };
};

成員

flags

傳輸資訊標誌,如上定義

band

要傳輸的頻段(例如,用於檢查競爭),如果介面是 MLD,則無效,因為我們不知道將在哪個鏈路上傳輸幀

status_data_idr

指示狀態資料是為 ack 幀分配的 IDR ID

status_data

TX 狀態處理的內部資料,私下分配,另請參閱 enum ieee80211_status_data 以獲取內部文件

hw_queue

將幀放入的 HW 佇列,skb_get_queue_mapping() 給出 AC

tx_time_est

TX 時間估計,以 4us 為單位,內部使用

{unnamed_union}

anonymous

control

控制資料的聯合部分

{unnamed_union}

anonymous

{unnamed_struct}

anonymous

control.rates

要嘗試的 TX 速率陣列

control.rts_cts_rate_idx

RTS 或 CTS 的速率

control.use_rts

使用 RTS

control.use_cts_prot

使用 RTS/CTS

control.short_preamble

使用短前導碼(僅限 CCK)

control.skip_table

跳過外部配置的速率表

control.jiffies

省電客戶端的到期時間戳

control.vif

虛擬介面(可能為 NULL)

control.hw_key

用於加密的金鑰(可能為 NULL)

control.flags

控制標誌,請參閱 enum mac80211_tx_control_flags

control.enqueue_time

排隊時間 (for iTXQs)

ack

純 ACK 資料的聯合部分

ack.cookie

ACK 的 cookie

status

狀態資料的聯合部分

status.rates

嘗試的速率

status.ack_signal

ACK 訊號

status.ampdu_ack_len

AMPDU ack 長度

status.ampdu_len

AMPDU 長度

status.antenna

(舊版,僅為 iwlegacy 保留)

status.tx_time

傳輸消耗的空中時間; 請注意,這僅用於 WMM AC,不用於空中時間公平性

status.flags

狀態標誌,請參閱 enum mac80211_tx_status_flags

status.status_driver_data

驅動程式使用區域

{unnamed_struct}

anonymous

driver_rates

control.rates 的別名,用於保留空間

pad

填充

rate_driver_data

如果驅動程式需要 control.rates,則驅動程式使用區域

driver_data

driver_data 指標陣列

描述

此結構放置在 skb->cb 中用於三個用途
  1. mac80211 TX 控制 - mac80211 告訴驅動程式要做什麼

  2. 驅動程式內部使用(如果適用)

  3. TX 狀態資訊 - 驅動程式告訴 mac80211 發生了什麼

void ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)

清除 TX 狀態

引數

struct ieee80211_tx_info *info

要清除的 struct ieee80211_tx_info

描述

當驅動程式將 skb 傳回 mac80211 時,它必須報告 TX 狀態中的許多內容。此函式清除 TX 狀態中的所有內容,但速率控制資訊除外(它會清除計數,因為無論如何都需要填寫該計數)。

注意

雖然速率陣列保持不變,但這將擦除所有

info 中的 driver_data 欄位,因此驅動程式有責任在呼叫此幫助函式後恢復它需要的任何欄位。

enum mac80211_rx_flags

接收標誌

常量

RX_FLAG_MMIC_ERROR

在此幀上報告了 Michael MIC 錯誤。與 RX_FLAG_MMIC_STRIPPED 一起使用。

RX_FLAG_DECRYPTED

此幀已在硬體中解密。

RX_FLAG_ONLY_MONITOR

僅將幀報告給監視器介面,而不以任何常規方式處理它。如果驅動程式解除安裝某些幀,但仍希望報告它們以用於嗅探目的,這將非常有用。

RX_FLAG_MMIC_STRIPPED

Michael MIC 已從此幀中剝離,驗證已由硬體完成。

RX_FLAG_IV_STRIPPED

IV 和 ICV 已從此幀中剝離。如果設定了此標誌,則堆疊無法進行任何重放檢測,因此驅動程式或硬體必須執行該操作。

RX_FLAG_FAILED_FCS_CRC

如果幀上的 FCS 檢查失敗,請設定此標誌。

RX_FLAG_FAILED_PLCP_CRC

如果 PCLP 檢查失敗,請設定此標誌。

RX_FLAG_MACTIME_IS_RTAP_TS64

RX 狀態中傳遞的時間戳 mactime 僅用於 radiotap 時間戳標頭,否則不是有效的 mactime 值。請注意,這是一個單獨的標誌,以便我們繼續看到 RX_FLAG_MACTIME 未設定。另請注意,在這種情況下,時間戳報告為 64 位寬,而不僅僅是 32 位。

RX_FLAG_NO_SIGNAL_VAL

訊號強度值不存在。僅對資料幀有效(主要是 A-MPDU)

RX_FLAG_AMPDU_DETAILS

A-MPDU 詳細資訊是已知的,特別是引用編號 (ampdu_reference) 必須填充,並且對於每個 A-MPDU 必須是一個不同的數字

RX_FLAG_PN_VALIDATED

目前僅對 CCMP/GCMP 幀有效,此標誌指示已驗證 PN 的重放保護。請注意,此標誌目前也僅在幀也被解密時才受支援(即必須設定 RX_FLAG_DECRYPTED

RX_FLAG_DUP_VALIDATED

如果驅動程式自己進行了去重,則應設定此標誌。

RX_FLAG_AMPDU_LAST_KNOWN

最後一個子幀是已知的,應在單個 A-MPDU 的所有子幀上設定

RX_FLAG_AMPDU_IS_LAST

此子幀是 A-MPDU 的最後一個子幀

RX_FLAG_AMPDU_DELIM_CRC_ERROR

在此子幀上檢測到分隔符 CRC 錯誤

RX_FLAG_MACTIME

如果此欄位為非零值,則 RX 狀態 (mactime 欄位) 中傳遞的時間戳有效,並且取樣時間戳的位置取決於該值。

RX_FLAG_MACTIME_PLCP_START

RX 狀態 (mactime 欄位) 中傳遞的時間戳有效,並且包含接收到 SYNC 前導碼的時間。

RX_FLAG_MACTIME_START

RX 狀態 (mactime 欄位) 中傳遞的時間戳有效,並且包含接收到 MPDU 的第一個符號的時間。這在監視器模式和正確的 IBSS 合併中非常有用。

RX_FLAG_MACTIME_END

RX 狀態 (mactime 欄位) 中傳遞的時間戳有效,並且包含接收到 MPDU 的最後一個符號(包括 FCS)的時間。

RX_FLAG_SKIP_MONITOR

處理幀並將幀報告給除監視器介面之外的所有介面。如果驅動程式解除安裝某些幀,但仍希望報告它們以用於嗅探目的,這將非常有用。

RX_FLAG_AMSDU_MORE

由於效能原因,某些驅動程式可能更喜歡報告單獨的 A-MSDU 子幀,而不是一個巨大的幀。來自 A-MSDU 的所有 MSDU(最後一個 MSDU 除外)都應設定此標誌。例如,如果 A-MSDU 有 3 個幀,則前 2 個幀必須設定該標誌,而第 3 個(最後一個)幀不得設定該標誌。該標誌用於正確處理重傳/重複恢復,因為 A-MSDU 子幀共享相同的序列號。報告的子幀可以是常規 MSDU 或單個 A-MSDU。子幀不得與其他幀交錯。

RX_FLAG_RADIOTAP_TLV_AT_END

此幀在 skb->data(802.11 標頭之前)中包含 radiotap TLV。如果使用,則 SKB 的 mac_header 指標必須設定為指向 TLV 之後的 802.11 標頭,並且驅動程式必須清除新增到 TLV 資料之後以對齊到 4 的任何填充,並將 TLV 放入 skb 中。

RX_FLAG_MIC_STRIPPED

此資料包的 mic 已被剝離。解密由硬體完成

RX_FLAG_ALLOW_SAME_PN

允許與之前的同一資料包相同的 PN。這用於 AMSDU 子幀,這些子幀可以與第一個子幀具有相同的 PN。

RX_FLAG_ICV_STRIPPED

ICV 已從此幀中剝離。CRC 檢查必須在硬體中完成。

RX_FLAG_AMPDU_EOF_BIT

此幀的 A-MPDU 分隔符中 EOF 位的值

RX_FLAG_AMPDU_EOF_BIT_KNOWN

EOF 值是已知的

RX_FLAG_RADIOTAP_HE

HE radiotap 資料存在 (struct ieee80211_radiotap_he, mac80211 將填寫

  • DATA3_DATA_MCS

  • DATA3_DATA_DCM

  • DATA3_CODING

  • DATA5_GI

  • DATA5_DATA_BW_RU_ALLOC

  • DATA6_NSTS

  • DATA3_STBC

來自 RX 資訊資料,因此在構建此資料時將這些資料保留為零)

RX_FLAG_RADIOTAP_HE_MU

HE MU radiotap 資料存在 (struct ieee80211_radiotap_he_mu)

RX_FLAG_RADIOTAP_LSIG

L-SIG radiotap 資料存在

RX_FLAG_NO_PSDU

僅將幀用於 radiotap 報告,並在其中包含“0 長度 PSDU”欄位。它的值在 struct ieee80211_rx_status 中。請注意,如果此值未知,則不應報告該幀。

RX_FLAG_8023

該幀具有 802.3 標頭(由硬體或驅動程式執行的解封裝解除安裝)

描述

這些標誌與 struct ieee80211_rx_statusflag 成員一起使用。

enum mac80211_rx_encoding_flags

MCS & 頻寬標誌

常量

RX_ENC_FLAG_SHORTPRE

此幀使用了短前導碼

RX_ENC_FLAG_SHORT_GI

使用了短保護間隔

RX_ENC_FLAG_HT_GF

此幀是在 HT-greenfield 傳輸中接收的,如果驅動程式填充此值,則應將 IEEE80211_RADIOTAP_MCS_HAVE_FMT 新增到 hw.radiotap_mcs_details 以通告該事實。

RX_ENC_FLAG_STBC_MASK

STBC 2 位位掩碼。1 - Nss=1, 2 - Nss=2, 3 - Nss=3

RX_ENC_FLAG_LDPC

使用了 LDPC

RX_ENC_FLAG_BF

資料包已進行波束成形

struct ieee80211_rx_status

接收狀態

定義:

struct ieee80211_rx_status {
    u64 mactime;
    union {
        u64 boottime_ns;
        ktime_t ack_tx_hwtstamp;
    };
    u32 device_timestamp;
    u32 ampdu_reference;
    u32 flag;
    u16 freq: 13, freq_offset: 1;
    u8 enc_flags;
    u8 encoding:3, bw:4;
    union {
        struct {
            u8 he_ru:3;
            u8 he_gi:2;
            u8 he_dcm:1;
        };
        struct {
            u8 ru:4;
            u8 gi:2;
        } eht;
    };
    u8 rate_idx;
    u8 nss;
    u8 rx_flags;
    u8 band;
    u8 antenna;
    s8 signal;
    u8 chains;
    s8 chain_signal[IEEE80211_MAX_CHAINS];
    u8 zero_length_psdu_type;
    u8 link_valid:1, link_id:4;
};

成員

mactime

當第一個資料符號 (MPDU) 到達硬體時,64 位時間同步函式 (TSF) 計時器的微秒值。

{unnamed_union}

anonymous

boottime_ns

接收到幀的 CLOCK_BOOTTIME 時間戳,這僅適用於更新掃描快取的信標和探測響應。

ack_tx_hwtstamp

確認 TX 的硬體時間戳(以納秒為單位)。僅計時測量和精細計時測量操作幀需要。僅由啟用了時間戳的裝置報告。

device_timestamp

裝置的任意時間戳,mac80211 不使用它,但可以儲存它並將其傳遞迴驅動程式以進行同步

ampdu_reference

A-MPDU 引用編號,對於每個 A-MPDU 必須是一個不同的值,但對於一個 A-MPDU 中的每個子幀必須相同

flag

RX_FLAG_*

freq

接收此幀時無線電調諧到的頻率,以 MHz 為單位。此欄位必須為管理幀設定,但對於資料(其他)幀不是嚴格必需的 - 對於這些幀,它僅影響 radiotap 報告。

freq_offset

freq 的正偏移為 500Khz。

enc_flags

使用來自 enum mac80211_rx_encoding_flags 的位

encoding

enum mac80211_rx_encoding

bw

enum rate_info_bw

{unnamed_union}

anonymous

{unnamed_struct}

anonymous

he_ru

HE RU, 來自 enum nl80211_he_ru_alloc

he_gi

HE GI, 來自 enum nl80211_he_gi

he_dcm

HE DCM 值

eht

EHT 特定速率資訊

eht.ru

EHT RU, 來自 enum nl80211_eht_ru_alloc

eht.gi

EHT GI, 來自 enum nl80211_eht_gi

rate_idx

資料速率在頻帶支援的速率中的索引,如果使用 HT 或 VHT,則為 MCS 索引 (RX_FLAG_HT/RX_FLAG_VHT)

nss

流的數量(僅 VHT、HE 和 EHT)

rx_flags

mac80211 的內部 RX 標誌

band

接收此幀時的活動頻帶

antenna

使用的天線

signal

接收此幀時的訊號強度,以 dBm、dB 或未指定單位表示,具體取決於硬體功能標誌 IEEE80211_HW_SIGNAL_*

chains

已填充單獨訊號強度值的接收鏈的位掩碼。

chain_signal

每鏈訊號強度,以 dBm 為單位(與 signal 不同,不支援 dB 或未指定單位)

zero_length_psdu_type

0 長度 PSDU 的 radiotap 型別

link_valid

如果由 link_id 標識的連結有效。僅當連線為 MLO 時才設定此標誌。

link_id

用於接收資料包的連結的 ID。這與 link_valid 一起使用。

描述

低階驅動程式應在 skb 的控制緩衝區 (cb) 中為每個接收的幀向 802.11 程式碼提供此資訊(硬體支援的子集)。

void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)

接收幀

引數

struct ieee80211_hw *hw

此幀進入的硬體

struct sk_buff *skb

接收的緩衝區,在此呼叫後歸 mac80211 所有

描述

使用此函式將接收到的幀傳遞給 mac80211。skb 中的接收緩衝區必須以 IEEE 802.11 標頭開頭。在使用分頁 skb 的情況下,建議驅動程式將幀的 ieee80211 標頭放在 skb 的線性部分上,以避免堆疊進行記憶體分配和/或 memcpy。

不得在 IRQ 上下文中呼叫此函式。對單個硬體的此函式的呼叫必須彼此同步。對該函式 ieee80211_rx_ni()ieee80211_rx_ni() 的呼叫不得混合用於單個硬體。不得與 ieee80211_tx_status_skb()ieee80211_tx_status_ni() 同時執行。

在程序上下文中,請改用 ieee80211_rx_ni()

void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)

接收幀

引數

struct ieee80211_hw *hw

此幀進入的硬體

struct sk_buff *skb

接收的緩衝區,在此呼叫後歸 mac80211 所有

描述

類似於 ieee80211_rx(),但可以在 IRQ 上下文中呼叫(內部延遲到 tasklet。)

對該函式 ieee80211_rx()ieee80211_rx_ni() 的呼叫不得混合用於單個硬體。不得與 ieee80211_tx_status_skb()ieee80211_tx_status_ni() 同時執行。

void ieee80211_rx_ni(struct ieee80211_hw *hw, struct sk_buff *skb)

接收幀(在程序上下文中)

引數

struct ieee80211_hw *hw

此幀進入的硬體

struct sk_buff *skb

接收的緩衝區,在此呼叫後歸 mac80211 所有

描述

類似於 ieee80211_rx(),但可以在程序上下文中呼叫(內部停用 bottom halves)。

對該函式 ieee80211_rx()ieee80211_rx_irqsafe() 的呼叫不得混合用於單個硬體。不得與 ieee80211_tx_status_skb()ieee80211_tx_status_ni() 同時執行。

void ieee80211_tx_status_skb(struct ieee80211_hw *hw, struct sk_buff *skb)

傳輸狀態回撥

引數

struct ieee80211_hw *hw

傳輸幀的硬體

struct sk_buff *skb

傳輸的幀,在此呼叫後歸 mac80211 所有

描述

在傳輸所有傳輸的幀後呼叫此函式。允許不對多播幀呼叫此函式,但這會影響統計資訊。

不得在 IRQ 上下文中呼叫此函式。對單個硬體的此函式的呼叫必須彼此同步。對該函式 ieee80211_tx_status_ni()ieee80211_tx_status_ni() 的呼叫不得混合用於單個硬體。不得與 ieee80211_rx()ieee80211_rx_ni() 同時執行。

void ieee80211_tx_status_ni(struct ieee80211_hw *hw, struct sk_buff *skb)

傳輸狀態回撥(在程序上下文中)

引數

struct ieee80211_hw *hw

傳輸幀的硬體

struct sk_buff *skb

傳輸的幀,在此呼叫後歸 mac80211 所有

描述

類似於 ieee80211_tx_status_skb(),但可以在程序上下文中呼叫。

對該函式 ieee80211_tx_status_skb()ieee80211_tx_status_irqsafe() 的呼叫不得混合用於單個硬體。

void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)

IRQ 安全的傳輸狀態回撥

引數

struct ieee80211_hw *hw

傳輸幀的硬體

struct sk_buff *skb

傳輸的幀,在此呼叫後歸 mac80211 所有

描述

類似於 ieee80211_tx_status_skb(),但可以在 IRQ 上下文中呼叫(內部延遲到 tasklet。)

對該函式 ieee80211_tx_status_skb()ieee80211_tx_status_ni() 的呼叫不得混合用於單個硬體。

void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const void *frame, size_t frame_len, const struct ieee80211_tx_info *frame_txctl, struct ieee80211_rts *rts)

RTS 幀生成函式

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

struct ieee80211_vif *vif

來自 add_interface 回撥的 struct ieee80211_vif 指標。

const void *frame

指向將受 RTS 保護的幀的指標。

size_t frame_len

幀長度(以八位位元組為單位)。

const struct ieee80211_tx_info *frame_txctl

幀的 struct ieee80211_tx_info

struct ieee80211_rts *rts

儲存 RTS 幀的緩衝區。

描述

如果 RTS 幀由主機系統生成(即不在硬體/韌體中),則低階驅動程式使用此函式從 802.11 程式碼接收下一個 RTS 幀。低階驅動程式負責在需要 RTS 幀之前呼叫此函式。

__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, struct ieee80211_vif *vif, size_t frame_len, const struct ieee80211_tx_info *frame_txctl)

獲取 RTS 幀的持續時間欄位

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

struct ieee80211_vif *vif

來自 add_interface 回撥的 struct ieee80211_vif 指標。

size_t frame_len

將受 RTS 保護的幀的長度。

const struct ieee80211_tx_info *frame_txctl

幀的 struct ieee80211_tx_info

描述

如果在韌體中生成 RTS,但主機系統必須提供持續時間欄位,則低階驅動程式使用此函式以小端位元組序接收持續時間欄位值。

返回

持續時間。

void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const void *frame, size_t frame_len, const struct ieee80211_tx_info *frame_txctl, struct ieee80211_cts *cts)

CTS-to-self 幀生成函式

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

struct ieee80211_vif *vif

來自 add_interface 回撥的 struct ieee80211_vif 指標。

const void *frame

指向將受 CTS-to-self 保護的幀的指標。

size_t frame_len

幀長度(以八位位元組為單位)。

const struct ieee80211_tx_info *frame_txctl

幀的 struct ieee80211_tx_info

struct ieee80211_cts *cts

儲存 CTS-to-self 幀的緩衝區。

描述

如果 CTS-to-self 幀由主機系統生成(即不在硬體/韌體中),則低階驅動程式使用此函式從 802.11 程式碼接收下一個 CTS-to-self 幀。低階驅動程式負責在需要 CTS-to-self 幀之前呼叫此函式。

__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, struct ieee80211_vif *vif, size_t frame_len, const struct ieee80211_tx_info *frame_txctl)

獲取 CTS-to-self 幀的持續時間欄位

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

struct ieee80211_vif *vif

來自 add_interface 回撥的 struct ieee80211_vif 指標。

size_t frame_len

將受 CTS-to-self 保護的幀的長度。

const struct ieee80211_tx_info *frame_txctl

幀的 struct ieee80211_tx_info

描述

如果在韌體中生成 CTS-to-self,但主機系統必須提供持續時間欄位,則低階驅動程式使用此函式以小端位元組序接收持續時間欄位值。

返回

持續時間。

__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_band band, size_t frame_len, struct ieee80211_rate *rate)

計算幀的持續時間欄位

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

struct ieee80211_vif *vif

來自 add_interface 回撥的 struct ieee80211_vif 指標。

enum nl80211_band band

計算幀持續時間的頻段

size_t frame_len

幀的長度。

struct ieee80211_rate *rate

幀的傳輸速率(單位為 100kbps)。

描述

計算某個通用幀的持續時間欄位,給定其長度和傳輸速率(單位為 100kbps)。

返回

持續時間。

void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)

喚醒特定佇列

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

int queue

佇列號(從零開始計數)。

描述

驅動程式必須使用此函式,而不是 netif_wake_queue。

void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)

停止特定佇列

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

int queue

佇列號(從零開始計數)。

描述

驅動程式必須使用此函式,而不是 netif_stop_queue。

int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)

測試佇列的狀態

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

int queue

佇列號(從零開始計數)。

描述

驅動程式必須使用此函式,而不是 netif_queue_stopped。

返回

如果佇列已停止,則為 true。否則為 false

void ieee80211_stop_queues(struct ieee80211_hw *hw)

停止所有佇列

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

描述

驅動程式必須使用此函式,而不是 netif_tx_stop_all_queues。

void ieee80211_wake_queues(struct ieee80211_hw *hw)

喚醒所有佇列

引數

struct ieee80211_hw *hw

ieee80211_alloc_hw() 獲取的指標。

描述

驅動程式必須使用此函式,而不是 netif_tx_wake_all_queues。

幀過濾

mac80211 需要檢視許多管理幀才能正常執行,並且使用者可能希望在監視模式下檢視更多幀。但是,為了獲得最佳 CPU 使用率和功耗,最好儘可能少地使幀滲透到堆疊中。因此,硬體應儘可能多地進行過濾。

為了實現這一點,mac80211 使用過濾標誌(見下文)來告訴驅動程式的 configure_filter() 函式哪些幀應傳遞給 mac80211,哪些應過濾掉。

在呼叫 configure_filter() 之前,將使用 mc_countmc_list 引數呼叫 prepare_multicast() 回撥,這些引數是所有虛擬介面的組合多播地址列表。它的使用是可選的,它返回一個 u64,該 u64 被傳遞給 configure_filter()。此外,configure_filter() 具有 changed_flags 引數,用於指示哪些標誌已更改,以及 total_flags 引數,用於指示新的標誌狀態。

如果您的裝置沒有多播地址過濾器,則您的驅動程式需要同時檢查 FIF_ALLMULTI 標誌和 mc_count 引數,以檢視是否應接受或丟棄多播幀。

必須清除 total_flags 中所有不受支援的標誌。如果硬體無法_傳遞_幀到堆疊,則硬體不支援標誌。否則,驅動程式必須忽略該標誌,但不要清除它。如果您無法將資料包型別傳遞到堆疊(因此硬體始終會過濾它),則您_只能_清除該標誌(宣告不支援 mac80211 的標誌)。因此,例如,如果您的硬體始終過濾控制幀,則應清除 FIF_CONTROL。如果您的硬體始終將控制幀傳遞到核心並且無法過濾它們,則您_不_清除 FIF_CONTROL 標誌。此規則也適用於所有其他 FIF 標誌。

enum ieee80211_filter_flags

硬體過濾標誌

常量

FIF_ALLMULTI

傳遞所有多播幀,如果使用者請求或硬體無法按多播地址進行過濾,則使用此標誌。

FIF_FCSFAIL

傳遞 FCS 失敗的幀(但您需要為它們設定 RX_FLAG_FAILED_FCS_CRC

FIF_PLCPFAIL

傳遞 PLCP CRC 失敗的幀(但您需要為它們設定 RX_FLAG_FAILED_PLCP_CRC

FIF_BCN_PRBRESP_PROMISC

此標誌在掃描期間設定,以指示硬體不應按 BSSID 過濾信標或探測響應。過濾它們可以大大減少 mac80211 需要執行的處理量和 CPU 喚醒次數,因此如果可能,您應該遵守此標誌。

FIF_CONTROL

傳遞定址到此站點的控制幀(PS Poll 除外)

FIF_OTHER_BSS

傳遞目標為其他 BSS 的幀

FIF_PSPOLL

傳遞 PS Poll 幀

FIF_PROBE_REQ

傳遞探測請求幀

FIF_MCAST_ACTION

傳遞多播 Action 幀

描述

這些標誌確定硬體中的過濾器應被程式設計為允許哪些幀透過,以及哪些幀不應傳遞到堆疊。傳遞比請求的幀更多的幀始終是安全的,但這會對功耗產生負面影響。

mac80211 工作佇列

mac80211 為驅動程式和內部 mac80211 使用提供了自己的工作佇列。工作佇列是一個單執行緒工作佇列,只能由助手訪問以進行健全性檢查。驅動程式必須確保新增到 mac80211 工作佇列中的所有工作都應在驅動程式的 stop() 回撥中取消。

mac80211 將在介面刪除和掛起期間重新整理工作佇列。

在 mac80211 工作佇列上執行的所有工作都不得獲取 RTNL 鎖。

void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)

將工作新增到 mac80211 工作佇列

引數

struct ieee80211_hw *hw

我們正在為其新增工作的介面的硬體結構

struct work_struct *work

我們要新增到 mac80211 工作佇列的工作

描述

驅動程式和 mac80211 使用此方法將工作新增到 mac80211 工作佇列。此助手確保驅動程式在不應該排隊工作時不會這樣做。

void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, struct delayed_work *dwork, unsigned long delay)

將工作新增到 mac80211 工作佇列

引數

struct ieee80211_hw *hw

我們正在為其新增工作的介面的硬體結構

struct delayed_work *dwork

要排隊到 mac80211 工作佇列中的可延遲工作

unsigned long delay

排隊之前要等待的 jiffies 數

描述

驅動程式和 mac80211 使用此方法將延遲工作排隊到 mac80211 工作佇列中。