Search Linux Wireless

[PATCH v2 10/10] ath11k: configure WPA and RSN parameters for nontransmitting interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx>
---
 drivers/net/wireless/ath/ath11k/mac.c | 99 ++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index a47f24ba767e..766c0cbb4e64 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -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)
-- 
2.17.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux