@@ -1376,6 +1376,89 @@ static void ath11k_mac_setup_bcn_tmpl_vif_params(struct ath11k_vif *arvif,
arvif->wpaie_present = false;
}
+static void ath11k_mac_setup_bcn_tmpl_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_setup_bcn_tmpl_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;
+
+ if (arvif == tx_arvif)
+ return true;
+
+ arvif->rsnie_present = tx_arvif->rsnie_present;
+
+ 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);
+
+ 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_bcn_tmpl_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 int __ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif,
struct sk_buff *bcn,
struct ieee80211_mutable_offsets offs,
@@ -1402,6 +1485,7 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
struct ieee80211_ema_beacons *beacons;
u8 i = 0;
int ret = 0;
+ bool found_vdev = false;
if (!arvif->vif->mbssid_tx_vif)
return -1;
@@ -1415,11 +1499,21 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
return -EPERM;
}
- if (tx_arvif == arvif)
+ if (tx_arvif == arvif) {
ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif,
beacons->bcn[0].skb);
+ found_vdev = true;
+ } else {
+ arvif->wpaie_present = tx_arvif->wpaie_present;
+ }
for (i = 0; i < beacons->cnt; i++) {
+ if (!found_vdev)
+ found_vdev =
+ ath11k_mac_setup_bcn_tmpl_nontx_vif_params(tx_arvif,
+ arvif,
+ beacons->bcn[i].skb);
+
ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, beacons->bcn[i].skb,
beacons->bcn[i].offs,
i, beacons->cnt);
@@ -1455,6 +1549,9 @@ static int ath11k_mac_setup_bcn_tmpl_non_ema(struct ath11k_vif *arvif)
if (tx_arvif == arvif)
ath11k_mac_setup_bcn_tmpl_vif_params(tx_arvif, bcn);
+ else
+ (void)ath11k_mac_setup_bcn_tmpl_nontx_vif_params(tx_arvif,
+ arvif, bcn);
ret = __ath11k_mac_setup_bcn_tmpl(tx_arvif, bcn, offs, 0, 0);
if (ret)
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> --- drivers/net/wireless/ath/ath11k/mac.c | 99 ++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-)