Merge tag 'wireless-2024-04-23' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorDavid S. Miller <davem@davemloft.net>
Thu, 25 Apr 2024 11:18:37 +0000 (12:18 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 25 Apr 2024 11:18:37 +0000 (12:18 +0100)
Johannes berg says:

====================
Fixes for the current cycle:
 * ath11k: convert to correct RCU iteration of IPv6 addresses
 * iwlwifi: link ID, FW API version, scanning and PASN fixes
 * cfg80211: NULL-deref and tracing fixes
 * mac80211: connection mode, mesh fast-TX, multi-link and
             various other small fixes
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
19 files changed:
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/intel/iwlwifi/cfg/bz.c
drivers/net/wireless/intel/iwlwifi/cfg/sc.c
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
drivers/net/wireless/intel/iwlwifi/mvm/link.c
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
drivers/net/wireless/virtual/mac80211_hwsim.c
include/net/mac80211.h
net/mac80211/chan.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_pathtbl.c
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/tx.c
net/wireless/nl80211.c
net/wireless/trace.h

index a6a37d67a50ad552b4185af654289d635c2cfd70..9f4bf41a3d41e4e1395aa77fb6874130e5783d96 100644 (file)
@@ -9020,6 +9020,7 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,
        offload = &arvif->arp_ns_offload;
        count = 0;
 
+       /* Note: read_lock_bh() calls rcu_read_lock() */
        read_lock_bh(&idev->lock);
 
        memset(offload->ipv6_addr, 0, sizeof(offload->ipv6_addr));
@@ -9050,7 +9051,8 @@ static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,
        }
 
        /* get anycast address */
-       for (ifaca6 = idev->ac_list; ifaca6; ifaca6 = ifaca6->aca_next) {
+       for (ifaca6 = rcu_dereference(idev->ac_list); ifaca6;
+            ifaca6 = rcu_dereference(ifaca6->aca_next)) {
                if (count >= ATH11K_IPV6_MAX_COUNT)
                        goto generate;
 
index 072b0a5827d19f801d9f0da38933aef21044b7fc..eca1457caa0cad9eb13edce501beba6d5540fe57 100644 (file)
@@ -10,7 +10,7 @@
 #include "fw/api/txq.h"
 
 /* Highest firmware API version supported */
-#define IWL_BZ_UCODE_API_MAX   90
+#define IWL_BZ_UCODE_API_MAX   89
 
 /* Lowest firmware API version supported */
 #define IWL_BZ_UCODE_API_MIN   80
index 9b79279fd76cad94170d28614b7eee0729ac02f8..dbbcb2d0968c0992d15f652409cf651dc625428c 100644 (file)
@@ -10,7 +10,7 @@
 #include "fw/api/txq.h"
 
 /* Highest firmware API version supported */
-#define IWL_SC_UCODE_API_MAX   90
+#define IWL_SC_UCODE_API_MAX   89
 
 /* Lowest firmware API version supported */
 #define IWL_SC_UCODE_API_MIN   82
index 4863a3c746406ed70a398d8939e080e72636fa0b..d84d7e955bb021fc1994d1b5fa9e21183e01027a 100644 (file)
@@ -53,6 +53,8 @@ int iwl_mvm_ftm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        if (!pasn)
                return -ENOBUFS;
 
+       iwl_mvm_ftm_remove_pasn_sta(mvm, addr);
+
        pasn->cipher = iwl_mvm_cipher_to_location_cipher(cipher);
 
        switch (pasn->cipher) {
index 9f69e04594e49cb59f3102071c905bd75b93f825..fe5bba8561d0c69abeef30221c5cc040f64c7b96 100644 (file)
@@ -279,6 +279,7 @@ int iwl_mvm_unset_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id],
                         NULL);
+       iwl_mvm_release_fw_link_id(mvm, link_info->fw_link_id);
        return 0;
 }
 
