aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch')
-rw-r--r--package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch190
1 files changed, 190 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch b/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch
new file mode 100644
index 0000000000..d23ea8deea
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch
@@ -0,0 +1,190 @@
+From 335a92765d308dfe22826f5562cd4b4389b45e71 Mon Sep 17 00:00:00 2001
+From: Aloka Dixit <quic_alokad@quicinc.com>
+Date: Fri, 5 May 2023 16:11:28 +0300
+Subject: [PATCH 76/77] wifi: ath11k: MBSSID beacon support
+
+- Split ath11k_mac_setup_bcn_tmpl() to move the beacon retrieval and
+ WMI command to a new function, ath11k_mac_setup_bcn_tmpl_legacy().
+ In the original function add checks to use the transmitting interface
+ when MBSSID is enabled.
+- Set rsnie_present and wpaie_present fields for the non-transmitting
+ interfaces when MBSSID is enabled.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
+Co-developed-by: John Crispin <john@phrozen.org>
+Signed-off-by: John Crispin <john@phrozen.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230405221648.17950-7-quic_alokad@quicinc.com
+---
+ drivers/net/wireless/ath/ath11k/mac.c | 116 ++++++++++++++++++++++++--
+ drivers/net/wireless/ath/ath11k/wmi.c | 1 +
+ 2 files changed, 112 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -1351,6 +1351,84 @@ err_mon_del:
+ return ret;
+ }
+
++static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif,
++ bool tx_arvif_rsnie_present,
++ const u8 *profile, u8 profile_len)
++{
++ if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {
++ arvif->rsnie_present = true;
++ } else if (tx_arvif_rsnie_present) {
++ int i;
++ u8 nie_len;
++ const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,
++ profile, profile_len);
++ if (!nie)
++ return;
++
++ nie_len = nie[1];
++ nie += 2;
++ for (i = 0; i < nie_len; i++) {
++ if (nie[i] == WLAN_EID_RSN) {
++ arvif->rsnie_present = false;
++ break;
++ }
++ }
++ }
++}
++
++static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
++ struct ath11k_vif *arvif,
++ struct sk_buff *bcn)
++{
++ struct ieee80211_mgmt *mgmt;
++ const u8 *ies, *profile, *next_profile;
++ int ies_len;
++
++ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
++ mgmt = (struct ieee80211_mgmt *)bcn->data;
++ ies += sizeof(mgmt->u.beacon);
++ ies_len = skb_tail_pointer(bcn) - ies;
++
++ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);
++ arvif->rsnie_present = tx_arvif->rsnie_present;
++
++ while (ies) {
++ u8 mbssid_len;
++
++ ies_len -= (2 + ies[1]);
++ mbssid_len = ies[1] - 1;
++ profile = &ies[3];
++
++ while (mbssid_len) {
++ u8 profile_len;
++
++ profile_len = profile[1];
++ next_profile = profile + (2 + profile_len);
++ mbssid_len -= (2 + profile_len);
++
++ profile += 2;
++ profile_len -= (2 + profile[1]);
++ profile += (2 + profile[1]); /* nontx capabilities */
++ profile_len -= (2 + profile[1]);
++ profile += (2 + profile[1]); /* SSID */
++ if (profile[2] == arvif->vif->bss_conf.bssid_index) {
++ profile_len -= 5;
++ profile = profile + 5;
++ ath11k_mac_setup_nontx_vif_rsnie(arvif,
++ tx_arvif->rsnie_present,
++ profile,
++ profile_len);
++ return true;
++ }
++ profile = next_profile;
++ }
++ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,
++ ies_len);
++ }
++
++ return false;
++}
++
+ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
+ struct sk_buff *bcn)
+ {
+@@ -1374,18 +1452,26 @@ static void ath11k_mac_set_vif_params(st
+ arvif->wpaie_present = false;
+ }
+
+-static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
++static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
+ {
+ struct ath11k *ar = arvif->ar;
+ struct ath11k_base *ab = ar->ab;
++ struct ath11k_vif *tx_arvif = arvif;
+ struct ieee80211_hw *hw = ar->hw;
+ struct ieee80211_vif *vif = arvif->vif;
+ struct ieee80211_mutable_offsets offs = {};
+ struct sk_buff *bcn;
+ int ret;
+
+- if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
+- return 0;
++ if (arvif->vif->mbssid_tx_vif) {
++ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
++ if (tx_arvif != arvif) {
++ ar = tx_arvif->ar;
++ ab = ar->ab;
++ hw = ar->hw;
++ vif = tx_arvif->vif;
++ }
++ }
+
+ bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
+ if (!bcn) {
+@@ -1393,9 +1479,12 @@ static int ath11k_mac_setup_bcn_tmpl(str
+ return -EPERM;
+ }
+
+- ath11k_mac_set_vif_params(arvif, bcn);
+- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
++ if (tx_arvif == arvif)
++ ath11k_mac_set_vif_params(tx_arvif, bcn);
++ else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
++ return -EINVAL;
+
++ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
+ kfree_skb(bcn);
+
+ if (ret)
+@@ -1405,6 +1494,23 @@ static int ath11k_mac_setup_bcn_tmpl(str
+ return ret;
+ }
+
++static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
++{
++ struct ieee80211_vif *vif = arvif->vif;
++
++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
++ return 0;
++
++ /* Target does not expect beacon templates for the already up
++ * non-transmitting interfaces, and results in a crash if sent.
++ */
++ if (vif->mbssid_tx_vif &&
++ arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up)
++ return 0;
++
++ return ath11k_mac_setup_bcn_tmpl_mbssid(arvif);
++}
++
+ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
+ {
+ struct ieee80211_vif *vif = arvif->vif;
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -1737,6 +1737,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a
+ }
+
+ cmd->buf_len = bcn->len;
++ cmd->mbssid_ie_offset = offs->mbssid_off;
+
+ ptr = skb->data + sizeof(*cmd);
+