diff --git a/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h b/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h index b588bb6795..c4ccd79c75 100644 --- a/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h +++ b/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +36,24 @@ int wlan_cfg80211_set_default_key(struct wlan_objmgr_vdev *vdev, uint8_t key_index, struct qdf_mac_addr *bssid); +/** + * wlan_cfg80211_translate_key() - Translate the cfg80211 keys to + * internal + * @vdev: Pointer to vdev object + * @key_index: Key index + * @key_type: key type + * @mac_addr: mac address + * @params: Params + * @crypto_key: Crypto keys + * + * Return: None + */ +void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, + uint8_t key_index, + enum wlan_crypto_key_type key_type, + const u8 *mac_addr, + struct key_params *params, + struct wlan_crypto_key *crypto_key); /** * wlan_cfg80211_store_key() - Store the key diff --git a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c index 01bb13bd8c..5c151b8fa8 100644 --- a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c +++ b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,12 +34,12 @@ #include #include -static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, - uint8_t key_index, - enum wlan_crypto_key_type key_type, - const u8 *mac_addr, - struct key_params *params, - struct wlan_crypto_key *crypto_key) +void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, + uint8_t key_index, + enum wlan_crypto_key_type key_type, + const u8 *mac_addr, + struct key_params *params, + struct wlan_crypto_key *crypto_key) { qdf_mem_zero(crypto_key, sizeof(*crypto_key)); crypto_key->keylen = params->key_len; diff --git a/target_if/crypto/inc/target_if_crypto.h b/target_if/crypto/inc/target_if_crypto.h index 4be54582b1..4b96f5d788 100644 --- a/target_if/crypto/inc/target_if_crypto.h +++ b/target_if/crypto/inc/target_if_crypto.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -45,4 +46,16 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *req, enum wlan_crypto_key_type key_type); +/** + * target_if_crypto_vdev_set_param() - Set crypto related vdev params to fw + * @psoc: Pointer to psoc + * @vdev_id: vdev id + * @param_id: param id + * @param_value: param value + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_crypto_vdev_set_param(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t param_id, uint32_t param_value); #endif diff --git a/target_if/crypto/src/target_if_crypto.c b/target_if/crypto/src/target_if_crypto.c index df7606a116..fa011662bc 100644 --- a/target_if/crypto/src/target_if_crypto.c +++ b/target_if/crypto/src/target_if_crypto.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -131,6 +132,31 @@ static inline void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev, } #endif /* FEATURE_WLAN_WAPI */ +QDF_STATUS +target_if_crypto_vdev_set_param(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t param_id, uint32_t param_value) +{ + wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + struct vdev_set_params param = {0}; + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (vdev_id >= WLAN_MAX_VDEVS) { + target_if_err("vdev_id: %d is invalid, reject the req: param id %d val %d", + vdev_id, param_id, param_value); + return QDF_STATUS_E_INVAL; + } + + param.vdev_id = vdev_id; + param.param_id = param_id; + param.param_value = param_value; + + return wmi_unified_vdev_set_param_send(wmi_handle, ¶m); +} + QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *req, enum wlan_crypto_key_type key_type) @@ -138,7 +164,9 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, struct set_key_params params = {0}; struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_peer *peer; enum cdp_sec_type sec_type = cdp_sec_type_none; + enum wlan_peer_type peer_type = 0; void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint32_t pn[4] = {0, 0, 0, 0}; bool peer_exist = false; @@ -185,6 +213,15 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, peer_exist = cdp_find_peer_exist(soc, pdev->pdev_objmgr.wlan_pdev_id, req->macaddr); + peer = wlan_objmgr_get_peer_by_mac(psoc, req->macaddr, WLAN_CRYPTO_ID); + if (peer) { + peer_type = wlan_peer_get_peer_type(peer); + if (peer_type == WLAN_PEER_RTT_PASN && + key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) + peer_exist = true; + + wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID); + } target_if_debug("key_type %d, mac: %02x:%02x:%02x:%02x:%02x:%02x", key_type, req->macaddr[0], req->macaddr[1], req->macaddr[2], req->macaddr[3], req->macaddr[4], @@ -223,6 +260,10 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, /* Set PN check & security type in data path */ qdf_mem_copy(&pn[0], ¶ms.key_rsc_ctr, sizeof(uint64_t)); + + if (peer_type == WLAN_PEER_RTT_PASN) + goto send_install_key; + cdp_set_pn_check(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, sec_type, pn); @@ -232,7 +273,7 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, cdp_set_key(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, pairwise, (uint32_t *)(req->keyval + WLAN_CRYPTO_IV_SIZE + WLAN_CRYPTO_MIC_LEN)); - +send_install_key: target_if_debug("vdev_id:%d, key: idx:%d,len:%d", params.vdev_id, params.key_idx, params.key_len); target_if_debug("peer mac "QDF_MAC_ADDR_FMT, @@ -366,6 +407,25 @@ target_if_crypto_deregister_events(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +static QDF_STATUS +target_if_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc, + struct wlan_crypto_ltf_keyseed_data *data) +{ + QDF_STATUS status; + wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc); + + if (!psoc || !wmi) { + target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_send_vdev_set_ltf_key_seed_cmd(wmi, data); + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("set LTF keyseed failed"); + + return status; +} + QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_crypto_tx_ops *crypto; @@ -377,6 +437,8 @@ QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) crypto = &tx_ops->crypto_tx_ops; crypto->set_key = target_if_crypto_set_key; + crypto->set_ltf_keyseed = target_if_crypto_set_ltf_keyseed; + crypto->set_vdev_param = target_if_crypto_vdev_set_param; crypto->register_events = target_if_crypto_register_events; crypto->deregister_events = target_if_crypto_deregister_events; diff --git a/target_if/wifi_pos/src/target_if_wifi_pos_tx_ops.c b/target_if/wifi_pos/src/target_if_wifi_pos_tx_ops.c index fac11d2ffc..41ed2e9dc3 100644 --- a/target_if/wifi_pos/src/target_if_wifi_pos_tx_ops.c +++ b/target_if/wifi_pos/src/target_if_wifi_pos_tx_ops.c @@ -102,6 +102,59 @@ target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev *pdev, } #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */ +#ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT +static QDF_STATUS +target_if_wifi_pos_send_rtt_pasn_auth_status(struct wlan_objmgr_psoc *psoc, + struct wlan_pasn_auth_status *data) +{ + QDF_STATUS status; + wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc); + + if (!psoc || !wmi) { + target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_send_rtt_pasn_auth_status_cmd(wmi, data); + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("send pasn auth status cmd failed"); + + return status; +} + +static QDF_STATUS +target_if_wifi_pos_send_rtt_pasn_deauth(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac) +{ + QDF_STATUS status; + wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc); + + if (!psoc || !wmi) { + target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_send_rtt_pasn_deauth_cmd(wmi, peer_mac); + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("send pasn deauth cmd failed"); + + return status; +} + +static void target_if_wifi_pos_register_11az_ops( + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops) +{ + tx_ops->send_rtt_pasn_auth_status = + target_if_wifi_pos_send_rtt_pasn_auth_status; + tx_ops->send_rtt_pasn_deauth = target_if_wifi_pos_send_rtt_pasn_deauth; +} +#else +static inline +void target_if_wifi_pos_register_11az_ops( + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops) +{} +#endif + #ifdef WIFI_POS_CONVERGED #ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT static QDF_STATUS @@ -258,5 +311,7 @@ void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req; wifi_pos_tx_ops->wifi_pos_parse_measreq_chan_info = target_if_wifi_pos_parse_measreq_chan_info; + + target_if_wifi_pos_register_11az_ops(wifi_pos_tx_ops); } #endif diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index d4f23435ff..25829bc593 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -1019,6 +1019,9 @@ enum wlan_status_code { #define KCK_192BIT_KEY_LEN 24 #define KEK_256BIT_KEY_LEN 32 +#define WLAN_MAX_SECURE_LTF_KEYSEED_LEN 48 +#define WLAN_MIN_SECURE_LTF_KEYSEED_LEN 32 + #define WLAN_WPA_OUI 0xf25000 #define WLAN_WPA_OUI_TYPE 0x01 #define WPA_VERSION 1 diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index 83aca3cd66..19a5b08cfd 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -967,6 +967,19 @@ static inline void wlan_crypto_reset_vdev_prarams(struct wlan_objmgr_vdev *vdev) } #endif /* CRYPTO_SET_KEY_CONVERGED */ +/** + * wlan_crypto_vdev_set_param() - Send vdev set param to firmware. + * @psoc: Pointer to PSOC object + * @vdev_id: vdev id + * @param_id: Param id + * @param_value: Param value + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_crypto_vdev_set_param(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t param_id, uint32_t param_value); + /** * wlan_crypto_get_peer_pmksa() - called to get pmksa based on pmksa parameter * @vdev: vdev @@ -1101,6 +1114,19 @@ wlan_crypto_set_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, } #endif +#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +QDF_STATUS +wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc, + struct wlan_crypto_ltf_keyseed_data *data); +#else +static inline QDF_STATUS +wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc, + struct wlan_crypto_ltf_keyseed_data *data) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef WLAN_FEATURE_FILS_SK /** * lim_create_fils_rik()- This API create rik using rrk coming from diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h index 89ce340830..f4e5a1c739 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h @@ -193,6 +193,22 @@ enum wlan_crypto_rsnx_cap { WLAN_CRYPTO_RSNX_CAP_PROTECTED_TWT = 0x10, WLAN_CRYPTO_RSNX_CAP_SAE_H2E = 0x20, WLAN_CRYPTO_RSNX_CAP_SAE_PK = 0x40, + WLAN_CRYPTO_RSNX_CAP_SECURE_LTF = 0x400, + WLAN_CRYPTO_RSNX_CAP_SECURE_RTT = 0x1000, + WLAN_CRYPTO_RSNX_CAP_URNM_MFPR = 0x2000, +}; + +/** + * wlan_crypto_vdev_pasn_caps - PASN peer related vdev + * crypto parameters + * @WLAN_CRYPTO_URNM_MFPR: URNM MFP required in RSNXE + * @WLAN_CRYPTO_MFPC: MFP capable bit from RSN IE + * @WLAN_CRYPTO_MFPR: MFP required from RSNIE + */ +enum wlan_crypto_vdev_pasn_caps { + WLAN_CRYPTO_URNM_MFPR = BIT(0), + WLAN_CRYPTO_MFPC = BIT(1), + WLAN_CRYPTO_MFPR = BIT(2), }; typedef enum wlan_crypto_key_mgmt { @@ -323,6 +339,24 @@ struct wlan_crypto_params { uint16_t rsn_caps; }; +/** + * struct wlan_crypto_ltf_keyseed_data - LTF keyseed parameters + * @vdev_id: Vdev id + * @peer_mac_addr: Peer mac address + * @src_mac_addr: Source mac address + * @rsn_authmode: Cipher suite + * @key_seed: Secure LTF key seed + * @key_seed_len: Key seed length + */ +struct wlan_crypto_ltf_keyseed_data { + uint8_t vdev_id; + struct qdf_mac_addr peer_mac_addr; + struct qdf_mac_addr src_mac_addr; + uint8_t rsn_authmode; + uint8_t key_seed[WLAN_MAX_SECURE_LTF_KEYSEED_LEN]; + uint16_t key_seed_len; +}; + typedef enum wlan_crypto_param_type { WLAN_CRYPTO_PARAM_AUTH_MODE, WLAN_CRYPTO_PARAM_UCAST_CIPHER, @@ -342,6 +376,7 @@ typedef enum wlan_crypto_param_type { * @keyix: key id * @cipher_type: cipher type being used for this key * @mac_addr: MAC address of the peer + * @src_addr: Source mac address associated with the key * @cipher_table: table which stores cipher related info * @private: private pointer to save cipher context * @keylock: spin lock @@ -363,6 +398,7 @@ struct wlan_crypto_key { uint16_t keyix; enum wlan_crypto_cipher_type cipher_type; uint8_t macaddr[QDF_MAC_ADDR_SIZE]; + struct qdf_mac_addr src_addr; void *cipher_table; void *private; qdf_spinlock_t keylock; @@ -423,6 +459,8 @@ struct wlan_crypto_req_key { * @defaultkey: function pointer to set default key * @set_key: converged function pointer to set key in hw * @getpn: function pointer to get current pn value of peer + * @set_ltf_keyseed: Set LTF keyseed + * @set_vdev_param: Set the vdev crypto parameter * @register_events: function pointer to register wmi event handler * @deregister_events: function pointer to deregister wmi event handler */ @@ -444,6 +482,11 @@ struct wlan_lmac_if_crypto_tx_ops { enum wlan_crypto_key_type key_type); QDF_STATUS(*getpn)(struct wlan_objmgr_vdev *vdev, uint8_t *macaddr, uint32_t key_type); + QDF_STATUS (*set_ltf_keyseed)(struct wlan_objmgr_psoc *psoc, + struct wlan_crypto_ltf_keyseed_data *ks); + QDF_STATUS (*set_vdev_param)(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t param_id, + uint32_t param_value); QDF_STATUS (*register_events)(struct wlan_objmgr_psoc *psoc); QDF_STATUS (*deregister_events)(struct wlan_objmgr_psoc *psoc); }; diff --git a/umac/cmn_services/crypto/src/wlan_crypto_def_i.h b/umac/cmn_services/crypto/src/wlan_crypto_def_i.h index 4d08571162..e1fe61bf0f 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_def_i.h +++ b/umac/cmn_services/crypto/src/wlan_crypto_def_i.h @@ -104,8 +104,12 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val) ((tx_ops)->crypto_tx_ops.defaultkey) #define WLAN_CRYPTO_TX_OPS_SET_KEY(tx_ops) \ ((tx_ops)->crypto_tx_ops.set_key) +#define WLAN_CRYPTO_TX_OPS_SET_VDEV_PARAM(tx_ops) \ + ((tx_ops)->crypto_tx_ops.set_vdev_param) #define WLAN_CRYPTO_TX_OPS_GETPN(tx_ops) \ ((tx_ops)->crypto_tx_ops.getpn) +#define WLAN_CRYPTO_TX_OPS_SET_LTF_KEYSEED(tx_ops) \ + ((tx_ops)->crypto_tx_ops.set_ltf_keyseed) #define WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(tx_ops) \ ((tx_ops)->crypto_tx_ops.register_events) #define WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(tx_ops) \ diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index 9d1aefb683..d6411f9e23 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -4803,3 +4803,46 @@ QDF_STATUS wlan_crypto_create_fils_rik(uint8_t *rrk, uint8_t rrk_len, return QDF_STATUS_SUCCESS; } #endif /* WLAN_FEATURE_FILS_SK */ + +#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +QDF_STATUS +wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc, + struct wlan_crypto_ltf_keyseed_data *data) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_lmac_if_tx_ops *tx_ops; + + tx_ops = wlan_psoc_get_lmac_if_txops(psoc); + if (!tx_ops) { + crypto_err("tx_ops is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (WLAN_CRYPTO_TX_OPS_SET_LTF_KEYSEED(tx_ops)) + status = WLAN_CRYPTO_TX_OPS_SET_LTF_KEYSEED(tx_ops)(psoc, data); + + return status; +} +#endif + +QDF_STATUS +wlan_crypto_vdev_set_param(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t param_id, uint32_t param_value) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_lmac_if_tx_ops *tx_ops; + + tx_ops = wlan_psoc_get_lmac_if_txops(psoc); + if (!tx_ops) { + crypto_err("tx_ops is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (WLAN_CRYPTO_TX_OPS_SET_VDEV_PARAM(tx_ops)) + status = WLAN_CRYPTO_TX_OPS_SET_VDEV_PARAM(tx_ops) (psoc, + vdev_id, + param_id, + param_value); + + return status; +} diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 2efb2c1c77..fa415c8525 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -890,6 +890,8 @@ struct wlan_lmac_if_iot_sim_tx_ops { * @wifi_pos_get_vht_ch_width: Function pointer to get max supported bw by FW * @wifi_pos_parse_measreq_chan_info: Parse channel info from LOWI measurement * request buffer. + * @send_rtt_pasn_auth_status: Send PASN peers authentication status + * @send_rtt_pasn_deauth: Send PASN peer deauth command */ struct wlan_lmac_if_wifi_pos_tx_ops { QDF_STATUS (*wifi_pos_register_events)(struct wlan_objmgr_psoc *psoc); @@ -907,7 +909,11 @@ struct wlan_lmac_if_wifi_pos_tx_ops { QDF_STATUS (*wifi_pos_parse_measreq_chan_info)( struct wlan_objmgr_pdev *pdev, uint32_t data_len, uint8_t *data, struct rtt_channel_info *chinfo); - + QDF_STATUS (*send_rtt_pasn_auth_status) + (struct wlan_objmgr_psoc *psoc, + struct wlan_pasn_auth_status *data); + QDF_STATUS (*send_rtt_pasn_deauth)(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac); }; #endif diff --git a/umac/wifi_pos/inc/wifi_pos_api.h b/umac/wifi_pos/inc/wifi_pos_api.h index 203320b6bc..a02254951e 100644 --- a/umac/wifi_pos/inc/wifi_pos_api.h +++ b/umac/wifi_pos/inc/wifi_pos_api.h @@ -640,6 +640,15 @@ QDF_STATUS wifi_pos_convert_host_pdev_id_to_target( uint32_t *target_pdev_id); #ifdef WIFI_POS_CONVERGED +/** + * wifi_pos_get_peer_private_object() - Wifi Pos get peer private object + * @peer: Peer object pointer + * + * Return: Peer private object pointer + */ +struct wlan_wifi_pos_peer_priv_obj * +wifi_pos_get_peer_private_object(struct wlan_objmgr_peer *peer); + /** * wifi_pos_register_osif_callbacks() - Register OSIF callbacks * @psoc: Pointer to psoc object diff --git a/umac/wifi_pos/inc/wifi_pos_pasn_api.h b/umac/wifi_pos/inc/wifi_pos_pasn_api.h index 50f7de7922..89868054c0 100644 --- a/umac/wifi_pos/inc/wifi_pos_pasn_api.h +++ b/umac/wifi_pos/inc/wifi_pos_pasn_api.h @@ -27,6 +27,26 @@ #include "wifi_pos_public_struct.h" #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +/** + * wifi_pos_set_peer_ltf_keyseed_required() - Set LTF keyseed required + * for the peer + * @peer: Peer object + * @value: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_set_peer_ltf_keyseed_required(struct wlan_objmgr_peer *peer, + bool value); +/** + * wifi_pos_is_ltf_keyseed_required_for_peer() - Is LTF keyseed required for + * the given peer + * @peer: Peer object + * + * Return: true or false + */ +bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer); + /** * wifi_pos_handle_ranging_peer_create() - Handle ranging peer create * @psoc: Pointer to PSOC @@ -92,6 +112,28 @@ wifi_pos_handle_ranging_peer_delete(struct wlan_objmgr_psoc *psoc, struct wlan_pasn_request *req, uint8_t vdev_id, uint8_t total_entries); + +/** + * wifi_pos_send_pasn_auth_status - Send PASN auth status to firmware + * @psoc: Pointer to PSOC object + * @data: pointer to auth status data + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_send_pasn_auth_status(struct wlan_objmgr_psoc *psoc, + struct wlan_pasn_auth_status *data); + +/** + * wifi_pos_send_pasn_peer_deauth - Send PASN peer deauth + * @psoc: Pointer to PSOC object + * @peer_mac: Peer mac address + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_send_pasn_peer_deauth(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac); #else static inline QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, @@ -130,5 +172,12 @@ wifi_pos_handle_ranging_peer_delete(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_SUCCESS; } + +static inline QDF_STATUS +wifi_pos_send_pasn_peer_deauth(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac) +{ + return QDF_STATUS_SUCCESS; +} #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */ #endif /* _WIFI_POS_PASN_API_H_ */ diff --git a/umac/wifi_pos/inc/wifi_pos_public_struct.h b/umac/wifi_pos/inc/wifi_pos_public_struct.h index a2f22e65bd..48407506dc 100644 --- a/umac/wifi_pos/inc/wifi_pos_public_struct.h +++ b/umac/wifi_pos/inc/wifi_pos_public_struct.h @@ -67,6 +67,7 @@ enum wifi_pos_pasn_peer_delete_actions { * derivation * @force_self_mac_usage: If this flag is true, the supplicant * should use the provided self mac address + * @is_ltf_keyseed_required: Is set LTF keyseed required * @control_flags: Control flags to indicate if its required to flush * the keys */ @@ -75,6 +76,7 @@ struct wlan_pasn_request { enum wifi_pos_pasn_peer_type peer_type; struct qdf_mac_addr self_mac; bool force_self_mac_usage; + bool is_ltf_keyseed_required; uint16_t control_flags; }; @@ -106,4 +108,54 @@ struct wifi_pos_11az_context { struct wifi_pos_vdev_priv_obj { struct wifi_pos_11az_context pasn_context; }; + +/** + * enum wlan_pasn_auth_status_code - PASN auth status code + * @WLAN_PASN_AUTH_STATUS_SUCCESS: PASN auth is successful + * @WLAN_PASN_AUTH_STATUS_PASN_FAILED: PASN authentication failed + * @WLAN_PASN_AUTH_STATUS_PEER_CREATE_FAILED: PASN peer create confirm received + * with failure status. + * @WLAN_PASN_AUTH_STATUS_PEER_ALREADY_EXISTS: Peer already exists + * @WLAN_PASN_AUTH_STATUS_HOST_INTERNAL_ERROR: WLAN driver internal error + */ +enum wlan_pasn_auth_status_code { + WLAN_PASN_AUTH_STATUS_SUCCESS = 0, + WLAN_PASN_AUTH_STATUS_PASN_FAILED = 1, + WLAN_PASN_AUTH_STATUS_PEER_CREATE_FAILED = 2, + WLAN_PASN_AUTH_STATUS_PEER_ALREADY_EXISTS = 3, + WLAN_PASN_AUTH_STATUS_HOST_INTERNAL_ERROR = 4, +}; + +/** + * struct wlan_pasn_auth_status_peer_info - PASN authentication status peer + * info + * @peer_mac: Peer mac address + * @self_mac: Self mac address + * @status: PASN auth status code + */ +struct wlan_pasn_auth_status_peer_info { + struct qdf_mac_addr peer_mac; + struct qdf_mac_addr self_mac; + enum wlan_pasn_auth_status_code status; +}; + +/** + * struct wlan_pasn_auth_status - PASN authentication status + * @vdev_id: vdev_id + * @num_peers: Number of peers for which auth status is to be sent + * @auth_status: Auth status details + */ +struct wlan_pasn_auth_status { + uint8_t vdev_id; + uint8_t num_peers; + struct wlan_pasn_auth_status_peer_info auth_status[WLAN_MAX_11AZ_PEERS]; +}; + +/** + * struct wlan_wifi_pos_peer_priv_obj - WLAN wifi pos peer private object + * @is_ltf_keyseed_required: Is LTF keyseed required for peer + */ +struct wlan_wifi_pos_peer_priv_obj { + bool is_ltf_keyseed_required; +}; #endif /* _WIFI_POS_PUBLIC_STRUCT_H_ */ diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c index ce853e63cb..4d027e6f68 100644 --- a/umac/wifi_pos/src/wifi_pos_api.c +++ b/umac/wifi_pos/src/wifi_pos_api.c @@ -144,8 +144,36 @@ QDF_STATUS wifi_pos_init(void) goto fail_vdev_destroy_handler; } + status = wlan_objmgr_register_peer_create_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_peer_object_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + wifi_pos_err("peer create register notification failed"); + goto fail_peer_create_handler; + } + + status = wlan_objmgr_register_peer_destroy_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_peer_object_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + wifi_pos_err("peer destroy register notification failed"); + goto fail_peer_destroy_handler; + } + return status; +fail_peer_destroy_handler: + wlan_objmgr_unregister_peer_create_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_peer_object_created_notification, + NULL); +fail_peer_create_handler: + wlan_objmgr_unregister_vdev_destroy_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_vdev_destroyed_notification, NULL); + fail_vdev_destroy_handler: wlan_objmgr_unregister_vdev_create_handler( WLAN_UMAC_COMP_WIFI_POS, @@ -168,6 +196,20 @@ QDF_STATUS wifi_pos_deinit(void) { QDF_STATUS status; + status = wlan_objmgr_unregister_peer_destroy_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_peer_object_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) + wifi_pos_err("unable to unregister peer destroy handle"); + + status = wlan_objmgr_unregister_peer_create_handler( + WLAN_UMAC_COMP_WIFI_POS, + wifi_pos_peer_object_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) + wifi_pos_err("unable to unregister peer create handle"); + status = wlan_objmgr_unregister_vdev_destroy_handler( WLAN_UMAC_COMP_WIFI_POS, wifi_pos_vdev_destroyed_notification, NULL); @@ -246,6 +288,23 @@ QDF_STATUS wifi_pos_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +struct wlan_wifi_pos_peer_priv_obj * +wifi_pos_get_peer_private_object(struct wlan_objmgr_peer *peer) +{ + struct wlan_wifi_pos_peer_priv_obj *peer_priv; + + if (!peer) { + wifi_pos_err("Peer is NULL"); + return NULL; + } + + peer_priv = + wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_WIFI_POS); + + return peer_priv; +} + void wifi_pos_set_oem_target_type(struct wlan_objmgr_psoc *psoc, uint32_t val) { struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c index 1bd1deca06..1da3411b8f 100644 --- a/umac/wifi_pos/src/wifi_pos_main.c +++ b/umac/wifi_pos/src/wifi_pos_main.c @@ -36,6 +36,7 @@ #include "wlan_objmgr_vdev_obj.h" #include "wlan_ptt_sock_svc.h" #include "target_if.h" +#include "wlan_objmgr_peer_obj.h" #ifndef CNSS_GENL #include @@ -993,7 +994,8 @@ QDF_STATUS wifi_pos_psoc_obj_destroyed_notification( return status; } -static void +#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +void wifi_pos_init_11az_context(struct wifi_pos_vdev_priv_obj *vdev_pos_obj) { struct wifi_pos_11az_context *pasn_context; @@ -1016,6 +1018,7 @@ wifi_pos_init_11az_context(struct wifi_pos_vdev_priv_obj *vdev_pos_obj) pasn_context->num_unsecure_peers = 0; pasn_context->num_failed_peers = 0; } +#endif QDF_STATUS wifi_pos_vdev_created_notification(struct wlan_objmgr_vdev *vdev, @@ -1067,6 +1070,64 @@ wifi_pos_vdev_destroyed_notification(struct wlan_objmgr_vdev *vdev, return status; } +QDF_STATUS +wifi_pos_peer_object_created_notification(struct wlan_objmgr_peer *peer, + void *arg) +{ + struct wlan_wifi_pos_peer_priv_obj *peer_priv; + QDF_STATUS status; + + if (!peer) { + wifi_pos_err("Peer is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + peer_priv = qdf_mem_malloc(sizeof(*peer_priv)); + if (!peer_priv) + return QDF_STATUS_E_NOMEM; + + status = wlan_objmgr_peer_component_obj_attach(peer, + WLAN_UMAC_COMP_WIFI_POS, + (void *)peer_priv, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + wifi_pos_err("unable to attach peer_priv obj to peer obj"); + qdf_mem_free(peer_priv); + } + + return status; +} + +QDF_STATUS +wifi_pos_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, + void *arg) +{ + struct wlan_wifi_pos_peer_priv_obj *peer_priv; + QDF_STATUS status; + + if (!peer) { + wifi_pos_err("Peer is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_WIFI_POS); + if (!peer_priv) { + wifi_pos_err("peer MLME component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_peer_component_obj_detach(peer, + WLAN_UMAC_COMP_WIFI_POS, + (void *)peer_priv); + if (QDF_IS_STATUS_ERROR(status)) + wifi_pos_err("unable to dettach peer_priv obj to peer obj"); + + qdf_mem_free(peer_priv); + + return status; +} + int wifi_pos_oem_rsp_handler(struct wlan_objmgr_psoc *psoc, struct oem_data_rsp *oem_rsp) { diff --git a/umac/wifi_pos/src/wifi_pos_main_i.h b/umac/wifi_pos/src/wifi_pos_main_i.h index 3ad4d7f88f..50487c2a8a 100644 --- a/umac/wifi_pos/src/wifi_pos_main_i.h +++ b/umac/wifi_pos/src/wifi_pos_main_i.h @@ -34,6 +34,21 @@ /* forward reference */ struct wlan_objmgr_psoc; +#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +/** + * wifi_pos_init_11az_context - Initialize 11az context + * @vdev_pos_obj: Vdev private object of WIFI Pos component + * + * Return: None + */ +void +wifi_pos_init_11az_context(struct wifi_pos_vdev_priv_obj *vdev_pos_obj); +#else +static inline void +wifi_pos_init_11az_context(struct wifi_pos_vdev_priv_obj *vdev_pos_obj) +{} +#endif + /** * wifi_pos_psoc_obj_created_notification: callback registered to be called when * psoc object is created. @@ -85,6 +100,30 @@ QDF_STATUS wifi_pos_vdev_destroyed_notification(struct wlan_objmgr_vdev *vdev, void *arg_list); +/** + * wifi_pos_peer_object_created_notification() - Handle peer object created + * notification. + * @peer: Objmgr peer + * @arg: Argument + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_peer_object_created_notification(struct wlan_objmgr_peer *peer, + void *arg); + +/** + * wifi_pos_peer_object_destroyed_notification() - Handler for peer object + * deleted notification + * @peer: Objmgr peer + * @arg: Argument + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, + void *arg); + /** * wifi_pos_oem_rsp_handler: lmac rx ops registered * @psoc: pointer to psoc object diff --git a/umac/wifi_pos/src/wifi_pos_pasn_api.c b/umac/wifi_pos/src/wifi_pos_pasn_api.c index 56fea1c1d6..2dbca716f4 100644 --- a/umac/wifi_pos/src/wifi_pos_pasn_api.c +++ b/umac/wifi_pos/src/wifi_pos_pasn_api.c @@ -369,6 +369,18 @@ QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, continue; } + if (req[i].is_ltf_keyseed_required) { + peer = wlan_objmgr_get_peer_by_mac(psoc, + req[i].peer_mac.bytes, + WLAN_WIFI_POS_CORE_ID); + if (peer) { + wifi_pos_set_peer_ltf_keyseed_required(peer, + true); + wlan_objmgr_peer_release_ref(peer, + WLAN_WIFI_POS_CORE_ID); + } + } + /* Track the peers only for I-STA mode */ if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) wifi_pos_add_peer_to_list(vdev, &req[i], true); @@ -523,3 +535,108 @@ no_peer: return status; } + +QDF_STATUS +wifi_pos_send_pasn_auth_status(struct wlan_objmgr_psoc *psoc, + struct wlan_pasn_auth_status *data) +{ + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + QDF_STATUS status; + uint8_t vdev_id = data->vdev_id; + struct wifi_pos_vdev_priv_obj *vdev_pos_obj; + struct wifi_pos_11az_context *pasn_context; + struct wlan_objmgr_vdev *vdev; + uint8_t i, failed_peers_counter = 0, total_peers_to_fill = 0; + + tx_ops = wifi_pos_get_tx_ops(psoc); + if (!tx_ops || !tx_ops->send_rtt_pasn_auth_status) { + wifi_pos_err("%s is null", + tx_ops ? "Tx_ops" : "send_auth_status cb"); + return QDF_STATUS_E_FAILURE; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_WIFI_POS_CORE_ID); + if (!vdev) { + wifi_pos_err("vdev obj is null"); + return QDF_STATUS_E_FAILURE; + } + + vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); + if (!vdev_pos_obj) { + wifi_pos_err("Wifi pos vdev priv obj is null"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); + return QDF_STATUS_E_FAILURE; + } + + pasn_context = &vdev_pos_obj->pasn_context; + total_peers_to_fill = data->num_peers + pasn_context->num_failed_peers; + for (i = data->num_peers; i < total_peers_to_fill; i++) { + data->auth_status[i].peer_mac = + pasn_context->failed_peer_list[failed_peers_counter]; + data->auth_status[i].status = + WLAN_PASN_AUTH_STATUS_PEER_CREATE_FAILED; + + failed_peers_counter++; + if (failed_peers_counter >= pasn_context->num_failed_peers) + break; + } + + status = tx_ops->send_rtt_pasn_auth_status(psoc, data); + if (QDF_IS_STATUS_ERROR(status)) + wifi_pos_err("Failed to send PASN authentication status"); + + wifi_pos_init_11az_context(vdev_pos_obj); + wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); + + return status; +} + +QDF_STATUS +wifi_pos_send_pasn_peer_deauth(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac) +{ + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + QDF_STATUS status; + + tx_ops = wifi_pos_get_tx_ops(psoc); + if (!tx_ops || !tx_ops->send_rtt_pasn_deauth) { + wifi_pos_err("%s is null", + tx_ops ? "Tx_ops" : "send_pasn deauth cb"); + return QDF_STATUS_E_FAILURE; + } + + status = tx_ops->send_rtt_pasn_deauth(psoc, peer_mac); + + return status; +} + +QDF_STATUS +wifi_pos_set_peer_ltf_keyseed_required(struct wlan_objmgr_peer *peer, + bool value) +{ + struct wlan_wifi_pos_peer_priv_obj *peer_priv; + + peer_priv = wifi_pos_get_peer_private_object(peer); + if (!peer_priv) { + wifi_pos_err("peer private object is null"); + return QDF_STATUS_E_FAILURE; + } + + peer_priv->is_ltf_keyseed_required = value; + + return QDF_STATUS_SUCCESS; +} + +bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer) +{ + struct wlan_wifi_pos_peer_priv_obj *peer_priv; + + peer_priv = wifi_pos_get_peer_private_object(peer); + if (!peer_priv) { + wifi_pos_err("peer private object is null"); + return QDF_STATUS_E_FAILURE; + } + + return peer_priv->is_ltf_keyseed_required; +} diff --git a/umac/wifi_pos/src/wifi_pos_ucfg_i.h b/umac/wifi_pos/src/wifi_pos_ucfg_i.h index 730be472f4..6299926002 100644 --- a/umac/wifi_pos/src/wifi_pos_ucfg_i.h +++ b/umac/wifi_pos/src/wifi_pos_ucfg_i.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,6 +28,9 @@ #include "qdf_types.h" #include "qdf_status.h" +#include "os_if_wifi_pos_utils.h" +#include "wifi_pos_pasn_api.h" +#include "wifi_pos_api.h" struct wlan_objmgr_psoc; struct wifi_pos_req_msg; @@ -44,4 +48,47 @@ QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, struct wifi_pos_req_msg *req, wifi_pos_send_rsp_handler send_rsp_cb); +#ifdef WIFI_POS_CONVERGED +/** + * ucfg_wifi_pos_register_osif_callbacks() - Register WIFI pos module OSIF + * callbacks + * @psoc: Pointer to PSOC object + * @osif_ops: Pointer to OSIF callbacks + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +ucfg_wifi_pos_register_osif_callbacks(struct wlan_objmgr_psoc *psoc, + struct wifi_pos_osif_ops *osif_ops) +{ + return wifi_pos_register_osif_callbacks(psoc, osif_ops); +} + +/** + * ucfg_wifi_pos_deregister_osif_callbacks() - De-Register WIFI pos module OSIF + * callbacks + * @psoc: Pointer to PSOC object + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +ucfg_wifi_pos_deregister_osif_callbacks(struct wlan_objmgr_psoc *psoc) +{ + return wifi_pos_register_osif_callbacks(psoc, NULL); +} +#else +static inline QDF_STATUS +ucfg_wifi_pos_deregister_osif_callbacks(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WIFI_POS_CONVERGED */ + +#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +static inline bool +ucfg_wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer) +{ + return wifi_pos_is_ltf_keyseed_required_for_peer(peer); +} +#endif #endif /* _WIFI_POS_UCFG_H_ */ diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index b0c5d5418b..8308b0cb4b 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -4411,6 +4411,28 @@ wmi_extract_pasn_peer_create_req(wmi_unified_t wmi, void *evt_buf, QDF_STATUS wmi_extract_pasn_peer_delete_req(wmi_unified_t wmi, void *evt_buf, struct wifi_pos_pasn_peer_data *dst); + +/** + * wmi_send_rtt_pasn_auth_status_cmd - Send PASN authentication status of all + * the PASN peers. + * @wmi: WMI handle + * @data: Auth status data + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_send_rtt_pasn_auth_status_cmd(wmi_unified_t wmi, + struct wlan_pasn_auth_status *data); + +/** + * wmi_send_rtt_pasn_deauth_cmd - Send RTT pasn deauthentication command + * @wmi: WMI handle + * @peer_mac: peer mac address + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_send_rtt_pasn_deauth_cmd(wmi_unified_t wmi, struct qdf_mac_addr *peer_mac); #endif /** diff --git a/wmi/inc/wmi_unified_crypto_api.h b/wmi/inc/wmi_unified_crypto_api.h index 3dce977c0b..68c0159144 100644 --- a/wmi/inc/wmi_unified_crypto_api.h +++ b/wmi/inc/wmi_unified_crypto_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -48,5 +49,17 @@ QDF_STATUS wmi_extract_install_key_comp_event(wmi_unified_t wmi_handle, void *evt_buf, uint32_t len, struct wmi_install_key_comp_event *param); + +/** + * wmi_send_vdev_set_ltf_key_seed_cmd - Set LTF key seed for PASN key + * derivation. + * @wmi: WMI handle + * @data: LTF Keyseed data + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_send_vdev_set_ltf_key_seed_cmd(wmi_unified_t wmi, + struct wlan_crypto_ltf_keyseed_data *data); #endif diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 3603223c1b..c1c6c2e2e1 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -2735,6 +2735,13 @@ QDF_STATUS (*extract_pasn_peer_delete_req_event) (wmi_unified_t wmi_handle, void *evt_buf, struct wifi_pos_pasn_peer_data *dst); + +QDF_STATUS (*send_rtt_pasn_auth_status_cmd) + (wmi_unified_t wmi_handle, + struct wlan_pasn_auth_status *data); + +QDF_STATUS (*send_rtt_pasn_deauth_cmd)(wmi_unified_t wmi_handle, + struct qdf_mac_addr *peer_mac); #endif QDF_STATUS (*extract_hw_mode_resp_event)(wmi_unified_t wmi_handle, @@ -2905,6 +2912,10 @@ QDF_STATUS void *evt_buf, uint32_t len, struct wmi_install_key_comp_event *param); +QDF_STATUS (*send_vdev_set_ltf_key_seed_cmd) + (wmi_unified_t wmi_handle, + struct wlan_crypto_ltf_keyseed_data *data); + #ifdef WLAN_ENH_CFR_ENABLE QDF_STATUS (*extract_cfr_phase_param)(wmi_unified_t wmi_handle, diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 355278c30e..2f393ffe84 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -3460,6 +3460,25 @@ wmi_extract_pasn_peer_delete_req(wmi_unified_t wmi, void *evt_buf, return QDF_STATUS_E_FAILURE; } + +QDF_STATUS +wmi_send_rtt_pasn_auth_status_cmd(wmi_unified_t wmi, + struct wlan_pasn_auth_status *data) +{ + if (wmi->ops->send_rtt_pasn_auth_status_cmd) + return wmi->ops->send_rtt_pasn_auth_status_cmd(wmi, data); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wmi_send_rtt_pasn_deauth_cmd(wmi_unified_t wmi, struct qdf_mac_addr *peer_mac) +{ + if (wmi->ops->send_rtt_pasn_deauth_cmd) + return wmi->ops->send_rtt_pasn_deauth_cmd(wmi, peer_mac); + + return QDF_STATUS_E_FAILURE; +} #endif QDF_STATUS wmi_unified_extract_hw_mode_resp(wmi_unified_t wmi, diff --git a/wmi/src/wmi_unified_crypto_api.c b/wmi/src/wmi_unified_crypto_api.c index ac63bd8a8f..513fe21632 100644 --- a/wmi/src/wmi_unified_crypto_api.c +++ b/wmi/src/wmi_unified_crypto_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -32,3 +33,13 @@ wmi_extract_install_key_comp_event(wmi_unified_t wmi_handle, void *evt_buf, return QDF_STATUS_E_FAILURE; } + +QDF_STATUS +wmi_send_vdev_set_ltf_key_seed_cmd(wmi_unified_t wmi, + struct wlan_crypto_ltf_keyseed_data *data) +{ + if (wmi->ops->send_vdev_set_ltf_key_seed_cmd) + return wmi->ops->send_vdev_set_ltf_key_seed_cmd(wmi, data); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index d1240cf521..1a28bd9a90 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -22,6 +22,7 @@ #include "wmi_version.h" #include "wmi_unified_priv.h" #include "wmi_version_allowlist.h" +#include "wifi_pos_public_struct.h" #include #include #include @@ -4926,7 +4927,6 @@ static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, cmd->group_key_ix = key_params->group_key_idx; } - WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); cmd->key_flags |= key_params->key_flags; cmd->key_cipher = key_params->key_cipher; @@ -16251,6 +16251,8 @@ extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, #endif /* WIFI_POS_CONVERGED */ #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) +#define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 + static QDF_STATUS extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, struct wifi_pos_pasn_peer_data *dst) @@ -16307,6 +16309,8 @@ extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, else dst->peer_info[i].peer_type = WLAN_WIFI_POS_PASN_UNSECURE_PEER; + if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) + dst->peer_info[i].is_ltf_keyseed_required = true; dst->peer_info[i].force_self_mac_usage = WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( @@ -16372,8 +16376,151 @@ extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, return QDF_STATUS_SUCCESS; } + +static QDF_STATUS +send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, + struct wlan_pasn_auth_status *data) +{ + QDF_STATUS status; + wmi_buf_t buf; + wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; + uint8_t *buf_ptr; + uint8_t i; + size_t len = sizeof(*fixed_param) + + data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + + WMI_TLV_HDR_SIZE; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err("wmi_buf_alloc failed"); + return QDF_STATUS_E_FAILURE; + } + buf_ptr = (uint8_t *)wmi_buf_data(buf); + fixed_param = + (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&fixed_param->tlv_header, + WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_rtt_pasn_auth_status_cmd_fixed_param)); + buf_ptr += sizeof(*fixed_param); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + (data->num_peers * + sizeof(wmi_rtt_pasn_auth_status_param))); + buf_ptr += WMI_TLV_HDR_SIZE; + + for (i = 0; i < data->num_peers; i++) { + wmi_rtt_pasn_auth_status_param *auth_status_tlv = + (wmi_rtt_pasn_auth_status_param *)buf_ptr; + + WMITLV_SET_HDR(&auth_status_tlv->tlv_header, + WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); + + WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, + &auth_status_tlv->peer_mac_addr); + WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, + &auth_status_tlv->source_mac_addr); + auth_status_tlv->status = data->auth_status[i].status; + + buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); + } + + wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_RTT_PASN_AUTH_STATUS_CMD); + if (QDF_IS_STATUS_ERROR(status)) { + wmi_err("Failed to send Auth status command ret = %d", status); + wmi_buf_free(buf); + } + + return status; +} + +static QDF_STATUS +send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, + struct qdf_mac_addr *peer_mac) +{ + QDF_STATUS status; + wmi_buf_t buf; + wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; + size_t len = sizeof(*fixed_param); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err("wmi_buf_alloc failed"); + return QDF_STATUS_E_FAILURE; + } + fixed_param = + (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&fixed_param->tlv_header, + WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_rtt_pasn_deauth_cmd_fixed_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, + &fixed_param->peer_mac_addr); + + wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_RTT_PASN_DEAUTH_CMD); + if (QDF_IS_STATUS_ERROR(status)) { + wmi_err("Failed to send pasn deauth command ret = %d", status); + wmi_buf_free(buf); + } + + return status; +} #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ +static QDF_STATUS +send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, + struct wlan_crypto_ltf_keyseed_data *data) +{ + QDF_STATUS status; + wmi_buf_t buf; + wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; + uint8_t *buf_ptr; + size_t len = sizeof(*fixed_param) + data->key_seed_len + + WMI_TLV_HDR_SIZE; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err("wmi_buf_alloc failed"); + return QDF_STATUS_E_FAILURE; + } + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + fixed_param = + (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&fixed_param->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); + + fixed_param->vdev_id = data->vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, + &fixed_param->peer_macaddr); + fixed_param->key_seed_len = data->key_seed_len; + fixed_param->rsn_authmode = data->rsn_authmode; + + buf_ptr += sizeof(*fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + (fixed_param->key_seed_len * sizeof(A_UINT8))); + buf_ptr += WMI_TLV_HDR_SIZE; + + qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); + + wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_VDEV_SET_LTF_KEY_SEED_CMDID); + if (QDF_IS_STATUS_ERROR(status)) { + wmi_err("Failed to send ltf keyseed command ret = %d", status); + wmi_buf_free(buf); + } + + return status; +} + /** * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status * @wmi_handle: wmi handle @@ -18380,6 +18527,10 @@ struct wmi_ops tlv_ops = { extract_pasn_peer_create_req_event_tlv, .extract_pasn_peer_delete_req_event = extract_pasn_peer_delete_req_event_tlv, + .send_rtt_pasn_auth_status_cmd = + send_rtt_pasn_auth_status_cmd_tlv, + .send_rtt_pasn_deauth_cmd = + send_rtt_pasn_deauth_cmd_tlv, #endif #ifdef WLAN_MWS_INFO_DEBUGFS .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, @@ -18429,6 +18580,8 @@ struct wmi_ops tlv_ops = { #endif .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, .extract_install_key_comp_event = extract_install_key_comp_event_tlv, + .send_vdev_set_ltf_key_seed_cmd = + send_vdev_set_ltf_key_seed_cmd_tlv, .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, .send_set_halphy_cal = send_set_halphy_cal_tlv, .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv,