Commit f99d93de authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'wireless-2024-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
Couple of more urgent fixes:
 * ath12k: wowlan loop iteration issue
 * ath12k: fix soft lockup on suspend in certain scenarios
 * mt76: fix crash when removing an interface
 * mac80211: fix injection crash with some drivers that
   don't want monitor vif
 * cfg80211: fix S1G beacon parsing in scan
 * cfg80211: fix MLO link status reporting on connect

* tag 'wireless-2024-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: ath12k: fix soft lockup on suspend
  wifi: mt76: mt7921: fix null pointer access in mt792x_mac_link_bss_remove
  wifi: ath12k: fix reusing outside iterator in ath12k_wow_vif_set_wakeups()
  wifi: cfg80211: correct S1G beacon length calculation
  wifi: cfg80211: fix reporting failed MLO links status with cfg80211_connect_done
  wifi: mac80211: use monitor sdata with driver only if desired
====================

Link: https://patch.msgid.link/20240726122638.942420-3-johannes@sipsolutions.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 225990c4 a47f3320
...@@ -473,7 +473,8 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) ...@@ -473,7 +473,8 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
{ {
int i; int i;
clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); if (!test_and_clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags))
return;
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
......
...@@ -361,7 +361,7 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif, ...@@ -361,7 +361,7 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif,
struct ath12k *ar = arvif->ar; struct ath12k *ar = arvif->ar;
unsigned long wow_mask = 0; unsigned long wow_mask = 0;
int pattern_id = 0; int pattern_id = 0;
int ret, i; int ret, i, j;
/* Setup requested WOW features */ /* Setup requested WOW features */
switch (arvif->vdev_type) { switch (arvif->vdev_type) {
...@@ -431,9 +431,9 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif, ...@@ -431,9 +431,9 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif,
eth_pattern->pattern_len); eth_pattern->pattern_len);
/* convert bitmask to bytemask */ /* convert bitmask to bytemask */
for (i = 0; i < eth_pattern->pattern_len; i++) for (j = 0; j < eth_pattern->pattern_len; j++)
if (eth_pattern->mask[i / 8] & BIT(i % 8)) if (eth_pattern->mask[j / 8] & BIT(j % 8))
new_pattern.bytemask[i] = 0xff; new_pattern.bytemask[j] = 0xff;
new_pattern.pattern_len = eth_pattern->pattern_len; new_pattern.pattern_len = eth_pattern->pattern_len;
new_pattern.pkt_offset = eth_pattern->pkt_offset; new_pattern.pkt_offset = eth_pattern->pkt_offset;
......
...@@ -303,6 +303,7 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -303,6 +303,7 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mvif->bss_conf.mt76.omac_idx = mvif->bss_conf.mt76.idx; mvif->bss_conf.mt76.omac_idx = mvif->bss_conf.mt76.idx;
mvif->phy = phy; mvif->phy = phy;
mvif->bss_conf.vif = mvif;
mvif->bss_conf.mt76.band_idx = 0; mvif->bss_conf.mt76.band_idx = 0;
mvif->bss_conf.mt76.wmm_idx = mvif->bss_conf.mt76.idx % MT76_CONNAC_MAX_WMM_SETS; mvif->bss_conf.mt76.wmm_idx = mvif->bss_conf.mt76.idx % MT76_CONNAC_MAX_WMM_SETS;
......
...@@ -114,7 +114,7 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata, ...@@ -114,7 +114,7 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
/* apply all changes now - no failures allowed */ /* apply all changes now - no failures allowed */
if (monitor_sdata) if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
ieee80211_set_mu_mimo_follow(monitor_sdata, params); ieee80211_set_mu_mimo_follow(monitor_sdata, params);
if (params->flags) { if (params->flags) {
...@@ -3053,6 +3053,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, ...@@ -3053,6 +3053,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
return -EOPNOTSUPP;
sdata = wiphy_dereference(local->hw.wiphy, sdata = wiphy_dereference(local->hw.wiphy,
local->monitor_sdata); local->monitor_sdata);
if (!sdata) if (!sdata)
...@@ -3115,7 +3118,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, ...@@ -3115,7 +3118,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
if (has_monitor) { if (has_monitor) {
sdata = wiphy_dereference(local->hw.wiphy, sdata = wiphy_dereference(local->hw.wiphy,
local->monitor_sdata); local->monitor_sdata);
if (sdata) { if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
sdata->deflink.user_power_level = local->user_power_level; sdata->deflink.user_power_level = local->user_power_level;
if (txp_type != sdata->vif.bss_conf.txpower_type) if (txp_type != sdata->vif.bss_conf.txpower_type)
update_txp_type = true; update_txp_type = true;
......
...@@ -1768,7 +1768,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local, ...@@ -1768,7 +1768,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
break; break;
} }
sdata = rcu_dereference(local->monitor_sdata); sdata = rcu_dereference(local->monitor_sdata);
if (sdata) { if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
vif = &sdata->vif; vif = &sdata->vif;
info->hw_queue = info->hw_queue =
vif->hw_queue[skb_get_queue_mapping(skb)]; vif->hw_queue[skb_get_queue_mapping(skb)];
...@@ -3957,7 +3957,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, ...@@ -3957,7 +3957,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
break; break;
} }
tx.sdata = rcu_dereference(local->monitor_sdata); tx.sdata = rcu_dereference(local->monitor_sdata);
if (tx.sdata) { if (tx.sdata &&
ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
vif = &tx.sdata->vif; vif = &tx.sdata->vif;
info->hw_queue = info->hw_queue =
vif->hw_queue[skb_get_queue_mapping(skb)]; vif->hw_queue[skb_get_queue_mapping(skb)];
......
...@@ -776,7 +776,7 @@ static void __iterate_interfaces(struct ieee80211_local *local, ...@@ -776,7 +776,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
sdata = rcu_dereference_check(local->monitor_sdata, sdata = rcu_dereference_check(local->monitor_sdata,
lockdep_is_held(&local->iflist_mtx) || lockdep_is_held(&local->iflist_mtx) ||
lockdep_is_held(&local->hw.wiphy->mtx)); lockdep_is_held(&local->hw.wiphy->mtx));
if (sdata && if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only || (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
sdata->flags & IEEE80211_SDATA_IN_DRIVER)) sdata->flags & IEEE80211_SDATA_IN_DRIVER))
iterator(data, sdata->vif.addr, &sdata->vif); iterator(data, sdata->vif.addr, &sdata->vif);
......
...@@ -3178,8 +3178,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ...@@ -3178,8 +3178,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_mgmt *mgmt, size_t len,
gfp_t gfp) gfp_t gfp)
{ {
size_t min_hdr_len = offsetof(struct ieee80211_mgmt, size_t min_hdr_len;
u.probe_resp.variable);
struct ieee80211_ext *ext = NULL; struct ieee80211_ext *ext = NULL;
enum cfg80211_bss_frame_type ftype; enum cfg80211_bss_frame_type ftype;
u16 beacon_interval; u16 beacon_interval;
...@@ -3202,10 +3201,16 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ...@@ -3202,10 +3201,16 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
ext = (void *) mgmt; ext = (void *) mgmt;
min_hdr_len = offsetof(struct ieee80211_ext, u.s1g_beacon);
if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
min_hdr_len = offsetof(struct ieee80211_ext, min_hdr_len = offsetof(struct ieee80211_ext,
u.s1g_short_beacon.variable); u.s1g_short_beacon.variable);
else
min_hdr_len = offsetof(struct ieee80211_ext,
u.s1g_beacon.variable);
} else {
/* same for beacons */
min_hdr_len = offsetof(struct ieee80211_mgmt,
u.probe_resp.variable);
} }
if (WARN_ON(len < min_hdr_len)) if (WARN_ON(len < min_hdr_len))
......
...@@ -1045,6 +1045,7 @@ void cfg80211_connect_done(struct net_device *dev, ...@@ -1045,6 +1045,7 @@ void cfg80211_connect_done(struct net_device *dev,
cfg80211_hold_bss( cfg80211_hold_bss(
bss_from_pub(params->links[link].bss)); bss_from_pub(params->links[link].bss));
ev->cr.links[link].bss = params->links[link].bss; ev->cr.links[link].bss = params->links[link].bss;
ev->cr.links[link].status = params->links[link].status;
if (params->links[link].addr) { if (params->links[link].addr) {
ev->cr.links[link].addr = next; ev->cr.links[link].addr = next;
......
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