@@ -296,7 +297,6 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                return 0;
 
        cmd.link_id = cpu_to_le32(link_info->fw_link_id);
-       iwl_mvm_release_fw_link_id(mvm, link_info->fw_link_id);
        link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
        cmd.spec_link_id = link_conf->link_id;
        cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID);
index f3e3986b4c72f2aabfd9ff67edf8c11a1bebc03c..11559563ae38162e8c138dddc79e0cc89f3b349d 100644 (file)
@@ -2813,7 +2813,8 @@ static int iwl_mvm_build_scan_cmd(struct iwl_mvm *mvm,
                if (ver_handler->version != scan_ver)
                        continue;
 
-               return ver_handler->handler(mvm, vif, params, type, uid);
+               err = ver_handler->handler(mvm, vif, params, type, uid);
+               return err ? : uid;
        }
 
        err = iwl_mvm_scan_umac(mvm, vif, params, type, uid);
index b55fe320633c74b42618d37be6bc40a951f0c898..59e1fc0018df3f32d60e3e52341350c10a44d0f0 100644 (file)
@@ -3899,7 +3899,7 @@ static int hwsim_pmsr_report_nl(struct sk_buff *msg, struct genl_info *info)
        }
 
        nla_for_each_nested(peer, peers, rem) {
-               struct cfg80211_pmsr_result result;
+               struct cfg80211_pmsr_result result = {};
 
                err = mac80211_hwsim_parse_pmsr_result(peer, &result, info);
                if (err)
index 353488ab94a294fd1fb2a985d015f9c8b59d421d..2d7f87bc5324b4823a8f70b960f0545bab8549c4 100644 (file)
@@ -953,6 +953,8 @@ enum mac80211_tx_info_flags {
  *     of their QoS TID or other priority field values.
  * @IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX: first MLO TX, used mostly internally
  *     for sequence number assignment
+ * @IEEE80211_TX_CTRL_SCAN_TX: Indicates that this frame is transmitted
+ *     due to scanning, not in normal operation on the interface.
  * @IEEE80211_TX_CTRL_MLO_LINK: If not @IEEE80211_LINK_UNSPECIFIED, this
  *     frame should be transmitted on the specific link. This really is
  *     only relevant for frames that do not have data present, and is
@@ -973,6 +975,7 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_CTRL_NO_SEQNO              = BIT(7),
        IEEE80211_TX_CTRL_DONT_REORDER          = BIT(8),
        IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX    = BIT(9),
+       IEEE80211_TX_CTRL_SCAN_TX               = BIT(10),
        IEEE80211_TX_CTRL_MLO_LINK              = 0xf0000000,
 };
 
index 80e4b9784131d149c6acf27f79be0b0c16edec85..ccacaed32817aed59240034f85753c47a353501a 100644 (file)
@@ -797,6 +797,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_chanctx_conf *conf;
        struct ieee80211_chanctx *curr_ctx = NULL;
+       bool new_idle;
        int ret = 0;
 
        if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
@@ -829,8 +830,6 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
 out:
        rcu_assign_pointer(link->conf->chanctx_conf, conf);
 
-       sdata->vif.cfg.idle = !conf;
-
        if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
                ieee80211_recalc_chanctx_chantype(local, curr_ctx);
                ieee80211_recalc_smps_chanctx(local, curr_ctx);
@@ -843,9 +842,27 @@ out:
                ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL);
        }
 
-       if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
-           sdata->vif.type != NL80211_IFTYPE_MONITOR)
-               ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE);
+       if (conf) {
+               new_idle = false;
+       } else {
+               struct ieee80211_link_data *tmp;
+
+               new_idle = true;
+               for_each_sdata_link(local, tmp) {
+                       if (rcu_access_pointer(tmp->conf->chanctx_conf)) {
+                               new_idle = false;
+                               break;
+                       }
+               }
+       }
+
+       if (new_idle != sdata->vif.cfg.idle) {
+               sdata->vif.cfg.idle = new_idle;
+
+               if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+                   sdata->vif.type != NL80211_IFTYPE_MONITOR)
+                       ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE);
+       }
 
        ieee80211_check_fast_xmit_iface(sdata);
 
index 32475da98d739cbe66d200f6bd8e8b0542f3cb04..cbc9b5e40cb35e81fb80dd55016c3afc8c31deb7 100644 (file)
@@ -747,6 +747,9 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
                              struct sk_buff *skb, u32 ctrl_flags)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       struct ieee80211_mesh_fast_tx_key key = {
+               .type = MESH_FAST_TX_TYPE_LOCAL
+       };
        struct ieee80211_mesh_fast_tx *entry;
        struct ieee80211s_hdr *meshhdr;
        u8 sa[ETH_ALEN] __aligned(2);
@@ -782,7 +785,10 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
                        return false;
        }
 
-       entry = mesh_fast_tx_get(sdata, skb->data);
+       ether_addr_copy(key.addr, skb->data);
+       if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr))
+               key.type = MESH_FAST_TX_TYPE_PROXIED;
+       entry = mesh_fast_tx_get(sdata, &key);
        if (!entry)
                return false;
 
index d913ce7ba72ef897fb6857f55df3fb20bc871b5e..3f9664e4e00c6c2e51faaa43d1a23860a6d22e4c 100644 (file)
@@ -134,10 +134,39 @@ struct mesh_path {
 #define MESH_FAST_TX_CACHE_THRESHOLD_SIZE      384
 #define MESH_FAST_TX_CACHE_TIMEOUT             8000 /* msecs */
 
+/**
+ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type
+ *
+ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA
+ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged)
+ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point
+ * @NUM_MESH_FAST_TX_TYPE: number of entry types
+ */
+enum ieee80211_mesh_fast_tx_type {
+       MESH_FAST_TX_TYPE_LOCAL,
+       MESH_FAST_TX_TYPE_PROXIED,
+       MESH_FAST_TX_TYPE_FORWARDED,
+
+       /* must be last */
+       NUM_MESH_FAST_TX_TYPE
+};
+
+
+/**
+ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key
+ *
+ * @addr: The Ethernet DA for this entry
+ * @type: cache entry type
+ */
+struct ieee80211_mesh_fast_tx_key {
+       u8 addr[ETH_ALEN] __aligned(2);
+       u16 type;
+};
+
 /**
  * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry
  * @rhash: rhashtable pointer
- * @addr_key: The Ethernet DA which is the key for this entry
+ * @key: the lookup key for this cache entry
  * @fast_tx: base fast_tx data
  * @hdr: cached mesh and rfc1042 headers
  * @hdrlen: length of mesh + rfc1042
@@ -148,7 +177,7 @@ struct mesh_path {
  */
 struct ieee80211_mesh_fast_tx {
        struct rhash_head rhash;
-       u8 addr_key[ETH_ALEN] __aligned(2);
+       struct ieee80211_mesh_fast_tx_key key;
 
        struct ieee80211_fast_tx fast_tx;
        u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
@@ -334,7 +363,8 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
 
 bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
 struct ieee80211_mesh_fast_tx *
-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr);
+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
+                struct ieee80211_mesh_fast_tx_key *key);
 bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
                              struct sk_buff *skb, u32 ctrl_flags);
 void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
index 91b55d6a68b9739f9d22786bf403c801fc34d864..a6b62169f08483c5aa481f4f8f59f67fa56a4ef7 100644 (file)
@@ -37,8 +37,8 @@ static const struct rhashtable_params mesh_rht_params = {
 static const struct rhashtable_params fast_tx_rht_params = {
        .nelem_hint = 10,
        .automatic_shrinking = true,
-       .key_len = ETH_ALEN,
-       .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key),
+       .key_len = sizeof_field(struct ieee80211_mesh_fast_tx, key),
+       .key_offset = offsetof(struct ieee80211_mesh_fast_tx, key),
        .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash),
        .hashfn = mesh_table_hash,
 };
