Commit 44d70bb5 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'wireless-2022-09-27' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
A few late-comer fixes:
 * locking in mac80211 MLME
 * non-QoS driver crash/regression
 * minstrel memory corruption
 * TX deadlock
 * TX queues not always enabled
 * HE/EHT bitrate calculation

* tag 'wireless-2022-09-27' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: mac80211: mlme: Fix double unlock on assoc success handling
  wifi: mac80211: mlme: Fix missing unlock on beacon RX
  wifi: mac80211: fix memory corruption in minstrel_ht_update_rates()
  wifi: mac80211: fix regression with non-QoS drivers
  wifi: mac80211: ensure vif queues are operational after start
  wifi: mac80211: don't start TX with fq->lock to fix deadlock
  wifi: cfg80211: fix MCS divisor value
====================

Link: https://lore.kernel.org/r/20220927135923.45312-1-johannes@sipsolutions.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 797666cd 6546646a
...@@ -4040,7 +4040,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, ...@@ -4040,7 +4040,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
if (!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && if (!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) &&
(!elems->he_cap || !elems->he_operation)) { (!elems->he_cap || !elems->he_operation)) {
mutex_unlock(&sdata->local->sta_mtx);
sdata_info(sdata, sdata_info(sdata,
"HE AP is missing HE capability/operation\n"); "HE AP is missing HE capability/operation\n");
ret = false; ret = false;
...@@ -5589,12 +5588,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link, ...@@ -5589,12 +5588,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
mutex_lock(&local->sta_mtx); mutex_lock(&local->sta_mtx);
sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
if (WARN_ON(!sta)) if (WARN_ON(!sta)) {
mutex_unlock(&local->sta_mtx);
goto free; goto free;
}
link_sta = rcu_dereference_protected(sta->link[link->link_id], link_sta = rcu_dereference_protected(sta->link[link->link_id],
lockdep_is_held(&local->sta_mtx)); lockdep_is_held(&local->sta_mtx));
if (WARN_ON(!link_sta)) if (WARN_ON(!link_sta)) {
mutex_unlock(&local->sta_mtx);
goto free; goto free;
}
changed |= ieee80211_recalc_twt_req(link, link_sta, elems); changed |= ieee80211_recalc_twt_req(link, link_sta, elems);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/random.h> #include <linux/random.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include <linux/minmax.h>
#include <net/mac80211.h> #include <net/mac80211.h>
#include "rate.h" #include "rate.h"
#include "sta_info.h" #include "sta_info.h"
...@@ -1550,6 +1551,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) ...@@ -1550,6 +1551,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
{ {
struct ieee80211_sta_rates *rates; struct ieee80211_sta_rates *rates;
int i = 0; int i = 0;
int max_rates = min_t(int, mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE);
rates = kzalloc(sizeof(*rates), GFP_ATOMIC); rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
if (!rates) if (!rates)
...@@ -1559,10 +1561,10 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) ...@@ -1559,10 +1561,10 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
/* Fill up remaining, keep one entry for max_probe_rate */ /* Fill up remaining, keep one entry for max_probe_rate */
for (; i < (mp->hw->max_rates - 1); i++) for (; i < (max_rates - 1); i++)
minstrel_ht_set_rate(mp, mi, rates, i, mi->max_tp_rate[i]); minstrel_ht_set_rate(mp, mi, rates, i, mi->max_tp_rate[i]);
if (i < mp->hw->max_rates) if (i < max_rates)
minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate);
if (i < IEEE80211_TX_RATE_TABLE_SIZE) if (i < IEEE80211_TX_RATE_TABLE_SIZE)
......
...@@ -729,7 +729,7 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, ...@@ -729,7 +729,7 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
if (!sdata) { if (!sdata) {
skb->dev = NULL; skb->dev = NULL;
} else { } else if (!dropped) {
unsigned int hdr_size = unsigned int hdr_size =
ieee80211_hdrlen(hdr->frame_control); ieee80211_hdrlen(hdr->frame_control);
......
...@@ -5878,6 +5878,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, ...@@ -5878,6 +5878,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
skb_reset_network_header(skb); skb_reset_network_header(skb);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
if (local->hw.queues < IEEE80211_NUM_ACS)
goto start_xmit;
/* update QoS header to prioritize control port frames if possible, /* update QoS header to prioritize control port frames if possible,
* priorization also happens for control port frames send over * priorization also happens for control port frames send over
* AF_PACKET * AF_PACKET
...@@ -5905,6 +5908,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, ...@@ -5905,6 +5908,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
} }
rcu_read_unlock(); rcu_read_unlock();
start_xmit:
/* mutex lock is only needed for incrementing the cookie counter */ /* mutex lock is only needed for incrementing the cookie counter */
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
......
...@@ -301,14 +301,14 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) ...@@ -301,14 +301,14 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
local_bh_disable(); local_bh_disable();
spin_lock(&fq->lock); spin_lock(&fq->lock);
sdata->vif.txqs_stopped[ac] = false;
if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) if (!test_bit(SDATA_STATE_RUNNING, &sdata->state))
goto out; goto out;
if (sdata->vif.type == NL80211_IFTYPE_AP) if (sdata->vif.type == NL80211_IFTYPE_AP)
ps = &sdata->bss->ps; ps = &sdata->bss->ps;
sdata->vif.txqs_stopped[ac] = false;
list_for_each_entry_rcu(sta, &local->sta_list, list) { list_for_each_entry_rcu(sta, &local->sta_list, list) {
if (sdata != sta->sdata) if (sdata != sta->sdata)
continue; continue;
......
...@@ -1361,7 +1361,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) ...@@ -1361,7 +1361,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
25599, /* 4.166666... */ 25599, /* 4.166666... */
17067, /* 2.777777... */ 17067, /* 2.777777... */
12801, /* 2.083333... */ 12801, /* 2.083333... */
11769, /* 1.851851... */ 11377, /* 1.851725... */
10239, /* 1.666666... */ 10239, /* 1.666666... */
8532, /* 1.388888... */ 8532, /* 1.388888... */
7680, /* 1.250000... */ 7680, /* 1.250000... */
...@@ -1444,7 +1444,7 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate) ...@@ -1444,7 +1444,7 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate)
25599, /* 4.166666... */ 25599, /* 4.166666... */
17067, /* 2.777777... */ 17067, /* 2.777777... */
12801, /* 2.083333... */ 12801, /* 2.083333... */
11769, /* 1.851851... */ 11377, /* 1.851725... */
10239, /* 1.666666... */ 10239, /* 1.666666... */
8532, /* 1.388888... */ 8532, /* 1.388888... */
7680, /* 1.250000... */ 7680, /* 1.250000... */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment