diff --git a/init_deinit/dispatcher/src/dispatcher_init_deinit.c b/init_deinit/dispatcher/src/dispatcher_init_deinit.c index 79ff575f33..0910289a1e 100644 --- a/init_deinit/dispatcher/src/dispatcher_init_deinit.c +++ b/init_deinit/dispatcher/src/dispatcher_init_deinit.c @@ -560,6 +560,16 @@ static QDF_STATUS dispatcher_deinit_crypto(void) { return wlan_crypto_deinit(); } + +static QDF_STATUS dispatcher_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_crypto_psoc_enable(psoc); +} + +static QDF_STATUS dispatcher_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_crypto_psoc_disable(psoc); +} #else static QDF_STATUS dispatcher_init_crypto(void) { @@ -570,6 +580,16 @@ static QDF_STATUS dispatcher_deinit_crypto(void) { return QDF_STATUS_SUCCESS; } + +static QDF_STATUS dispatcher_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dispatcher_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} #endif /* END of WLAN_CONV_CRYPTO_SUPPORTED */ #ifdef WIFI_POS_CONVERGED @@ -1280,6 +1300,9 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc) if (QDF_STATUS_SUCCESS != dispatcher_dbr_psoc_enable(psoc)) goto dbr_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != dispatcher_crypto_psoc_enable(psoc)) + goto crypto_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != wlan_mlme_psoc_enable(psoc)) goto mlme_psoc_enable_fail; @@ -1292,6 +1315,8 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc) spectral_psoc_enable_fail: wlan_mlme_psoc_disable(psoc); mlme_psoc_enable_fail: + dispatcher_crypto_psoc_disable(psoc); +crypto_psoc_enable_fail: dispatcher_dbr_psoc_disable(psoc); dbr_psoc_enable_fail: fd_psoc_disable(psoc); @@ -1322,6 +1347,8 @@ QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_BUG(QDF_STATUS_SUCCESS == wlan_mlme_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_crypto_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_dbr_psoc_disable(psoc)); QDF_BUG(QDF_STATUS_SUCCESS == fd_psoc_disable(psoc)); diff --git a/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h b/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h index 64e760cb34..ca27b6fcfe 100644 --- a/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h +++ b/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. 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 @@ -65,10 +65,12 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, * @vdev: vdev object * @key_type: denotes if the add key request is for pairwise or group key * @key_index: Index of the key that needs to be added + * @sync: flag to indicate whether or not to add key synchronously. + * DO NOT set to true if it's in scheduler context. * * Return: Zero on Success, negative value on failure */ int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, enum wlan_crypto_key_type key_type, - uint8_t key_index); + uint8_t key_index, bool sync); #endif diff --git a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c index ed039056d7..b74be913e1 100644 --- a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c +++ b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. 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 @@ -23,10 +23,15 @@ #include #include #include +#include +#include +#include +#include #include #include #include "wlan_cfg80211_crypto.h" #include +#include static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, uint8_t key_index, @@ -134,19 +139,83 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, return 0; } +#define WLAN_WAIT_TIME_ADD_KEY 100 + +static void +wlan_cfg80211_crypto_add_key_cb(void *context, + struct crypto_add_key_result *result) +{ + struct osif_request *request; + struct crypto_add_key_result *priv; + + request = osif_request_get(context); + if (!request) { + osif_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + qdf_mem_copy(priv, result, sizeof(*priv)); + osif_request_complete(request); + osif_request_put(request); +} + int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, enum wlan_crypto_key_type key_type, - uint8_t key_index) + uint8_t key_index, bool sync) { struct wlan_crypto_key *crypto_key; QDF_STATUS status; + struct osif_request *request; + struct crypto_add_key_result *result; + struct wlan_crypto_comp_priv *priv; + int ret; + static const struct osif_request_params params = { + .priv_size = sizeof(*result), + .timeout_ms = WLAN_WAIT_TIME_ADD_KEY, + }; crypto_key = wlan_crypto_get_key(vdev, key_index); if (!crypto_key) { osif_err("Crypto KEY is NULL"); return -EINVAL; } - status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + + if (sync) { + priv = wlan_get_vdev_crypto_obj(vdev); + if (!priv) { + osif_err("Invalid crypto_priv"); + return -EINVAL; + } + + request = osif_request_alloc(¶ms); + if (!request) { + osif_err("Request allocation failure"); + return -ENOMEM; + } + + priv->add_key_ctx = osif_request_cookie(request);; + priv->add_key_cb = wlan_cfg80211_crypto_add_key_cb; + + status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + if (QDF_IS_STATUS_SUCCESS(status)) { + ret = osif_request_wait_for_response(request); + if (ret) { + osif_err("Target response timed out"); + } else { + result = osif_request_priv(request); + osif_debug("complete, vdev_id %u, ix: %u, flags: %u, status: %u", + result->vdev_id, result->key_ix, + result->key_flags, result->status); + } + } + + priv->add_key_ctx = NULL; + priv->add_key_cb = NULL; + osif_request_put(request); + } else { + status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + } return qdf_status_to_os_return(status); } diff --git a/target_if/crypto/src/target_if_crypto.c b/target_if/crypto/src/target_if_crypto.c index bb6f0a3acf..df7606a116 100644 --- a/target_if/crypto/src/target_if_crypto.c +++ b/target_if/crypto/src/target_if_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. 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 @@ -36,6 +36,10 @@ #include #include #include +#include +#include +#include "wlan_crypto_def_i.h" +#include "wlan_crypto_obj_mgr_i.h" #ifdef FEATURE_WLAN_WAPI #ifdef FEATURE_WAPI_BIG_ENDIAN @@ -232,16 +236,136 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, 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, - QDF_MAC_ADDR_REF(params.peer_mac)); + QDF_MAC_ADDR_REF(params.peer_mac)); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_DEBUG, ¶ms.key_rsc_ctr, sizeof(uint64_t)); status = wmi_unified_setup_install_key_cmd(pdev_wmi_handle, ¶ms); /* Zero-out local key variables */ qdf_mem_zero(¶ms, sizeof(struct set_key_params)); + return status; } +/** + * target_if_crypto_install_key_comp_evt_handler() - install key complete + * handler + * @handle: wma handle + * @event: event data + * @len: data length + * + * This event is sent by fw once WPA/WPA2 keys are installed in fw. + * + * Return: 0 for success or error code + */ +static int +target_if_crypto_install_key_comp_evt_handler(void *handle, uint8_t *event, + uint32_t len) +{ + struct wlan_crypto_comp_priv *priv_obj; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct wmi_install_key_comp_event params; + QDF_STATUS status; + wmi_unified_t wmi_handle; + struct crypto_add_key_result result; + + if (!event || !handle) { + target_if_err("invalid param"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(handle); + if (!psoc) { + target_if_err("psoc is null"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("invalid wmi handle"); + return -EINVAL; + } + + status = wmi_extract_install_key_comp_event(wmi_handle, event, + len, ¶ms); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("received invalid buf from target"); + return -EINVAL; + } + + target_if_debug("vdev %d mac " QDF_MAC_ADDR_FMT " ix %x flags %x status %d", + params.vdev_id, + QDF_MAC_ADDR_REF(params.peer_macaddr), + params.key_ix, params.key_flags, params.status); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, params.vdev_id, + WLAN_CRYPTO_ID); + if (!vdev) { + target_if_err("vdev %d is null", params.vdev_id); + return -EINVAL; + } + + priv_obj = wlan_get_vdev_crypto_obj(vdev); + if (!priv_obj) { + target_if_err("priv_obj is null"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID); + return -EINVAL; + } + + result.vdev_id = params.vdev_id; + result.key_ix = params.key_ix; + result.key_flags = params.key_flags; + result.status = params.status; + qdf_mem_copy(result.peer_macaddr, params.peer_macaddr, + QDF_MAC_ADDR_SIZE); + + if (priv_obj->add_key_cb) + priv_obj->add_key_cb(priv_obj->add_key_ctx, &result); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID); + + return 0; +} + +static QDF_STATUS +target_if_crypto_register_events(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + + if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { + target_if_err("psoc or psoc->tgt_if_handle is null"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event_handler( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_vdev_install_key_complete_event_id, + target_if_crypto_install_key_comp_evt_handler, + WMI_RX_WORK_CTX); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("register_event_handler failed: err %d", status); + return status; + } + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +target_if_crypto_deregister_events(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { + target_if_err("psoc or psoc->tgt_if_handle is null"); + return QDF_STATUS_E_INVAL; + } + + wmi_unified_unregister_event_handler( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_vdev_install_key_complete_event_id); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_crypto_tx_ops *crypto; @@ -253,6 +377,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->register_events = target_if_crypto_register_events; + crypto->deregister_events = target_if_crypto_deregister_events; return QDF_STATUS_SUCCESS; } 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 df72eff262..bca6724db1 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h @@ -422,6 +422,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 + * @register_events: function pointer to register wmi event handler + * @deregister_events: function pointer to deregister wmi event handler */ struct wlan_lmac_if_crypto_tx_ops { @@ -441,6 +443,8 @@ 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 (*register_events)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*deregister_events)(struct wlan_objmgr_psoc *psoc); }; /** diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_main.h b/umac/cmn_services/crypto/inc/wlan_crypto_main.h index 7f4e59f959..20c1be62ab 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_main.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2021 The Linux Foundation. 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 @@ -21,6 +21,7 @@ */ #ifndef _WLAN_CRYPTO_MAIN_H_ #define _WLAN_CRYPTO_MAIN_H_ +#include "wlan_crypto_global_def.h" /** * wlan_crypto_init - Init the crypto service with object manager @@ -38,5 +39,32 @@ QDF_STATUS wlan_crypto_init(void); */ QDF_STATUS wlan_crypto_deinit(void); +#ifdef CRYPTO_SET_KEY_CONVERGED +/** + * wlan_crypto_psoc_enable: psoc enable API for wlan crypto component + * @psoc: pointer to PSOC + * + * Return: status of operation + */ +QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_crypto_psoc_disable: psoc disable API for wlan crypto component + * @psoc: pointer to PSOC + * + * Return: status of operation + */ +QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* end of _WLAN_CRYPTO_MAIN_H_ */ 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 a891ea3270..b086bb9ec4 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_def_i.h +++ b/umac/cmn_services/crypto/src/wlan_crypto_def_i.h @@ -173,6 +173,10 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val) ((tx_ops)->crypto_tx_ops.set_key) #define WLAN_CRYPTO_TX_OPS_GETPN(tx_ops) \ ((tx_ops)->crypto_tx_ops.getpn) +#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) \ + ((tx_ops)->crypto_tx_ops.deregister_events) /* unalligned little endian access */ #ifndef LE_READ_2 @@ -421,6 +425,33 @@ struct wlan_crypto_mmie { uint8_t mic[16]; } __packed; +/** + * struct crypto_add_key_result - add key result structure + * @vdev_id: unique id identifying the VDEV + * @key_ix: key index + * @key_flags: key flags + * @status: status of add key + * @peer_macaddr: MAC address of the peer + * + * Structure used for add key result. + */ +struct crypto_add_key_result { + uint32_t vdev_id; + uint32_t key_ix; + uint32_t key_flags; + uint32_t status; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; +}; + +/** + * typedef crypto_add_key_callback - add key callback + * @context: opaque context that the client can use to associate the + * callback with the request + * @result: result of add key + */ +typedef void (*crypto_add_key_callback)(void *context, + struct crypto_add_key_result *result); + /** * struct wlan_crypto_comp_priv - crypto component private structure * @crypto_params: crypto params for the peer @@ -432,6 +463,9 @@ struct wlan_crypto_mmie { * @def_igtk_tx_keyid default igtk key used for this peer * @def_bigtk_tx_keyid default bigtk key used for this peer * @fils_aead_set fils params for this peer + * @add_key_ctx: Opaque context to be used by the caller to associate the + * add key request with the response + * @add_key_cb: Callback function to be called with the add key result * */ struct wlan_crypto_comp_priv { @@ -444,6 +478,8 @@ struct wlan_crypto_comp_priv { uint8_t def_igtk_tx_keyid; uint8_t def_bigtk_tx_keyid; uint8_t fils_aead_set; + void *add_key_ctx; + crypto_add_key_callback add_key_cb; }; /** 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 99959628fc..91d571e785 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -35,6 +35,7 @@ #include "wlan_crypto_def_i.h" #include "wlan_crypto_param_handling_i.h" #include "wlan_crypto_obj_mgr_i.h" +#include "wlan_crypto_main.h" #include const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; @@ -4585,6 +4586,38 @@ void wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev *vdev) wlan_crypto_reset_prarams(&crypto_priv->crypto_params); } + +QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + 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_FAILURE; + } + + if (WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(tx_ops)) + return WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(tx_ops)(psoc); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + 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_FAILURE; + } + + if (WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(tx_ops)) + return WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(tx_ops)(psoc); + + return QDF_STATUS_E_FAILURE; +} #endif #ifdef WLAN_FEATURE_FILS_SK diff --git a/wmi/inc/wmi_unified_crypto_api.h b/wmi/inc/wmi_unified_crypto_api.h index 044ccc0e38..3dce977c0b 100644 --- a/wmi/inc/wmi_unified_crypto_api.h +++ b/wmi/inc/wmi_unified_crypto_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019, 2021 The Linux Foundation. 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 @@ -34,5 +34,19 @@ typedef enum { PMK_USAGE = 0x04, /* PMK cache */ } KEY_USAGE; +/** + * wmi_extract_install_key_comp_event() - extract params of install key complete + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @len: length of the event buffer + * @params: Pointer to hold params of install key complete + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +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); #endif diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 3e9eade363..dd9df446e9 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -7962,4 +7962,21 @@ struct wmi_host_pdev_get_dpd_status_event { uint32_t pdev_id; enum wmi_host_dpd_status dpd_status; }; + +/** + * struct wmi_install_key_comp_event - params of install key complete event + * @vdev_id: unique id identifying the VDEV, generated by the caller + * @key_ix: key index + * @key_flags: key flags + * @status: Event status + * @peer_macaddr: MAC address used for installing + */ +struct wmi_install_key_comp_event { + uint32_t vdev_id; + uint32_t key_ix; + uint32_t key_flags; + uint32_t status; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; +}; + #endif /* _WMI_UNIFIED_PARAM_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index fcbfd3232d..1f2abe7ddd 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -2528,6 +2528,7 @@ QDF_STATUS (*config_peer_latency_info_cmd)( QDF_STATUS (*send_set_tpc_power_cmd)(wmi_unified_t wmi_handle, uint8_t vdev_id, struct reg_tpc_power_info *param); + #ifdef WLAN_FEATURE_BIG_DATA_STATS QDF_STATUS (*send_big_data_stats_request_cmd)( wmi_unified_t wmi_handle, @@ -2536,6 +2537,11 @@ QDF_STATUS (*send_big_data_stats_request_cmd)( QDF_STATUS (*extract_dpd_status_ev_param)(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_host_pdev_get_dpd_status_event *param); + +QDF_STATUS +(*extract_install_key_comp_event)(wmi_unified_t wmi_handle, + void *evt_buf, uint32_t len, + struct wmi_install_key_comp_event *param); }; /* Forward declartion for psoc*/ diff --git a/wmi/src/wmi_unified_crypto_api.c b/wmi/src/wmi_unified_crypto_api.c new file mode 100644 index 0000000000..ac63bd8a8f --- /dev/null +++ b/wmi/src/wmi_unified_crypto_api.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, The Linux Foundation. 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** + * DOC: Implement API's specific to crypto component. + */ + +#include "wmi_unified_priv.h" +#include "wmi_unified_param.h" +#include "wmi_unified_crypto_api.h" + +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) +{ + if (wmi_handle->ops->extract_install_key_comp_event) + return wmi_handle->ops->extract_install_key_comp_event( + wmi_handle, evt_buf, len, param); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 4ff7d0a519..5568222ad7 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -15062,6 +15062,50 @@ extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +/** + * extract_install_key_comp_event_tlv() - extract install key complete event tlv + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @len: length of the event buffer + * @param: Pointer to hold install key complete event param + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +static QDF_STATUS +extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, + void *evt_buf, uint32_t len, + struct wmi_install_key_comp_event *param) +{ + WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; + wmi_vdev_install_key_complete_event_fixed_param *key_fp; + + if (len < sizeof(*param_buf)) { + wmi_err("invalid event buf len %d", len); + return QDF_STATUS_E_INVAL; + } + + param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; + if (!param_buf) { + wmi_err("received null buf from target"); + return QDF_STATUS_E_INVAL; + } + + key_fp = param_buf->fixed_param; + if (!key_fp) { + wmi_err("received null event data from target"); + return QDF_STATUS_E_INVAL; + } + + param->vdev_id = key_fp->vdev_id; + param->key_ix = key_fp->key_ix; + param->key_flags = key_fp->key_flags; + param->status = key_fp->status; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, + param->peer_macaddr); + + return QDF_STATUS_SUCCESS; +} + struct wmi_ops tlv_ops = { .send_vdev_create_cmd = send_vdev_create_cmd_tlv, .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, @@ -15430,6 +15474,7 @@ struct wmi_ops tlv_ops = { extract_pdev_csa_switch_count_status_tlv, .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, + .extract_install_key_comp_event = extract_install_key_comp_event_tlv, }; /**