123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- 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);
-
|