wifi: nl80211: retrieve EHT related elements in AP mode
authorAloka Dixit <quic_alokad@quicinc.com>
Mon, 23 May 2022 06:49:04 +0000 (23:49 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 1 Jul 2022 10:37:54 +0000 (12:37 +0200)
Add support to retrieve EHT capabilities and EHT operation elements
passed by the userspace in the beacon template and store the pointers
in struct cfg80211_ap_settings to be used by the drivers.

Co-developed-by: Vikram Kandukuri <quic_vikram@quicinc.com>
Signed-off-by: Vikram Kandukuri <quic_vikram@quicinc.com>
Co-developed-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Link: https://lore.kernel.org/r/20220523064904.28523-1-quic_alokad@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/wireless/nl80211.c

index 6bc161d653f39faebda87e1a65b08dbb28d4b034..140354f5f15b87961074ecf7ef99ad7b9cd6c482 100644 (file)
@@ -1296,6 +1296,8 @@ struct cfg80211_unsol_bcast_probe_resp {
  * @ht_cap: HT capabilities (or %NULL if HT isn't enabled)
  * @vht_cap: VHT capabilities (or %NULL if VHT isn't enabled)
  * @he_cap: HE capabilities (or %NULL if HE isn't enabled)
+ * @eht_cap: EHT capabilities (or %NULL if EHT isn't enabled)
+ * @eht_oper: EHT operation IE (or %NULL if EHT isn't enabled)
  * @ht_required: stations must support HT
  * @vht_required: stations must support VHT
  * @twt_responder: Enable Target Wait Time
@@ -1332,6 +1334,8 @@ struct cfg80211_ap_settings {
        const struct ieee80211_vht_cap *vht_cap;
        const struct ieee80211_he_cap_elem *he_cap;
        const struct ieee80211_he_operation *he_oper;
+       const struct ieee80211_eht_cap_elem *eht_cap;
+       const struct ieee80211_eht_operation *eht_oper;
        bool ht_required, vht_required, he_required, sae_h2e_required;
        bool twt_responder;
        u32 flags;
index e2b6740268a6424316f3bdf1d5e22cf75192b74f..eda2ad029c90c2810b9399a4f124a6b31d829604 100644 (file)
@@ -5522,7 +5522,7 @@ static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
  * HT/VHT requirements/capabilities, we parse them out of the IEs for the
  * benefit of drivers that rebuild IEs in the firmware.
  */
-static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
+static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
 {
        const struct cfg80211_beacon_data *bcn = &params->beacon;
        size_t ies_len = bcn->tail_len;
@@ -5548,6 +5548,26 @@ static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
        cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
        if (cap && cap->datalen >= sizeof(*params->he_oper) + 1)
                params->he_oper = (void *)(cap->data + 1);
+       cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_CAPABILITY, ies, ies_len);
+       if (cap) {
+               if (!cap->datalen)
+                       return -EINVAL;
+               params->eht_cap = (void *)(cap->data + 1);
+               if (!ieee80211_eht_capa_size_ok((const u8 *)params->he_cap,
+                                               (const u8 *)params->eht_cap,
+                                               cap->datalen - 1))
+                       return -EINVAL;
+       }
+       cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION, ies, ies_len);
+       if (cap) {
+               if (!cap->datalen)
+                       return -EINVAL;
+               params->eht_oper = (void *)(cap->data + 1);
+               if (!ieee80211_eht_oper_size_ok((const u8 *)params->eht_oper,
+                                               cap->datalen - 1))
+                       return -EINVAL;
+       }
+       return 0;
 }
 
 static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
@@ -5873,7 +5893,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
                        goto out_unlock;
        }
 
-       nl80211_calculate_ap_params(params);
+       err = nl80211_calculate_ap_params(params);
+       if (err)
+               goto out_unlock;
 
        if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS])
                params->flags = nla_get_u32(