Skip to content

Commit

Permalink
Merge tag 'wireless-2024-04-23' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/wireless/wireless

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>
  • Loading branch information
davem330 committed Apr 25, 2024
2 parents 6c9cd59 + 91112fc commit 46bf0c9
Show file tree
Hide file tree
Showing 19 changed files with 152 additions and 44 deletions.
4 changes: 3 additions & 1 deletion drivers/net/wireless/ath/ath11k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/intel/iwlwifi/cfg/bz.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/intel/iwlwifi/cfg/sc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/virtual/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
};

Expand Down
27 changes: 22 additions & 5 deletions net/mac80211/chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand All @@ -843,9 +842,27 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
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);

Expand Down
8 changes: 7 additions & 1 deletion net/mac80211/mesh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
36 changes: 33 additions & 3 deletions net/mac80211/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)];
Expand Down Expand Up @@ -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,
Expand Down
31 changes: 22 additions & 9 deletions net/mac80211/mesh_pathtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
Loading

0 comments on commit 46bf0c9

Please sign in to comment.