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 faf13f0015..89ce340830 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h @@ -455,6 +455,7 @@ struct wlan_lmac_if_crypto_tx_ops { * @decap: function pointer to decap rx frame in hw * @enmic: function pointer to enmic tx frame * @demic: function pointer to demic rx frame + * @get_rxpn: function pointer to get current Rx pn value of peer */ struct wlan_lmac_if_crypto_rx_ops { @@ -472,6 +473,8 @@ struct wlan_lmac_if_crypto_rx_ops { uint8_t tid, uint8_t keyid); QDF_STATUS(*set_peer_wep_keys)(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_peer *peer); + QDF_STATUS (*get_rxpn)(struct wlan_objmgr_vdev *vdev, + uint8_t *macaddr, uint16_t keyix); }; #define WLAN_CRYPTO_RX_OPS_ENCAP(crypto_rx_ops) \ @@ -484,5 +487,7 @@ struct wlan_lmac_if_crypto_rx_ops { (crypto_rx_ops->crypto_demic) #define WLAN_CRYPTO_RX_OPS_SET_PEER_WEP_KEYS(crypto_rx_ops) \ (crypto_rx_ops->set_peer_wep_keys) +#define WLAN_CRYPTO_RX_OPS_GET_RXPN(crypto_rx_ops) \ + ((crypto_rx_ops)->get_rxpn) #endif /* end of _WLAN_CRYPTO_GLOBAL_DEF_H_ */ 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 5edee89842..599cb3d32d 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -1286,11 +1286,20 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *key; struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_tx_ops *tx_ops; + struct wlan_lmac_if_rx_ops *rx_ops; uint8_t macaddr[QDF_MAC_ADDR_SIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_peer *peer = NULL; uint8_t pdev_id; + uint16_t get_pn_enable; + + if (!req_key) { + crypto_err("req_key NULL"); + return QDF_STATUS_E_INVAL; + } + + get_pn_enable = req_key->flags & WLAN_CRYPTO_KEY_GET_PN; wlan_vdev_obj_lock(vdev); qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(vdev), @@ -1309,6 +1318,12 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } + rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); + if (!rx_ops) { + crypto_err("rx_ops is NULL"); + return QDF_STATUS_E_INVAL; + } + if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) { key = wlan_crypto_vdev_getkey(vdev, req_key->keyix); if (!key) @@ -1365,10 +1380,13 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev, sizeof(req_key->recviv)); } - if (WLAN_CRYPTO_TX_OPS_GETPN(tx_ops) && - (req_key->flags & WLAN_CRYPTO_KEY_GET_PN)) { - WLAN_CRYPTO_TX_OPS_GETPN(tx_ops)(vdev, mac_addr, - req_key->type); + if (get_pn_enable) { + if (WLAN_CRYPTO_TX_OPS_GETPN(tx_ops)) + WLAN_CRYPTO_TX_OPS_GETPN(tx_ops)(vdev, mac_addr, + req_key->type); + if (WLAN_CRYPTO_RX_OPS_GET_RXPN(&rx_ops->crypto_rx_ops)) + WLAN_CRYPTO_RX_OPS_GET_RXPN(&rx_ops->crypto_rx_ops)( + vdev, mac_addr, req_key->keyix); } } status = QDF_STATUS_SUCCESS; @@ -3675,7 +3693,7 @@ exit: * Return: QDF_STATUS */ QDF_STATUS wlan_crypto_register_crypto_rx_ops( - struct wlan_lmac_if_crypto_rx_ops *crypto_rx_ops){ + struct wlan_lmac_if_crypto_rx_ops *crypto_rx_ops) { crypto_rx_ops->crypto_encap = wlan_crypto_encap; crypto_rx_ops->crypto_decap = wlan_crypto_decap; crypto_rx_ops->crypto_enmic = wlan_crypto_enmic; diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index 6f161580fe..94968d4388 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -768,9 +768,21 @@ enum mgmt_frame_type { }; #define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4 +#define WLAN_MGMT_TXRX_HOST_MAX_PN_LEN 8 #define WLAN_INVALID_PER_CHAIN_RSSI 0xFF #define WLAN_INVALID_PER_CHAIN_SNR 0x80 #define WLAN_NOISE_FLOOR_DBM_DEFAULT -96 + +/** + * struct frame_pn_params - host PN params + * @curr_pn: current running PN of rx frames + * @prev_pn: previous PN of rx frames + */ +struct frame_pn_params { + uint8_t curr_pn[WLAN_MGMT_TXRX_HOST_MAX_PN_LEN]; + uint8_t prev_pn[WLAN_MGMT_TXRX_HOST_MAX_PN_LEN]; +}; + /** * struct mgmt_rx_event_params - host mgmt header params * @chan_freq: channel frequency on which this frame is received @@ -794,6 +806,7 @@ enum mgmt_frame_type { * @rx_params: pointer to other rx params * (win specific, will be removed in phase 4) * @reo_params: Pointer to MGMT Rx REO params + * @pn_params: Frame PN params */ struct mgmt_rx_event_params { uint32_t chan_freq; @@ -813,6 +826,7 @@ struct mgmt_rx_event_params { #ifdef WLAN_MGMT_RX_REO_SUPPORT struct mgmt_rx_reo_params *reo_params; #endif + struct frame_pn_params pn_params; }; #ifdef WLAN_MGMT_RX_REO_SUPPORT diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c index 58c6ad7732..019c59a95d 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c +++ b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c @@ -23,6 +23,8 @@ * southbound interface. */ +#include + #include "wlan_mgmt_txrx_tgt_api.h" #include "wlan_mgmt_txrx_utils_api.h" #include "../../core/src/wlan_mgmt_txrx_main_i.h" @@ -1207,6 +1209,28 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler( WLAN_SEQ_SEQ_SHIFT), mgmt_rx_params->rssi, mgmt_rx_params->tsf_delta); + /* Print a hexdump of packet for host debug */ + if (mgmt_type == IEEE80211_FC0_TYPE_MGT && + ((mgmt_rx_params->status & WMI_HOST_RXERR_PN) || + (mgmt_rx_params->status & WMI_HOST_RXERR_CRC) || + (mgmt_rx_params->status & WMI_HOST_RXERR_DECRYPT) || + (mgmt_rx_params->status & WMI_HOST_RXERR_MIC) || + (mgmt_rx_params->status & WMI_HOST_RXERR_KEY_CACHE_MISS))) { + uint64_t curr_pn, prev_pn; + uint8_t *pn = NULL; + + pn = mgmt_rx_params->pn_params.curr_pn; + curr_pn = qdf_le64_to_cpu(*((uint64_t *)pn)); + + pn = mgmt_rx_params->pn_params.prev_pn; + prev_pn = qdf_le64_to_cpu(*((uint64_t *)pn)); + + mgmt_txrx_debug("Current PN=0x%llx Previous PN=0x%llx. Packet dumped below", + curr_pn, prev_pn); + qdf_trace_hex_dump(QDF_MODULE_ID_MGMT_TXRX, + QDF_TRACE_LEVEL_DEBUG, data, buflen); + } + if (simulation_frame_update(psoc, buf, mgmt_rx_params)) return QDF_STATUS_E_FAILURE; diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h index dc42ee1f7d..651ee9ceb7 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2018, 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 @@ -49,6 +50,19 @@ QDF_STATUS wlan_lmac_if_umac_rx_ops_register QDF_STATUS wlan_lmac_if_set_umac_txops_registration_cb (QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *)); +/** + * wlan_lmac_if_set_umac_crypto_rxpn_ops_registration_cb() - crypto rxpn + * registration callback assignment + * @dev_type: Dev type can be either Direct attach or Offload + * @handler: handler to be called for LMAC crypto rxpn ops registration + * + * API to assign appropriate crypto rxpn registration callback handler + * based on the device type + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS wlan_lmac_if_set_umac_crypto_rxpn_ops_registration_cb + (QDF_STATUS (*handler)(struct wlan_lmac_if_rx_ops *)); /** * wlan_lmac_if_get_mgmt_txrx_rx_ops() - retrieve the mgmt rx_ops 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 bcfa36c1b7..43f27c49dc 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 @@ -2258,6 +2258,10 @@ struct wlan_lmac_if_rx_ops { */ extern QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register) (struct wlan_lmac_if_tx_ops *tx_ops); + +/* Function pointer to call legacy crypto rxpn registration in OL */ +extern QDF_STATUS (*wlan_lmac_if_umac_crypto_rxpn_ops_register) + (struct wlan_lmac_if_rx_ops *rx_ops); #ifdef WLAN_FEATURE_SON /** * wlan_lmac_if_son_mod_register_rx_ops() - SON Module lmac_if rx_ops @@ -2270,4 +2274,5 @@ extern QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register) */ void wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops); #endif + #endif /* _WLAN_LMAC_IF_DEF_H_ */ diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index 7e5f700a86..ef254f47f6 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -91,6 +91,11 @@ QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register) (struct wlan_lmac_if_tx_ops *tx_ops); qdf_export_symbol(wlan_lmac_if_umac_tx_ops_register); +/* Function pointer to call legacy crypto rxpn registration in OL */ +QDF_STATUS (*wlan_lmac_if_umac_crypto_rxpn_ops_register) + (struct wlan_lmac_if_rx_ops *rx_ops); +qdf_export_symbol(wlan_lmac_if_umac_crypto_rxpn_ops_register); + static void tgt_vdev_mgr_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) { @@ -297,6 +302,8 @@ static void wlan_lmac_if_crypto_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) { wlan_crypto_register_crypto_rx_ops(&rx_ops->crypto_rx_ops); + if (wlan_lmac_if_umac_crypto_rxpn_ops_register) + wlan_lmac_if_umac_crypto_rxpn_ops_register(rx_ops); } #ifdef WIFI_POS_CONVERGED @@ -970,3 +977,21 @@ QDF_STATUS wlan_lmac_if_set_umac_txops_registration_cb(QDF_STATUS (*handler) } qdf_export_symbol(wlan_lmac_if_set_umac_txops_registration_cb); +/** + * wlan_lmac_if_set_umac_crypto_rxpn_ops_registration_cb() - crypto rxpn + * registration callback assignment + * @dev_type: Dev type can be either Direct attach or Offload + * @handler: handler to be called for LMAC crypto rxpn ops registration + * + * API to assign appropriate crypto rxpn registration callback handler + * based on the device type + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS wlan_lmac_if_set_umac_crypto_rxpn_ops_registration_cb( + QDF_STATUS (*handler)(struct wlan_lmac_if_rx_ops *)) +{ + wlan_lmac_if_umac_crypto_rxpn_ops_register = handler; + return QDF_STATUS_SUCCESS; +} +qdf_export_symbol(wlan_lmac_if_set_umac_crypto_rxpn_ops_registration_cb); diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 4dfd00c147..53fa7d6b96 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1425,6 +1425,17 @@ QDF_STATUS wmi_unified_get_pn_send_cmd(wmi_unified_t wmi_hdl, struct peer_request_pn_param *pn_params); +/** + * wmi_unified_get_rxpn_send_cmd() - send command to fw get Rx PN for peer + * @wmi_handle: wmi handle + * @pn_params: PN parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_get_rxpn_send_cmd(wmi_unified_t wmi_hdl, + struct peer_request_rxpn_param *pn_params); + /** * wmi_unified_p2p_go_set_beacon_ie_cmd() - set beacon IE for p2p go * @wmi_handle: wmi handle @@ -2839,6 +2850,17 @@ QDF_STATUS wmi_unified_lcr_set_cmd_send(wmi_unified_t wmi_handle, QDF_STATUS wmi_unified_extract_pn(wmi_unified_t wmi_hdl, void *evt_buf, struct wmi_host_get_pn_event *param); +/** + * wmi_unified_extract_rxpn() - extract Rx PN event data + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: pointer to get Rx PN event param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extract_rxpn(wmi_unified_t wmi_hdl, void *evt_buf, + struct wmi_host_get_rxpn_event *param); + /** * wmi_unified_send_periodic_chan_stats_config_cmd() - send periodic chan * stats cmd to fw @@ -2935,6 +2957,18 @@ QDF_STATUS wmi_unified_mgmt_rx_reo_filter_config_cmd( struct mgmt_rx_reo_filter *filter); #endif +/** + * wmi_extract_frame_pn_params() - extract PN params from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @pn_params: Pointer to Frame PN params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_frame_pn_params(wmi_unified_t wmi_handle, void *evt_buf, + struct frame_pn_params *pn_params); + /** * wmi_extract_vdev_roam_param() - extract vdev roam param from event * @wmi_handle: wmi handle diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index f5fee760fb..deb0192e8f 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -3870,6 +3870,18 @@ struct peer_request_pn_param { uint32_t key_type; }; +/** + * struct peer_request_rxpn_param - Rx PN request params + * @vdev_id: vdev id + * @peer_macaddr: Peer mac address + * @keyix: key index + */ +struct peer_request_rxpn_param { + uint32_t vdev_id; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; + uint16_t keyix; +}; + /** * struct rtt_meas_req_params - RTT measurement request params * @req_id: Request id @@ -4927,6 +4939,7 @@ typedef enum { #ifdef WLAN_FEATURE_MCC_QUOTA wmi_resmgr_chan_time_quota_changed_eventid, #endif + wmi_peer_rx_pn_response_event_id, wmi_events_max, } wmi_conv_event_id; @@ -5565,6 +5578,7 @@ typedef enum { #ifdef WLAN_FEATURE_11BE wmi_service_radar_found_chan_freq_eq_center_freq, #endif + wmi_service_pn_replay_check_support, wmi_services_max, } wmi_conv_service_ids; #define WMI_SERVICE_UNAVAILABLE 0xFFFF @@ -7436,6 +7450,7 @@ enum wmi_host_fatal_condition_subtype_packet_log_config { #endif /* OL_ATH_SMART_LOGGING */ #define GET_PN_MAX_LEN 16 +#define GET_RX_PN_MAX_LEN 8 /** * struct wmi_host_get_pn_event - PN event params @@ -7451,6 +7466,20 @@ struct wmi_host_get_pn_event { uint8_t pn[GET_PN_MAX_LEN]; }; +/** + * struct wmi_host_get_rxpn_event - Rx PN event params + * @vdev_id: vdev id + * @peer_macaddr: Peer mac address + * @keyix: key index + * @pn: pn value + */ +struct wmi_host_get_rxpn_event { + uint32_t vdev_id; + uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + uint16_t keyix; + uint8_t pn[GET_RX_PN_MAX_LEN]; +}; + /** * struct wmi_init_cmd_param - INIT command params * @target_resource_config: pointer to resource config diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 20ac0a0839..a4a7360972 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1851,6 +1851,9 @@ QDF_STATUS (*extract_muedca_params_handler)(wmi_unified_t wmi_hdl, QDF_STATUS (*extract_mgmt_rx_params)(wmi_unified_t wmi_handle, void *evt_buf, struct mgmt_rx_event_params *hdr, uint8_t **bufp); +QDF_STATUS (*extract_frame_pn_params)(wmi_unified_t wmi_handle, void *evt_buf, + struct frame_pn_params *pn_params); + QDF_STATUS (*extract_vdev_stopped_param)(wmi_unified_t wmi_handle, void *evt_buf, uint32_t *vdev_id); @@ -2721,6 +2724,11 @@ QDF_STATUS (*send_pdev_get_pn_cmd)(wmi_unified_t wmi_handle, QDF_STATUS (*extract_get_pn_data)(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_host_get_pn_event *param); +QDF_STATUS (*send_pdev_get_rxpn_cmd)(wmi_unified_t wmi_handle, + struct peer_request_rxpn_param *pn_params); +QDF_STATUS (*extract_get_rxpn_data)(wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_host_get_rxpn_event *param); #ifdef FEATURE_ANI_LEVEL_REQUEST QDF_STATUS (*send_ani_level_cmd)(wmi_unified_t wmi_handle, uint32_t *freqs, uint8_t num_freqs); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 1028d8763e..3e008d2fe4 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -1513,6 +1513,18 @@ QDF_STATUS wmi_unified_get_pn_send_cmd(wmi_unified_t wmi_hdl, return QDF_STATUS_E_FAILURE; } +QDF_STATUS wmi_unified_get_rxpn_send_cmd( + wmi_unified_t wmi_hdl, + struct peer_request_rxpn_param *pn_params) +{ + if (wmi_hdl->ops->send_pdev_get_rxpn_cmd) + return wmi_hdl->ops->send_pdev_get_rxpn_cmd(wmi_hdl, + pn_params); + + return QDF_STATUS_E_FAILURE; +} +qdf_export_symbol(wmi_unified_get_rxpn_send_cmd); + /** * wmi_unified_mgmt_cmd_send() - WMI mgmt cmd function * @param wmi_handle : handle to WMI. @@ -1992,6 +2004,17 @@ QDF_STATUS wmi_unified_extract_pn(wmi_unified_t wmi_hdl, void *evt_buf, return QDF_STATUS_E_FAILURE; } +QDF_STATUS wmi_unified_extract_rxpn(wmi_unified_t wmi_hdl, void *evt_buf, + struct wmi_host_get_rxpn_event *param) +{ + if (wmi_hdl->ops->extract_get_rxpn_data) + return wmi_hdl->ops->extract_get_rxpn_data(wmi_hdl, + evt_buf, param); + return QDF_STATUS_E_FAILURE; +} + +qdf_export_symbol(wmi_unified_extract_rxpn); + #ifdef WLAN_FEATURE_DISA QDF_STATUS wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl, void *evt_buf, @@ -2057,6 +2080,18 @@ QDF_STATUS wmi_unified_mgmt_rx_reo_filter_config_cmd( } #endif +QDF_STATUS +wmi_extract_frame_pn_params(wmi_unified_t wmi_handle, void *evt_buf, + struct frame_pn_params *pn_params) +{ + if (wmi_handle->ops->extract_frame_pn_params) + return wmi_handle->ops->extract_frame_pn_params(wmi_handle, + evt_buf, + pn_params); + + return QDF_STATUS_E_FAILURE; +} + QDF_STATUS wmi_extract_vdev_roam_param(wmi_unified_t wmi_handle, void *evt_buf, wmi_host_roam_event *param) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 4206a0ea9c..fc7bc8733d 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -11584,6 +11584,51 @@ static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( } #endif +/** + * extract_frame_pn_params_tlv() - extract PN params from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @pn_params: Pointer to Frame PN params + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, + void *evt_buf, + struct frame_pn_params *pn_params) +{ + WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; + wmi_frame_pn_params *pn_params_tlv; + + if (!is_service_enabled_tlv(wmi_handle, + WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) + return QDF_STATUS_SUCCESS; + + param_tlvs = evt_buf; + if (!param_tlvs) { + wmi_err("Got NULL point message from FW"); + return QDF_STATUS_E_INVAL; + } + + if (!pn_params) { + wmi_err("PN Params is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* PN Params TLV will be populated only if WMI_RXERR_PN error is + * found by target + */ + pn_params_tlv = param_tlvs->pn_params; + if (!pn_params_tlv) + return QDF_STATUS_SUCCESS; + + qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, + sizeof(pn_params->curr_pn)); + qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, + sizeof(pn_params->prev_pn)); + + return QDF_STATUS_SUCCESS; +} + /** * extract_vdev_roam_param_tlv() - extract vdev roam param from event * @wmi_handle: wmi handle @@ -13238,6 +13283,78 @@ extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, return QDF_STATUS_SUCCESS; } +/** + * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw + * @wmi_handle: wmi handle + * @params: Rx PN request params for peer + * + * Return: QDF_STATUS - success or error status + */ +static QDF_STATUS +send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, + struct peer_request_rxpn_param *params) +{ + wmi_peer_rx_pn_request_cmd_fixed_param *cmd; + wmi_buf_t buf; + uint8_t *buf_ptr; + uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); + + if (!is_service_enabled_tlv(wmi_handle, + WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { + wmi_err("Rx PN Replay Check not supported by target"); + return QDF_STATUS_E_NOSUPPORT; + } + + 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); + cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); + + cmd->vdev_id = params->vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); + cmd->key_ix = params->keyix; + if (wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_PEER_RX_PN_REQUEST_CMDID)) { + wmi_err("Failed to send WMI command"); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +} + +/** + * extract_get_rxpn_data_tlv() - extract Rx PN resp + * @wmi_handle: wmi handle + * @params: Rx PN response params for peer + * + * Return: QDF_STATUS - success or error status + */ +static QDF_STATUS +extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_host_get_rxpn_event *params) +{ + WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; + wmi_peer_rx_pn_response_event_fixed_param *event; + + param_buf = evt_buf; + event = param_buf->fixed_param; + + params->vdev_id = event->vdev_id; + params->keyix = event->key_idx; + qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); + WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); + + return QDF_STATUS_SUCCESS; +} + /** * extract_fips_event_data_tlv() - extract fips event data * @wmi_handle: wmi handle @@ -17411,6 +17528,7 @@ struct wmi_ops tlv_ops = { .extract_ready_event_params = extract_ready_event_params_tlv, .extract_dbglog_data_len = extract_dbglog_data_len_tlv, .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, + .extract_frame_pn_params = extract_frame_pn_params_tlv, .extract_vdev_roam_param = extract_vdev_roam_param_tlv, .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, #ifdef FEATURE_WLAN_SCAN_PNO @@ -17469,6 +17587,8 @@ struct wmi_ops tlv_ops = { #endif .extract_get_pn_data = extract_get_pn_data_tlv, .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, + .extract_get_rxpn_data = extract_get_rxpn_data_tlv, + .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, #ifdef WLAN_FEATURE_DISA .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, @@ -18108,6 +18228,8 @@ event_ids[wmi_roam_scan_chan_list_id] = event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; #endif + event_ids[wmi_peer_rx_pn_response_event_id] = + WMI_PEER_RX_PN_RESPONSE_EVENTID; } #ifdef WLAN_FEATURE_LINK_LAYER_STATS @@ -18571,6 +18693,8 @@ static void populate_tlv_service(uint32_t *wmi_service) wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; #endif + wmi_service[wmi_service_pn_replay_check_support] = + WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; } /**