@@ -431,20 +431,21 @@ static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache,
 }
 
 struct ieee80211_mesh_fast_tx *
-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr)
+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
+                struct ieee80211_mesh_fast_tx_key *key)
 {
        struct ieee80211_mesh_fast_tx *entry;
        struct mesh_tx_cache *cache;
 
        cache = &sdata->u.mesh.tx_cache;
-       entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
+       entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
        if (!entry)
                return NULL;
 
        if (!(entry->mpath->flags & MESH_PATH_ACTIVE) ||
            mpath_expired(entry->mpath)) {
                spin_lock_bh(&cache->walk_lock);
-               entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
+               entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
                if (entry)
                    mesh_fast_tx_entry_free(cache, entry);
                spin_unlock_bh(&cache->walk_lock);
@@ -489,18 +490,24 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
        if (!sta)
                return;
 
+       build.key.type = MESH_FAST_TX_TYPE_LOCAL;
        if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
                /* This is required to keep the mppath alive */
                mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
                if (!mppath)
                        return;
                build.mppath = mppath;
+               if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr))
+                       build.key.type = MESH_FAST_TX_TYPE_PROXIED;
        } else if (ieee80211_has_a4(hdr->frame_control)) {
                mppath = mpath;
        } else {
                return;
        }
 
+       if (!ether_addr_equal(hdr->addr4, sdata->vif.addr))
+               build.key.type = MESH_FAST_TX_TYPE_FORWARDED;
+
        /* rate limit, in case fast xmit can't be enabled */
        if (mppath->fast_tx_check == jiffies)
                return;
@@ -547,7 +554,7 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
                }
        }
 
-       memcpy(build.addr_key, mppath->dst, ETH_ALEN);
+       memcpy(build.key.addr, mppath->dst, ETH_ALEN);
        build.timestamp = jiffies;
        build.fast_tx.band = info->band;
        build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3);
@@ -646,12 +653,18 @@ void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata,
                             const u8 *addr)
 {
        struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache;
+       struct ieee80211_mesh_fast_tx_key key = {};
        struct ieee80211_mesh_fast_tx *entry;
+       int i;
 
+       ether_addr_copy(key.addr, addr);
        spin_lock_bh(&cache->walk_lock);
-       entry = rhashtable_lookup_fast(&cache->rht, addr, fast_tx_rht_params);
-       if (entry)
-               mesh_fast_tx_entry_free(cache, entry);
+       for (i = 0; i < NUM_MESH_FAST_TX_TYPE; i++) {
+               key.type = i;
+               entry = rhashtable_lookup_fast(&cache->rht, &key, fast_tx_rht_params);
+               if (entry)
+                       mesh_fast_tx_entry_free(cache, entry);
+       }
        spin_unlock_bh(&cache->walk_lock);
 }
 
index 96b70006b7fc0b11b12f423fb74ec32a030d91af..3bbb216a0fc8ce58138420d13008b2240e260a77 100644 (file)
@@ -616,7 +616,6 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
                .from_ap = true,
                .start = ies->data,
                .len = ies->len,
-               .mode = conn->mode,
        };
        struct ieee802_11_elems *elems;
        struct ieee80211_supported_band *sband;
@@ -625,6 +624,7 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
        int ret;
 
 again:
+       parse_params.mode = conn->mode;
        elems = ieee802_11_parse_elems_full(&parse_params);
        if (!elems)
                return ERR_PTR(-ENOMEM);
@@ -632,15 +632,21 @@ again:
        ap_mode = ieee80211_determine_ap_chan(sdata, channel, bss->vht_cap_info,
                                              elems, false, conn, &ap_chandef);
 
-       mlme_link_id_dbg(sdata, link_id, "determined AP %pM to be %s\n",
-                        cbss->bssid, ieee80211_conn_mode_str(ap_mode));
-
        /* this should be impossible since parsing depends on our mode */
        if (WARN_ON(ap_mode > conn->mode)) {
                ret = -EINVAL;
                goto free;
        }
 
+       if (conn->mode != ap_mode) {
+               conn->mode = ap_mode;
+               kfree(elems);
+               goto again;
+       }
+
+       mlme_link_id_dbg(sdata, link_id, "determined AP %pM to be %s\n",
+                        cbss->bssid, ieee80211_conn_mode_str(ap_mode));
+
        sband = sdata->local->hw.wiphy->bands[channel->band];
 
        switch (channel->band) {
@@ -691,7 +697,6 @@ again:
                break;
        }
 
-       conn->mode = ap_mode;
        chanreq->oper = ap_chandef;
 
        /* wider-bandwidth OFDMA is only done in EHT */
@@ -753,8 +758,10 @@ again:
        }
 
        /* the mode can only decrease, so this must terminate */
-       if (ap_mode != conn->mode)
+       if (ap_mode != conn->mode) {
+               kfree(elems);
                goto again;
+       }
 
        mlme_link_id_dbg(sdata, link_id,
                         "connecting with %s mode, max bandwidth %d MHz\n",
@@ -5812,7 +5819,7 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata,
                 */
                if (control &
                    IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT)
-                       link_removal_timeout[link_id] = le16_to_cpu(*(__le16 *)pos);
+                       link_removal_timeout[link_id] = get_unaligned_le16(pos);
        }
 
        removed_links &= sdata->vif.valid_links;
@@ -5837,8 +5844,11 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata,
                        continue;
                }
 
-               link_delay = link_conf->beacon_int *
-                       link_removal_timeout[link_id];
+               if (link_removal_timeout[link_id] < 1)
+                       link_delay = 0;
+               else
+                       link_delay = link_conf->beacon_int *
+                               (link_removal_timeout[link_id] - 1);
 
                if (!delay)
                        delay = link_delay;
@@ -6193,7 +6203,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
                        link->u.mgd.dtim_period = elems->dtim_period;
                link->u.mgd.have_beacon = true;
                ifmgd->assoc_data->need_beacon = false;
-               if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
+               if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY) &&
+                   !ieee80211_is_s1g_beacon(hdr->frame_control)) {
                        link->conf->sync_tsf =
                                le64_to_cpu(mgmt->u.beacon.timestamp);
                        link->conf->sync_device_ts =
index 23404b275457a74868cd935653bc1a6192ec4cb5..4dc1def695486567b486fdada893557752f8df43 100644 (file)
@@ -877,6 +877,7 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_supported_band *sband;
+       u32 mask = ~0;
 
        rate_control_fill_sta_table(sta, info, dest, max_rates);
 
@@ -889,9 +890,12 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
        if (ieee80211_is_tx_data(skb))
                rate_control_apply_mask(sdata, sta, sband, dest, max_rates);
 
+       if (!(info->control.flags & IEEE80211_TX_CTRL_SCAN_TX))
+               mask = sdata->rc_rateidx_mask[info->band];
+
        if (dest[0].idx < 0)
                __rate_control_send_low(&sdata->local->hw, sband, sta, info,
-                                       sdata->rc_rateidx_mask[info->band]);
+                                       mask);
 
        if (sta)
                rate_fixup_ratelist(vif, sband, info, dest, max_rates);
index c1f8501384056d3ebbb9ba7ddbd5c659c579d582..6e24864f9a40ba1b8d689263cf905cc0ff5d3d69 100644 (file)
@@ -2763,7 +2763,10 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
                               struct sk_buff *skb, int hdrlen)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-       struct ieee80211_mesh_fast_tx *entry = NULL;
+       struct ieee80211_mesh_fast_tx_key key = {
+               .type = MESH_FAST_TX_TYPE_FORWARDED
+       };
+       struct ieee80211_mesh_fast_tx *entry;
        struct ieee80211s_hdr *mesh_hdr;
        struct tid_ampdu_tx *tid_tx;
        struct sta_info *sta;
