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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmYnhcAACgkQ10qiO8sP aAAR9w//ZU+X4jehyQ3JDN+vYk+Fjl0A8iYELaLMBk2GrHBQztBR5LqKdNuEj2xB 8/550V3KDw0s58FVS6KaYzuViYYVgtZCcE4xDls6A3IA5rs/zgfRKQTXW+QBbX0J LoKOtvTWoTlBGCSp+GMhihU2IG5QBrYOxuNlxNQWld0BE1u/+PLfdg5UzyydpVVl osjN/8ieGJwpu9S+0IvS9uQu+1sDGZqLHGAEkk5er+3brXxyvZ0I2jHZwoYVqPpn Pd4qcc15zo6I3IudCastUJQyEOHTp+P4Vy4nEaqb6g3B7xEJwwL021wqVhek3Cdm kYRWoHq7a48FI8eJoywR4NrexP8vPpK2vaC9u+kC8AmgaI2w+BHYePMrivQeLYFP gd/eWqZfp/O5E2ULbc2sZ9651TiSMQEVy/mprxsjq52+wZnEiwF3hfiH2tqz5AK+ /JZuwRiY30LwnodkasPHei1jFkDPt8dMbp+y0ProTPw6nbM38xLQ/BOzWduV+QWZ RLNtCuYHF2OpUyCJjJS1VF40PUUBSvGiArXy9tddzeHqEyow+E9DAohlv0nPusCZ 9CN1q07YKN3GZnvEIZjPOn4IQ5D8/sLYbGYjhY5AVXJAo5A8RdtjeUeISKBxqn+j K/zJ1jGFjdV3nPpC55ayI//uaLemoW6GAwXC1q+OSiKf998DAtE= =dPas -----END PGP SIGNATURE----- Merge tag 'wireless-2024-04-23' of git://git.kernel.org/pub/scm/linux/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>
This commit is contained in:
commit
46bf0c9ab7
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user