summaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-rx.c4
-rw-r--r--net/mac80211/agg-tx.c6
-rw-r--r--net/mac80211/cfg.c78
-rw-r--r--net/mac80211/chan.c3
-rw-r--r--net/mac80211/debugfs_sta.c6
-rw-r--r--net/mac80211/ibss.c21
-rw-r--r--net/mac80211/ieee80211_i.h16
-rw-r--r--net/mac80211/iface.c92
-rw-r--r--net/mac80211/led.c2
-rw-r--r--net/mac80211/link.c90
-rw-r--r--net/mac80211/main.c6
-rw-r--r--net/mac80211/mesh.c18
-rw-r--r--net/mac80211/mesh_hwmp.c6
-rw-r--r--net/mac80211/mesh_pathtbl.c2
-rw-r--r--net/mac80211/mesh_plink.c22
-rw-r--r--net/mac80211/mlme.c32
-rw-r--r--net/mac80211/ocb.c2
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/parse.c3
-rw-r--r--net/mac80211/pm.c4
-rw-r--r--net/mac80211/rate.c12
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c13
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c18
-rw-r--r--net/mac80211/spectmgmt.c55
-rw-r--r--net/mac80211/sta_info.c30
-rw-r--r--net/mac80211/sta_info.h11
-rw-r--r--net/mac80211/status.c8
-rw-r--r--net/mac80211/tdls.c4
-rw-r--r--net/mac80211/tx.c35
-rw-r--r--net/mac80211/util.c25
31 files changed, 353 insertions, 279 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index aeb99d102c6e..85612234742a 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -103,13 +103,13 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
if (!tid_rx)
return;
- del_timer_sync(&tid_rx->session_timer);
+ timer_delete_sync(&tid_rx->session_timer);
/* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */
spin_lock_bh(&tid_rx->reorder_lock);
tid_rx->removed = true;
spin_unlock_bh(&tid_rx->reorder_lock);
- del_timer_sync(&tid_rx->reorder_timer);
+ timer_delete_sync(&tid_rx->reorder_timer);
call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
}
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 63a5e48291ac..8dc8c3c96b96 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -362,8 +362,8 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n",
sta->sta.addr, tid);
- del_timer_sync(&tid_tx->addba_resp_timer);
- del_timer_sync(&tid_tx->session_timer);
+ timer_delete_sync(&tid_tx->addba_resp_timer);
+ timer_delete_sync(&tid_tx->session_timer);
/*
* After this packets are no longer handed right through
@@ -1002,7 +1002,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
return;
}
- del_timer_sync(&tid_tx->addba_resp_timer);
+ timer_delete_sync(&tid_tx->addba_resp_timer);
ht_dbg(sta->sdata, "switched off addBA timer for %pM tid %d\n",
sta->sta.addr, tid);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9f683f838431..d9d88f2f2831 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -146,8 +146,8 @@ static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss_conf *link_conf)
{
struct ieee80211_sub_if_data *tx_sdata;
+ struct ieee80211_bss_conf *old;
- sdata->vif.mbssid_tx_vif = NULL;
link_conf->bssid_index = 0;
link_conf->nontransmitted = false;
link_conf->ema_ap = false;
@@ -156,14 +156,26 @@ static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata,
if (sdata->vif.type != NL80211_IFTYPE_AP || !params->tx_wdev)
return -EINVAL;
+ old = sdata_dereference(link_conf->tx_bss_conf, sdata);
+ if (old)
+ return -EALREADY;
+
tx_sdata = IEEE80211_WDEV_TO_SUB_IF(params->tx_wdev);
if (!tx_sdata)
return -EINVAL;
if (tx_sdata == sdata) {
- sdata->vif.mbssid_tx_vif = &sdata->vif;
+ rcu_assign_pointer(link_conf->tx_bss_conf, link_conf);
} else {
- sdata->vif.mbssid_tx_vif = &tx_sdata->vif;
+ struct ieee80211_bss_conf *tx_bss_conf;
+
+ tx_bss_conf = sdata_dereference(tx_sdata->vif.link_conf[params->tx_link_id],
+ sdata);
+ if (rcu_access_pointer(tx_bss_conf->tx_bss_conf) != tx_bss_conf)
+ return -EINVAL;
+
+ rcu_assign_pointer(link_conf->tx_bss_conf, tx_bss_conf);
+
link_conf->nontransmitted = true;
link_conf->bssid_index = params->index;
}
@@ -1278,9 +1290,9 @@ static u8 ieee80211_num_beaconing_links(struct ieee80211_sub_if_data *sdata)
sdata->vif.type != NL80211_IFTYPE_P2P_GO)
return num;
- if (!sdata->vif.valid_links)
- return num;
-
+ /* non-MLO mode of operation also uses link_id 0 in sdata so it is
+ * safe to directly proceed with the below loop
+ */
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
link = sdata_dereference(sdata->link[link_id], sdata);
if (!link)
@@ -1409,6 +1421,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
(IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ |
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ |
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ);
+ link_conf->eht_disable_mcs15 =
+ u8_get_bits(params->eht_oper->params,
+ IEEE80211_EHT_OPER_MCS15_DISABLE);
} else {
link_conf->eht_su_beamformer = false;
link_conf->eht_su_beamformee = false;
@@ -1669,7 +1684,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
kfree(link_conf->ftmr_params);
link_conf->ftmr_params = NULL;
- sdata->vif.mbssid_tx_vif = NULL;
link_conf->bssid_index = 0;
link_conf->nontransmitted = false;
link_conf->ema_ap = false;
@@ -1683,6 +1697,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
ieee80211_free_key_list(local, &keys);
}
+ ieee80211_stop_mbssid(sdata);
+ RCU_INIT_POINTER(link_conf->tx_bss_conf, NULL);
+
link_conf->enable_beacon = false;
sdata->beacon_rate_set = false;
sdata->vif.cfg.ssid_len = 0;
@@ -2066,6 +2083,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
if (params->listen_interval >= 0)
sta->listen_interval = params->listen_interval;
+ if (params->eml_cap_present)
+ sta->sta.eml_cap = params->eml_cap;
+
ret = sta_link_apply_parameters(local, sta, STA_LINK_MODE_STA_MODIFY,
&params->link_sta_params);
if (ret)
@@ -2904,7 +2924,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
* the frames sent while scanning on other channel will be
* lost)
*/
- if (sdata->deflink.u.ap.beacon &&
+ if (ieee80211_num_beaconing_links(sdata) &&
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
!(req->flags & NL80211_SCAN_FLAG_AP)))
return -EOPNOTSUPP;
@@ -3700,6 +3720,7 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif, unsigned int link_id)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_bss_conf *tx_bss_conf;
struct ieee80211_link_data *link_data;
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
@@ -3713,25 +3734,24 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif, unsigned int link_id)
return;
}
- /* TODO: MBSSID with MLO changes */
- if (vif->mbssid_tx_vif == vif) {
+ tx_bss_conf = rcu_dereference(link_data->conf->tx_bss_conf);
+ if (tx_bss_conf == link_data->conf) {
/* Trigger ieee80211_csa_finish() on the non-transmitting
* interfaces when channel switch is received on
* transmitting interface
*/
- struct ieee80211_sub_if_data *iter;
-
- list_for_each_entry_rcu(iter, &local->interfaces, list) {
- if (!ieee80211_sdata_running(iter))
- continue;
+ struct ieee80211_link_data *iter;
- if (iter == sdata || iter->vif.mbssid_tx_vif != vif)
+ for_each_sdata_link(local, iter) {
+ if (iter->sdata == sdata ||
+ rcu_access_pointer(iter->conf->tx_bss_conf) != tx_bss_conf)
continue;
- wiphy_work_queue(iter->local->hw.wiphy,
- &iter->deflink.csa.finalize_work);
+ wiphy_work_queue(iter->sdata->local->hw.wiphy,
+ &iter->csa.finalize_work);
}
}
+
wiphy_work_queue(local->hw.wiphy, &link_data->csa.finalize_work);
rcu_read_unlock();
@@ -4833,17 +4853,19 @@ ieee80211_color_change_bss_config_notify(struct ieee80211_link_data *link,
ieee80211_link_info_change_notify(sdata, link, changed);
- if (!sdata->vif.bss_conf.nontransmitted && sdata->vif.mbssid_tx_vif) {
- struct ieee80211_sub_if_data *child;
+ if (!link->conf->nontransmitted &&
+ rcu_access_pointer(link->conf->tx_bss_conf)) {
+ struct ieee80211_link_data *tmp;
- list_for_each_entry(child, &sdata->local->interfaces, list) {
- if (child != sdata && child->vif.mbssid_tx_vif == &sdata->vif) {
- child->vif.bss_conf.he_bss_color.color = color;
- child->vif.bss_conf.he_bss_color.enabled = enable;
- ieee80211_link_info_change_notify(child,
- &child->deflink,
- BSS_CHANGED_HE_BSS_COLOR);
- }
+ for_each_sdata_link(sdata->local, tmp) {
+ if (tmp->sdata == sdata ||
+ rcu_access_pointer(tmp->conf->tx_bss_conf) != link->conf)
+ continue;
+
+ tmp->conf->he_bss_color.color = color;
+ tmp->conf->he_bss_color.enabled = enable;
+ ieee80211_link_info_change_notify(tmp->sdata, tmp,
+ BSS_CHANGED_HE_BSS_COLOR);
}
}
}
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index c3bfac58151f..3aaf5abf1acc 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -2131,6 +2131,9 @@ void ieee80211_link_release_channel(struct ieee80211_link_data *link)
{
struct ieee80211_sub_if_data *sdata = link->sdata;
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ return;
+
lockdep_assert_wiphy(sdata->local->hw.wiphy);
if (rcu_access_pointer(link->conf->chanctx_conf))
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index a8948f4d983e..49061bd4151b 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -152,12 +152,6 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
p += scnprintf(p,
bufsz + buf - p,
- "target %uus interval %uus ecn %s\n",
- codel_time_to_us(sta->cparams.target),
- codel_time_to_us(sta->cparams.interval),
- sta->cparams.ecn ? "yes" : "no");
- p += scnprintf(p,
- bufsz + buf - p,
"tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets flags\n");
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 05a945df3259..a6e7b7ba6a01 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -48,7 +48,7 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt;
u8 *pos;
struct ieee80211_supported_band *sband;
- u32 rate_flags, rates = 0, rates_added = 0;
+ u32 rates = 0, rates_added = 0;
struct beacon_data *presp;
int frame_len;
@@ -90,14 +90,11 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
pos += ifibss->ssid_len;
sband = local->hw.wiphy->bands[chandef->chan->band];
- rate_flags = ieee80211_chandef_rate_flags(chandef);
rates_n = 0;
if (have_higher_than_11mbit)
*have_higher_than_11mbit = false;
for (i = 0; i < sband->n_bitrates; i++) {
- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
- continue;
if (sband->bitrates[i].bitrate > 110 &&
have_higher_than_11mbit)
*have_higher_than_11mbit = true;
@@ -395,7 +392,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
const struct cfg80211_bss_ies *ies;
enum nl80211_channel_type chan_type;
u64 tsf;
- u32 rate_flags;
lockdep_assert_wiphy(sdata->local->hw.wiphy);
@@ -429,7 +425,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
}
sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
- rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef);
basic_rates = 0;
@@ -439,9 +434,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
for (j = 0; j < sband->n_bitrates; j++) {
int brate;
- if ((rate_flags & sband->bitrates[j].flags)
- != rate_flags)
- continue;
brate = DIV_ROUND_UP(sband->bitrates[j].bitrate, 5);
if (brate == rate) {
@@ -1717,12 +1709,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params)
{
u64 changed = 0;
- u32 rate_flags;
- struct ieee80211_supported_band *sband;
enum ieee80211_chanctx_mode chanmode;
struct ieee80211_local *local = sdata->local;
int radar_detect_width = 0;
- int i;
int ret;
lockdep_assert_wiphy(local->hw.wiphy);
@@ -1765,12 +1754,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.last_scan_completed = jiffies;
/* fix basic_rates if channel does not support these rates */
- rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
- sband = local->hw.wiphy->bands[params->chandef.chan->band];
- for (i = 0; i < sband->n_bitrates; i++) {
- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
- sdata->u.ibss.basic_rates &= ~BIT(i);
- }
memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
sizeof(params->mcast_rate));
@@ -1844,7 +1827,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
skb_queue_purge(&sdata->skb_queue);
- del_timer_sync(&sdata->u.ibss.timer);
+ timer_delete_sync(&sdata->u.ibss.timer);
return 0;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index fb05f3cd37ec..30809f0b35f7 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1226,6 +1226,15 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
if ((_link = wiphy_dereference((_local)->hw.wiphy, \
___sdata->link[___link_id])))
+#define for_each_link_data(sdata, __link) \
+ struct ieee80211_sub_if_data *__sdata = sdata; \
+ for (int __link_id = 0; \
+ __link_id < ARRAY_SIZE((__sdata)->link); __link_id++) \
+ if ((!(__sdata)->vif.valid_links || \
+ (__sdata)->vif.valid_links & BIT(__link_id)) && \
+ ((__link) = sdata_dereference((__sdata)->link[__link_id], \
+ (__sdata))))
+
static inline int
ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems,
struct cfg80211_rnr_elems *rnr_elems,
@@ -2078,6 +2087,9 @@ static inline void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata
ieee80211_vif_set_links(sdata, 0, 0);
}
+void ieee80211_apvlan_link_setup(struct ieee80211_sub_if_data *sdata);
+void ieee80211_apvlan_link_clear(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);
@@ -2613,7 +2625,7 @@ void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata,
/* element building in SKBs */
int ieee80211_put_srates_elem(struct sk_buff *skb,
const struct ieee80211_supported_band *sband,
- u32 basic_rates, u32 rate_flags, u32 masked_rates,
+ u32 basic_rates, u32 masked_rates,
u8 element_id);
int ieee80211_put_he_cap(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata,
@@ -2795,6 +2807,8 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len);
+void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata);
+
#if IS_ENABLED(CONFIG_MAC80211_KUNIT_TEST)
#define EXPORT_SYMBOL_IF_MAC80211_KUNIT(sym) EXPORT_SYMBOL_IF_KUNIT(sym)
#define VISIBLE_IF_MAC80211_KUNIT
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b0423046028c..7c27f3cd841c 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -485,6 +485,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
case NL80211_IFTYPE_MONITOR:
list_del_rcu(&sdata->u.mntr.list);
break;
+ case NL80211_IFTYPE_AP_VLAN:
+ ieee80211_apvlan_link_clear(sdata);
+ break;
default:
break;
}
@@ -526,7 +529,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
netif_addr_unlock_bh(sdata->dev);
}
- del_timer_sync(&local->dynamic_ps_timer);
+ timer_delete_sync(&local->dynamic_ps_timer);
wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);
WARN(ieee80211_vif_is_mld(&sdata->vif),
@@ -659,6 +662,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
ieee80211_txq_remove_vlan(local, sdata);
+ if (sdata->vif.txq)
+ ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq));
+
sdata->bss = NULL;
if (local->open_count == 0)
@@ -726,30 +732,59 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
ieee80211_add_virtual_monitor(local);
}
-static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata)
+void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata)
{
- struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata;
- struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif;
+ struct ieee80211_sub_if_data *tx_sdata;
+ struct ieee80211_bss_conf *link_conf, *tx_bss_conf;
+ struct ieee80211_link_data *tx_link, *link;
+ unsigned int link_id;
- if (!tx_vif)
- return;
+ lockdep_assert_wiphy(sdata->local->hw.wiphy);
+
+ /* Check if any of the links of current sdata is an MBSSID. */
+ for_each_vif_active_link(&sdata->vif, link_conf, link_id) {
+ tx_bss_conf = sdata_dereference(link_conf->tx_bss_conf, sdata);
+ if (!tx_bss_conf)
+ continue;
+
+ tx_sdata = vif_to_sdata(tx_bss_conf->vif);
+ RCU_INIT_POINTER(link_conf->tx_bss_conf, NULL);
- tx_sdata = vif_to_sdata(tx_vif);
- sdata->vif.mbssid_tx_vif = NULL;
+ /* If we are not tx sdata reset tx sdata's tx_bss_conf to avoid recusrion
+ * while closing tx sdata at the end of outer loop below.
+ */
+ if (sdata != tx_sdata) {
+ tx_link = sdata_dereference(tx_sdata->link[tx_bss_conf->link_id],
+ tx_sdata);
+ if (!tx_link)
+ continue;
- list_for_each_entry_safe(non_tx_sdata, tmp_sdata,
- &tx_sdata->local->interfaces, list) {
- if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata &&
- non_tx_sdata->vif.mbssid_tx_vif == tx_vif &&
- ieee80211_sdata_running(non_tx_sdata)) {
- non_tx_sdata->vif.mbssid_tx_vif = NULL;
- dev_close(non_tx_sdata->wdev.netdev);
+ RCU_INIT_POINTER(tx_link->conf->tx_bss_conf, NULL);
}
- }
- if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) {
- tx_sdata->vif.mbssid_tx_vif = NULL;
- dev_close(tx_sdata->wdev.netdev);
+ /* loop through sdatas to find if any of their links
+ * belong to same MBSSID set as the one getting deleted.
+ */
+ for_each_sdata_link(tx_sdata->local, link) {
+ struct ieee80211_sub_if_data *link_sdata = link->sdata;
+
+ if (link_sdata == sdata || link_sdata == tx_sdata ||
+ rcu_access_pointer(link->conf->tx_bss_conf) != tx_bss_conf)
+ continue;
+
+ RCU_INIT_POINTER(link->conf->tx_bss_conf, NULL);
+
+ /* Remove all links of matching MLD until dynamic link
+ * removal can be supported.
+ */
+ cfg80211_stop_iface(link_sdata->wdev.wiphy, &link_sdata->wdev,
+ GFP_KERNEL);
+ }
+
+ /* If we are not tx sdata, remove links of tx sdata and proceed */
+ if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata))
+ cfg80211_stop_iface(tx_sdata->wdev.wiphy,
+ &tx_sdata->wdev, GFP_KERNEL);
}
}
@@ -757,21 +792,25 @@ static int ieee80211_stop(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- /* close dependent VLAN and MBSSID interfaces before locking wiphy */
+ /* close dependent VLAN interfaces before locking wiphy */
if (sdata->vif.type == NL80211_IFTYPE_AP) {
struct ieee80211_sub_if_data *vlan, *tmpsdata;
list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
u.vlan.list)
dev_close(vlan->dev);
-
- ieee80211_stop_mbssid(sdata);
}
guard(wiphy)(sdata->local->hw.wiphy);
wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->activate_links_work);
+ /* Close the dependent MBSSID interfaces with wiphy lock as we may be
+ * terminating its partner links too in case of MLD.
+ */
+ if (sdata->vif.type == NL80211_IFTYPE_AP)
+ ieee80211_stop_mbssid(sdata);
+
ieee80211_do_stop(sdata, true);
return 0;
@@ -1265,6 +1304,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
sdata->crypto_tx_tailroom_needed_cnt +=
master->crypto_tx_tailroom_needed_cnt;
+ ieee80211_apvlan_link_setup(sdata);
+
break;
}
case NL80211_IFTYPE_AP:
@@ -1321,7 +1362,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
case NL80211_IFTYPE_AP_VLAN:
/* no need to tell driver, but set carrier and chanctx */
if (sdata->bss->active) {
- ieee80211_link_vlan_copy_chanctx(&sdata->deflink);
+ struct ieee80211_link_data *link;
+
+ for_each_link_data(sdata, link) {
+ ieee80211_link_vlan_copy_chanctx(link);
+ }
+
netif_carrier_on(dev);
ieee80211_set_vif_encap_ops(sdata);
} else {
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 2dc732147e85..885fa6aa3fc1 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -342,7 +342,7 @@ static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
return;
tpt_trig->running = false;
- del_timer_sync(&tpt_trig->timer);
+ timer_delete_sync(&tpt_trig->timer);
led_trigger_event(&local->tpt_led, LED_OFF);
}
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 58a76bcd6ae6..d40c2bd3b50b 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -12,6 +12,71 @@
#include "key.h"
#include "debugfs_netdev.h"
+static void ieee80211_update_apvlan_links(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_sub_if_data *vlan;
+ struct ieee80211_link_data *link;
+ u16 ap_bss_links = sdata->vif.valid_links;
+ u16 new_links, vlan_links;
+ unsigned long add;
+
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
+ int link_id;
+
+ if (!vlan)
+ continue;
+
+ /* No support for 4addr with MLO yet */
+ if (vlan->wdev.use_4addr)
+ return;
+
+ vlan_links = vlan->vif.valid_links;
+
+ new_links = ap_bss_links;
+
+ add = new_links & ~vlan_links;
+ if (!add)
+ continue;
+
+ ieee80211_vif_set_links(vlan, add, 0);
+
+ for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+ link = sdata_dereference(vlan->link[link_id], vlan);
+ ieee80211_link_vlan_copy_chanctx(link);
+ }
+ }
+}
+
+void ieee80211_apvlan_link_setup(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_sub_if_data *ap_bss = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+ u16 new_links = ap_bss->vif.valid_links;
+ unsigned long add;
+ int link_id;
+
+ if (!ap_bss->vif.valid_links)
+ return;
+
+ add = new_links;
+ for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+ sdata->wdev.valid_links |= BIT(link_id);
+ ether_addr_copy(sdata->wdev.links[link_id].addr,
+ ap_bss->wdev.links[link_id].addr);
+ }
+
+ ieee80211_vif_set_links(sdata, new_links, 0);
+}
+
+void ieee80211_apvlan_link_clear(struct ieee80211_sub_if_data *sdata)
+{
+ if (!sdata->wdev.valid_links)
+ return;
+
+ sdata->wdev.valid_links = 0;
+ ieee80211_vif_clear_links(sdata);
+}
+
void ieee80211_link_setup(struct ieee80211_link_data *link)
{
if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
@@ -31,6 +96,17 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf);
rcu_assign_pointer(sdata->link[link_id], link);
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ struct ieee80211_sub_if_data *ap_bss;
+ struct ieee80211_bss_conf *ap_bss_conf;
+
+ ap_bss = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+ ap_bss_conf = sdata_dereference(ap_bss->vif.link_conf[link_id],
+ ap_bss);
+ memcpy(link_conf, ap_bss_conf, sizeof(*link_conf));
+ }
+
link->sdata = sdata;
link->link_id = link_id;
link->conf = link_conf;
@@ -54,6 +130,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
if (!deflink) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
ether_addr_copy(link_conf->addr,
sdata->wdev.links[link_id].addr);
link_conf->bssid = link_conf->addr;
@@ -177,6 +254,7 @@ static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
/* in an AP all links are always active */
sdata->vif.active_links = valid_links;
@@ -278,12 +356,16 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata,
ieee80211_set_vif_links_bitmaps(sdata, new_links, dormant_links);
/* tell the driver */
- ret = drv_change_vif_links(sdata->local, sdata,
- old_links & old_active,
- new_links & sdata->vif.active_links,
- old);
+ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
+ ret = drv_change_vif_links(sdata->local, sdata,
+ old_links & old_active,
+ new_links & sdata->vif.active_links,
+ old);
if (!new_links)
ieee80211_debugfs_recreate_netdev(sdata, false);
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP)
+ ieee80211_update_apvlan_links(sdata);
}
if (ret) {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 741e6c7edcb7..6b6de43d9420 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1354,10 +1354,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
- local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
- sizeof(void *) * channels, GFP_KERNEL);
+ local->int_scan_req = kzalloc(struct_size(local->int_scan_req,
+ channels, channels),
+ GFP_KERNEL);
if (!local->int_scan_req)
return -ENOMEM;
+ local->int_scan_req->n_channels = channels;
eth_broadcast_addr(local->int_scan_req->bssid);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 974081324aa4..5cc56d578048 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -8,6 +8,7 @@
#include <linux/slab.h>
#include <linux/unaligned.h>
+#include <net/sock.h>
#include "ieee80211_i.h"
#include "mesh.h"
#include "wme.h"
@@ -706,7 +707,7 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
else {
clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
/* stop running timer */
- del_timer_sync(&ifmsh->mesh_path_root_timer);
+ timer_delete_sync(&ifmsh->mesh_path_root_timer);
}
}
@@ -776,7 +777,7 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
if (ethertype < ETH_P_802_3_MIN)
return false;
- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
+ if (sk_requests_wifi_status(skb->sk))
return false;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -956,13 +957,10 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
u8 *pos;
struct ieee80211_sub_if_data *sdata;
int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
- u32 rate_flags;
sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
sband = ieee80211_get_sband(sdata);
- rate_flags =
- ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chanreq.oper);
ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata);
@@ -1091,7 +1089,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
if (ieee80211_put_srates_elem(skb, sband,
sdata->vif.bss_conf.basic_rates,
- rate_flags, 0, WLAN_EID_SUPP_RATES) ||
+ 0, WLAN_EID_SUPP_RATES) ||
mesh_add_ds_params_ie(sdata, skb))
goto out_free;
@@ -1104,7 +1102,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
if (ieee80211_put_srates_elem(skb, sband,
sdata->vif.bss_conf.basic_rates,
- rate_flags, 0, WLAN_EID_EXT_SUPP_RATES) ||
+ 0, WLAN_EID_EXT_SUPP_RATES) ||
mesh_add_rsn_ie(sdata, skb) ||
mesh_add_ht_cap_ie(sdata, skb) ||
mesh_add_ht_oper_ie(sdata, skb) ||
@@ -1241,9 +1239,9 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
local->total_ps_buffered -= skb_queue_len(&ifmsh->ps.bc_buf);
skb_queue_purge(&ifmsh->ps.bc_buf);
- del_timer_sync(&sdata->u.mesh.housekeeping_timer);
- del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
- del_timer_sync(&sdata->u.mesh.mesh_path_timer);
+ timer_delete_sync(&sdata->u.mesh.housekeeping_timer);
+ timer_delete_sync(&sdata->u.mesh.mesh_path_root_timer);
+ timer_delete_sync(&sdata->u.mesh.mesh_path_timer);
/* clear any mesh work (for next join) we may have accrued */
ifmsh->wrkq_flags = 0;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index c94a9c7ca960..91444301a84a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -636,7 +636,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
mesh_path_add_gate(mpath);
}
rcu_read_unlock();
- } else {
+ } else if (ifmsh->mshcfg.dot11MeshForwarding) {
rcu_read_lock();
mpath = mesh_path_lookup(sdata, target_addr);
if (mpath) {
@@ -654,6 +654,8 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
}
}
rcu_read_unlock();
+ } else {
+ forward = false;
}
if (reply) {
@@ -671,7 +673,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
}
}
- if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
+ if (forward) {
u32 preq_id;
u8 hopcount;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 9f9cb5af0a97..0319674be832 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -22,7 +22,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
{
/* Use last four bytes of hw addr as hash index */
- return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed);
+ return jhash_1word(get_unaligned((u32 *)((u8 *)addr + 2)), seed);
}
static const struct rhashtable_params mesh_rht_params = {
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 5a0156e11c91..9c6a2b342170 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -264,7 +264,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
if (action != WLAN_SP_MESH_PEERING_CLOSE) {
struct ieee80211_supported_band *sband;
- u32 rate_flags, basic_rates;
+ u32 basic_rates;
sband = ieee80211_get_sband(sdata);
if (!sband) {
@@ -280,16 +280,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
put_unaligned_le16(sta->sta.aid, pos);
}
- rate_flags =
- ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chanreq.oper);
basic_rates = sdata->vif.bss_conf.basic_rates;
if (ieee80211_put_srates_elem(skb, sband, basic_rates,
- rate_flags, 0,
- WLAN_EID_SUPP_RATES) ||
+ 0, WLAN_EID_SUPP_RATES) ||
ieee80211_put_srates_elem(skb, sband, basic_rates,
- rate_flags, 0,
- WLAN_EID_EXT_SUPP_RATES) ||
+ 0, WLAN_EID_EXT_SUPP_RATES) ||
mesh_add_rsn_ie(sdata, skb) ||
mesh_add_meshid_ie(sdata, skb) ||
mesh_add_meshconf_ie(sdata, skb))
@@ -417,7 +413,7 @@ u64 mesh_plink_deactivate(struct sta_info *sta)
}
spin_unlock_bh(&sta->mesh->plink_lock);
if (!sdata->u.mesh.user_mpm)
- del_timer_sync(&sta->mesh->plink_timer);
+ timer_delete_sync(&sta->mesh->plink_timer);
mesh_path_flush_by_nexthop(sta);
/* make sure no readers can access nexthop sta from here on */
@@ -666,7 +662,7 @@ void mesh_plink_timer(struct timer_list *t)
/*
* This STA is valid because sta_info_destroy() will
- * del_timer_sync() this timer after having made sure
+ * timer_delete_sync() this timer after having made sure
* it cannot be re-added (by deleting the plink.)
*/
sta = mesh->plink_sta;
@@ -689,7 +685,7 @@ void mesh_plink_timer(struct timer_list *t)
return;
}
- /* del_timer() and handler may race when entering these states */
+ /* timer_delete() and handler may race when entering these states */
if (sta->mesh->plink_state == NL80211_PLINK_LISTEN ||
sta->mesh->plink_state == NL80211_PLINK_ESTAB) {
mpl_dbg(sta->sdata,
@@ -735,7 +731,7 @@ void mesh_plink_timer(struct timer_list *t)
break;
case NL80211_PLINK_HOLDING:
/* holding timer */
- del_timer(&sta->mesh->plink_timer);
+ timer_delete(&sta->mesh->plink_timer);
mesh_plink_fsm_restart(sta);
break;
default:
@@ -848,7 +844,7 @@ static u64 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
u64 changed = 0;
- del_timer(&sta->mesh->plink_timer);
+ timer_delete(&sta->mesh->plink_timer);
sta->mesh->plink_state = NL80211_PLINK_ESTAB;
changed |= mesh_plink_inc_estab_count(sdata);
changed |= mesh_set_ht_prot_mode(sdata);
@@ -975,7 +971,7 @@ static u64 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
case NL80211_PLINK_HOLDING:
switch (event) {
case CLS_ACPT:
- del_timer(&sta->mesh->plink_timer);
+ timer_delete(&sta->mesh->plink_timer);
mesh_plink_fsm_restart(sta);
break;
case OPN_ACPT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c010bb3d24e3..b84150dbfe8c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1525,9 +1525,9 @@ static void ieee80211_assoc_add_rates(struct ieee80211_local *local,
rates = ~0;
}
- ieee80211_put_srates_elem(skb, sband, 0, 0, ~rates,
+ ieee80211_put_srates_elem(skb, sband, 0, ~rates,
WLAN_EID_SUPP_RATES);
- ieee80211_put_srates_elem(skb, sband, 0, 0, ~rates,
+ ieee80211_put_srates_elem(skb, sband, 0, ~rates,
WLAN_EID_EXT_SUPP_RATES);
}
@@ -3194,7 +3194,7 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
} else if (conf->flags & IEEE80211_CONF_PS) {
conf->flags &= ~IEEE80211_CONF_PS;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- del_timer_sync(&local->dynamic_ps_timer);
+ timer_delete_sync(&local->dynamic_ps_timer);
wiphy_work_cancel(local->hw.wiphy,
&local->dynamic_ps_enable_work);
}
@@ -4069,7 +4069,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
- del_timer_sync(&local->dynamic_ps_timer);
+ timer_delete_sync(&local->dynamic_ps_timer);
wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);
/* Disable ARP filtering */
@@ -4097,9 +4097,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
/* disassociated - set to defaults now */
ieee80211_set_wmm_default(&sdata->deflink, false, false);
- del_timer_sync(&sdata->u.mgd.conn_mon_timer);
- del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
- del_timer_sync(&sdata->u.mgd.timer);
+ timer_delete_sync(&sdata->u.mgd.conn_mon_timer);
+ timer_delete_sync(&sdata->u.mgd.bcn_mon_timer);
+ timer_delete_sync(&sdata->u.mgd.timer);
sdata->vif.bss_conf.dtim_period = 0;
sdata->vif.bss_conf.beacon_rate = NULL;
@@ -4589,7 +4589,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
* running is the timeout for the authentication response which
* which is not relevant anymore.
*/
- del_timer_sync(&sdata->u.mgd.timer);
+ timer_delete_sync(&sdata->u.mgd.timer);
sta_info_destroy_addr(sdata, auth_data->ap_addr);
/* other links are destroyed */
@@ -4628,7 +4628,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
* running is the timeout for the association response which
* which is not relevant anymore.
*/
- del_timer_sync(&sdata->u.mgd.timer);
+ timer_delete_sync(&sdata->u.mgd.timer);
sta_info_destroy_addr(sdata, assoc_data->ap_addr);
eth_zero_addr(sdata->deflink.u.mgd.bssid);
@@ -7675,6 +7675,7 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res);
int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 +
2 * 2 * IEEE80211_TTLM_NUM_TIDS;
+ u16 status_code;
skb = dev_alloc_skb(local->tx_headroom + hdr_len + ttlm_max_len);
if (!skb)
@@ -7697,19 +7698,18 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
WARN_ON(1);
fallthrough;
case NEG_TTLM_RES_REJECT:
- mgmt->u.action.u.ttlm_res.status_code =
- WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING;
+ status_code = WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING;
break;
case NEG_TTLM_RES_ACCEPT:
- mgmt->u.action.u.ttlm_res.status_code = WLAN_STATUS_SUCCESS;
+ status_code = WLAN_STATUS_SUCCESS;
break;
case NEG_TTLM_RES_SUGGEST_PREFERRED:
- mgmt->u.action.u.ttlm_res.status_code =
- WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED;
+ status_code = WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED;
ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm);
break;
}
+ mgmt->u.action.u.ttlm_res.status_code = cpu_to_le16(status_code);
ieee80211_tx_skb(sdata, skb);
}
@@ -7875,7 +7875,7 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
* This can be better implemented in the future, to handle request
* rejections.
*/
- if (mgmt->u.action.u.ttlm_res.status_code != WLAN_STATUS_SUCCESS)
+ if (le16_to_cpu(mgmt->u.action.u.ttlm_res.status_code) != WLAN_STATUS_SUCCESS)
__ieee80211_disconnect(sdata);
}
@@ -9852,7 +9852,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
ifmgd->assoc_req_ies = NULL;
ifmgd->assoc_req_ies_len = 0;
spin_unlock_bh(&ifmgd->teardown_lock);
- del_timer_sync(&ifmgd->timer);
+ timer_delete_sync(&ifmgd->timer);
}
void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
index 6218abc3e441..ece1e83c7b2f 100644
--- a/net/mac80211/ocb.c
+++ b/net/mac80211/ocb.c
@@ -230,7 +230,7 @@ int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata)
skb_queue_purge(&sdata->skb_queue);
- del_timer_sync(&sdata->u.ocb.housekeeping_timer);
+ timer_delete_sync(&sdata->u.ocb.housekeeping_timer);
/* If the timer fired while we waited for it, it will have
* requeued the work. Now the work will be running again
* but will not rearm the timer again because it checks
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 29fab7ae47b4..2b9abc27462e 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -30,9 +30,9 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
/* FIXME: what to do when local->pspolling is true? */
- del_timer_sync(&local->dynamic_ps_timer);
- del_timer_sync(&ifmgd->bcn_mon_timer);
- del_timer_sync(&ifmgd->conn_mon_timer);
+ timer_delete_sync(&local->dynamic_ps_timer);
+ timer_delete_sync(&ifmgd->bcn_mon_timer);
+ timer_delete_sync(&ifmgd->conn_mon_timer);
wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);
diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c
index 6da39c864f45..96584b39215e 100644
--- a/net/mac80211/parse.c
+++ b/net/mac80211/parse.c
@@ -1101,7 +1101,6 @@ int ieee80211_parse_bitrates(enum nl80211_chan_width width,
const struct ieee80211_supported_band *sband,
const u8 *srates, int srates_len, u32 *rates)
{
- u32 rate_flags = ieee80211_chanwidth_rate_flags(width);
struct ieee80211_rate *br;
int brate, rate, i, j, count = 0;
@@ -1112,8 +1111,6 @@ int ieee80211_parse_bitrates(enum nl80211_chan_width width,
for (j = 0; j < sband->n_bitrates; j++) {
br = &sband->bitrates[j];
- if ((rate_flags & br->flags) != rate_flags)
- continue;
brate = DIV_ROUND_UP(br->bitrate, 5);
if (brate == rate) {
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 7be52345f218..a9cc832240a5 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -69,14 +69,14 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
flush_workqueue(local->workqueue);
/* Don't try to run timers while suspended. */
- del_timer_sync(&local->sta_cleanup);
+ timer_delete_sync(&local->sta_cleanup);
/*
* Note that this particular timer doesn't need to be
* restarted at resume.
*/
wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);
- del_timer_sync(&local->dynamic_ps_timer);
+ timer_delete_sync(&local->dynamic_ps_timer);
local->wowlan = wowlan;
if (local->wowlan) {
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 0d056db9f81e..3cb2ad6d0b28 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -368,9 +368,8 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info,
u32 rate_mask)
{
+ u32 rate_flags = 0;
int i;
- u32 rate_flags =
- ieee80211_chandef_rate_flags(&hw->conf.chandef);
if (sband->band == NL80211_BAND_S1GHZ) {
info->control.rates[0].flags |= IEEE80211_TX_RC_S1G_MCS;
@@ -778,14 +777,9 @@ static bool rate_control_cap_mask(struct ieee80211_sub_if_data *sdata,
u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN],
u16 vht_mask[NL80211_VHT_NSS_MAX])
{
- u32 i, flags;
+ u32 i;
*mask = sdata->rc_rateidx_mask[sband->band];
- flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chanreq.oper);
- for (i = 0; i < sband->n_bitrates; i++) {
- if ((flags & sband->bitrates[i].flags) != flags)
- *mask &= ~BIT(i);
- }
if (*mask == (1 << sband->n_bitrates) - 1 &&
!sdata->rc_has_mcs_mask[sband->band] &&
@@ -990,8 +984,6 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
if (sta->uploaded)
drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
- ieee80211_sta_set_expected_throughput(pubsta, sta_get_expected_throughput(sta));
-
return 0;
}
EXPORT_SYMBOL(rate_control_set_rates);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 706cbc99f718..f66910013218 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1873,16 +1873,13 @@ minstrel_ht_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
static void
minstrel_ht_fill_rate_array(u8 *dest, struct ieee80211_supported_band *sband,
- const s16 *bitrates, int n_rates, u32 rate_flags)
+ const s16 *bitrates, int n_rates)
{
int i, j;
for (i = 0; i < sband->n_bitrates; i++) {
struct ieee80211_rate *rate = &sband->bitrates[i];
- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
- continue;
-
for (j = 0; j < n_rates; j++) {
if (rate->bitrate != bitrates[j])
continue;
@@ -1898,7 +1895,6 @@ minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
{
static const s16 bitrates[4] = { 10, 20, 55, 110 };
struct ieee80211_supported_band *sband;
- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
memset(mp->cck_rates, 0xff, sizeof(mp->cck_rates));
sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ];
@@ -1908,8 +1904,7 @@ minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
BUILD_BUG_ON(ARRAY_SIZE(mp->cck_rates) != ARRAY_SIZE(bitrates));
minstrel_ht_fill_rate_array(mp->cck_rates, sband,
minstrel_cck_bitrates,
- ARRAY_SIZE(minstrel_cck_bitrates),
- rate_flags);
+ ARRAY_SIZE(minstrel_cck_bitrates));
}
static void
@@ -1917,7 +1912,6 @@ minstrel_ht_init_ofdm_rates(struct minstrel_priv *mp, enum nl80211_band band)
{
static const s16 bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 };
struct ieee80211_supported_band *sband;
- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
memset(mp->ofdm_rates[band], 0xff, sizeof(mp->ofdm_rates[band]));
sband = mp->hw->wiphy->bands[band];
@@ -1927,8 +1921,7 @@ minstrel_ht_init_ofdm_rates(struct minstrel_priv *mp, enum nl80211_band band)
BUILD_BUG_ON(ARRAY_SIZE(mp->ofdm_rates[band]) != ARRAY_SIZE(bitrates));
minstrel_ht_fill_rate_array(mp->ofdm_rates[band], sband,
minstrel_ofdm_bitrates,
- ARRAY_SIZE(minstrel_ofdm_bitrates),
- rate_flags);
+ ARRAY_SIZE(minstrel_ofdm_bitrates));
}
static void *
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f7f89cd1b7d7..09beb65d6108 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1242,7 +1242,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
tid_agg_rx->reorder_time[j] + 1 +
HT_RX_REORDER_BUF_TIMEOUT);
} else {
- del_timer(&tid_agg_rx->reorder_timer);
+ timer_delete(&tid_agg_rx->reorder_timer);
}
}
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index cb7079071885..7b8da40a912d 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -240,6 +240,9 @@ static bool ieee80211_scan_accept_presp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *channel,
u32 scan_flags, const u8 *da)
{
+ struct ieee80211_link_data *link_sdata;
+ u8 link_id;
+
if (!sdata)
return false;
@@ -251,7 +254,20 @@ static bool ieee80211_scan_accept_presp(struct ieee80211_sub_if_data *sdata,
if (scan_flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
return true;
- return ether_addr_equal(da, sdata->vif.addr);
+
+ if (ether_addr_equal(da, sdata->vif.addr))
+ return true;
+
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
+ link_sdata = rcu_dereference(sdata->link[link_id]);
+ if (!link_sdata)
+ continue;
+
+ if (ether_addr_equal(da, link_sdata->conf->addr))
+ return true;
+ }
+
+ return false;
}
void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index c6015cd00372..7422888d3640 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -147,14 +147,14 @@ validate_chandef_by_6ghz_he_eht_oper(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
u32 control_freq, center_freq1, center_freq2;
enum nl80211_chan_width chan_width;
- struct {
- struct ieee80211_he_operation _oper;
- struct ieee80211_he_6ghz_oper _6ghz_oper;
- } __packed he;
- struct {
- struct ieee80211_eht_operation _oper;
- struct ieee80211_eht_operation_info _oper_info;
- } __packed eht;
+ DEFINE_RAW_FLEX(struct ieee80211_he_operation, he, optional,
+ sizeof(struct ieee80211_he_6ghz_oper));
+ struct ieee80211_he_6ghz_oper *_6ghz_oper =
+ (struct ieee80211_he_6ghz_oper *)he->optional;
+ DEFINE_RAW_FLEX(struct ieee80211_eht_operation, eht, optional,
+ sizeof(struct ieee80211_eht_operation_info));
+ struct ieee80211_eht_operation_info *_oper_info =
+ (struct ieee80211_eht_operation_info *)eht->optional;
const struct ieee80211_eht_operation *eht_oper;
if (conn->mode < IEEE80211_CONN_MODE_HE) {
@@ -167,38 +167,38 @@ validate_chandef_by_6ghz_he_eht_oper(struct ieee80211_sub_if_data *sdata,
center_freq2 = chandef->center_freq2;
chan_width = chandef->width;
- he._oper.he_oper_params =
+ he->he_oper_params =
le32_encode_bits(1, IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
- he._6ghz_oper.primary =
+ _6ghz_oper->primary =
ieee80211_frequency_to_channel(control_freq);
- he._6ghz_oper.ccfs0 = ieee80211_frequency_to_channel(center_freq1);
- he._6ghz_oper.ccfs1 = center_freq2 ?
+ _6ghz_oper->ccfs0 = ieee80211_frequency_to_channel(center_freq1);
+ _6ghz_oper->ccfs1 = center_freq2 ?
ieee80211_frequency_to_channel(center_freq2) : 0;
switch (chan_width) {
case NL80211_CHAN_WIDTH_320:
- he._6ghz_oper.ccfs1 = he._6ghz_oper.ccfs0;
- he._6ghz_oper.ccfs0 += control_freq < center_freq1 ? -16 : 16;
- he._6ghz_oper.control = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
+ _6ghz_oper->ccfs1 = _6ghz_oper->ccfs0;
+ _6ghz_oper->ccfs0 += control_freq < center_freq1 ? -16 : 16;
+ _6ghz_oper->control = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
break;
case NL80211_CHAN_WIDTH_160:
- he._6ghz_oper.ccfs1 = he._6ghz_oper.ccfs0;
- he._6ghz_oper.ccfs0 += control_freq < center_freq1 ? -8 : 8;
+ _6ghz_oper->ccfs1 = _6ghz_oper->ccfs0;
+ _6ghz_oper->ccfs0 += control_freq < center_freq1 ? -8 : 8;
fallthrough;
case NL80211_CHAN_WIDTH_80P80:
- he._6ghz_oper.control =
+ _6ghz_oper->control =
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
break;
case NL80211_CHAN_WIDTH_80:
- he._6ghz_oper.control =
+ _6ghz_oper->control =
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
break;
case NL80211_CHAN_WIDTH_40:
- he._6ghz_oper.control =
+ _6ghz_oper->control =
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
break;
default:
- he._6ghz_oper.control =
+ _6ghz_oper->control =
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
break;
}
@@ -206,15 +206,14 @@ validate_chandef_by_6ghz_he_eht_oper(struct ieee80211_sub_if_data *sdata,
if (conn->mode < IEEE80211_CONN_MODE_EHT) {
eht_oper = NULL;
} else {
- eht._oper.params = IEEE80211_EHT_OPER_INFO_PRESENT;
- eht._oper_info.control = he._6ghz_oper.control;
- eht._oper_info.ccfs0 = he._6ghz_oper.ccfs0;
- eht._oper_info.ccfs1 = he._6ghz_oper.ccfs1;
- eht_oper = &eht._oper;
+ eht->params = IEEE80211_EHT_OPER_INFO_PRESENT;
+ _oper_info->control = _6ghz_oper->control;
+ _oper_info->ccfs0 = _6ghz_oper->ccfs0;
+ _oper_info->ccfs1 = _6ghz_oper->ccfs1;
+ eht_oper = eht;
}
- if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper,
- eht_oper, chandef))
+ if (!ieee80211_chandef_he_6ghz_oper(local, he, eht_oper, chandef))
chandef->chan = NULL;
}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 30cdc783999d..84b18be1f0b1 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -18,7 +18,6 @@
#include <linux/timer.h>
#include <linux/rtnetlink.h>
-#include <net/codel.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
@@ -701,12 +700,6 @@ __sta_info_alloc(struct ieee80211_sub_if_data *sdata,
}
}
- sta->cparams.ce_threshold = CODEL_DISABLED_THRESHOLD;
- sta->cparams.target = MS2TIME(20);
- sta->cparams.interval = MS2TIME(100);
- sta->cparams.ecn = true;
- sta->cparams.ce_threshold_selector = 0;
- sta->cparams.ce_threshold_mask = 0;
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
@@ -1592,7 +1585,7 @@ int sta_info_init(struct ieee80211_local *local)
void sta_info_stop(struct ieee80211_local *local)
{
- del_timer_sync(&local->sta_cleanup);
+ timer_delete_sync(&local->sta_cleanup);
rhltable_destroy(&local->sta_hash);
rhltable_destroy(&local->link_sta_hash);
}
@@ -2905,27 +2898,6 @@ unsigned long ieee80211_sta_last_active(struct sta_info *sta)
return sta->deflink.status_stats.last_ack;
}
-static void sta_update_codel_params(struct sta_info *sta, u32 thr)
-{
- if (thr && thr < STA_SLOW_THRESHOLD * sta->local->num_sta) {
- sta->cparams.target = MS2TIME(50);
- sta->cparams.interval = MS2TIME(300);
- sta->cparams.ecn = false;
- } else {
- sta->cparams.target = MS2TIME(20);
- sta->cparams.interval = MS2TIME(100);
- sta->cparams.ecn = true;
- }
-}
-
-void ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
- u32 thr)
-{
- struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-
- sta_update_codel_params(sta, thr);
-}
-
int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 07b7ec39a52f..7a95d8d34fca 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -466,14 +466,6 @@ struct ieee80211_fragment_cache {
unsigned int next;
};
-/*
- * The bandwidth threshold below which the per-station CoDel parameters will be
- * scaled to be more lenient (to prevent starvation of slow stations). This
- * value will be scaled by the number of active stations when it is being
- * applied.
- */
-#define STA_SLOW_THRESHOLD 6000 /* 6 Mbps */
-
/**
* struct link_sta_info - Link STA information
* All link specific sta info are stored here for reference. This can be
@@ -626,7 +618,6 @@ struct link_sta_info {
* @sta: station information we share with the driver
* @sta_state: duplicates information about station state (for debug)
* @rcu_head: RCU head used for freeing this station struct
- * @cparams: CoDel parameters for this station.
* @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED)
* @amsdu_mesh_control: track the mesh A-MSDU format used by the peer:
*
@@ -717,8 +708,6 @@ struct sta_info {
struct dentry *debugfs_dir;
#endif
- struct codel_params cparams;
-
u8 reserved_tid;
s8 amsdu_mesh_control;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index b17b3cc7fb90..a362254b310c 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -1085,7 +1085,13 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
ieee80211_report_used_skb(local, skb, false, status->ack_hwtstamp);
- if (status->free_list)
+ /*
+ * This is a bit racy but we can avoid a lot of work
+ * with this test...
+ */
+ if (local->tx_mntrs)
+ ieee80211_tx_monitor(local, skb, retry_count, status);
+ else if (status->free_list)
list_add_tail(&skb->list, status->free_list);
else
dev_kfree_skb(skb);
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 2f92e7c7f203..94714f8ffd22 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -382,8 +382,8 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_link_data *link,
if (WARN_ON_ONCE(!sband))
return;
- ieee80211_put_srates_elem(skb, sband, 0, 0, 0, WLAN_EID_SUPP_RATES);
- ieee80211_put_srates_elem(skb, sband, 0, 0, 0, WLAN_EID_EXT_SUPP_RATES);
+ ieee80211_put_srates_elem(skb, sband, 0, 0, WLAN_EID_SUPP_RATES);
+ ieee80211_put_srates_elem(skb, sband, 0, 0, WLAN_EID_EXT_SUPP_RATES);
ieee80211_tdls_add_supp_channels(sdata, skb);
/* add any custom IEs that go before Extended Capabilities */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 20179db88c4a..d8d4f3d7d7f2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -26,6 +26,7 @@
#include <net/codel_impl.h>
#include <linux/unaligned.h>
#include <net/fq_impl.h>
+#include <net/sock.h>
#include <net/gso.h>
#include "ieee80211_i.h"
@@ -49,19 +50,11 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_chanctx_conf *chanctx_conf;
- u32 rate_flags = 0;
/* assume HW handles this */
if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
return 0;
- rcu_read_lock();
- chanctx_conf = rcu_dereference(tx->sdata->vif.bss_conf.chanctx_conf);
- if (chanctx_conf)
- rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
- rcu_read_unlock();
-
/* uh huh? */
if (WARN_ON_ONCE(tx->rate.idx < 0))
return 0;
@@ -138,9 +131,6 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
if (r->bitrate > txrate->bitrate)
break;
- if ((rate_flags & r->flags) != rate_flags)
- continue;
-
if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
rate = r->bitrate;
@@ -1402,16 +1392,9 @@ static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
local = container_of(fq, struct ieee80211_local, fq);
txqi = container_of(tin, struct txq_info, tin);
+ cparams = &local->cparams;
cstats = &txqi->cstats;
- if (txqi->txq.sta) {
- struct sta_info *sta = container_of(txqi->txq.sta,
- struct sta_info, sta);
- cparams = &sta->cparams;
- } else {
- cparams = &local->cparams;
- }
-
if (flow == &tin->default_flow)
cvars = &txqi->def_cvars;
else
@@ -2876,8 +2859,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
}
if (unlikely(!multicast &&
- ((skb->sk &&
- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) ||
+ (sk_requests_wifi_status(skb->sk) ||
ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS)))
info_id = ieee80211_store_ack_skb(local, skb, &info_flags,
cookie);
@@ -3774,7 +3756,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
return false;
/* don't handle TX status request here either */
- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
+ if (sk_requests_wifi_status(skb->sk))
return false;
if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
@@ -4526,8 +4508,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
IEEE80211_TX_CTRL_MLO_LINK_UNSPEC,
NULL);
} else if (ieee80211_vif_is_mld(&sdata->vif) &&
- sdata->vif.type == NL80211_IFTYPE_AP &&
- !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) {
+ ((sdata->vif.type == NL80211_IFTYPE_AP &&
+ !ieee80211_hw_check(&sdata->local->hw, MLO_MCAST_MULTI_LINK_TX)) ||
+ (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+ !sdata->wdev.use_4addr))) {
ieee80211_mlo_multicast_tx(dev, skb);
} else {
normal:
@@ -4664,8 +4648,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info));
}
- if (unlikely(skb->sk &&
- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
+ if (unlikely(sk_requests_wifi_status(skb->sk))) {
info->status_data = ieee80211_store_ack_skb(local, skb,
&info->flags, NULL);
if (info->status_data)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dec6e16b8c7d..27d414efa3fd 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1204,7 +1204,6 @@ static int ieee80211_put_preq_ies_band(struct sk_buff *skb,
struct ieee80211_supported_band *sband;
int i, err;
size_t noffset;
- u32 rate_flags;
bool have_80mhz = false;
*offset = 0;
@@ -1213,13 +1212,11 @@ static int ieee80211_put_preq_ies_band(struct sk_buff *skb,
if (WARN_ON_ONCE(!sband))
return 0;
- rate_flags = ieee80211_chandef_rate_flags(chandef);
-
/* For direct scan add S1G IE and consider its override bits */
if (band == NL80211_BAND_S1GHZ)
return ieee80211_put_s1g_cap(skb, &sband->s1g_cap);
- err = ieee80211_put_srates_elem(skb, sband, 0, rate_flags,
+ err = ieee80211_put_srates_elem(skb, sband, 0,
~rate_mask, WLAN_EID_SUPP_RATES);
if (err)
return err;
@@ -1241,7 +1238,7 @@ static int ieee80211_put_preq_ies_band(struct sk_buff *skb,
*offset = noffset;
}
- err = ieee80211_put_srates_elem(skb, sband, 0, rate_flags,
+ err = ieee80211_put_srates_elem(skb, sband, 0,
~rate_mask, WLAN_EID_EXT_SUPP_RATES);
if (err)
return err;
@@ -1522,16 +1519,13 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_supported_band *sband;
size_t num_rates;
- u32 supp_rates, rate_flags;
+ u32 supp_rates;
int i, j;
sband = sdata->local->hw.wiphy->bands[band];
if (WARN_ON(!sband))
return 1;
- rate_flags =
- ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chanreq.oper);
-
num_rates = sband->n_bitrates;
supp_rates = 0;
for (i = 0; i < elems->supp_rates_len +
@@ -1551,12 +1545,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
continue;
for (j = 0; j < num_rates; j++) {
- int brate;
- if ((rate_flags & sband->bitrates[j].flags)
- != rate_flags)
- continue;
-
- brate = sband->bitrates[j].bitrate;
+ int brate = sband->bitrates[j].bitrate;
if (brate == own_rate) {
supp_rates |= BIT(j);
@@ -3223,15 +3212,13 @@ bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
int ieee80211_put_srates_elem(struct sk_buff *skb,
const struct ieee80211_supported_band *sband,
- u32 basic_rates, u32 rate_flags, u32 masked_rates,
+ u32 basic_rates, u32 masked_rates,
u8 element_id)
{
u8 i, rates, skip;
rates = 0;
for (i = 0; i < sband->n_bitrates; i++) {
- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
- continue;
if (masked_rates & BIT(i))
continue;
rates++;
@@ -3257,8 +3244,6 @@ int ieee80211_put_srates_elem(struct sk_buff *skb,
int rate;
u8 basic;
- if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
- continue;
if (masked_rates & BIT(i))
continue;