aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_i.h
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211_i.h')
-rw-r--r--net/mac80211/ieee80211_i.h770
1 files changed, 402 insertions, 368 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 330ea62231fa..a842f2e1c230 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH
- * Copyright (C) 2018-2021 Intel Corporation
+ * Copyright (C) 2018-2022 Intel Corporation
*/
#ifndef IEEE80211_I_H
@@ -83,6 +83,13 @@ extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS];
#define IEEE80211_MAX_NAN_INSTANCE_ID 255
+
+/*
+ * Keep a station's queues on the active list for deficit accounting purposes
+ * if it was active or queued during the last 100ms
+ */
+#define AIRTIME_ACTIVE_DURATION (HZ / 10)
+
struct ieee80211_bss {
u32 device_ts_beacon, device_ts_presp;
@@ -204,7 +211,9 @@ struct ieee80211_rx_data {
struct sk_buff *skb;
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_link_data *link;
struct sta_info *sta;
+ struct link_sta_info *link_sta;
struct ieee80211_key *key;
unsigned int flags;
@@ -224,6 +233,8 @@ struct ieee80211_rx_data {
*/
int security_idx;
+ int link_id;
+
union {
struct {
u32 iv32;
@@ -257,6 +268,7 @@ struct beacon_data {
struct ieee80211_meshconf_ie *meshconf;
u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
u8 cntdwn_current_counter;
+ struct cfg80211_mbssid_elems *mbssid_ies;
struct rcu_head rcu_head;
};
@@ -292,19 +304,13 @@ struct ps_data {
};
struct ieee80211_if_ap {
- struct beacon_data __rcu *beacon;
- struct probe_resp __rcu *probe_resp;
- struct fils_discovery_data __rcu *fils_discovery;
- struct unsol_bcast_probe_resp_data __rcu *unsol_bcast_probe_resp;
-
- /* to be used after channel switch. */
- struct cfg80211_beacon_data *next_beacon;
struct list_head vlans; /* write-protected with RTNL and local->mtx */
struct ps_data ps;
atomic_t num_mcast_sta; /* number of stations receiving multicast */
bool multicast_to_unicast;
+ bool active;
};
struct ieee80211_if_vlan {
@@ -354,18 +360,23 @@ struct ieee80211_roc_work {
enum ieee80211_sta_flags {
IEEE80211_STA_CONNECTION_POLL = BIT(1),
IEEE80211_STA_CONTROL_PORT = BIT(2),
- IEEE80211_STA_DISABLE_HT = BIT(4),
IEEE80211_STA_MFP_ENABLED = BIT(6),
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
- IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
- IEEE80211_STA_DISABLE_40MHZ = BIT(10),
- IEEE80211_STA_DISABLE_VHT = BIT(11),
- IEEE80211_STA_DISABLE_80P80MHZ = BIT(12),
- IEEE80211_STA_DISABLE_160MHZ = BIT(13),
- IEEE80211_STA_DISABLE_WMM = BIT(14),
IEEE80211_STA_ENABLE_RRM = BIT(15),
- IEEE80211_STA_DISABLE_HE = BIT(16),
+};
+
+typedef u32 __bitwise ieee80211_conn_flags_t;
+
+enum ieee80211_conn_flags {
+ IEEE80211_CONN_DISABLE_HT = (__force ieee80211_conn_flags_t)BIT(0),
+ IEEE80211_CONN_DISABLE_40MHZ = (__force ieee80211_conn_flags_t)BIT(1),
+ IEEE80211_CONN_DISABLE_VHT = (__force ieee80211_conn_flags_t)BIT(2),
+ IEEE80211_CONN_DISABLE_80P80MHZ = (__force ieee80211_conn_flags_t)BIT(3),
+ IEEE80211_CONN_DISABLE_160MHZ = (__force ieee80211_conn_flags_t)BIT(4),
+ IEEE80211_CONN_DISABLE_HE = (__force ieee80211_conn_flags_t)BIT(5),
+ IEEE80211_CONN_DISABLE_EHT = (__force ieee80211_conn_flags_t)BIT(6),
+ IEEE80211_CONN_DISABLE_320MHZ = (__force ieee80211_conn_flags_t)BIT(7),
};
struct ieee80211_mgd_auth_data {
@@ -376,41 +387,59 @@ struct ieee80211_mgd_auth_data {
u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
- bool done;
+ bool done, waiting;
bool peer_confirmed;
bool timeout_started;
+ u8 ap_addr[ETH_ALEN] __aligned(2);
+
u16 sae_trans, sae_status;
size_t data_len;
u8 data[];
};
struct ieee80211_mgd_assoc_data {
- struct cfg80211_bss *bss;
+ struct {
+ struct cfg80211_bss *bss;
+
+ u8 addr[ETH_ALEN] __aligned(2);
+
+ u8 ap_ht_param;
+
+ struct ieee80211_vht_cap ap_vht_cap;
+
+ size_t elems_len;
+ u8 *elems; /* pointing to inside ie[] below */
+
+ ieee80211_conn_flags_t conn_flags;
+ } link[IEEE80211_MLD_MAX_NUM_LINKS];
+
+ u8 ap_addr[ETH_ALEN] __aligned(2);
+
+ /* this is for a workaround, so we use it only for non-MLO */
const u8 *supp_rates;
+ u8 supp_rates_len;
unsigned long timeout;
int tries;
- u16 capability;
- u8 prev_bssid[ETH_ALEN];
+ u8 prev_ap_addr[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
- u8 supp_rates_len;
bool wmm, uapsd;
bool need_beacon;
bool synced;
bool timeout_started;
+ bool s1g;
- u8 ap_ht_param;
-
- struct ieee80211_vht_cap ap_vht_cap;
+ unsigned int assoc_link_id;
u8 fils_nonces[2 * FILS_NONCE_LEN];
u8 fils_kek[FILS_MAX_KEK_LEN];
size_t fils_kek_len;
size_t ie_len;
+ u8 *ie_pos; /* used to fill ie[] with link[].elems */
u8 ie[];
};
@@ -438,9 +467,7 @@ struct ieee80211_if_managed {
struct timer_list timer;
struct timer_list conn_mon_timer;
struct timer_list bcn_mon_timer;
- struct timer_list chswitch_timer;
struct work_struct monitor_work;
- struct work_struct chswitch_work;
struct work_struct beacon_connection_loss_work;
struct work_struct csa_connection_drop_work;
@@ -450,31 +477,17 @@ struct ieee80211_if_managed {
bool nullfunc_failed;
u8 connection_loss:1,
driver_disconnect:1,
- reconnect:1;
+ reconnect:1,
+ associated:1;
- struct cfg80211_bss *associated;
struct ieee80211_mgd_auth_data *auth_data;
struct ieee80211_mgd_assoc_data *assoc_data;
- u8 bssid[ETH_ALEN] __aligned(2);
-
bool powersave; /* powersave requested for this iface */
bool broken_ap; /* AP is broken -- turn off powersave */
- bool have_beacon;
- u8 dtim_period;
- enum ieee80211_smps_mode req_smps, /* requested smps mode */
- driver_smps_mode; /* smps mode request */
-
- struct work_struct request_smps_work;
unsigned int flags;
- bool csa_waiting_bcn;
- bool csa_ignored_same_chan;
-
- bool beacon_crc_valid;
- u32 beacon_crc;
-
bool status_acked;
bool status_received;
__le16 status_fc;
@@ -499,39 +512,14 @@ struct ieee80211_if_managed {
*/
unsigned int uapsd_max_sp_len;
- int wmm_last_param_set;
- int mu_edca_last_param_set;
-
u8 use_4addr;
- s16 p2p_noa_index;
-
- struct ewma_beacon_signal ave_beacon_signal;
-
- /*
- * Number of Beacon frames used in ave_beacon_signal. This can be used
- * to avoid generating less reliable cqm events that would be based
- * only on couple of received frames.
- */
- unsigned int count_beacon_signal;
-
- /* Number of times beacon loss was invoked. */
- unsigned int beacon_loss_count;
-
- /*
- * Last Beacon frame signal strength average (ave_beacon_signal / 16)
- * that triggered a cqm event. 0 indicates that no event has been
- * generated for the current association.
- */
- int last_cqm_event_signal;
-
/*
* State variables for keeping track of RSSI of the AP currently
* connected to and informing driver when RSSI has gone
* below/above a certain threshold.
*/
int rssi_min_thold, rssi_max_thold;
- int last_ave_beacon_signal;
struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
@@ -546,7 +534,6 @@ struct ieee80211_if_managed {
struct sk_buff *orig_teardown_skb; /* The original teardown skb */
struct sk_buff *teardown_skb; /* A copy to send through the AP */
spinlock_t teardown_lock; /* To lock changing teardown_skb */
- bool tdls_chan_switch_prohibited;
bool tdls_wider_bw_prohibited;
/* WMM-AC TSPEC support */
@@ -759,19 +746,20 @@ struct ieee80211_if_mesh {
* enum ieee80211_sub_if_data_flags - virtual interface flags
*
* @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets
- * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode
* @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between
* associated stations and deliver multicast frames both
* back to wireless media and to the local net stack.
* @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume.
* @IEEE80211_SDATA_IN_DRIVER: indicates interface was added to driver
+ * @IEEE80211_SDATA_DISCONNECT_HW_RESTART: Disconnect after hardware restart
+ * recovery
*/
enum ieee80211_sub_if_data_flags {
IEEE80211_SDATA_ALLMULTI = BIT(0),
- IEEE80211_SDATA_OPERATING_GMODE = BIT(2),
IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3),
IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4),
IEEE80211_SDATA_IN_DRIVER = BIT(5),
+ IEEE80211_SDATA_DISCONNECT_HW_RESTART = BIT(6),
};
/**
@@ -826,8 +814,8 @@ struct ieee80211_chanctx {
struct list_head list;
struct rcu_head rcu_head;
- struct list_head assigned_vifs;
- struct list_head reserved_vifs;
+ struct list_head assigned_links;
+ struct list_head reserved_links;
enum ieee80211_chanctx_replace_state replace_state;
struct ieee80211_chanctx *replace_ctx;
@@ -857,16 +845,20 @@ enum txq_info_flags {
* @def_flow: used as a fallback flow when a packet destined to @tin hashes to
* a fq_flow which is already owned by a different tin
* @def_cvars: codel vars for @def_flow
- * @schedule_order: used with ieee80211_local->active_txqs
* @frags: used to keep fragments created after dequeue
+ * @schedule_order: used with ieee80211_local->active_txqs
+ * @schedule_round: counter to prevent infinite loops on TXQ scheduling
*/
struct txq_info {
struct fq_tin tin;
struct codel_vars def_cvars;
struct codel_stats cstats;
- struct rb_node schedule_order;
+
+ u16 schedule_round;
+ struct list_head schedule_order;
struct sk_buff_head frags;
+
unsigned long flags;
/* keep last! */
@@ -894,6 +886,117 @@ struct ieee80211_if_nan {
struct idr function_inst_ids;
};
+struct ieee80211_link_data_managed {
+ u8 bssid[ETH_ALEN] __aligned(2);
+
+ u8 dtim_period;
+ enum ieee80211_smps_mode req_smps, /* requested smps mode */
+ driver_smps_mode; /* smps mode request */
+
+ ieee80211_conn_flags_t conn_flags;
+
+ s16 p2p_noa_index;
+
+ bool tdls_chan_switch_prohibited;
+
+ bool have_beacon;
+ bool tracking_signal_avg;
+ bool disable_wmm_tracking;
+ bool operating_11g_mode;
+
+ bool csa_waiting_bcn;
+ bool csa_ignored_same_chan;
+ struct timer_list chswitch_timer;
+ struct work_struct chswitch_work;
+
+ struct work_struct request_smps_work;
+ bool beacon_crc_valid;
+ u32 beacon_crc;
+ struct ewma_beacon_signal ave_beacon_signal;
+ int last_ave_beacon_signal;
+
+ /*
+ * Number of Beacon frames used in ave_beacon_signal. This can be used
+ * to avoid generating less reliable cqm events that would be based
+ * only on couple of received frames.
+ */
+ unsigned int count_beacon_signal;
+
+ /* Number of times beacon loss was invoked. */
+ unsigned int beacon_loss_count;
+
+ /*
+ * Last Beacon frame signal strength average (ave_beacon_signal / 16)
+ * that triggered a cqm event. 0 indicates that no event has been
+ * generated for the current association.
+ */
+ int last_cqm_event_signal;
+
+ int wmm_last_param_set;
+ int mu_edca_last_param_set;
+
+ struct cfg80211_bss *bss;
+};
+
+struct ieee80211_link_data_ap {
+ struct beacon_data __rcu *beacon;
+ struct probe_resp __rcu *probe_resp;
+ struct fils_discovery_data __rcu *fils_discovery;
+ struct unsol_bcast_probe_resp_data __rcu *unsol_bcast_probe_resp;
+
+ /* to be used after channel switch. */
+ struct cfg80211_beacon_data *next_beacon;
+};
+
+struct ieee80211_link_data {
+ struct ieee80211_sub_if_data *sdata;
+ unsigned int link_id;
+
+ struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
+ struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
+
+ /* multicast keys only */
+ struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS +
+ NUM_DEFAULT_MGMT_KEYS +
+ NUM_DEFAULT_BEACON_KEYS];
+ struct ieee80211_key __rcu *default_multicast_key;
+ struct ieee80211_key __rcu *default_mgmt_key;
+ struct ieee80211_key __rcu *default_beacon_key;
+
+ struct work_struct csa_finalize_work;
+ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
+
+ bool operating_11g_mode;
+
+ struct cfg80211_chan_def csa_chandef;
+
+ struct work_struct color_change_finalize_work;
+
+ /* context reservation -- protected with chanctx_mtx */
+ struct ieee80211_chanctx *reserved_chanctx;
+ struct cfg80211_chan_def reserved_chandef;
+ bool reserved_radar_required;
+ bool reserved_ready;
+
+ u8 needed_rx_chains;
+ enum ieee80211_smps_mode smps_mode;
+
+ int user_power_level; /* in dBm */
+ int ap_power_level; /* in dBm */
+
+ bool radar_required;
+ struct delayed_work dfs_cac_timer_work;
+
+ union {
+ struct ieee80211_link_data_managed mgd;
+ struct ieee80211_link_data_ap ap;
+ } u;
+
+ struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
+
+ struct ieee80211_bss_conf *conf;
+};
+
struct ieee80211_sub_if_data {
struct list_head list;
@@ -924,42 +1027,19 @@ struct ieee80211_sub_if_data {
/* bit field of ACM bits (BIT(802.1D tag)) */
u8 wmm_acm;
- struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS +
- NUM_DEFAULT_MGMT_KEYS +
- NUM_DEFAULT_BEACON_KEYS];
+ struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS];
struct ieee80211_key __rcu *default_unicast_key;
- struct ieee80211_key __rcu *default_multicast_key;
- struct ieee80211_key __rcu *default_mgmt_key;
- struct ieee80211_key __rcu *default_beacon_key;
u16 sequence_number;
+ u16 mld_mcast_seq;
__be16 control_port_protocol;
bool control_port_no_encrypt;
bool control_port_no_preauth;
bool control_port_over_nl80211;
- int encrypt_headroom;
atomic_t num_tx_queued;
- struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
struct mac80211_qos_map __rcu *qos_map;
- struct airtime_info airtime[IEEE80211_NUM_ACS];
-
- struct work_struct csa_finalize_work;
- bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
- struct cfg80211_chan_def csa_chandef;
-
- struct work_struct color_change_finalize_work;
-
- struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
- struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
-
- /* context reservation -- protected with chanctx_mtx */
- struct ieee80211_chanctx *reserved_chanctx;
- struct cfg80211_chan_def reserved_chandef;
- bool reserved_radar_required;
- bool reserved_ready;
-
/* used to reconfigure hardware SM PS */
struct work_struct recalc_smps;
@@ -967,15 +1047,6 @@ struct ieee80211_sub_if_data {
struct sk_buff_head skb_queue;
struct sk_buff_head status_queue;
- u8 needed_rx_chains;
- enum ieee80211_smps_mode smps_mode;
-
- int user_power_level; /* in dBm */
- int ap_power_level; /* in dBm */
-
- bool radar_required;
- struct delayed_work dfs_cac_timer_work;
-
/*
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
@@ -1007,6 +1078,13 @@ struct ieee80211_sub_if_data {
struct ieee80211_if_nan nan;
} u;
+ struct ieee80211_link_data deflink;
+ struct ieee80211_link_data __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
+
+ /* for ieee80211_set_active_links_async() */
+ struct work_struct activate_links_work;
+ u16 desired_active_links;
+
#ifdef CONFIG_MAC80211_DEBUGFS
struct {
struct dentry *subdir_stations;
@@ -1051,9 +1129,9 @@ sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
}
static inline int
-ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
+ieee80211_chanwidth_get_shift(enum nl80211_chan_width width)
{
- switch (chandef->width) {
+ switch (width) {
case NL80211_CHAN_WIDTH_5:
return 2;
case NL80211_CHAN_WIDTH_10:
@@ -1064,13 +1142,19 @@ ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
}
static inline int
+ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
+{
+ return ieee80211_chanwidth_get_shift(chandef->width);
+}
+
+static inline int
ieee80211_vif_get_shift(struct ieee80211_vif *vif)
{
struct ieee80211_chanctx_conf *chanctx_conf;
int shift = 0;
rcu_read_lock();
- chanctx_conf = rcu_dereference(vif->chanctx_conf);
+ chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
if (chanctx_conf)
shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
rcu_read_unlock();
@@ -1078,6 +1162,20 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif)
return shift;
}
+static inline int
+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems)
+{
+ int i, len = 0;
+
+ if (!elems)
+ return 0;
+
+ for (i = 0; i < elems->cnt; i++)
+ len += elems->elem[i].len;
+
+ return len;
+}
+
enum {
IEEE80211_RX_MSG = 1,
IEEE80211_TX_STATUS_MSG = 2,
@@ -1128,6 +1226,9 @@ struct tpt_led_trigger {
* a scan complete for an aborted scan.
* @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
* cancelled.
+ * @SCAN_BEACON_WAIT: Set whenever we're passive scanning because of radar/no-IR
+ * and could send a probe request after receiving a beacon.
+ * @SCAN_BEACON_DONE: Beacon received, we can now send a probe request
*/
enum {
SCAN_SW_SCANNING,
@@ -1136,6 +1237,8 @@ enum {
SCAN_COMPLETED,
SCAN_ABORTED,
SCAN_HW_CANCELLED,
+ SCAN_BEACON_WAIT,
+ SCAN_BEACON_DONE,
};
/**
@@ -1160,44 +1263,6 @@ enum mac80211_scan_state {
SCAN_ABORT,
};
-/**
- * struct airtime_sched_info - state used for airtime scheduling and AQL
- *
- * @lock: spinlock that protects all the fields in this struct
- * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time
- * @schedule_pos: the current position maintained while a driver walks the tree
- * with ieee80211_next_txq()
- * @active_list: list of struct airtime_info structs that were active within
- * the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute
- * weight_sum
- * @last_weight_update: used for rate limiting walking active_list
- * @last_schedule_time: tracks the last time a transmission was scheduled; used
- * for catching up v_t if no stations are eligible for
- * transmission.
- * @v_t: global virtual time; queues with v_t < this are eligible for
- * transmission
- * @weight_sum: total sum of all active stations used for dividing airtime
- * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast
- * path - see comment above
- * IEEE80211_RECIPROCAL_DIVISOR_64)
- * @aql_txq_limit_low: AQL limit when total outstanding airtime
- * is < IEEE80211_AQL_THRESHOLD
- * @aql_txq_limit_high: AQL limit when total outstanding airtime
- * is > IEEE80211_AQL_THRESHOLD
- */
-struct airtime_sched_info {
- spinlock_t lock;
- struct rb_root_cached active_txqs;
- struct rb_node *schedule_pos;
- struct list_head active_list;
- u64 last_weight_update;
- u64 last_schedule_activity;
- u64 v_t;
- u64 weight_sum;
- u64 weight_sum_reciprocal;
- u32 aql_txq_limit_low;
- u32 aql_txq_limit_high;
-};
DECLARE_STATIC_KEY_FALSE(aql_disable);
struct ieee80211_local {
@@ -1211,10 +1276,16 @@ struct ieee80211_local {
struct codel_params cparams;
/* protects active_txqs and txqi->schedule_order */
- struct airtime_sched_info airtime[IEEE80211_NUM_ACS];
+ spinlock_t active_txq_lock[IEEE80211_NUM_ACS];
+ struct list_head active_txqs[IEEE80211_NUM_ACS];
+ u16 schedule_round[IEEE80211_NUM_ACS];
+
u16 airtime_flags;
+ u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
+ u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
u32 aql_threshold;
atomic_t aql_total_pending_airtime;
+ atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
const struct ieee80211_ops *ops;
@@ -1318,6 +1389,7 @@ struct ieee80211_local {
unsigned long num_sta;
struct list_head sta_list;
struct rhltable sta_hash;
+ struct rhltable link_sta_hash;
struct timer_list sta_cleanup;
int sta_generation;
@@ -1501,9 +1573,31 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)
struct ieee80211_chanctx_conf *chanctx_conf;
enum nl80211_band band;
+ WARN_ON(sdata->vif.valid_links);
+
rcu_read_lock();
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+
+ if (!chanctx_conf) {
+ rcu_read_unlock();
+ return NULL;
+ }
+
+ band = chanctx_conf->def.chan->band;
+ rcu_read_unlock();
+
+ return local->hw.wiphy->bands[band];
+}
+
+static inline struct ieee80211_supported_band *
+ieee80211_get_link_sband(struct ieee80211_link_data *link)
+{
+ struct ieee80211_local *local = link->sdata->local;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ enum nl80211_band band;
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
if (!chanctx_conf) {
rcu_read_unlock();
return NULL;
@@ -1587,6 +1681,9 @@ struct ieee802_11_elems {
const struct ieee80211_s1g_oper_ie *s1g_oper;
const struct ieee80211_s1g_bcn_compat_ie *s1g_bcn_compat;
const struct ieee80211_aid_response_ie *aid_resp;
+ const struct ieee80211_eht_cap_elem *eht_cap;
+ const struct ieee80211_eht_operation *eht_operation;
+ const struct ieee80211_multi_link_elem *multi_link;
/* length of them, respectively */
u8 ext_capab_len;
@@ -1608,9 +1705,18 @@ struct ieee802_11_elems {
u8 bssid_index_len;
u8 tx_pwr_env_len[IEEE80211_TPE_MAX_IE_COUNT];
u8 tx_pwr_env_num;
+ u8 eht_cap_len;
/* whether a parse error occurred while retrieving these elements */
bool parse_error;
+
+ /*
+ * scratch buffer that can be used for various element parsing related
+ * tasks, e.g., element de-fragmentation etc.
+ */
+ size_t scratch_len;
+ u8 *scratch_pos;
+ u8 scratch[];
};
static inline struct ieee80211_local *hw_to_local(
@@ -1631,131 +1737,6 @@ static inline bool txq_has_queue(struct ieee80211_txq *txq)
return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets);
}
-static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq)
-{
- struct ieee80211_sub_if_data *sdata;
- struct sta_info *sta;
-
- if (txq->sta) {
- sta = container_of(txq->sta, struct sta_info, sta);
- return &sta->airtime[txq->ac];
- }
-
- sdata = vif_to_sdata(txq->vif);
- return &sdata->airtime[txq->ac];
-}
-
-/* To avoid divisions in the fast path, we keep pre-computed reciprocals for
- * airtime weight calculations. There are two different weights to keep track
- * of: The per-station weight and the sum of weights per phy.
- *
- * For the per-station weights (kept in airtime_info below), we use 32-bit
- * reciprocals with a devisor of 2^19. This lets us keep the multiplications and
- * divisions for the station weights as 32-bit operations at the cost of a bit
- * of rounding error for high weights; but the choice of divisor keeps rounding
- * errors <10% for weights <2^15, assuming no more than 8ms of airtime is
- * reported at a time.
- *
- * For the per-phy sum of weights the values can get higher, so we use 64-bit
- * operations for those with a 32-bit divisor, which should avoid any
- * significant rounding errors.
- */
-#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL
-#define IEEE80211_RECIPROCAL_SHIFT_64 32
-#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U
-#define IEEE80211_RECIPROCAL_SHIFT_32 19
-
-static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight)
-{
- if (air_info->weight == weight)
- return;
-
- air_info->weight = weight;
- if (weight) {
- air_info->weight_reciprocal =
- IEEE80211_RECIPROCAL_DIVISOR_32 / weight;
- } else {
- air_info->weight_reciprocal = 0;
- }
-}
-
-static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched,
- int weight_sum)
-{
- if (air_sched->weight_sum == weight_sum)
- return;
-
- air_sched->weight_sum = weight_sum;
- if (air_sched->weight_sum) {
- air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64;
- do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum);
- } else {
- air_sched->weight_sum_reciprocal = 0;
- }
-}
-
-/* A problem when trying to enforce airtime fairness is that we want to divide
- * the airtime between the currently *active* stations. However, basing this on
- * the instantaneous queue state of stations doesn't work, as queues tend to
- * oscillate very quickly between empty and occupied, leading to the scheduler
- * thinking only a single station is active when deciding whether to allow
- * transmission (and thus not throttling correctly).
- *
- * To fix this we use a timer-based notion of activity: a station is considered
- * active if it has been scheduled within the last 100 ms; we keep a separate
- * list of all the stations considered active in this manner, and lazily update
- * the total weight of active stations from this list (filtering the stations in
- * the list by their 'last active' time).
- *
- * We add one additional safeguard to guard against stations that manage to get
- * scheduled every 100 ms but don't transmit a lot of data, and thus don't use
- * up any airtime. Such stations would be able to get priority for an extended
- * period of time if they do start transmitting at full capacity again, and so
- * we add an explicit maximum for how far behind a station is allowed to fall in
- * the virtual airtime domain. This limit is set to a relatively high value of
- * 20 ms because the main mechanism for catching up idle stations is the active
- * state as described above; i.e., the hard limit should only be hit in
- * pathological cases.
- */
-#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC)
-#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */
-
-static inline bool airtime_is_active(struct airtime_info *air_info, u64 now)
-{
- return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION;
-}
-
-static inline void airtime_set_active(struct airtime_sched_info *air_sched,
- struct airtime_info *air_info, u64 now)
-{
- air_info->last_scheduled = now;
- air_sched->last_schedule_activity = now;
- list_move_tail(&air_info->list, &air_sched->active_list);
-}
-
-static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched,
- u64 v_t, u64 now)
-{
- air_sched->v_t = v_t;
- return true;
-}
-
-static inline void init_airtime_info(struct airtime_info *air_info,
- struct airtime_sched_info *air_sched)
-{
- atomic_set(&air_info->aql_tx_pending, 0);
- air_info->aql_limit_low = air_sched->aql_txq_limit_low;
- air_info->aql_limit_high = air_sched->aql_txq_limit_high;
- airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT);
- INIT_LIST_HEAD(&air_info->list);
-}
-
-static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
-{
- return ether_addr_equal(raddr, addr) ||
- is_broadcast_ether_addr(raddr);
-}
-
static inline bool
ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
{
@@ -1789,7 +1770,12 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
- u32 changed);
+ u64 changed);
+void ieee80211_vif_cfg_change_notify(struct ieee80211_sub_if_data *sdata,
+ u64 changed);
+void ieee80211_link_info_change_notify(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_data *link,
+ u64 changed);
void ieee80211_configure_filter(struct ieee80211_local *local);
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
@@ -1802,6 +1788,9 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata);
void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata);
void ieee80211_clear_fast_rx(struct sta_info *sta);
+bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata,
+ const u8 *addr, int *out_link_id);
+
/* STA code */
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -1831,7 +1820,10 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
- u8 *bssid, u8 reason, bool tx);
+ u8 reason, bool tx);
+void ieee80211_mgd_setup_link(struct ieee80211_link_data *link);
+void ieee80211_mgd_stop_link(struct ieee80211_link_data *link);
+void ieee80211_mgd_set_link_qos_params(struct ieee80211_link_data *link);
/* IBSS code */
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1961,6 +1953,17 @@ static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
return test_bit(SDATA_STATE_RUNNING, &sdata->state);
}
+/* link handling */
+void ieee80211_link_setup(struct ieee80211_link_data *link);
+void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
+ int link_id,
+ struct ieee80211_link_data *link,
+ struct ieee80211_bss_conf *link_conf);
+void ieee80211_link_stop(struct ieee80211_link_data *link);
+int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata,
+ u16 new_links);
+void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata);
+
/* tx handling */
void ieee80211_clear_tx_pending(struct ieee80211_local *local);
void ieee80211_tx_pending(struct tasklet_struct *t);
@@ -1981,7 +1984,6 @@ struct sk_buff *
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, u32 info_flags);
void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
- struct ieee80211_supported_band *sband,
int retry_count, int shift, bool send_to_cooked,
struct ieee80211_tx_status *status);
@@ -1992,17 +1994,9 @@ void ieee80211_clear_fast_xmit(struct sta_info *sta);
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted,
- u64 *cookie);
+ int link_id, u64 *cookie);
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len);
-void ieee80211_resort_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq);
-void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq,
- bool purge);
-void ieee80211_update_airtime_weight(struct ieee80211_local *local,
- struct airtime_sched_info *air_sched,
- u64 now, bool force);
/* HT */
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
@@ -2010,15 +2004,13 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
const struct ieee80211_ht_cap *ht_cap_ie,
- struct sta_info *sta);
+ struct link_sta_info *link_sta);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
const u8 *da, u16 tid,
u16 initiator, u16 reason_code);
int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps, const u8 *da,
const u8 *bssid);
-void ieee80211_request_smps_ap_work(struct work_struct *work);
-void ieee80211_request_smps_mgd_work(struct work_struct *work);
bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
enum ieee80211_smps_mode smps_mode_new);
@@ -2066,27 +2058,31 @@ void
ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
const struct ieee80211_vht_cap *vht_cap_ie,
- struct sta_info *sta);
-enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
-enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
-void ieee80211_sta_set_rx_nss(struct sta_info *sta);
+ struct link_sta_info *link_sta);
+enum ieee80211_sta_rx_bandwidth
+ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta);
+enum ieee80211_sta_rx_bandwidth
+ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta);
+void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta);
enum ieee80211_sta_rx_bandwidth
ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
-enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta);
+enum nl80211_chan_width
+ieee80211_sta_cap_chan_bw(struct link_sta_info *link_sta);
void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_data *link,
struct ieee80211_mgmt *mgmt);
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta, u8 opmode,
- enum nl80211_band band);
+ struct link_sta_info *sta,
+ u8 opmode, enum nl80211_band band);
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta, u8 opmode,
- enum nl80211_band band);
+ struct link_sta_info *sta,
+ u8 opmode, enum nl80211_band band);
void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta_vht_cap *vht_cap);
void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
u16 vht_mask[NL80211_VHT_NSS_MAX]);
enum nl80211_chan_width
-ieee80211_sta_rx_bw_to_chan_width(struct sta_info *sta);
+ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *sta);
/* HE */
void
@@ -2094,7 +2090,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband,
const u8 *he_cap_ie, u8 he_cap_len,
const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
- struct sta_info *sta);
+ struct link_sta_info *link_sta);
void
ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
const struct ieee80211_he_spr *he_spr_ie_elem);
@@ -2121,12 +2117,9 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
* @elems: parsed 802.11 elements received with the frame
* @current_band: indicates the current band
* @vht_cap_info: VHT capabilities of the transmitter
- * @sta_flags: contains information about own capabilities and restrictions
- * to decide which channel switch announcements can be accepted. Only the
- * following subset of &enum ieee80211_sta_flags are evaluated:
- * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
- * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
- * %IEEE80211_STA_DISABLE_160MHZ.
+ * @conn_flags: contains information about own capabilities and restrictions
+ * to decide which channel switch announcements can be accepted, using
+ * flags from &enum ieee80211_conn_flags.
* @bssid: the currently connected bssid (for reporting)
* @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl.
All of them will be filled with if success only.
@@ -2136,7 +2129,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems,
enum nl80211_band current_band,
u32 vht_cap_info,
- u32 sta_flags, u8 *bssid,
+ ieee80211_conn_flags_t conn_flags, u8 *bssid,
struct ieee80211_csa_ie *csa_ie);
/* Suspend/resume and hw reconfiguration */
@@ -2166,13 +2159,13 @@ int ieee80211_frame_duration(enum nl80211_band band, size_t len,
void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_queue_params *qparam,
int ac);
-void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
+void ieee80211_set_wmm_default(struct ieee80211_link_data *link,
bool bss_notify, bool enable_qos);
void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, struct sk_buff *skb);
void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb, int tid,
+ struct sk_buff *skb, int tid, int link_id,
enum nl80211_band band);
/* sta_out needs to be checked for ERR_PTR() before using */
@@ -2186,49 +2179,76 @@ ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
enum nl80211_band band)
{
rcu_read_lock();
- __ieee80211_tx_skb_tid_band(sdata, skb, tid, band);
+ __ieee80211_tx_skb_tid_band(sdata, skb, tid, -1, band);
rcu_read_unlock();
}
-static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb, int tid)
-{
- struct ieee80211_chanctx_conf *chanctx_conf;
-
- rcu_read_lock();
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
- if (WARN_ON(!chanctx_conf)) {
- rcu_read_unlock();
- kfree_skb(skb);
- return;
- }
-
- __ieee80211_tx_skb_tid_band(sdata, skb, tid,
- chanctx_conf->def.chan->band);
- rcu_read_unlock();
-}
+void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, int tid, int link_id);
static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
/* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
- ieee80211_tx_skb_tid(sdata, skb, 7);
+ ieee80211_tx_skb_tid(sdata, skb, 7, -1);
+}
+
+/**
+ * struct ieee80211_elems_parse_params - element parsing parameters
+ * @start: pointer to the elements
+ * @len: length of the elements
+ * @action: %true if the elements came from an action frame
+ * @filter: bitmap of element IDs to filter out while calculating
+ * the element CRC
+ * @crc: CRC starting value
+ * @bss: the BSS to parse this as, for multi-BSSID cases this can
+ * represent a non-transmitting BSS in which case the data
+ * for that non-transmitting BSS is returned
+ * @link_id: the link ID to parse elements for, if a STA profile
+ * is present in the multi-link element, or -1 to ignore
+ * @from_ap: frame is received from an AP (currently used only
+ * for EHT capabilities parsing)
+ */
+struct ieee80211_elems_parse_params {
+ const u8 *start;
+ size_t len;
+ bool action;
+ u64 filter;
+ u32 crc;
+ struct cfg80211_bss *bss;
+ int link_id;
+ bool from_ap;
+};
+
+struct ieee802_11_elems *
+ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params);
+
+static inline struct ieee802_11_elems *
+ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
+ u64 filter, u32 crc,
+ struct cfg80211_bss *bss)
+{
+ struct ieee80211_elems_parse_params params = {
+ .start = start,
+ .len = len,
+ .action = action,
+ .filter = filter,
+ .crc = crc,
+ .bss = bss,
+ .link_id = -1,
+ };
+
+ return ieee802_11_parse_elems_full(&params);
}
-struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
- bool action,
- u64 filter, u32 crc,
- const u8 *transmitter_bssid,
- const u8 *bss_bssid);
static inline struct ieee802_11_elems *
ieee802_11_parse_elems(const u8 *start, size_t len, bool action,
- const u8 *transmitter_bssid,
- const u8 *bss_bssid)
+ struct cfg80211_bss *bss)
{
- return ieee802_11_parse_elems_crc(start, len, action, 0, 0,
- transmitter_bssid, bss_bssid);
+ return ieee802_11_parse_elems_crc(start, len, action, 0, 0, bss);
}
+void ieee80211_fragment_element(struct sk_buff *skb, u8 *len_pos);
extern const int ieee802_1d_to_ac[8];
@@ -2363,9 +2383,12 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems,
enum nl80211_band band, u32 *basic_rates);
int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_data *link,
enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
-void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_link_data *link);
+void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata,
+ int link_id);
size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
@@ -2380,13 +2403,14 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
const struct cfg80211_chan_def *chandef);
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
-u8 *ieee80211_ie_build_he_cap(u8 *pos,
+u8 *ieee80211_ie_build_he_cap(ieee80211_conn_flags_t disable_flags, u8 *pos,
const struct ieee80211_sta_he_cap *he_cap,
u8 *end);
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
+ enum ieee80211_smps_mode smps_mode,
struct sk_buff *skb);
u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef);
-int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
+int ieee80211_parse_bitrates(enum nl80211_chan_width width,
const struct ieee80211_supported_band *sband,
const u8 *srates, int srates_len, u32 *rates);
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
@@ -2409,34 +2433,38 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
const struct ieee80211_vht_operation *oper,
const struct ieee80211_ht_operation *htop,
struct cfg80211_chan_def *chandef);
+void ieee80211_chandef_eht_oper(const struct ieee80211_eht_operation *eht_oper,
+ bool support_160, bool support_320,
+ struct cfg80211_chan_def *chandef);
bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_he_operation *he_oper,
+ const struct ieee80211_eht_operation *eht_oper,
struct cfg80211_chan_def *chandef);
bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
struct cfg80211_chan_def *chandef);
-u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
+ieee80211_conn_flags_t ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
int __must_check
-ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
- const struct cfg80211_chan_def *chandef,
- enum ieee80211_chanctx_mode mode);
+ieee80211_link_use_channel(struct ieee80211_link_data *link,
+ const struct cfg80211_chan_def *chandef,
+ enum ieee80211_chanctx_mode mode);
int __must_check
-ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
- const struct cfg80211_chan_def *chandef,
- enum ieee80211_chanctx_mode mode,
- bool radar_required);
+ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
+ const struct cfg80211_chan_def *chandef,
+ enum ieee80211_chanctx_mode mode,
+ bool radar_required);
int __must_check
-ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata);
-int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata);
+ieee80211_link_use_reserved_context(struct ieee80211_link_data *link);
+int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link);
int __must_check
-ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
- const struct cfg80211_chan_def *chandef,
- u32 *changed);
-void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
-void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
-void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
- bool clear);
+ieee80211_link_change_bandwidth(struct ieee80211_link_data *link,
+ const struct cfg80211_chan_def *chandef,
+ u32 *changed);
+void ieee80211_link_release_channel(struct ieee80211_link_data *link);
+void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link);
+void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
+ bool clear);
int ieee80211_chanctx_refcount(struct ieee80211_local *local,
struct ieee80211_chanctx *ctx);
@@ -2453,14 +2481,6 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work);
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
struct cfg80211_csa_settings *csa_settings);
-bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs);
-bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n);
-const struct ieee80211_cipher_scheme *
-ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
- enum nl80211_iftype iftype);
-int ieee80211_cs_headroom(struct ieee80211_local *local,
- struct cfg80211_crypto_settings *crypto,
- enum nl80211_iftype iftype);
void ieee80211_recalc_dtim(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata);
int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
@@ -2514,4 +2534,18 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache);
void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache);
+u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
+u8 *ieee80211_ie_build_eht_cap(u8 *pos,
+ const struct ieee80211_sta_he_cap *he_cap,
+ const struct ieee80211_sta_eht_cap *eht_cap,
+ u8 *end,
+ bool for_ap);
+
+void
+ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
+ const u8 *he_cap_ie, u8 he_cap_len,
+ const struct ieee80211_eht_cap_elem *eht_cap_ie_elem,
+ u8 eht_cap_len,
+ struct link_sta_info *link_sta);
#endif /* IEEE80211_I_H */