mirror of
https://github.com/openwrt/openwrt.git
synced 2025-04-09 04:15:47 +00:00
mac80211: Update to version 6.1.110-1
This updates mac80211 to version 6.1.110-1. This code is based on Linux 6.1.110 and contains all fixes included in the upstream wireless subsystem from that kernel version. This includes many bugfixes and also some security fixes. The removed patches are already integrated in upstream Linux 6.1.110. The following patches were integrated in upstream Linux: subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch subsys/321-mac80211-fix-mesh-forwarding.patch subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch subsys/350-v6.3-wifi-mac80211-Allow-NSS-change-only-up-to-capability.patch subsys/351-v6.9-wifi-mac80211-track-capability-opmode-NSS-separately.patch Link: https://github.com/openwrt/openwrt/pull/16368 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
4fa16c1e24
commit
7e42fdcafe
@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=6.1.102-1
|
||||
PKG_VERSION:=6.1.110-1
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v6.1.102/
|
||||
PKG_HASH:=c03fd1ed946e5e4b756145ffad7a73fa821630f22c5d442456db16c96be2c9b2
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v6.1.110/
|
||||
PKG_HASH:=2415bc529ca25be0aa597f9638d8b6fc4138080bbaea96881a38101896df6703
|
||||
|
||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
|
||||
|
@ -20,7 +20,7 @@ Link: https://lore.kernel.org/r/20221006005842.8599-1-quic_periyasa@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -6418,18 +6418,16 @@ static int ath11k_mac_op_add_interface(s
|
||||
@@ -6425,18 +6425,16 @@ static int ath11k_mac_op_add_interface(s
|
||||
|
||||
ath11k_dp_vdev_tx_attach(ar, arvif);
|
||||
|
||||
@ -42,7 +42,7 @@ Link: https://lore.kernel.org/r/20221006005842.8599-1-quic_periyasa@quicinc.com
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
@@ -6454,7 +6452,6 @@ err_vdev_del:
|
||||
@@ -6461,7 +6459,6 @@ err_vdev_del:
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
err:
|
||||
|
@ -90,7 +90,7 @@ Link: https://lore.kernel.org/r/20221007051130.6067-1-quic_mpubbise@quicinc.com
|
||||
|
||||
exit:
|
||||
kfree(arg.chan_list);
|
||||
@@ -9065,6 +9087,9 @@ static int __ath11k_mac_register(struct
|
||||
@@ -9072,6 +9094,9 @@ static int __ath11k_mac_register(struct
|
||||
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -6230,6 +6230,40 @@ void ath11k_mac_11d_scan_stop_all(struct
|
||||
@@ -6237,6 +6237,40 @@ void ath11k_mac_11d_scan_stop_all(struct
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com
|
||||
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@@ -6465,10 +6499,7 @@ err_peer_del:
|
||||
@@ -6472,10 +6506,7 @@ err_peer_del:
|
||||
}
|
||||
|
||||
err_vdev_del:
|
||||
@ -74,7 +74,7 @@ Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_del(&arvif->list);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
@@ -6496,7 +6527,6 @@ static void ath11k_mac_op_remove_interfa
|
||||
@@ -6503,7 +6534,6 @@ static void ath11k_mac_op_remove_interfa
|
||||
struct ath11k *ar = hw->priv;
|
||||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
@ -82,7 +82,7 @@ Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -6517,29 +6547,13 @@ static void ath11k_mac_op_remove_interfa
|
||||
@@ -6524,29 +6554,13 @@ static void ath11k_mac_op_remove_interfa
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ Link: https://lore.kernel.org/r/20221104085403.11025-1-quic_youghand@quicinc.com
|
||||
struct ath11k_hw_ops {
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -8007,6 +8007,7 @@ ath11k_mac_op_reconfig_complete(struct i
|
||||
@@ -8014,6 +8014,7 @@ ath11k_mac_op_reconfig_complete(struct i
|
||||
struct ath11k *ar = hw->priv;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
int recovery_count;
|
||||
@ -104,7 +104,7 @@ Link: https://lore.kernel.org/r/20221104085403.11025-1-quic_youghand@quicinc.com
|
||||
|
||||
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
|
||||
return;
|
||||
@@ -8042,6 +8043,12 @@ ath11k_mac_op_reconfig_complete(struct i
|
||||
@@ -8049,6 +8050,12 @@ ath11k_mac_op_reconfig_complete(struct i
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n");
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ Link: https://lore.kernel.org/r/20221220044435.10506-1-quic_rajkbhag@quicinc.com
|
||||
if (changed & BSS_CHANGED_FILS_DISCOVERY ||
|
||||
changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
|
||||
ath11k_mac_fils_discovery(arvif, info);
|
||||
@@ -9118,6 +9132,10 @@ static int __ath11k_mac_register(struct
|
||||
@@ -9125,6 +9139,10 @@ static int __ath11k_mac_register(struct
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
|
||||
|
@ -179,7 +179,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@q
|
||||
ath11k_control_beaconing(arvif, info);
|
||||
|
||||
if (arvif->is_up && vif->bss_conf.he_support &&
|
||||
@@ -5389,6 +5512,10 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
@@ -5388,6 +5511,10 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
|
||||
he_cap_elem->mac_cap_info[1] &=
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
|
||||
@ -190,7 +190,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@q
|
||||
|
||||
he_cap_elem->phy_cap_info[5] &=
|
||||
~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
|
||||
@@ -6023,69 +6150,6 @@ ath11k_mac_setup_vdev_create_params(stru
|
||||
@@ -6030,69 +6157,6 @@ ath11k_mac_setup_vdev_create_params(stru
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +260,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@q
|
||||
static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@@ -6754,7 +6818,6 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
@@ -6761,7 +6825,6 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct wmi_vdev_start_req_arg arg = {};
|
||||
const struct cfg80211_chan_def *chandef = &ctx->def;
|
||||
@ -268,7 +268,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@q
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
@@ -6795,15 +6858,6 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
@@ -6802,15 +6865,6 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
arg.regdomain = ar->ab->dfs_region;
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
@ -17,7 +17,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-4-git-send-email-quic_msinada@q
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5480,6 +5480,27 @@ static __le16 ath11k_mac_setup_he_6ghz_c
|
||||
@@ -5479,6 +5479,27 @@ static __le16 ath11k_mac_setup_he_6ghz_c
|
||||
return cpu_to_le16(bcap->he_6ghz_capa);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-4-git-send-email-quic_msinada@q
|
||||
static int ath11k_mac_copy_he_cap(struct ath11k *ar,
|
||||
struct ath11k_pdev_cap *cap,
|
||||
struct ieee80211_sband_iftype_data *data,
|
||||
@@ -5541,18 +5562,7 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
@@ -5540,18 +5561,7 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ Link: https://lore.kernel.org/r/1666128501-12364-5-git-send-email-quic_msinada@q
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5485,20 +5485,36 @@ static void ath11k_mac_set_hemcsmap(stru
|
||||
@@ -5484,20 +5484,36 @@ static void ath11k_mac_set_hemcsmap(stru
|
||||
struct ieee80211_sta_he_cap *he_cap,
|
||||
int band)
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ Link: https://lore.kernel.org/r/20221219053844.4084486-1-quic_mkenna@quicinc.com
|
||||
static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -9179,6 +9179,11 @@ static int __ath11k_mac_register(struct
|
||||
@@ -9186,6 +9186,11 @@ static int __ath11k_mac_register(struct
|
||||
goto err_free_if_combs;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ Link: https://lore.kernel.org/r/20230309164434.32660-1-quic_hprem@quicinc.com
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3038,39 +3015,51 @@ static int ath11k_dp_rx_reap_mon_status_
|
||||
@@ -3037,39 +3014,51 @@ static int ath11k_dp_rx_reap_mon_status_
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
skb = idr_find(&rx_ring->bufs_idr, buf_id);
|
||||
|
@ -106,7 +106,7 @@ Link: https://lore.kernel.org/r/20230317072034.8217-1-quic_gjothira@quicinc.com
|
||||
(vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_MESH_POINT)) {
|
||||
arvif->ftm_responder = info->ftm_responder;
|
||||
@@ -9239,7 +9239,7 @@ static int __ath11k_mac_register(struct
|
||||
@@ -9246,7 +9246,7 @@ static int __ath11k_mac_register(struct
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
|
||||
|
@ -22,7 +22,7 @@ Link: https://lore.kernel.org/r/20230328071150.29645-1-quic_tamizhr@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -6682,6 +6682,11 @@ static void ath11k_mac_op_remove_interfa
|
||||
@@ -6689,6 +6689,11 @@ static void ath11k_mac_op_remove_interfa
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "mac remove interface (vdev %d)\n",
|
||||
arvif->vdev_id);
|
||||
|
||||
|
@ -19,7 +19,7 @@ Link: https://lore.kernel.org/r/20230405090425.1351-1-kvalo@kernel.org
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3115,8 +3115,11 @@ int ath11k_peer_rx_frag_setup(struct ath
|
||||
@@ -3114,8 +3114,11 @@ int ath11k_peer_rx_frag_setup(struct ath
|
||||
int i;
|
||||
|
||||
tfm = crypto_alloc_shash("michael_mic", 0, 0);
|
||||
|
@ -18,7 +18,7 @@ Link: https://lore.kernel.org/r/20230403184155.8670-3-quic_nmaran@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3607,7 +3607,7 @@ static int ath11k_dp_rx_frag_h_mpdu(stru
|
||||
@@ -3606,7 +3606,7 @@ static int ath11k_dp_rx_frag_h_mpdu(stru
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ Link: https://lore.kernel.org/r/1681762947-13882-1-git-send-email-quic_msinada@q
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5582,10 +5582,6 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
@@ -5581,10 +5581,6 @@ static int ath11k_mac_copy_he_cap(struct
|
||||
|
||||
he_cap_elem->mac_cap_info[1] &=
|
||||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
|
||||
|
@ -56,7 +56,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-2-quic_alokad@quicinc.com
|
||||
#define ATH11K_QUEUE_LEN 4096
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -9006,19 +9006,23 @@ static int ath11k_mac_setup_iface_combin
|
||||
@@ -9013,19 +9013,23 @@ static int ath11k_mac_setup_iface_combin
|
||||
|
||||
static const u8 ath11k_if_types_ext_capa[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
@ -80,7 +80,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-2-quic_alokad@quicinc.com
|
||||
};
|
||||
|
||||
static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = {
|
||||
@@ -9256,6 +9260,9 @@ static int __ath11k_mac_register(struct
|
||||
@@ -9263,6 +9267,9 @@ static int __ath11k_mac_register(struct
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
|
||||
|
||||
|
@ -23,7 +23,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -6178,17 +6178,62 @@ static void ath11k_mac_op_stop(struct ie
|
||||
@@ -6185,17 +6185,62 @@ static void ath11k_mac_op_stop(struct ie
|
||||
atomic_set(&ar->num_pending_mgmt_tx, 0);
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com
|
||||
|
||||
if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
|
||||
params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
|
||||
@@ -6203,6 +6248,7 @@ ath11k_mac_setup_vdev_create_params(stru
|
||||
@@ -6210,6 +6255,7 @@ ath11k_mac_setup_vdev_create_params(stru
|
||||
params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
|
||||
params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
|
||||
}
|
||||
@ -97,7 +97,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com
|
||||
}
|
||||
|
||||
static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
|
||||
@@ -6497,7 +6543,12 @@ static int ath11k_mac_op_add_interface(s
|
||||
@@ -6504,7 +6550,12 @@ static int ath11k_mac_op_add_interface(s
|
||||
for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
|
||||
vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1);
|
||||
|
||||
@ -111,7 +111,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com
|
||||
|
||||
ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param);
|
||||
if (ret) {
|
||||
@@ -6902,6 +6953,17 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
@@ -6909,6 +6960,17 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
arg.pref_tx_streams = ar->num_tx_chains;
|
||||
arg.pref_rx_streams = ar->num_rx_chains;
|
||||
|
||||
|
@ -63,7 +63,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-5-quic_alokad@quicinc.com
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@@ -7130,7 +7138,8 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
@@ -7137,7 +7145,8 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
int n_vifs)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
@ -73,7 +73,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-5-quic_alokad@quicinc.com
|
||||
int ret;
|
||||
int i;
|
||||
bool monitor_vif = false;
|
||||
@@ -7184,8 +7193,15 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
@@ -7191,8 +7200,15 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
@ -90,7 +90,7 @@ Link: https://lore.kernel.org/r/20230405221648.17950-5-quic_alokad@quicinc.com
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@@ -7303,7 +7319,8 @@ static int ath11k_start_vdev_delay(struc
|
||||
@@ -7310,7 +7326,8 @@ static int ath11k_start_vdev_delay(struc
|
||||
}
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
|
@ -31,7 +31,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-2-quic_mkenna@quicinc.com
|
||||
*/
|
||||
|
||||
#include <net/mac80211.h>
|
||||
@@ -4335,6 +4335,20 @@ exit:
|
||||
@@ -4334,6 +4334,20 @@ exit:
|
||||
}
|
||||
|
||||
static int
|
||||
@ -52,7 +52,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-2-quic_mkenna@quicinc.com
|
||||
ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar,
|
||||
enum nl80211_band band,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
@@ -7788,20 +7802,6 @@ static void ath11k_mac_op_flush(struct i
|
||||
@@ -7795,20 +7809,6 @@ static void ath11k_mac_op_flush(struct i
|
||||
ath11k_mac_flush_tx_complete(ar);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4477,6 +4477,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct
|
||||
@@ -4476,6 +4476,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
static int ath11k_station_assoc(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@@ -4488,7 +4536,7 @@ static int ath11k_station_assoc(struct a
|
||||
@@ -4487,7 +4535,7 @@ static int ath11k_station_assoc(struct a
|
||||
struct cfg80211_chan_def def;
|
||||
enum nl80211_band band;
|
||||
struct cfg80211_bitrate_mask *mask;
|
||||
@ -91,7 +91,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
@@ -4516,6 +4564,7 @@ static int ath11k_station_assoc(struct a
|
||||
@@ -4515,6 +4563,7 @@ static int ath11k_station_assoc(struct a
|
||||
|
||||
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
|
||||
num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask);
|
||||
@ -99,7 +99,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
|
||||
/* If single VHT/HE rate is configured (by set_bitrate_mask()),
|
||||
* peer_assoc will disable VHT/HE. This is now enabled by a peer specific
|
||||
@@ -4532,6 +4581,11 @@ static int ath11k_station_assoc(struct a
|
||||
@@ -4531,6 +4580,11 @@ static int ath11k_station_assoc(struct a
|
||||
band);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -111,7 +111,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
}
|
||||
|
||||
/* Re-assoc is run only to update supported rates for given station. It
|
||||
@@ -4605,7 +4659,7 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
@@ -4604,7 +4658,7 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
const u16 *vht_mcs_mask;
|
||||
const u16 *he_mcs_mask;
|
||||
u32 changed, bw, nss, smps, bw_prev;
|
||||
@ -120,7 +120,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
const struct cfg80211_bitrate_mask *mask;
|
||||
struct peer_assoc_params peer_arg;
|
||||
enum wmi_phy_mode peer_phymode;
|
||||
@@ -4721,6 +4775,8 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
@@ -4720,6 +4774,8 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
|
||||
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
|
||||
mask = &arvif->bitrate_mask;
|
||||
@ -129,7 +129,7 @@ Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com
|
||||
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,
|
||||
mask);
|
||||
num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
|
||||
@@ -4743,6 +4799,9 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
@@ -4742,6 +4798,9 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {
|
||||
ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
|
||||
band);
|
||||
|
@ -226,7 +226,7 @@ Link: https://lore.kernel.org/r/20230517135934.16408-4-quic_rajkbhag@quicinc.com
|
||||
|
||||
if (pdev && pdev->pdev_id == pdev_id)
|
||||
return (pdev->ar ? pdev->ar : NULL);
|
||||
@@ -6268,6 +6271,11 @@ static int ath11k_mac_op_start(struct ie
|
||||
@@ -6275,6 +6278,11 @@ static int ath11k_mac_op_start(struct ie
|
||||
struct ath11k_pdev *pdev = ar->pdev;
|
||||
int ret;
|
||||
|
||||
@ -238,7 +238,7 @@ Link: https://lore.kernel.org/r/20230517135934.16408-4-quic_rajkbhag@quicinc.com
|
||||
ath11k_mac_drain_tx(ar);
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@@ -6282,6 +6290,7 @@ static int ath11k_mac_op_start(struct ie
|
||||
@@ -6289,6 +6297,7 @@ static int ath11k_mac_op_start(struct ie
|
||||
case ATH11K_STATE_RESTARTED:
|
||||
case ATH11K_STATE_WEDGED:
|
||||
case ATH11K_STATE_ON:
|
||||
|
@ -8,7 +8,7 @@ Subject: [PATCH] mac80211: allow scans in access point mode (for site survey)
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2733,6 +2733,8 @@ static int ieee80211_scan(struct wiphy *
|
||||
@@ -2734,6 +2734,8 @@ static int ieee80211_scan(struct wiphy *
|
||||
*/
|
||||
fallthrough;
|
||||
case NL80211_IFTYPE_AP:
|
||||
|
@ -36,7 +36,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
.remove_interface = ar5523_remove_interface,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -8592,6 +8592,7 @@ err_fallback:
|
||||
@@ -8599,6 +8599,7 @@ err_fallback:
|
||||
|
||||
static const struct ieee80211_ops ath11k_ops = {
|
||||
.tx = ath11k_mac_op_tx,
|
||||
|
@ -11,7 +11,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4358,9 +4358,6 @@ static int ieee80211_get_txq_stats(struc
|
||||
@@ -4359,9 +4359,6 @@ static int ieee80211_get_txq_stats(struc
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
int ret = 0;
|
||||
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
--- a/net/mac80211/debugfs_netdev.c
|
||||
+++ b/net/mac80211/debugfs_netdev.c
|
||||
@@ -677,8 +677,7 @@ static void add_common_files(struct ieee
|
||||
@@ -675,8 +675,7 @@ static void add_common_files(struct ieee
|
||||
DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
|
||||
DEBUGFS_ADD(hw_queues);
|
||||
|
||||
@ -63,7 +63,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
NL80211_EXT_FEATURE_AQL))
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -2302,7 +2302,6 @@ void ieee80211_wake_queue_by_reason(stru
|
||||
@@ -2301,7 +2301,6 @@ void ieee80211_wake_queue_by_reason(stru
|
||||
void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
||||
enum queue_stop_reason reason,
|
||||
bool refcounted);
|
||||
@ -73,7 +73,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
void ieee80211_add_pending_skbs(struct ieee80211_local *local,
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -460,12 +460,6 @@ static void ieee80211_do_stop(struct iee
|
||||
@@ -481,12 +481,6 @@ static void ieee80211_do_stop(struct iee
|
||||
if (cancel_scan)
|
||||
ieee80211_scan_cancel(local);
|
||||
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
ieee80211_roc_purge(local, sdata);
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
@@ -813,25 +807,6 @@ static void ieee80211_uninit(struct net_
|
||||
@@ -834,25 +828,6 @@ static void ieee80211_uninit(struct net_
|
||||
ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
static void
|
||||
ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
{
|
||||
@@ -845,7 +820,6 @@ static const struct net_device_ops ieee8
|
||||
@@ -866,7 +841,6 @@ static const struct net_device_ops ieee8
|
||||
.ndo_start_xmit = ieee80211_subif_start_xmit,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
@ -120,7 +120,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
.ndo_get_stats64 = ieee80211_get_stats64,
|
||||
};
|
||||
|
||||
@@ -967,7 +941,6 @@ static const struct net_device_ops ieee8
|
||||
@@ -988,7 +962,6 @@ static const struct net_device_ops ieee8
|
||||
.ndo_start_xmit = ieee80211_subif_start_xmit_8023,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
@ -128,7 +128,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
.ndo_get_stats64 = ieee80211_get_stats64,
|
||||
#if LINUX_VERSION_IS_GEQ(5,13,0)
|
||||
.ndo_fill_forward_path = ieee80211_netdev_fill_forward_path,
|
||||
@@ -1471,35 +1444,6 @@ int ieee80211_do_open(struct wireless_de
|
||||
@@ -1492,35 +1465,6 @@ int ieee80211_do_open(struct wireless_de
|
||||
|
||||
ieee80211_recalc_ps(local);
|
||||
|
||||
@ -164,7 +164,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
set_bit(SDATA_STATE_RUNNING, &sdata->state);
|
||||
|
||||
return 0;
|
||||
@@ -1529,17 +1473,12 @@ static void ieee80211_if_setup(struct ne
|
||||
@@ -1550,17 +1494,12 @@ static void ieee80211_if_setup(struct ne
|
||||
{
|
||||
ether_setup(dev);
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
@ -183,7 +183,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
static void ieee80211_iface_process_skb(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
@@ -2124,9 +2063,7 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
@@ -2145,9 +2084,7 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
struct net_device *ndev = NULL;
|
||||
struct ieee80211_sub_if_data *sdata = NULL;
|
||||
struct txq_info *txqi;
|
||||
@ -193,7 +193,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@@ -2149,30 +2086,18 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
@@ -2170,30 +2107,18 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
sizeof(void *));
|
||||
int txq_size = 0;
|
||||
|
||||
@ -317,7 +317,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
int i;
|
||||
|
||||
sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
|
||||
@@ -600,21 +599,18 @@ __sta_info_alloc(struct ieee80211_sub_if
|
||||
@@ -603,21 +602,18 @@ __sta_info_alloc(struct ieee80211_sub_if
|
||||
|
||||
sta->last_connected = ktime_get_seconds();
|
||||
|
||||
@ -348,7 +348,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
}
|
||||
|
||||
if (sta_prepare_rate_control(local, sta, gfp))
|
||||
@@ -688,8 +684,7 @@ __sta_info_alloc(struct ieee80211_sub_if
|
||||
@@ -691,8 +687,7 @@ __sta_info_alloc(struct ieee80211_sub_if
|
||||
return sta;
|
||||
|
||||
free_txq:
|
||||
@ -358,7 +358,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
free:
|
||||
sta_info_free_link(&sta->deflink);
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
@@ -1965,9 +1960,6 @@ ieee80211_sta_ps_deliver_response(struct
|
||||
@@ -1982,9 +1977,6 @@ ieee80211_sta_ps_deliver_response(struct
|
||||
* TIM recalculation.
|
||||
*/
|
||||
|
||||
@ -368,7 +368,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
|
||||
if (!sta->sta.txq[tid] ||
|
||||
!(driver_release_tids & BIT(tid)) ||
|
||||
@@ -2452,7 +2444,7 @@ static void sta_set_tidstats(struct sta_
|
||||
@@ -2469,7 +2461,7 @@ static void sta_set_tidstats(struct sta_
|
||||
tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid];
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
spin_lock_bh(&local->fq.lock);
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -2780,9 +2772,6 @@ unsigned long ieee80211_sta_last_active(
|
||||
@@ -2797,9 +2789,6 @@ unsigned long ieee80211_sta_last_active(
|
||||
|
||||
static void sta_update_codel_params(struct sta_info *sta, u32 thr)
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -2197,6 +2197,7 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
@@ -2218,6 +2218,7 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||
ndev->hw_features |= ndev->features &
|
||||
MAC80211_SUPPORTED_FEATURES_TX;
|
||||
|
@ -1,87 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 1 Dec 2022 14:57:30 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for
|
||||
mesh
|
||||
|
||||
ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and
|
||||
ieee80211_frame_allowed.
|
||||
|
||||
Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes
|
||||
and is called earlier, it needs to check the decryptions status and if the
|
||||
packet is using the control protocol on its own, instead of deferring to
|
||||
the later call from ieee80211_frame_allowed.
|
||||
|
||||
Because of that, ieee80211_drop_unencrypted has a mesh specific check
|
||||
that skips over the mesh header in order to check the payload protocol.
|
||||
This code is invalid when called from ieee80211_frame_allowed, since that
|
||||
happens after the 802.11->802.3 conversion.
|
||||
|
||||
Fix this by moving the mesh specific check directly into
|
||||
ieee80211_rx_h_mesh_fwding.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2405,7 +2405,6 @@ static int ieee80211_802_1x_port_control
|
||||
|
||||
static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
|
||||
{
|
||||
- struct ieee80211_hdr *hdr = (void *)rx->skb->data;
|
||||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
@@ -2416,31 +2415,6 @@ static int ieee80211_drop_unencrypted(st
|
||||
if (status->flag & RX_FLAG_DECRYPTED)
|
||||
return 0;
|
||||
|
||||
- /* check mesh EAPOL frames first */
|
||||
- if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) &&
|
||||
- ieee80211_is_data(fc))) {
|
||||
- struct ieee80211s_hdr *mesh_hdr;
|
||||
- u16 hdr_len = ieee80211_hdrlen(fc);
|
||||
- u16 ethertype_offset;
|
||||
- __be16 ethertype;
|
||||
-
|
||||
- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr))
|
||||
- goto drop_check;
|
||||
-
|
||||
- /* make sure fixed part of mesh header is there, also checks skb len */
|
||||
- if (!pskb_may_pull(rx->skb, hdr_len + 6))
|
||||
- goto drop_check;
|
||||
-
|
||||
- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len);
|
||||
- ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) +
|
||||
- sizeof(rfc1042_header);
|
||||
-
|
||||
- if (skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2) == 0 &&
|
||||
- ethertype == rx->sdata->control_port_protocol)
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
-drop_check:
|
||||
/* Drop unencrypted frames if key is set. */
|
||||
if (unlikely(!ieee80211_has_protected(fc) &&
|
||||
!ieee80211_is_any_nullfunc(fc) &&
|
||||
@@ -2898,8 +2872,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
|
||||
|
||||
- if (ieee80211_drop_unencrypted(rx, hdr->frame_control))
|
||||
- return RX_DROP_MONITOR;
|
||||
+ if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
|
||||
+ int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
|
||||
+ sizeof(rfc1042_header);
|
||||
+ __be16 ethertype;
|
||||
+
|
||||
+ if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
|
||||
+ skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 ||
|
||||
+ ethertype != rx->sdata->control_port_protocol)
|
||||
+ return RX_DROP_MONITOR;
|
||||
+ }
|
||||
|
||||
/* frame is in RMC, don't forward */
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
@ -1,25 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 2 Dec 2022 13:53:11 +0100
|
||||
Subject: [PATCH] wifi: cfg80211: move A-MSDU check in
|
||||
ieee80211_data_to_8023_exthdr
|
||||
|
||||
When parsing the outer A-MSDU header, don't check for inner bridge tunnel
|
||||
or RFC1042 headers. This is handled by ieee80211_amsdu_to_8023s already.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -631,8 +631,9 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
break;
|
||||
}
|
||||
|
||||
- if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
|
||||
- ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||
+ if (likely(!is_amsdu &&
|
||||
+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
|
||||
+ ((ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||
payload.proto != htons(ETH_P_AARP) &&
|
||||
payload.proto != htons(ETH_P_IPX)) ||
|
||||
ether_addr_equal(payload.hdr, bridge_tunnel_header)))) {
|
@ -1,76 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 2 Dec 2022 13:54:15 +0100
|
||||
Subject: [PATCH] wifi: cfg80211: factor out bridge tunnel / RFC1042 header
|
||||
check
|
||||
|
||||
The same check is done in multiple places, unify it.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(s
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
|
||||
|
||||
+static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
|
||||
+{
|
||||
+ const __be16 *hdr_proto = hdr + ETH_ALEN;
|
||||
+
|
||||
+ if (!(ether_addr_equal(hdr, rfc1042_header) &&
|
||||
+ *hdr_proto != htons(ETH_P_AARP) &&
|
||||
+ *hdr_proto != htons(ETH_P_IPX)) &&
|
||||
+ !ether_addr_equal(hdr, bridge_tunnel_header))
|
||||
+ return false;
|
||||
+
|
||||
+ *proto = *hdr_proto;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
const u8 *addr, enum nl80211_iftype iftype,
|
||||
u8 data_offset, bool is_amsdu)
|
||||
@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
|
||||
if (likely(!is_amsdu &&
|
||||
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
|
||||
- ((ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||
- payload.proto != htons(ETH_P_AARP) &&
|
||||
- payload.proto != htons(ETH_P_IPX)) ||
|
||||
- ether_addr_equal(payload.hdr, bridge_tunnel_header)))) {
|
||||
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
|
||||
- * replace EtherType */
|
||||
+ ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
|
||||
+ /* remove RFC1042 or Bridge-Tunnel encapsulation */
|
||||
hdrlen += ETH_ALEN + 2;
|
||||
- tmp.h_proto = payload.proto;
|
||||
skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2);
|
||||
} else {
|
||||
tmp.h_proto = htons(skb->len - hdrlen);
|
||||
@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||
{
|
||||
unsigned int hlen = ALIGN(extra_headroom, 4);
|
||||
struct sk_buff *frame = NULL;
|
||||
- u16 ethertype;
|
||||
- u8 *payload;
|
||||
int offset = 0, remaining;
|
||||
struct ethhdr eth;
|
||||
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
|
||||
@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||
frame->dev = skb->dev;
|
||||
frame->priority = skb->priority;
|
||||
|
||||
- payload = frame->data;
|
||||
- ethertype = (payload[6] << 8) | payload[7];
|
||||
- if (likely((ether_addr_equal(payload, rfc1042_header) &&
|
||||
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
|
||||
- ether_addr_equal(payload, bridge_tunnel_header))) {
|
||||
- eth.h_proto = htons(ethertype);
|
||||
+ if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto)))
|
||||
skb_pull(frame, ETH_ALEN + 2);
|
||||
- }
|
||||
|
||||
memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth));
|
||||
__skb_queue_tail(list, frame);
|
@ -1,54 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 2 Dec 2022 17:01:46 +0100
|
||||
Subject: [PATCH] wifi: mac80211: remove mesh forwarding congestion check
|
||||
|
||||
Now that all drivers use iTXQ, it does not make sense to check to drop
|
||||
tx forwarding packets when the driver has stopped the queues.
|
||||
fq_codel will take care of dropping packets when the queues fill up
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/debugfs_netdev.c
|
||||
+++ b/net/mac80211/debugfs_netdev.c
|
||||
@@ -603,8 +603,6 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.ms
|
||||
IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
|
||||
IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
|
||||
-IEEE80211_IF_FILE(dropped_frames_congestion,
|
||||
- u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_no_route,
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
|
||||
@@ -740,7 +738,6 @@ static void add_mesh_stats(struct ieee80
|
||||
MESHSTATS_ADD(fwded_frames);
|
||||
MESHSTATS_ADD(dropped_frames_ttl);
|
||||
MESHSTATS_ADD(dropped_frames_no_route);
|
||||
- MESHSTATS_ADD(dropped_frames_congestion);
|
||||
#undef MESHSTATS_ADD
|
||||
}
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -333,7 +333,6 @@ struct mesh_stats {
|
||||
__u32 fwded_frames; /* Mesh total forwarded frames */
|
||||
__u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/
|
||||
__u32 dropped_frames_no_route; /* Not transmitted, no route found */
|
||||
- __u32 dropped_frames_congestion;/* Not forwarded due to congestion */
|
||||
};
|
||||
|
||||
#define PREQ_Q_F_START 0x1
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2932,11 +2932,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
return RX_CONTINUE;
|
||||
|
||||
ac = ieee802_1d_to_ac[skb->priority];
|
||||
- q = sdata->vif.hw_queue[ac];
|
||||
- if (ieee80211_queue_stopped(&local->hw, q)) {
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
skb_set_queue_mapping(skb, ac);
|
||||
|
||||
if (!--mesh_hdr->ttl) {
|
@ -1,753 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 6 Dec 2022 11:15:02 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
|
||||
interfaces
|
||||
|
||||
The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets
|
||||
on mesh interfaces, because it assumes that the Mesh Control field is always
|
||||
directly after the 802.11 header.
|
||||
802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is
|
||||
actually part of the A-MSDU subframe header.
|
||||
This makes more sense, since it allows packets for multiple different
|
||||
destinations to be included in the same A-MSDU, as long as RA and TID are
|
||||
still the same.
|
||||
Another issue is the fact that the A-MSDU subframe length field was apparently
|
||||
accidentally defined as little-endian in the standard.
|
||||
|
||||
In order to fix this, the mesh forwarding path needs happen at a different
|
||||
point in the receive path.
|
||||
|
||||
ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field
|
||||
and leave it in after the ethernet header. This also affects the source/dest
|
||||
MAC address fields, which now in the case of mesh point to the mesh SA/DA.
|
||||
|
||||
ieee80211_amsdu_to_8023s is changed to deal with the endian difference and
|
||||
to add the Mesh Control length to the subframe length, since it's not covered
|
||||
by the MSDU length field.
|
||||
|
||||
With these changes, the mac80211 will get the same packet structure for
|
||||
converted regular data packets and unpacked A-MSDU subframes.
|
||||
|
||||
The mesh forwarding checks are now only performed after the A-MSDU decap.
|
||||
For locally received packets, the Mesh Control header is stripped away.
|
||||
For forwarded packets, a new 802.11 header gets added.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
|
||||
@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk
|
||||
skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
|
||||
|
||||
ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
|
||||
- priv->wdev.iftype, 0, NULL, NULL);
|
||||
+ priv->wdev.iftype, 0, NULL, NULL, false);
|
||||
|
||||
while (!skb_queue_empty(&list)) {
|
||||
struct rx_packet_hdr *rx_hdr;
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6324,11 +6324,36 @@ static inline int ieee80211_data_to_8023
|
||||
* @extra_headroom: The hardware extra headroom for SKBs in the @list.
|
||||
* @check_da: DA to check in the inner ethernet header, or NULL
|
||||
* @check_sa: SA to check in the inner ethernet header, or NULL
|
||||
+ * @mesh_control: A-MSDU subframe header includes the mesh control field
|
||||
*/
|
||||
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
|
||||
const u8 *addr, enum nl80211_iftype iftype,
|
||||
const unsigned int extra_headroom,
|
||||
- const u8 *check_da, const u8 *check_sa);
|
||||
+ const u8 *check_da, const u8 *check_sa,
|
||||
+ bool mesh_control);
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol
|
||||
+ *
|
||||
+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated
|
||||
+ * protocol.
|
||||
+ *
|
||||
+ * @hdr: pointer to the MSDU payload
|
||||
+ * @proto: destination pointer to store the protocol
|
||||
+ * Return: true if encapsulation was found
|
||||
+ */
|
||||
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto);
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames
|
||||
+ *
|
||||
+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part
|
||||
+ * of the MSDU data. Also move any source/destination addresses from the mesh
|
||||
+ * header to the ethernet header (if present).
|
||||
+ *
|
||||
+ * @skb: The 802.3 frame with embedded mesh header
|
||||
+ */
|
||||
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb);
|
||||
|
||||
/**
|
||||
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2726,6 +2726,174 @@ ieee80211_deliver_skb(struct ieee80211_r
|
||||
}
|
||||
}
|
||||
|
||||
+static ieee80211_rx_result
|
||||
+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+#ifdef CPTCFG_MAC80211_MESH
|
||||
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
|
||||
+ struct ieee80211_hdr hdr = {
|
||||
+ .frame_control = cpu_to_le16(fc)
|
||||
+ };
|
||||
+ struct ieee80211_hdr *fwd_hdr;
|
||||
+ struct ieee80211s_hdr *mesh_hdr;
|
||||
+ struct ieee80211_tx_info *info;
|
||||
+ struct sk_buff *fwd_skb;
|
||||
+ struct ethhdr *eth;
|
||||
+ bool multicast;
|
||||
+ int tailroom = 0;
|
||||
+ int hdrlen, mesh_hdrlen;
|
||||
+ u8 *qos;
|
||||
+
|
||||
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
|
||||
+ return RX_CONTINUE;
|
||||
+
|
||||
+ if (!pskb_may_pull(skb, sizeof(*eth) + 6))
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth));
|
||||
+ mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr);
|
||||
+
|
||||
+ if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen))
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ eth = (struct ethhdr *)skb->data;
|
||||
+ multicast = is_multicast_ether_addr(eth->h_dest);
|
||||
+
|
||||
+ mesh_hdr = (struct ieee80211s_hdr *)(eth + 1);
|
||||
+ if (!mesh_hdr->ttl)
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ /* frame is in RMC, don't forward */
|
||||
+ if (is_multicast_ether_addr(eth->h_dest) &&
|
||||
+ mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ /* Frame has reached destination. Don't forward */
|
||||
+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ if (!ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
+ if (is_multicast_ether_addr(eth->h_dest))
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ return RX_DROP_MONITOR;
|
||||
+ }
|
||||
+
|
||||
+ /* forward packet */
|
||||
+ if (sdata->crypto_tx_tailroom_needed_cnt)
|
||||
+ tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
||||
+
|
||||
+ if (!--mesh_hdr->ttl) {
|
||||
+ if (multicast)
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
|
||||
+ return RX_DROP_MONITOR;
|
||||
+ }
|
||||
+
|
||||
+ if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
+ struct mesh_path *mppath;
|
||||
+ char *proxied_addr;
|
||||
+
|
||||
+ if (multicast)
|
||||
+ proxied_addr = mesh_hdr->eaddr1;
|
||||
+ else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
|
||||
+ /* has_a4 already checked in ieee80211_rx_mesh_check */
|
||||
+ proxied_addr = mesh_hdr->eaddr2;
|
||||
+ else
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ mppath = mpp_path_lookup(sdata, proxied_addr);
|
||||
+ if (!mppath) {
|
||||
+ mpp_path_add(sdata, proxied_addr, eth->h_source);
|
||||
+ } else {
|
||||
+ spin_lock_bh(&mppath->state_lock);
|
||||
+ if (!ether_addr_equal(mppath->mpp, eth->h_source))
|
||||
+ memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
|
||||
+ mppath->exp_time = jiffies;
|
||||
+ spin_unlock_bh(&mppath->state_lock);
|
||||
+ }
|
||||
+ rcu_read_unlock();
|
||||
+ }
|
||||
+
|
||||
+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
|
||||
+
|
||||
+ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
|
||||
+ eth->h_dest, eth->h_source);
|
||||
+ hdrlen = ieee80211_hdrlen(hdr.frame_control);
|
||||
+ if (multicast) {
|
||||
+ int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth);
|
||||
+
|
||||
+ fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head +
|
||||
+ IEEE80211_ENCRYPT_HEADROOM,
|
||||
+ tailroom, GFP_ATOMIC);
|
||||
+ if (!fwd_skb)
|
||||
+ goto rx_accept;
|
||||
+ } else {
|
||||
+ fwd_skb = skb;
|
||||
+ skb = NULL;
|
||||
+
|
||||
+ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+ }
|
||||
+
|
||||
+ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
|
||||
+ memcpy(fwd_hdr, &hdr, hdrlen - 2);
|
||||
+ qos = ieee80211_get_qos_ctl(fwd_hdr);
|
||||
+ qos[0] = qos[1] = 0;
|
||||
+
|
||||
+ skb_reset_mac_header(fwd_skb);
|
||||
+ hdrlen += mesh_hdrlen;
|
||||
+ if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen,
|
||||
+ &fwd_skb->protocol))
|
||||
+ hdrlen += ETH_ALEN;
|
||||
+ else
|
||||
+ fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
|
||||
+ skb_set_network_header(fwd_skb, hdrlen);
|
||||
+
|
||||
+ info = IEEE80211_SKB_CB(fwd_skb);
|
||||
+ memset(info, 0, sizeof(*info));
|
||||
+ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
||||
+ info->control.vif = &sdata->vif;
|
||||
+ info->control.jiffies = jiffies;
|
||||
+ if (multicast) {
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
|
||||
+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
+ /* update power mode indication when forwarding */
|
||||
+ ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
|
||||
+ } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
|
||||
+ /* mesh power mode flags updated in mesh_nexthop_lookup */
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
|
||||
+ } else {
|
||||
+ /* unable to resolve next hop */
|
||||
+ if (sta)
|
||||
+ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
|
||||
+ hdr.addr3, 0,
|
||||
+ WLAN_REASON_MESH_PATH_NOFORWARD,
|
||||
+ sta->sta.addr);
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
|
||||
+ kfree_skb(fwd_skb);
|
||||
+ goto rx_accept;
|
||||
+ }
|
||||
+
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
|
||||
+ fwd_skb->dev = sdata->dev;
|
||||
+ ieee80211_add_pending_skb(local, fwd_skb);
|
||||
+
|
||||
+rx_accept:
|
||||
+ if (!skb)
|
||||
+ return RX_QUEUED;
|
||||
+
|
||||
+ ieee80211_strip_8023_mesh_hdr(skb);
|
||||
+#endif
|
||||
+
|
||||
+ return RX_CONTINUE;
|
||||
+}
|
||||
+
|
||||
static ieee80211_rx_result debug_noinline
|
||||
__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
|
||||
{
|
||||
@@ -2734,8 +2902,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
struct sk_buff_head frame_list;
|
||||
+ static ieee80211_rx_result res;
|
||||
struct ethhdr ethhdr;
|
||||
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
|
||||
+ bool mesh = false;
|
||||
|
||||
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
|
||||
check_da = NULL;
|
||||
@@ -2752,6 +2922,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
check_sa = NULL;
|
||||
+ check_da = NULL;
|
||||
+ mesh = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2769,17 +2941,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
|
||||
rx->sdata->vif.type,
|
||||
rx->local->hw.extra_tx_headroom,
|
||||
- check_da, check_sa);
|
||||
+ check_da, check_sa, mesh);
|
||||
|
||||
while (!skb_queue_empty(&frame_list)) {
|
||||
rx->skb = __skb_dequeue(&frame_list);
|
||||
|
||||
- if (!ieee80211_frame_allowed(rx, fc)) {
|
||||
- dev_kfree_skb(rx->skb);
|
||||
+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
|
||||
+ switch (res) {
|
||||
+ case RX_QUEUED:
|
||||
continue;
|
||||
+ case RX_CONTINUE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto free;
|
||||
}
|
||||
|
||||
+ if (!ieee80211_frame_allowed(rx, fc))
|
||||
+ goto free;
|
||||
+
|
||||
ieee80211_deliver_skb(rx);
|
||||
+ continue;
|
||||
+
|
||||
+free:
|
||||
+ dev_kfree_skb(rx->skb);
|
||||
}
|
||||
|
||||
return RX_QUEUED;
|
||||
@@ -2812,6 +2996,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
|
||||
if (!rx->sdata->u.mgd.use_4addr)
|
||||
return RX_DROP_UNUSABLE;
|
||||
break;
|
||||
+ case NL80211_IFTYPE_MESH_POINT:
|
||||
+ break;
|
||||
default:
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
@@ -2840,155 +3026,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
|
||||
return __ieee80211_rx_h_amsdu(rx, 0);
|
||||
}
|
||||
|
||||
-#ifdef CPTCFG_MAC80211_MESH
|
||||
-static ieee80211_rx_result
|
||||
-ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
||||
-{
|
||||
- struct ieee80211_hdr *fwd_hdr, *hdr;
|
||||
- struct ieee80211_tx_info *info;
|
||||
- struct ieee80211s_hdr *mesh_hdr;
|
||||
- struct sk_buff *skb = rx->skb, *fwd_skb;
|
||||
- struct ieee80211_local *local = rx->local;
|
||||
- struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
- u16 ac, q, hdrlen;
|
||||
- int tailroom = 0;
|
||||
-
|
||||
- hdr = (struct ieee80211_hdr *) skb->data;
|
||||
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
-
|
||||
- /* make sure fixed part of mesh header is there, also checks skb len */
|
||||
- if (!pskb_may_pull(rx->skb, hdrlen + 6))
|
||||
- return RX_DROP_MONITOR;
|
||||
-
|
||||
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
|
||||
-
|
||||
- /* make sure full mesh header is there, also checks skb len */
|
||||
- if (!pskb_may_pull(rx->skb,
|
||||
- hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
|
||||
- return RX_DROP_MONITOR;
|
||||
-
|
||||
- /* reload pointers */
|
||||
- hdr = (struct ieee80211_hdr *) skb->data;
|
||||
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
|
||||
-
|
||||
- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
|
||||
- int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
|
||||
- sizeof(rfc1042_header);
|
||||
- __be16 ethertype;
|
||||
-
|
||||
- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
|
||||
- skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 ||
|
||||
- ethertype != rx->sdata->control_port_protocol)
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
-
|
||||
- /* frame is in RMC, don't forward */
|
||||
- if (ieee80211_is_data(hdr->frame_control) &&
|
||||
- is_multicast_ether_addr(hdr->addr1) &&
|
||||
- mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
|
||||
- return RX_DROP_MONITOR;
|
||||
-
|
||||
- if (!ieee80211_is_data(hdr->frame_control))
|
||||
- return RX_CONTINUE;
|
||||
-
|
||||
- if (!mesh_hdr->ttl)
|
||||
- return RX_DROP_MONITOR;
|
||||
-
|
||||
- if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
- struct mesh_path *mppath;
|
||||
- char *proxied_addr;
|
||||
- char *mpp_addr;
|
||||
-
|
||||
- if (is_multicast_ether_addr(hdr->addr1)) {
|
||||
- mpp_addr = hdr->addr3;
|
||||
- proxied_addr = mesh_hdr->eaddr1;
|
||||
- } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
|
||||
- MESH_FLAGS_AE_A5_A6) {
|
||||
- /* has_a4 already checked in ieee80211_rx_mesh_check */
|
||||
- mpp_addr = hdr->addr4;
|
||||
- proxied_addr = mesh_hdr->eaddr2;
|
||||
- } else {
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
-
|
||||
- rcu_read_lock();
|
||||
- mppath = mpp_path_lookup(sdata, proxied_addr);
|
||||
- if (!mppath) {
|
||||
- mpp_path_add(sdata, proxied_addr, mpp_addr);
|
||||
- } else {
|
||||
- spin_lock_bh(&mppath->state_lock);
|
||||
- if (!ether_addr_equal(mppath->mpp, mpp_addr))
|
||||
- memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
|
||||
- mppath->exp_time = jiffies;
|
||||
- spin_unlock_bh(&mppath->state_lock);
|
||||
- }
|
||||
- rcu_read_unlock();
|
||||
- }
|
||||
-
|
||||
- /* Frame has reached destination. Don't forward */
|
||||
- if (!is_multicast_ether_addr(hdr->addr1) &&
|
||||
- ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
||||
- return RX_CONTINUE;
|
||||
-
|
||||
- ac = ieee802_1d_to_ac[skb->priority];
|
||||
- skb_set_queue_mapping(skb, ac);
|
||||
-
|
||||
- if (!--mesh_hdr->ttl) {
|
||||
- if (!is_multicast_ether_addr(hdr->addr1))
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh,
|
||||
- dropped_frames_ttl);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if (!ifmsh->mshcfg.dot11MeshForwarding)
|
||||
- goto out;
|
||||
-
|
||||
- if (sdata->crypto_tx_tailroom_needed_cnt)
|
||||
- tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
||||
-
|
||||
- fwd_skb = skb_copy_expand(skb, local->tx_headroom +
|
||||
- IEEE80211_ENCRYPT_HEADROOM,
|
||||
- tailroom, GFP_ATOMIC);
|
||||
- if (!fwd_skb)
|
||||
- goto out;
|
||||
-
|
||||
- fwd_skb->dev = sdata->dev;
|
||||
- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
|
||||
- fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
|
||||
- info = IEEE80211_SKB_CB(fwd_skb);
|
||||
- memset(info, 0, sizeof(*info));
|
||||
- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
||||
- info->control.vif = &rx->sdata->vif;
|
||||
- info->control.jiffies = jiffies;
|
||||
- if (is_multicast_ether_addr(fwd_hdr->addr1)) {
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
|
||||
- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
- /* update power mode indication when forwarding */
|
||||
- ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
|
||||
- } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
|
||||
- /* mesh power mode flags updated in mesh_nexthop_lookup */
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
|
||||
- } else {
|
||||
- /* unable to resolve next hop */
|
||||
- mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
|
||||
- fwd_hdr->addr3, 0,
|
||||
- WLAN_REASON_MESH_PATH_NOFORWARD,
|
||||
- fwd_hdr->addr2);
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
|
||||
- kfree_skb(fwd_skb);
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
-
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
|
||||
- ieee80211_add_pending_skb(local, fwd_skb);
|
||||
- out:
|
||||
- if (is_multicast_ether_addr(hdr->addr1))
|
||||
- return RX_CONTINUE;
|
||||
- return RX_DROP_MONITOR;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
@@ -2997,6 +3034,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
|
||||
struct net_device *dev = sdata->dev;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
+ static ieee80211_rx_result res;
|
||||
bool port_control;
|
||||
int err;
|
||||
|
||||
@@ -3023,6 +3061,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
|
||||
if (unlikely(err))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
|
||||
+ if (res != RX_CONTINUE)
|
||||
+ return res;
|
||||
+
|
||||
if (!ieee80211_frame_allowed(rx, fc))
|
||||
return RX_DROP_MONITOR;
|
||||
|
||||
@@ -3997,10 +4039,6 @@ static void ieee80211_rx_handlers(struct
|
||||
CALL_RXH(ieee80211_rx_h_defragment);
|
||||
CALL_RXH(ieee80211_rx_h_michael_mic_verify);
|
||||
/* must be after MMIC verify so header is counted in MPDU mic */
|
||||
-#ifdef CPTCFG_MAC80211_MESH
|
||||
- if (ieee80211_vif_is_mesh(&rx->sdata->vif))
|
||||
- CALL_RXH(ieee80211_rx_h_mesh_fwding);
|
||||
-#endif
|
||||
CALL_RXH(ieee80211_rx_h_amsdu);
|
||||
CALL_RXH(ieee80211_rx_h_data);
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
|
||||
|
||||
-static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
|
||||
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
|
||||
{
|
||||
const __be16 *hdr_proto = hdr + ETH_ALEN;
|
||||
|
||||
@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr
|
||||
|
||||
return true;
|
||||
}
|
||||
+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto);
|
||||
+
|
||||
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb)
|
||||
+{
|
||||
+ const void *mesh_addr;
|
||||
+ struct {
|
||||
+ struct ethhdr eth;
|
||||
+ u8 flags;
|
||||
+ } payload;
|
||||
+ int hdrlen;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = skb_copy_bits(skb, 0, &payload, sizeof(payload));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags);
|
||||
+
|
||||
+ if (likely(pskb_may_pull(skb, hdrlen + 8) &&
|
||||
+ ieee80211_get_8023_tunnel_proto(skb->data + hdrlen,
|
||||
+ &payload.eth.h_proto)))
|
||||
+ hdrlen += ETH_ALEN + 2;
|
||||
+ else if (!pskb_may_pull(skb, hdrlen))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
|
||||
+ switch (payload.flags & MESH_FLAGS_AE) {
|
||||
+ case MESH_FLAGS_AE_A4:
|
||||
+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
|
||||
+ break;
|
||||
+ case MESH_FLAGS_AE_A5_A6:
|
||||
+ memcpy(&payload.eth.h_dest, mesh_addr, 2 * ETH_ALEN);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ pskb_pull(skb, hdrlen - sizeof(payload.eth));
|
||||
+ memcpy(skb->data, &payload.eth, sizeof(payload.eth));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr);
|
||||
|
||||
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
const u8 *addr, enum nl80211_iftype iftype,
|
||||
@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
} payload;
|
||||
struct ethhdr tmp;
|
||||
u16 hdrlen;
|
||||
- u8 mesh_flags = 0;
|
||||
|
||||
if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
|
||||
return -1;
|
||||
@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
|
||||
memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN);
|
||||
|
||||
- if (iftype == NL80211_IFTYPE_MESH_POINT &&
|
||||
- skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- mesh_flags &= MESH_FLAGS_AE;
|
||||
-
|
||||
switch (hdr->frame_control &
|
||||
cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
|
||||
case cpu_to_le16(IEEE80211_FCTL_TODS):
|
||||
@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
iftype != NL80211_IFTYPE_AP_VLAN &&
|
||||
iftype != NL80211_IFTYPE_STATION))
|
||||
return -1;
|
||||
- if (iftype == NL80211_IFTYPE_MESH_POINT) {
|
||||
- if (mesh_flags == MESH_FLAGS_AE_A4)
|
||||
- return -1;
|
||||
- if (mesh_flags == MESH_FLAGS_AE_A5_A6 &&
|
||||
- skb_copy_bits(skb, hdrlen +
|
||||
- offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
- tmp.h_dest, 2 * ETH_ALEN) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
|
||||
- }
|
||||
break;
|
||||
case cpu_to_le16(IEEE80211_FCTL_FROMDS):
|
||||
if ((iftype != NL80211_IFTYPE_STATION &&
|
||||
@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
(is_multicast_ether_addr(tmp.h_dest) &&
|
||||
ether_addr_equal(tmp.h_source, addr)))
|
||||
return -1;
|
||||
- if (iftype == NL80211_IFTYPE_MESH_POINT) {
|
||||
- if (mesh_flags == MESH_FLAGS_AE_A5_A6)
|
||||
- return -1;
|
||||
- if (mesh_flags == MESH_FLAGS_AE_A4 &&
|
||||
- skb_copy_bits(skb, hdrlen +
|
||||
- offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
- tmp.h_source, ETH_ALEN) < 0)
|
||||
- return -1;
|
||||
- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
|
||||
- }
|
||||
break;
|
||||
case cpu_to_le16(0):
|
||||
if (iftype != NL80211_IFTYPE_ADHOC &&
|
||||
@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
break;
|
||||
}
|
||||
|
||||
- if (likely(!is_amsdu &&
|
||||
+ if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT &&
|
||||
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
|
||||
ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
|
||||
/* remove RFC1042 or Bridge-Tunnel encapsulation */
|
||||
@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu
|
||||
|
||||
static struct sk_buff *
|
||||
__ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
|
||||
- int offset, int len, bool reuse_frag)
|
||||
+ int offset, int len, bool reuse_frag,
|
||||
+ int min_len)
|
||||
{
|
||||
struct sk_buff *frame;
|
||||
int cur_len = len;
|
||||
@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
|
||||
* in the stack later.
|
||||
*/
|
||||
if (reuse_frag)
|
||||
- cur_len = min_t(int, len, 32);
|
||||
+ cur_len = min_t(int, len, min_len);
|
||||
|
||||
/*
|
||||
* Allocate and reserve two bytes more for payload
|
||||
@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
+ frame->priority = skb->priority;
|
||||
skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
|
||||
skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
|
||||
|
||||
@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s
|
||||
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
|
||||
const u8 *addr, enum nl80211_iftype iftype,
|
||||
const unsigned int extra_headroom,
|
||||
- const u8 *check_da, const u8 *check_sa)
|
||||
+ const u8 *check_da, const u8 *check_sa,
|
||||
+ bool mesh_control)
|
||||
{
|
||||
unsigned int hlen = ALIGN(extra_headroom, 4);
|
||||
struct sk_buff *frame = NULL;
|
||||
int offset = 0, remaining;
|
||||
- struct ethhdr eth;
|
||||
+ struct {
|
||||
+ struct ethhdr eth;
|
||||
+ uint8_t flags;
|
||||
+ } hdr;
|
||||
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
|
||||
bool reuse_skb = false;
|
||||
bool last = false;
|
||||
+ int copy_len = sizeof(hdr.eth);
|
||||
+
|
||||
+ if (iftype == NL80211_IFTYPE_MESH_POINT)
|
||||
+ copy_len = sizeof(hdr);
|
||||
|
||||
while (!last) {
|
||||
unsigned int subframe_len;
|
||||
- int len;
|
||||
+ int len, mesh_len = 0;
|
||||
u8 padding;
|
||||
|
||||
- skb_copy_bits(skb, offset, ð, sizeof(eth));
|
||||
- len = ntohs(eth.h_proto);
|
||||
+ skb_copy_bits(skb, offset, &hdr, copy_len);
|
||||
+ if (iftype == NL80211_IFTYPE_MESH_POINT)
|
||||
+ mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags);
|
||||
+ if (mesh_control)
|
||||
+ len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len;
|
||||
+ else
|
||||
+ len = ntohs(hdr.eth.h_proto);
|
||||
+
|
||||
subframe_len = sizeof(struct ethhdr) + len;
|
||||
padding = (4 - subframe_len) & 0x3;
|
||||
|
||||
@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||
if (subframe_len > remaining)
|
||||
goto purge;
|
||||
/* mitigate A-MSDU aggregation injection attacks */
|
||||
- if (ether_addr_equal(eth.h_dest, rfc1042_header))
|
||||
+ if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header))
|
||||
goto purge;
|
||||
|
||||
offset += sizeof(struct ethhdr);
|
||||
last = remaining <= subframe_len + padding;
|
||||
|
||||
/* FIXME: should we really accept multicast DA? */
|
||||
- if ((check_da && !is_multicast_ether_addr(eth.h_dest) &&
|
||||
- !ether_addr_equal(check_da, eth.h_dest)) ||
|
||||
- (check_sa && !ether_addr_equal(check_sa, eth.h_source))) {
|
||||
+ if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) &&
|
||||
+ !ether_addr_equal(check_da, hdr.eth.h_dest)) ||
|
||||
+ (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) {
|
||||
offset += len + padding;
|
||||
continue;
|
||||
}
|
||||
@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||
reuse_skb = true;
|
||||
} else {
|
||||
frame = __ieee80211_amsdu_copy(skb, hlen, offset, len,
|
||||
- reuse_frag);
|
||||
+ reuse_frag, 32 + mesh_len);
|
||||
if (!frame)
|
||||
goto purge;
|
||||
|
||||
@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_
|
||||
frame->dev = skb->dev;
|
||||
frame->priority = skb->priority;
|
||||
|
||||
- if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto)))
|
||||
+ if (likely(iftype != NL80211_IFTYPE_MESH_POINT &&
|
||||
+ ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto)))
|
||||
skb_pull(frame, ETH_ALEN + 2);
|
||||
|
||||
- memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth));
|
||||
+ memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth));
|
||||
__skb_queue_tail(list, frame);
|
||||
}
|
||||
|
@ -1,145 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 9 Dec 2022 21:15:04 +0100
|
||||
Subject: [PATCH] wifi: mac80211: add a workaround for receiving
|
||||
non-standard mesh A-MSDU
|
||||
|
||||
At least ath10k and ath11k supported hardware (maybe more) does not implement
|
||||
mesh A-MSDU aggregation in a standard compliant way.
|
||||
802.11-2020 9.3.2.2.2 declares that the Mesh Control field is part of the
|
||||
A-MSDU header. As such, its length must not be included in the subframe
|
||||
length field.
|
||||
Hardware affected by this bug treats the mesh control field as part of the
|
||||
MSDU data and sets the length accordingly.
|
||||
In order to avoid packet loss, keep track of which stations are affected
|
||||
by this and take it into account when converting A-MSDU to 802.3 + mesh control
|
||||
packets.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6310,6 +6310,19 @@ static inline int ieee80211_data_to_8023
|
||||
}
|
||||
|
||||
/**
|
||||
+ * ieee80211_is_valid_amsdu - check if subframe lengths of an A-MSDU are valid
|
||||
+ *
|
||||
+ * This is used to detect non-standard A-MSDU frames, e.g. the ones generated
|
||||
+ * by ath10k and ath11k, where the subframe length includes the length of the
|
||||
+ * mesh control field.
|
||||
+ *
|
||||
+ * @skb: The input A-MSDU frame without any headers.
|
||||
+ * @mesh_hdr: use standard compliant mesh A-MSDU subframe header
|
||||
+ * Returns: true if subframe header lengths are valid for the @mesh_hdr mode
|
||||
+ */
|
||||
+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
|
||||
*
|
||||
* Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames.
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2905,7 +2905,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
static ieee80211_rx_result res;
|
||||
struct ethhdr ethhdr;
|
||||
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
|
||||
- bool mesh = false;
|
||||
|
||||
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
|
||||
check_da = NULL;
|
||||
@@ -2923,7 +2922,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
check_sa = NULL;
|
||||
check_da = NULL;
|
||||
- mesh = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2938,10 +2936,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
|
||||
data_offset, true))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
+ if (rx->sta && rx->sta->amsdu_mesh_control < 0) {
|
||||
+ bool valid_std = ieee80211_is_valid_amsdu(skb, true);
|
||||
+ bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false);
|
||||
+
|
||||
+ if (valid_std && !valid_nonstd)
|
||||
+ rx->sta->amsdu_mesh_control = 1;
|
||||
+ else if (valid_nonstd && !valid_std)
|
||||
+ rx->sta->amsdu_mesh_control = 0;
|
||||
+ }
|
||||
+
|
||||
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
|
||||
rx->sdata->vif.type,
|
||||
rx->local->hw.extra_tx_headroom,
|
||||
- check_da, check_sa, mesh);
|
||||
+ check_da, check_sa,
|
||||
+ rx->sta->amsdu_mesh_control);
|
||||
|
||||
while (!skb_queue_empty(&frame_list)) {
|
||||
rx->skb = __skb_dequeue(&frame_list);
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -594,6 +594,9 @@ __sta_info_alloc(struct ieee80211_sub_if
|
||||
|
||||
sta->sta_state = IEEE80211_STA_NONE;
|
||||
|
||||
+ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
|
||||
+ sta->amsdu_mesh_control = -1;
|
||||
+
|
||||
/* Mark TID as unreserved */
|
||||
sta->reserved_tid = IEEE80211_TID_UNRESERVED;
|
||||
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -702,6 +702,7 @@ struct sta_info {
|
||||
struct codel_params cparams;
|
||||
|
||||
u8 reserved_tid;
|
||||
+ s8 amsdu_mesh_control;
|
||||
|
||||
struct cfg80211_chan_def tdls_chandef;
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -776,6 +776,38 @@ __ieee80211_amsdu_copy(struct sk_buff *s
|
||||
return frame;
|
||||
}
|
||||
|
||||
+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr)
|
||||
+{
|
||||
+ int offset = 0, remaining, subframe_len, padding;
|
||||
+
|
||||
+ for (offset = 0; offset < skb->len; offset += subframe_len + padding) {
|
||||
+ struct {
|
||||
+ __be16 len;
|
||||
+ u8 mesh_flags;
|
||||
+ } hdr;
|
||||
+ u16 len;
|
||||
+
|
||||
+ if (skb_copy_bits(skb, offset + 2 * ETH_ALEN, &hdr, sizeof(hdr)) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ if (mesh_hdr)
|
||||
+ len = le16_to_cpu(*(__le16 *)&hdr.len) +
|
||||
+ __ieee80211_get_mesh_hdrlen(hdr.mesh_flags);
|
||||
+ else
|
||||
+ len = ntohs(hdr.len);
|
||||
+
|
||||
+ subframe_len = sizeof(struct ethhdr) + len;
|
||||
+ padding = (4 - subframe_len) & 0x3;
|
||||
+ remaining = skb->len - offset;
|
||||
+
|
||||
+ if (subframe_len > remaining)
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_is_valid_amsdu);
|
||||
+
|
||||
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
|
||||
const u8 *addr, enum nl80211_iftype iftype,
|
||||
const unsigned int extra_headroom,
|
@ -698,7 +698,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2797,6 +2797,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
@@ -2778,6 +2778,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
struct mesh_path *mppath;
|
||||
char *proxied_addr;
|
||||
@ -706,7 +706,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
if (multicast)
|
||||
proxied_addr = mesh_hdr->eaddr1;
|
||||
@@ -2812,11 +2813,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
@@ -2793,11 +2794,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
mpp_path_add(sdata, proxied_addr, eth->h_source);
|
||||
} else {
|
||||
spin_lock_bh(&mppath->state_lock);
|
||||
|
@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
|
||||
eth->h_dest, eth->h_source);
|
||||
hdrlen = ieee80211_hdrlen(hdr.frame_control);
|
||||
@@ -2868,6 +2931,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
@@ -2871,6 +2934,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
||||
info->control.vif = &sdata->vif;
|
||||
info->control.jiffies = jiffies;
|
||||
@ -96,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (multicast) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
|
||||
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
@@ -2889,7 +2953,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
@@ -2892,7 +2956,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
}
|
||||
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
|
||||
|
@ -1,32 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 20 Feb 2023 12:50:50 +0100
|
||||
Subject: [PATCH] mac80211: fix mesh forwarding
|
||||
|
||||
Linearize packets (needed for forwarding A-MSDU subframes).
|
||||
Fix network header offset to fix flow dissector (and fair queueing).
|
||||
|
||||
Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2910,6 +2910,9 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
|
||||
if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
|
||||
return RX_DROP_UNUSABLE;
|
||||
+
|
||||
+ if (skb_linearize(fwd_skb))
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
|
||||
@@ -2924,7 +2927,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
hdrlen += ETH_ALEN;
|
||||
else
|
||||
fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
|
||||
- skb_set_network_header(fwd_skb, hdrlen);
|
||||
+ skb_set_network_header(fwd_skb, hdrlen + 2);
|
||||
|
||||
info = IEEE80211_SKB_CB(fwd_skb);
|
||||
memset(info, 0, sizeof(*info));
|
@ -1,52 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 26 Feb 2023 20:30:20 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix mesh path discovery based on unicast
|
||||
packets
|
||||
|
||||
If a packet has reached its intended destination, it was bumped to the code
|
||||
that accepts it, without first checking if a mesh_path needs to be created
|
||||
based on the discovered source.
|
||||
Fix this by moving the destination address check further down
|
||||
|
||||
Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2830,17 +2830,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
|
||||
return RX_DROP_MONITOR;
|
||||
|
||||
- /* Frame has reached destination. Don't forward */
|
||||
- if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
|
||||
- goto rx_accept;
|
||||
-
|
||||
- if (!ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
- if (is_multicast_ether_addr(eth->h_dest))
|
||||
- goto rx_accept;
|
||||
-
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
-
|
||||
/* forward packet */
|
||||
if (sdata->crypto_tx_tailroom_needed_cnt)
|
||||
tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
||||
@@ -2887,6 +2876,17 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
+ /* Frame has reached destination. Don't forward */
|
||||
+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ if (!ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
+ if (is_multicast_ether_addr(eth->h_dest))
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ return RX_DROP_MONITOR;
|
||||
+ }
|
||||
+
|
||||
skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
|
||||
|
||||
if (!multicast &&
|
@ -34,7 +34,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
* @tid: the TID to BA on.
|
||||
--- a/net/mac80211/agg-tx.c
|
||||
+++ b/net/mac80211/agg-tx.c
|
||||
@@ -554,6 +554,23 @@ void ieee80211_tx_ba_session_handle_star
|
||||
@@ -550,6 +550,23 @@ void ieee80211_tx_ba_session_handle_star
|
||||
ieee80211_send_addba_with_timeout(sta, tid_tx);
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
MAC80211_SUPPORTED_FEATURES_RX)
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device
|
||||
@@ -834,6 +834,21 @@ ieee80211_get_stats64(struct net_device
|
||||
dev_fetch_sw_netstats(stats, dev->tstats);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
static const struct net_device_ops ieee80211_dataif_ops = {
|
||||
.ndo_open = ieee80211_open,
|
||||
.ndo_stop = ieee80211_stop,
|
||||
@@ -821,6 +836,7 @@ static const struct net_device_ops ieee8
|
||||
@@ -842,6 +857,7 @@ static const struct net_device_ops ieee8
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
.ndo_get_stats64 = ieee80211_get_stats64,
|
||||
@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_IS_GEQ(5,2,0)
|
||||
@@ -945,6 +961,7 @@ static const struct net_device_ops ieee8
|
||||
@@ -966,6 +982,7 @@ static const struct net_device_ops ieee8
|
||||
#if LINUX_VERSION_IS_GEQ(5,13,0)
|
||||
.ndo_fill_forward_path = ieee80211_netdev_fill_forward_path,
|
||||
#endif
|
||||
|
@ -1,50 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 26 Mar 2023 17:11:34 +0200
|
||||
Subject: [PATCH] wifi: mac80211: fix receiving mesh packets in forwarding=0
|
||||
networks
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When forwarding is set to 0, frames are typically sent with ttl=1.
|
||||
Move the ttl decrement check below the check for local receive in order to
|
||||
fix packet drops.
|
||||
|
||||
Reported-by: Thomas Hühn <thomas.huehn@hs-nordhausen.de>
|
||||
Reported-by: Nick Hainke <vincent@systemli.org>
|
||||
Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2834,14 +2834,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
if (sdata->crypto_tx_tailroom_needed_cnt)
|
||||
tailroom = IEEE80211_ENCRYPT_TAILROOM;
|
||||
|
||||
- if (!--mesh_hdr->ttl) {
|
||||
- if (multicast)
|
||||
- goto rx_accept;
|
||||
-
|
||||
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
|
||||
- return RX_DROP_MONITOR;
|
||||
- }
|
||||
-
|
||||
if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
struct mesh_path *mppath;
|
||||
char *proxied_addr;
|
||||
@@ -2880,6 +2872,14 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
|
||||
goto rx_accept;
|
||||
|
||||
+ if (!--mesh_hdr->ttl) {
|
||||
+ if (multicast)
|
||||
+ goto rx_accept;
|
||||
+
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
|
||||
+ return RX_DROP_MONITOR;
|
||||
+ }
|
||||
+
|
||||
if (!ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
if (is_multicast_ether_addr(eth->h_dest))
|
||||
goto rx_accept;
|
@ -19,7 +19,7 @@ Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
|
||||
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -1276,6 +1276,14 @@ static void __sta_info_destroy_part2(str
|
||||
@@ -1290,6 +1290,14 @@ static void __sta_info_destroy_part2(str
|
||||
WARN_ON_ONCE(ret);
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -1281,8 +1281,12 @@ static void __sta_info_destroy_part2(str
|
||||
@@ -1295,8 +1295,12 @@ static void __sta_info_destroy_part2(str
|
||||
* frames sitting on hardware queues might be sent out without
|
||||
* any encryption at all.
|
||||
*/
|
||||
|
@ -129,7 +129,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
}
|
||||
|
||||
new = kzalloc(size, GFP_KERNEL);
|
||||
@@ -3395,8 +3395,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
|
||||
@@ -3396,8 +3396,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
|
||||
|
||||
len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
|
||||
beacon->proberesp_ies_len + beacon->assocresp_ies_len +
|
||||
|
@ -1,25 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 11 Jul 2023 13:30:12 +0200
|
||||
Subject: [PATCH] wifi: cfg80211: fix receving mesh packets without RFC1042
|
||||
header
|
||||
|
||||
Fix ethernet header length field after stripping the mesh header
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Link: https://lore.kernel.org/all/CT5GNZSK28AI.2K6M69OXM9RW5@syracuse/
|
||||
Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
|
||||
Reported-by: Nicolas Escande <nico.escande@gmail.com>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -580,6 +580,8 @@ int ieee80211_strip_8023_mesh_hdr(struct
|
||||
hdrlen += ETH_ALEN + 2;
|
||||
else if (!pskb_may_pull(skb, hdrlen))
|
||||
return -EINVAL;
|
||||
+ else
|
||||
+ payload.eth.h_proto = htons(skb->len - hdrlen);
|
||||
|
||||
mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
|
||||
switch (payload.flags & MESH_FLAGS_AE) {
|
@ -113,7 +113,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
{
|
||||
--- a/net/wireless/core.h
|
||||
+++ b/net/wireless/core.h
|
||||
@@ -491,6 +491,8 @@ void cfg80211_set_dfs_state(struct wiphy
|
||||
@@ -497,6 +497,8 @@ void cfg80211_set_dfs_state(struct wiphy
|
||||
enum nl80211_dfs_state dfs_state);
|
||||
|
||||
void cfg80211_dfs_channels_update_work(struct work_struct *work);
|
||||
|
@ -76,7 +76,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
--- a/net/wireless/core.h
|
||||
+++ b/net/wireless/core.h
|
||||
@@ -277,6 +277,8 @@ struct cfg80211_event {
|
||||
@@ -283,6 +283,8 @@ struct cfg80211_event {
|
||||
} ij;
|
||||
struct {
|
||||
u8 bssid[ETH_ALEN];
|
||||
@ -85,7 +85,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
} pa;
|
||||
};
|
||||
};
|
||||
@@ -421,7 +423,8 @@ int cfg80211_disconnect(struct cfg80211_
|
||||
@@ -427,7 +429,8 @@ int cfg80211_disconnect(struct cfg80211_
|
||||
bool wextev);
|
||||
void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
struct cfg80211_roam_info *info);
|
||||
@ -97,7 +97,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
void cfg80211_autodisconnect_wk(struct work_struct *work);
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -17993,7 +17993,8 @@ void nl80211_send_roamed(struct cfg80211
|
||||
@@ -18024,7 +18024,8 @@ void nl80211_send_roamed(struct cfg80211
|
||||
}
|
||||
|
||||
void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
|
||||
@ -107,7 +107,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
@@ -18013,6 +18014,11 @@ void nl80211_send_port_authorized(struct
|
||||
@@ -18044,6 +18045,11 @@ void nl80211_send_port_authorized(struct
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
|
||||
goto nla_put_failure;
|
||||
|
||||
@ -176,7 +176,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
* Use the wdev event list so that if there are pending
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -1059,7 +1059,9 @@ void cfg80211_process_wdev_events(struct
|
||||
@@ -1065,7 +1065,9 @@ void cfg80211_process_wdev_events(struct
|
||||
__cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
|
||||
break;
|
||||
case EVENT_PORT_AUTHORIZED:
|
||||
|
@ -94,7 +94,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -2389,6 +2389,13 @@ static void sta_stats_decode_rate(struct
|
||||
@@ -2403,6 +2403,13 @@ static void sta_stats_decode_rate(struct
|
||||
rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate);
|
||||
rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate);
|
||||
break;
|
||||
@ -110,7 +110,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -930,6 +930,7 @@ enum sta_stats_type {
|
||||
@@ -936,6 +936,7 @@ enum sta_stats_type {
|
||||
STA_STATS_RATE_TYPE_VHT,
|
||||
STA_STATS_RATE_TYPE_HE,
|
||||
STA_STATS_RATE_TYPE_S1G,
|
||||
@ -118,7 +118,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
};
|
||||
|
||||
#define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0)
|
||||
@@ -939,12 +940,16 @@ enum sta_stats_type {
|
||||
@@ -945,12 +946,16 @@ enum sta_stats_type {
|
||||
#define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4)
|
||||
#define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0)
|
||||
#define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4)
|
||||
@ -141,7 +141,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
#define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v)
|
||||
#define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v)
|
||||
@@ -983,6 +988,13 @@ static inline u32 sta_stats_encode_rate(
|
||||
@@ -989,6 +994,13 @@ static inline u32 sta_stats_encode_rate(
|
||||
r |= STA_STATS_FIELD(HE_RU, s->he_ru);
|
||||
r |= STA_STATS_FIELD(HE_DCM, s->he_dcm);
|
||||
break;
|
||||
|
@ -62,7 +62,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
bool mu_mimo_owner;
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4196,7 +4196,7 @@ static int ieee80211_set_ap_chanwidth(st
|
||||
@@ -4197,7 +4197,7 @@ static int ieee80211_set_ap_chanwidth(st
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_link_data *link;
|
||||
int ret;
|
||||
|
@ -107,7 +107,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -819,6 +819,7 @@ static const struct nla_policy nl80211_p
|
||||
@@ -829,6 +829,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
|
||||
[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
|
||||
@ -115,7 +115,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -3187,6 +3188,21 @@ static bool nl80211_can_set_dev_channel(
|
||||
@@ -3197,6 +3198,21 @@ static bool nl80211_can_set_dev_channel(
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_GO;
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
|
||||
struct genl_info *info,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
@@ -5938,6 +5954,14 @@ static int nl80211_start_ap(struct sk_bu
|
||||
@@ -5969,6 +5985,14 @@ static int nl80211_start_ap(struct sk_bu
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms->chandef,
|
||||
wdev->iftype)) {
|
||||
err = -EINVAL;
|
||||
@@ -10076,6 +10100,14 @@ skip_beacons:
|
||||
@@ -10107,6 +10131,14 @@ skip_beacons:
|
||||
if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
|
||||
params.block_tx = true;
|
||||
|
||||
|
@ -91,7 +91,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
* ieee80211_operating_class_to_band - convert operating class to band
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3611,7 +3611,8 @@ static int __ieee80211_csa_finalize(stru
|
||||
@@ -3612,7 +3612,8 @@ static int __ieee80211_csa_finalize(stru
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -101,7 +101,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3883,7 +3884,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
@@ -3884,7 +3885,7 @@ __ieee80211_channel_switch(struct wiphy
|
||||
|
||||
cfg80211_ch_switch_started_notify(sdata->dev,
|
||||
&sdata->deflink.csa_chandef, 0,
|
||||
@ -132,7 +132,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
/* use driver's channel switch callback */
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -19054,7 +19054,7 @@ static void nl80211_ch_switch_notify(str
|
||||
@@ -19085,7 +19085,7 @@ static void nl80211_ch_switch_notify(str
|
||||
struct cfg80211_chan_def *chandef,
|
||||
gfp_t gfp,
|
||||
enum nl80211_commands notif,
|
||||
@ -141,7 +141,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
{
|
||||
struct wireless_dev *wdev = netdev->ieee80211_ptr;
|
||||
struct sk_buff *msg;
|
||||
@@ -19088,6 +19088,9 @@ static void nl80211_ch_switch_notify(str
|
||||
@@ -19119,6 +19119,9 @@ static void nl80211_ch_switch_notify(str
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
||||
@@ -19100,7 +19103,7 @@ static void nl80211_ch_switch_notify(str
|
||||
@@ -19131,7 +19134,7 @@ static void nl80211_ch_switch_notify(str
|
||||
|
||||
void cfg80211_ch_switch_notify(struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
@ -160,7 +160,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
@@ -19109,7 +19112,7 @@ void cfg80211_ch_switch_notify(struct ne
|
||||
@@ -19140,7 +19143,7 @@ void cfg80211_ch_switch_notify(struct ne
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
WARN_INVALID_LINK_ID(wdev, link_id);
|
||||
|
||||
@ -169,7 +169,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@@ -19137,14 +19140,15 @@ void cfg80211_ch_switch_notify(struct ne
|
||||
@@ -19168,14 +19171,15 @@ void cfg80211_ch_switch_notify(struct ne
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
|
||||
nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
|
||||
@ -187,7 +187,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
@@ -19153,11 +19157,13 @@ void cfg80211_ch_switch_started_notify(s
|
||||
@@ -19184,11 +19188,13 @@ void cfg80211_ch_switch_started_notify(s
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
WARN_INVALID_LINK_ID(wdev, link_id);
|
||||
|
||||
|
@ -59,7 +59,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP &&
|
||||
params->mbssid_config.tx_wdev) {
|
||||
err = ieee80211_set_ap_mbssid_options(sdata,
|
||||
@@ -3570,6 +3575,12 @@ static int __ieee80211_csa_finalize(stru
|
||||
@@ -3571,6 +3576,12 @@ static int __ieee80211_csa_finalize(stru
|
||||
lockdep_assert_held(&local->mtx);
|
||||
lockdep_assert_held(&local->chanctx_mtx);
|
||||
|
||||
@ -72,7 +72,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
/*
|
||||
* using reservation isn't immediate as it may be deferred until later
|
||||
* with multi-vif. once reservation is complete it will re-schedule the
|
||||
@@ -3612,7 +3623,7 @@ static int __ieee80211_csa_finalize(stru
|
||||
@@ -3613,7 +3624,7 @@ static int __ieee80211_csa_finalize(stru
|
||||
return err;
|
||||
|
||||
cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0,
|
||||
@ -81,7 +81,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3874,9 +3885,13 @@ __ieee80211_channel_switch(struct wiphy
|
||||
@@ -3875,9 +3886,13 @@ __ieee80211_channel_switch(struct wiphy
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
if (sdata->deflink.csa_block_tx)
|
||||
ieee80211_stop_vif_queues(local, sdata,
|
||||
@@ -3884,7 +3899,8 @@ __ieee80211_channel_switch(struct wiphy
|
||||
@@ -3885,7 +3900,8 @@ __ieee80211_channel_switch(struct wiphy
|
||||
|
||||
cfg80211_ch_switch_started_notify(sdata->dev,
|
||||
&sdata->deflink.csa_chandef, 0,
|
||||
|
@ -132,7 +132,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -521,7 +521,7 @@ static void ieee80211_do_stop(struct iee
|
||||
@@ -542,7 +542,7 @@ static void ieee80211_do_stop(struct iee
|
||||
cancel_work_sync(&sdata->recalc_smps);
|
||||
|
||||
sdata_lock(sdata);
|
||||
@ -141,7 +141,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
"destroying interface with valid links 0x%04x\n",
|
||||
sdata->vif.valid_links);
|
||||
|
||||
@@ -1834,7 +1834,7 @@ static int ieee80211_runtime_change_ifty
|
||||
@@ -1855,7 +1855,7 @@ static int ieee80211_runtime_change_ifty
|
||||
return -EBUSY;
|
||||
|
||||
/* for now, don't support changing while links exist */
|
||||
|
@ -1,69 +0,0 @@
|
||||
From 1b7c710a8e912d54a24742ed5a87a047be64141a Mon Sep 17 00:00:00 2001
|
||||
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Date: Tue, 7 Feb 2023 17:11:46 +0530
|
||||
Subject: [PATCH 350/351] wifi: mac80211: Allow NSS change only up to
|
||||
capability
|
||||
|
||||
Stations can update bandwidth/NSS change in
|
||||
VHT action frame with action type Operating Mode Notification.
|
||||
(IEEE Std 802.11-2020 - 9.4.1.53 Operating Mode field)
|
||||
|
||||
For Operating Mode Notification, an RX NSS change to a value
|
||||
greater than AP's maximum NSS should not be allowed.
|
||||
During fuzz testing, by forcefully sending VHT Op. mode notif.
|
||||
frames from STA with random rx_nss values, it is found that AP
|
||||
accepts rx_nss values greater that APs maximum NSS instead of
|
||||
discarding such NSS change.
|
||||
|
||||
Hence allow NSS change only up to maximum NSS that is negotiated
|
||||
and capped to AP's capability during association.
|
||||
|
||||
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230207114146.10567-1-quic_ramess@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
(cherry picked from commit 57b341e9ab13e5688491bfd54f8b5502416c8905)
|
||||
---
|
||||
net/mac80211/vht.c | 25 ++++++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/net/mac80211/vht.c
|
||||
+++ b/net/mac80211/vht.c
|
||||
@@ -637,7 +637,7 @@ u32 __ieee80211_vht_handle_opmode(struct
|
||||
enum ieee80211_sta_rx_bandwidth new_bw;
|
||||
struct sta_opmode_info sta_opmode = {};
|
||||
u32 changed = 0;
|
||||
- u8 nss;
|
||||
+ u8 nss, cur_nss;
|
||||
|
||||
/* ignore - no support for BF yet */
|
||||
if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
|
||||
@@ -648,10 +648,25 @@ u32 __ieee80211_vht_handle_opmode(struct
|
||||
nss += 1;
|
||||
|
||||
if (link_sta->pub->rx_nss != nss) {
|
||||
- link_sta->pub->rx_nss = nss;
|
||||
- sta_opmode.rx_nss = nss;
|
||||
- changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
- sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
|
||||
+ cur_nss = link_sta->pub->rx_nss;
|
||||
+ /* Reset rx_nss and call ieee80211_sta_set_rx_nss() which
|
||||
+ * will set the same to max nss value calculated based on capability.
|
||||
+ */
|
||||
+ link_sta->pub->rx_nss = 0;
|
||||
+ ieee80211_sta_set_rx_nss(link_sta);
|
||||
+ /* Do not allow an nss change to rx_nss greater than max_nss
|
||||
+ * negotiated and capped to APs capability during association.
|
||||
+ */
|
||||
+ if (nss <= link_sta->pub->rx_nss) {
|
||||
+ link_sta->pub->rx_nss = nss;
|
||||
+ sta_opmode.rx_nss = nss;
|
||||
+ changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
+ sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
|
||||
+ } else {
|
||||
+ link_sta->pub->rx_nss = cur_nss;
|
||||
+ pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d",
|
||||
+ link_sta->pub->addr, nss);
|
||||
+ }
|
||||
}
|
||||
|
||||
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
|
@ -1,186 +0,0 @@
|
||||
From 32d043fc10f1814e421c0ff90c0ee6b303f2821c Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Wed, 28 Feb 2024 12:01:57 +0100
|
||||
Subject: [PATCH 351/351] wifi: mac80211: track capability/opmode NSS
|
||||
separately
|
||||
|
||||
We're currently tracking rx_nss for each station, and that
|
||||
is meant to be initialized to the capability NSS and later
|
||||
reduced by the operating mode notification NSS.
|
||||
|
||||
However, we're mixing up capabilities and operating mode
|
||||
NSS in the same variable. This forces us to recalculate
|
||||
the NSS capability on operating mode notification RX,
|
||||
which is a bit strange; due to the previous fix I had to
|
||||
never keep rx_nss as zero, it also means that the capa is
|
||||
never taken into account properly.
|
||||
|
||||
Fix all this by storing the capability value, that can be
|
||||
recalculated unconditionally whenever needed, and storing
|
||||
the operating mode notification NSS separately, taking it
|
||||
into account when assigning the final rx_nss value.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: dd6c064cfc3f ("wifi: mac80211: set station RX-NSS on reconfig")
|
||||
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
|
||||
Link: https://msgid.link/20240228120157.0e1c41924d1d.I0acaa234e0267227b7e3ef81a59117c8792116bc@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
(cherry picked from commit a8bca3e9371dc5e276af4168be099b2a05554c2a)
|
||||
---
|
||||
net/mac80211/cfg.c | 2 +-
|
||||
net/mac80211/ieee80211_i.h | 2 +-
|
||||
net/mac80211/rate.c | 2 +-
|
||||
net/mac80211/sta_info.h | 6 ++++-
|
||||
net/mac80211/vht.c | 46 ++++++++++++++++++--------------------
|
||||
5 files changed, 30 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1836,7 +1836,7 @@ static int sta_link_apply_parameters(str
|
||||
sband->band);
|
||||
}
|
||||
|
||||
- ieee80211_sta_set_rx_nss(link_sta);
|
||||
+ ieee80211_sta_init_nss(link_sta);
|
||||
|
||||
return ret;
|
||||
}
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -2103,7 +2103,7 @@ enum ieee80211_sta_rx_bandwidth
|
||||
ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta);
|
||||
enum ieee80211_sta_rx_bandwidth
|
||||
ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta);
|
||||
-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta);
|
||||
+void ieee80211_sta_init_nss(struct link_sta_info *link_sta);
|
||||
enum ieee80211_sta_rx_bandwidth
|
||||
ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
|
||||
enum nl80211_chan_width
|
||||
--- a/net/mac80211/rate.c
|
||||
+++ b/net/mac80211/rate.c
|
||||
@@ -37,7 +37,7 @@ void rate_control_rate_init(struct sta_i
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
|
||||
- ieee80211_sta_set_rx_nss(&sta->deflink);
|
||||
+ ieee80211_sta_init_nss(&sta->deflink);
|
||||
|
||||
if (!ref)
|
||||
return;
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright 2002-2005, Devicescape Software, Inc.
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
- * Copyright(c) 2020-2022 Intel Corporation
|
||||
+ * Copyright(c) 2020-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef STA_INFO_H
|
||||
@@ -485,6 +485,8 @@ struct ieee80211_fragment_cache {
|
||||
* same for non-MLD STA. This is used as key for searching link STA
|
||||
* @link_id: Link ID uniquely identifying the link STA. This is 0 for non-MLD
|
||||
* and set to the corresponding vif LinkId for MLD STA
|
||||
+ * @op_mode_nss: NSS limit as set by operating mode notification, or 0
|
||||
+ * @capa_nss: NSS limit as determined by local and peer capabilities
|
||||
* @link_hash_node: hash node for rhashtable
|
||||
* @sta: Points to the STA info
|
||||
* @gtk: group keys negotiated with this station, if any
|
||||
@@ -520,6 +522,8 @@ struct link_sta_info {
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 link_id;
|
||||
|
||||
+ u8 op_mode_nss, capa_nss;
|
||||
+
|
||||
struct rhlist_head link_hash_node;
|
||||
|
||||
struct sta_info *sta;
|
||||
--- a/net/mac80211/vht.c
|
||||
+++ b/net/mac80211/vht.c
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Portions of this file
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
- * Copyright (C) 2018 - 2023 Intel Corporation
|
||||
+ * Copyright (C) 2018 - 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
@@ -541,15 +541,11 @@ ieee80211_sta_cur_vht_bw(struct link_sta
|
||||
return bw;
|
||||
}
|
||||
|
||||
-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta)
|
||||
+void ieee80211_sta_init_nss(struct link_sta_info *link_sta)
|
||||
{
|
||||
u8 ht_rx_nss = 0, vht_rx_nss = 0, he_rx_nss = 0, eht_rx_nss = 0, rx_nss;
|
||||
bool support_160;
|
||||
|
||||
- /* if we received a notification already don't overwrite it */
|
||||
- if (link_sta->pub->rx_nss)
|
||||
- return;
|
||||
-
|
||||
if (link_sta->pub->eht_cap.has_eht) {
|
||||
int i;
|
||||
const u8 *rx_nss_mcs = (void *)&link_sta->pub->eht_cap.eht_mcs_nss_supp;
|
||||
@@ -627,7 +623,15 @@ void ieee80211_sta_set_rx_nss(struct lin
|
||||
rx_nss = max(vht_rx_nss, ht_rx_nss);
|
||||
rx_nss = max(he_rx_nss, rx_nss);
|
||||
rx_nss = max(eht_rx_nss, rx_nss);
|
||||
- link_sta->pub->rx_nss = max_t(u8, 1, rx_nss);
|
||||
+ rx_nss = max_t(u8, 1, rx_nss);
|
||||
+ link_sta->capa_nss = rx_nss;
|
||||
+
|
||||
+ /* that shouldn't be set yet, but we can handle it anyway */
|
||||
+ if (link_sta->op_mode_nss)
|
||||
+ link_sta->pub->rx_nss =
|
||||
+ min_t(u8, rx_nss, link_sta->op_mode_nss);
|
||||
+ else
|
||||
+ link_sta->pub->rx_nss = rx_nss;
|
||||
}
|
||||
|
||||
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||
@@ -637,7 +641,7 @@ u32 __ieee80211_vht_handle_opmode(struct
|
||||
enum ieee80211_sta_rx_bandwidth new_bw;
|
||||
struct sta_opmode_info sta_opmode = {};
|
||||
u32 changed = 0;
|
||||
- u8 nss, cur_nss;
|
||||
+ u8 nss;
|
||||
|
||||
/* ignore - no support for BF yet */
|
||||
if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
|
||||
@@ -647,23 +651,17 @@ u32 __ieee80211_vht_handle_opmode(struct
|
||||
nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
|
||||
nss += 1;
|
||||
|
||||
- if (link_sta->pub->rx_nss != nss) {
|
||||
- cur_nss = link_sta->pub->rx_nss;
|
||||
- /* Reset rx_nss and call ieee80211_sta_set_rx_nss() which
|
||||
- * will set the same to max nss value calculated based on capability.
|
||||
- */
|
||||
- link_sta->pub->rx_nss = 0;
|
||||
- ieee80211_sta_set_rx_nss(link_sta);
|
||||
- /* Do not allow an nss change to rx_nss greater than max_nss
|
||||
- * negotiated and capped to APs capability during association.
|
||||
- */
|
||||
- if (nss <= link_sta->pub->rx_nss) {
|
||||
- link_sta->pub->rx_nss = nss;
|
||||
- sta_opmode.rx_nss = nss;
|
||||
- changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
- sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
|
||||
+ if (link_sta->op_mode_nss != nss) {
|
||||
+ if (nss <= link_sta->capa_nss) {
|
||||
+ link_sta->op_mode_nss = nss;
|
||||
+
|
||||
+ if (nss != link_sta->pub->rx_nss) {
|
||||
+ link_sta->pub->rx_nss = nss;
|
||||
+ changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
+ sta_opmode.rx_nss = link_sta->pub->rx_nss;
|
||||
+ sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
|
||||
+ }
|
||||
} else {
|
||||
- link_sta->pub->rx_nss = cur_nss;
|
||||
pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d",
|
||||
link_sta->pub->addr, nss);
|
||||
}
|
@ -56,7 +56,7 @@
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3078,6 +3078,19 @@ static int ieee80211_get_tx_power(struct
|
||||
@@ -3079,6 +3079,19 @@ static int ieee80211_get_tx_power(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
static void ieee80211_rfkill_poll(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
@@ -5008,6 +5021,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
@@ -5009,6 +5022,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_wiphy_params = ieee80211_set_wiphy_params,
|
||||
.set_tx_power = ieee80211_set_tx_power,
|
||||
.get_tx_power = ieee80211_get_tx_power,
|
||||
@ -128,7 +128,7 @@
|
||||
local->hw.max_mtu = IEEE80211_MAX_DATA_LEN;
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -820,6 +820,7 @@ static const struct nla_policy nl80211_p
|
||||
@@ -830,6 +830,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
|
||||
[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
|
||||
@ -136,7 +136,7 @@
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -3547,6 +3548,22 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
@@ -3584,6 +3585,22 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
if (result)
|
||||
goto out;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -2368,6 +2368,13 @@ static void sta_stats_decode_rate(struct
|
||||
@@ -2382,6 +2382,13 @@ static void sta_stats_decode_rate(struct
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user