mac80211: ath11k: sync with ath-next
[openwrt/staging/hauke.git] / package / kernel / mac80211 / patches / ath11k / 0076-wifi-ath11k-MBSSID-beacon-support.patch
1 From 335a92765d308dfe22826f5562cd4b4389b45e71 Mon Sep 17 00:00:00 2001
2 From: Aloka Dixit <quic_alokad@quicinc.com>
3 Date: Fri, 5 May 2023 16:11:28 +0300
4 Subject: [PATCH 76/77] wifi: ath11k: MBSSID beacon support
5
6 - Split ath11k_mac_setup_bcn_tmpl() to move the beacon retrieval and
7 WMI command to a new function, ath11k_mac_setup_bcn_tmpl_legacy().
8 In the original function add checks to use the transmitting interface
9 when MBSSID is enabled.
10 - Set rsnie_present and wpaie_present fields for the non-transmitting
11 interfaces when MBSSID is enabled.
12
13 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
14
15 Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
16 Co-developed-by: John Crispin <john@phrozen.org>
17 Signed-off-by: John Crispin <john@phrozen.org>
18 Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
19 Link: https://lore.kernel.org/r/20230405221648.17950-7-quic_alokad@quicinc.com
20 ---
21 drivers/net/wireless/ath/ath11k/mac.c | 116 ++++++++++++++++++++++++--
22 drivers/net/wireless/ath/ath11k/wmi.c | 1 +
23 2 files changed, 112 insertions(+), 5 deletions(-)
24
25 --- a/drivers/net/wireless/ath/ath11k/mac.c
26 +++ b/drivers/net/wireless/ath/ath11k/mac.c
27 @@ -1351,6 +1351,84 @@ err_mon_del:
28 return ret;
29 }
30
31 +static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif,
32 + bool tx_arvif_rsnie_present,
33 + const u8 *profile, u8 profile_len)
34 +{
35 + if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {
36 + arvif->rsnie_present = true;
37 + } else if (tx_arvif_rsnie_present) {
38 + int i;
39 + u8 nie_len;
40 + const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,
41 + profile, profile_len);
42 + if (!nie)
43 + return;
44 +
45 + nie_len = nie[1];
46 + nie += 2;
47 + for (i = 0; i < nie_len; i++) {
48 + if (nie[i] == WLAN_EID_RSN) {
49 + arvif->rsnie_present = false;
50 + break;
51 + }
52 + }
53 + }
54 +}
55 +
56 +static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
57 + struct ath11k_vif *arvif,
58 + struct sk_buff *bcn)
59 +{
60 + struct ieee80211_mgmt *mgmt;
61 + const u8 *ies, *profile, *next_profile;
62 + int ies_len;
63 +
64 + ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
65 + mgmt = (struct ieee80211_mgmt *)bcn->data;
66 + ies += sizeof(mgmt->u.beacon);
67 + ies_len = skb_tail_pointer(bcn) - ies;
68 +
69 + ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);
70 + arvif->rsnie_present = tx_arvif->rsnie_present;
71 +
72 + while (ies) {
73 + u8 mbssid_len;
74 +
75 + ies_len -= (2 + ies[1]);
76 + mbssid_len = ies[1] - 1;
77 + profile = &ies[3];
78 +
79 + while (mbssid_len) {
80 + u8 profile_len;
81 +
82 + profile_len = profile[1];
83 + next_profile = profile + (2 + profile_len);
84 + mbssid_len -= (2 + profile_len);
85 +
86 + profile += 2;
87 + profile_len -= (2 + profile[1]);
88 + profile += (2 + profile[1]); /* nontx capabilities */
89 + profile_len -= (2 + profile[1]);
90 + profile += (2 + profile[1]); /* SSID */
91 + if (profile[2] == arvif->vif->bss_conf.bssid_index) {
92 + profile_len -= 5;
93 + profile = profile + 5;
94 + ath11k_mac_setup_nontx_vif_rsnie(arvif,
95 + tx_arvif->rsnie_present,
96 + profile,
97 + profile_len);
98 + return true;
99 + }
100 + profile = next_profile;
101 + }
102 + ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,
103 + ies_len);
104 + }
105 +
106 + return false;
107 +}
108 +
109 static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
110 struct sk_buff *bcn)
111 {
112 @@ -1374,18 +1452,26 @@ static void ath11k_mac_set_vif_params(st
113 arvif->wpaie_present = false;
114 }
115
116 -static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
117 +static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
118 {
119 struct ath11k *ar = arvif->ar;
120 struct ath11k_base *ab = ar->ab;
121 + struct ath11k_vif *tx_arvif = arvif;
122 struct ieee80211_hw *hw = ar->hw;
123 struct ieee80211_vif *vif = arvif->vif;
124 struct ieee80211_mutable_offsets offs = {};
125 struct sk_buff *bcn;
126 int ret;
127
128 - if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
129 - return 0;
130 + if (arvif->vif->mbssid_tx_vif) {
131 + tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
132 + if (tx_arvif != arvif) {
133 + ar = tx_arvif->ar;
134 + ab = ar->ab;
135 + hw = ar->hw;
136 + vif = tx_arvif->vif;
137 + }
138 + }
139
140 bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
141 if (!bcn) {
142 @@ -1393,9 +1479,12 @@ static int ath11k_mac_setup_bcn_tmpl(str
143 return -EPERM;
144 }
145
146 - ath11k_mac_set_vif_params(arvif, bcn);
147 - ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
148 + if (tx_arvif == arvif)
149 + ath11k_mac_set_vif_params(tx_arvif, bcn);
150 + else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
151 + return -EINVAL;
152
153 + ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
154 kfree_skb(bcn);
155
156 if (ret)
157 @@ -1405,6 +1494,23 @@ static int ath11k_mac_setup_bcn_tmpl(str
158 return ret;
159 }
160
161 +static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
162 +{
163 + struct ieee80211_vif *vif = arvif->vif;
164 +
165 + if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
166 + return 0;
167 +
168 + /* Target does not expect beacon templates for the already up
169 + * non-transmitting interfaces, and results in a crash if sent.
170 + */
171 + if (vif->mbssid_tx_vif &&
172 + arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up)
173 + return 0;
174 +
175 + return ath11k_mac_setup_bcn_tmpl_mbssid(arvif);
176 +}
177 +
178 void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
179 {
180 struct ieee80211_vif *vif = arvif->vif;
181 --- a/drivers/net/wireless/ath/ath11k/wmi.c
182 +++ b/drivers/net/wireless/ath/ath11k/wmi.c
183 @@ -1737,6 +1737,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a
184 }
185
186 cmd->buf_len = bcn->len;
187 + cmd->mbssid_ie_offset = offs->mbssid_off;
188
189 ptr = skb->data + sizeof(*cmd);
190