@@ -2772,9 +2775,13 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
 
        mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
        if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
-               entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1);
+               ether_addr_copy(key.addr, mesh_hdr->eaddr1);
        else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
-               entry = mesh_fast_tx_get(sdata, skb->data);
+               ether_addr_copy(key.addr, skb->data);
+       else
+               return false;
+
+       entry = mesh_fast_tx_get(sdata, &key);
        if (!entry)
                return false;
 
@@ -3780,6 +3787,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                }
                break;
        case WLAN_CATEGORY_PROTECTED_EHT:
+               if (len < offsetofend(typeof(*mgmt),
+                                     u.action.u.ttlm_req.action_code))
+                       break;
+
                switch (mgmt->u.action.u.ttlm_req.action_code) {
                case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ:
                        if (sdata->vif.type != NL80211_IFTYPE_STATION)
index 0429e59ba387c931f42ae1e74255a7deb5ebf5d6..73850312580f7054c60550dd5a2486583ab48f0a 100644 (file)
@@ -648,6 +648,7 @@ static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata,
                                cpu_to_le16(IEEE80211_SN_TO_SEQ(sn));
                }
                IEEE80211_SKB_CB(skb)->flags |= tx_flags;
+               IEEE80211_SKB_CB(skb)->control.flags |= IEEE80211_TX_CTRL_SCAN_TX;
                ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band);
        }
 }
index 6bf223e6cd1a54aa432ef0bd41da48cd9316ffc5..cfd0a62d0152bd28f32fbb022cdbd094defefca4 100644 (file)
@@ -698,11 +698,16 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        txrc.bss_conf = &tx->sdata->vif.bss_conf;
        txrc.skb = tx->skb;
        txrc.reported_rate.idx = -1;
-       txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
 
-       if (tx->sdata->rc_has_mcs_mask[info->band])
-               txrc.rate_idx_mcs_mask =
-                       tx->sdata->rc_rateidx_mcs_mask[info->band];
+       if (unlikely(info->control.flags & IEEE80211_TX_CTRL_SCAN_TX)) {
+               txrc.rate_idx_mask = ~0;
+       } else {
+               txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
+
+               if (tx->sdata->rc_has_mcs_mask[info->band])
+                       txrc.rate_idx_mcs_mask =
+                               tx->sdata->rc_rateidx_mcs_mask[info->band];
+       }
 
        txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
                    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
index b4edba6b0b7ba0bf3200c7ce966a3e286a6fdf24..30ff9a47081348d1b14d1db520aeedf9c9ffdd09 100644 (file)
@@ -14030,6 +14030,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
 error:
        for (i = 0; i < new_coalesce.n_rules; i++) {
                tmp_rule = &new_coalesce.rules[i];
+               if (!tmp_rule)
+                       continue;
                for (j = 0; j < tmp_rule->n_patterns; j++)
                        kfree(tmp_rule->patterns[j].mask);
                kfree(tmp_rule->patterns);
index cbbf347c6b2e099802b135266ca7fae59bd467f9..df013c98b80dfb0e06a86a78415e51d79cd76693 100644 (file)
@@ -1758,7 +1758,7 @@ TRACE_EVENT(rdev_return_void_tx_rx,
 
 DECLARE_EVENT_CLASS(tx_rx_evt,
        TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
-       TP_ARGS(wiphy, rx, tx),
+       TP_ARGS(wiphy, tx, rx),
        TP_STRUCT__entry(
                WIPHY_ENTRY
                __field(u32, tx)
@@ -1775,7 +1775,7 @@ DECLARE_EVENT_CLASS(tx_rx_evt,
 
 DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
        TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
-       TP_ARGS(wiphy, rx, tx)
+       TP_ARGS(wiphy, tx, rx)
 );
 
 DECLARE_EVENT_CLASS(wiphy_netdev_id_evt,