From ec1bd31ce7521bb3210b12736855eccb1bdc47f3 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Thu, 19 Mar 2020 14:17:46 +0530 Subject: [PATCH] qcacld-3.0: BIGTK feature support BIGTK feature support Change-Id: Ide9b0db436e43152a4180a460f21a7340b443756 CRs-Fixed: 2648269 --- components/mlme/core/inc/wlan_mlme_main.h | 2 + .../core/inc/wlan_mlme_vdev_mgr_interface.h | 4 ++ .../core/src/wlan_mlme_vdev_mgr_interface.c | 28 ++++++++++ .../mlme/dispatcher/inc/wlan_mlme_api.h | 10 ++++ .../dispatcher/inc/wlan_mlme_public_struct.h | 4 ++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 17 +++++++ .../mlme/dispatcher/src/wlan_mlme_api.c | 15 ++++++ core/hdd/src/wlan_hdd_cfg80211.c | 51 +++++++++++++++++++ core/hdd/src/wlan_hdd_hostapd.c | 24 +++++++++ core/hdd/src/wlan_hdd_main.c | 4 ++ core/mac/src/include/parser_api.h | 3 ++ .../src/sys/legacy/src/utils/src/parser_api.c | 2 + core/sme/inc/csr_api.h | 4 +- core/wma/src/wma_main.c | 5 ++ core/wma/src/wma_mgmt.c | 2 + 15 files changed, 173 insertions(+), 2 deletions(-) diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 8326baffa1..dd43b5064f 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -139,6 +139,7 @@ struct wlan_mlme_roam { * @disconnect_info: Disconnection information * @vdev_stop_type: vdev stop type request * @roam_off_state: Roam offload state + * @bigtk_vdev_support: BIGTK feature support for this vdev (SAP) */ struct mlme_legacy_priv { bool chan_switch_in_progress; @@ -155,6 +156,7 @@ struct mlme_legacy_priv { struct wlan_disconnect_info disconnect_info; uint32_t vdev_stop_type; struct wlan_mlme_roam mlme_roam; + bool bigtk_vdev_support; }; /** diff --git a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h index 6186a5c7b1..8db94c1537 100644 --- a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h +++ b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h @@ -111,6 +111,10 @@ mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val); */ bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev); +QDF_STATUS mlme_set_bigtk_support(struct wlan_objmgr_vdev *vdev, bool val); + +bool mlme_get_bigtk_support(struct wlan_objmgr_vdev *vdev); + /** * mlme_set_connection_fail() - set connection failure flag * @vdev: vdev pointer diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index 1812ef15bf..db70cac88e 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -628,6 +628,34 @@ bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev) return mlme_priv->hidden_ssid_restart_in_progress; } +QDF_STATUS mlme_set_bigtk_support(struct wlan_objmgr_vdev *vdev, bool val) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv->bigtk_vdev_support = val; + + return QDF_STATUS_SUCCESS; +} + +bool mlme_get_bigtk_support(struct wlan_objmgr_vdev *vdev) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return false; + } + + return mlme_priv->bigtk_vdev_support; +} + QDF_STATUS mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val) { struct mlme_legacy_priv *mlme_priv; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 73c83a2a82..8aa54b8bbe 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -794,6 +794,16 @@ QDF_STATUS wlan_mlme_set_sap_11ac_override(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value); +/** + * wlan_mlme_get_bigtk_support() - Get the BIGTK support + * @psoc: pointer to psoc object + * @value: pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS wlan_mlme_get_bigtk_support(struct wlan_objmgr_psoc *psoc, + bool *value); + /** * wlan_mlme_get_oce_sap_enabled_info() - Get the OCE feature enable * info for SAP diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 00078eb233..afb73cc59d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -951,12 +951,14 @@ struct wlan_mlme_chain_cfg { /** * struct mlme_tgt_caps - mlme related capability coming from target (FW) * @data_stall_recovery_fw_support: does target supports data stall recovery. + * @bigtk_support: does the target support bigtk capability or not. * * Add all the mlme-tgt related capablities here, and the public API would fill * the related capability in the required mlme cfg structure. */ struct mlme_tgt_caps { bool data_stall_recovery_fw_support; + bool bigtk_support; }; /** @@ -1134,6 +1136,7 @@ struct wlan_mlme_chainmask { * @enable_ring_buffer: Decide to enable/disable ring buffer for bug report * @enable_peer_unmap_conf_support: Indicate whether to send conf for peer unmap * @dfs_chan_ageout_time: Set DFS Channel ageout time + * @bigtk_support: Whether BIGTK is supported or not */ struct wlan_mlme_generic { enum band_info band_capability; @@ -1170,6 +1173,7 @@ struct wlan_mlme_generic { bool enable_ring_buffer; bool enable_peer_unmap_conf_support; uint8_t dfs_chan_ageout_time; + bool bigtk_support; }; /* diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 5242c10a03..dcc05629a7 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1835,6 +1835,23 @@ QDF_STATUS ucfg_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, return wlan_mlme_get_oce_sta_enabled_info(psoc, value); } +/** + * ucfg_mlme_get_bigtk_support() - Get whether bigtk is supported or not. + * + * @psoc: pointer to psoc object + * @value: pointer to the value which will be filled for the caller + * + * Inline UCFG API to be used by HDD/OSIF callers to get the BIGTK support + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE + */ +static inline +QDF_STATUS ucfg_mlme_get_bigtk_support(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + return wlan_mlme_get_bigtk_support(psoc, value); +} + /** * ucfg_mlme_get_oce_sap_enabled_info() - Get OCE feature enable/disable * info for SAP diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 666fd32ffd..986c08fd3d 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -455,6 +455,8 @@ wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc, mlme_obj->cfg.gen.data_stall_recovery_fw_support = tgt_caps->data_stall_recovery_fw_support; + + mlme_obj->cfg.gen.bigtk_support = tgt_caps->bigtk_support; } #ifdef WLAN_FEATURE_11AX @@ -2021,6 +2023,19 @@ QDF_STATUS wlan_mlme_set_go_11ac_override(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_mlme_get_bigtk_support(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.gen.bigtk_support; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value) { diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 006160c833..f4d6ccdc7b 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14550,6 +14550,17 @@ static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy) } #endif +#if defined(CFG80211_BIGTK_CONFIGURATION_SUPPORT) +static void wlan_hdd_cfg80211_set_bigtk_flags(struct wiphy *wiphy) +{ + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION); +} +#else +static void wlan_hdd_cfg80211_set_bigtk_flags(struct wiphy *wiphy) +{ +} +#endif + #if defined(CFG80211_SCAN_OCE_CAPABILITY_SUPPORT) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) static void wlan_hdd_cfg80211_set_wiphy_oce_scan_flags(struct wiphy *wiphy) @@ -15206,6 +15217,7 @@ void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx) QDF_STATUS status; struct wiphy *wiphy = hdd_ctx->wiphy; uint8_t allow_mcc_go_diff_bi = 0, enable_mcc = 0; + bool is_bigtk_supported; if (!wiphy) { hdd_err("Invalid wiphy"); @@ -15230,6 +15242,13 @@ void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx) if (QDF_IS_STATUS_SUCCESS(status) && dfs_master_capable) wlan_hdd_cfg80211_set_dfs_offload_feature(wiphy); + + status = ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, + &is_bigtk_supported); + + if (QDF_IS_STATUS_SUCCESS(status) && is_bigtk_supported) + wlan_hdd_cfg80211_set_bigtk_flags(wiphy); + status = ucfg_mlme_get_oce_sta_enabled_info(hdd_ctx->psoc, &is_oce_sta_enabled); if (QDF_IS_STATUS_ERROR(status)) @@ -16747,6 +16766,35 @@ static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, return errno; } +#if defined (CFG80211_BIGTK_CONFIGURATION_SUPPORT) +static int _wlan_hdd_cfg80211_set_default_beacon_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index) +{ + hdd_enter(); + return 0; +} + +static int wlan_hdd_cfg80211_set_default_beacon_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(ndev, &vdev_sync); + if (errno) + return errno; + + errno = _wlan_hdd_cfg80211_set_default_beacon_key(wiphy, ndev, + key_index); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} +#endif + void wlan_hdd_cfg80211_unlink_bss(struct hdd_adapter *adapter, tSirMacAddr bssid, uint8_t *ssid, uint8_t ssid_len) @@ -23306,6 +23354,9 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { .mgmt_tx = wlan_hdd_mgmt_tx, .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait, .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key, +#if defined (CFG80211_BIGTK_CONFIGURATION_SUPPORT) + .set_default_beacon_key = wlan_hdd_cfg80211_set_default_beacon_key, +#endif .set_txq_params = wlan_hdd_set_txq_params, .dump_station = wlan_hdd_cfg80211_dump_station, .get_station = wlan_hdd_cfg80211_get_station, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 84b236a1a9..b59696fa82 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5070,6 +5070,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, bool go_force_11n_for_11ac = 0; bool bval = false; bool enable_dfs_scan = true; + struct s_ext_cap *p_ext_cap; hdd_enter(); @@ -5206,6 +5207,29 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, if (adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) { + ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, + beacon->tail, + beacon->tail_len); + if (ie && (ie[0] != DOT11F_EID_EXTCAP || + ie[1] > DOT11F_IE_EXTCAP_MAX_LEN)) { + hdd_err("Invalid IEs eid: %d elem_len: %d", ie[0], + ie[1]); + ret = -EINVAL; + goto error; + } + if (ie) { + bool target_bigtk_support = false; + + p_ext_cap = (struct s_ext_cap *)(&ie[2]); + hdd_err("beacon protection %d", + p_ext_cap->beacon_protection_enable); + ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, + &target_bigtk_support); + if (target_bigtk_support && + p_ext_cap->beacon_protection_enable) + mlme_set_bigtk_support(adapter->vdev, true); + } + ie = wlan_get_ie_ptr_from_eid(WLAN_EID_COUNTRY, beacon->tail, beacon->tail_len); if ((adapter->device_mode == QDF_SAP_MODE) && ie) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 86f6b59476..086b0d0c01 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5002,6 +5002,7 @@ int hdd_vdev_create(struct hdd_adapter *adapter) struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; struct wlan_vdev_create_params vdev_params = {0}; + bool target_bigtk_support = false; hdd_nofl_debug("creating new vdev"); @@ -5082,6 +5083,9 @@ int hdd_vdev_create(struct hdd_adapter *adapter) if (!vdev) goto hdd_vdev_destroy_procedure; wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT); + ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &target_bigtk_support); + if (target_bigtk_support) + mlme_set_bigtk_support(adapter->vdev, true); hdd_objmgr_put_vdev(vdev); } diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index 57c77fe679..5db01c520d 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -584,6 +584,9 @@ struct s_ext_cap { uint8_t reserved7:2; uint8_t twt_requestor_support:1; uint8_t twt_responder_support:1; + uint8_t reserved8: 1; + uint8_t reserved9: 4; + uint8_t beacon_protection_enable: 1; }; void swap_bit_field16(uint16_t in, uint16_t *out); diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 77efa9550f..19776a2223 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -1218,6 +1218,8 @@ populate_dot11f_ext_cap(struct mac_context *mac, if (pe_session && pe_session->is_mbssid_enabled) p_ext_cap->multi_bssid = 1; + p_ext_cap->beacon_protection_enable = pe_session ? + mlme_get_bigtk_support(pe_session->vdev) : false; /* Need to calculate the num_bytes based on bits set */ if (pDot11f->present) pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f); diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index bae1a6448b..79ae79622c 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -602,8 +602,8 @@ typedef enum { } eCsrWEPStaticKeyID; -/* Two extra key indicies are used for the IGTK (which is used by BIP) */ -#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1) +/* Two extra key indicies are used for the IGTK, two for BIGTK */ +#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1 + 2) typedef enum { /* diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 80dd625d6a..ca26008f77 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5361,6 +5361,11 @@ static void wma_update_mlme_related_tgt_caps(struct wlan_objmgr_psoc *psoc, wmi_service_enabled(wmi_handle, wmi_service_data_stall_recovery_support); + mlme_tgt_cfg.bigtk_support = + wmi_service_enabled(wmi_handle, wmi_beacon_protection_support); + + wma_debug("beacon protection support %d", mlme_tgt_cfg.bigtk_support); + /* Call this at last only after filling all the tgt caps */ wlan_mlme_update_cfg_with_tgt_caps(psoc, &mlme_tgt_cfg); } diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 53cf2d369a..e3d50c6f93 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2154,6 +2154,8 @@ static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma, params.tmpl_len = tmpl_len; params.frm = frm; params.tmpl_len_aligned = tmpl_len_aligned; + params.enable_bigtk = + mlme_get_bigtk_support(wma->interfaces[vdev_id].vdev); if (bcn_info->csa_count_offset && (bcn_info->csa_count_offset > bytes_to_strip)) params.csa_switch_count_offset =