فهرست منبع

qcacmn: Add Get RxPN WMI to obtain Rx PN

Add WMI support to obtain Rx packet number of a non-bss peer.

Change-Id: I841c1869299ebf5eeb21ee6406426a964d2d7112
CRs-Fixed: 3150832
Pooventhiran G 3 سال پیش
والد
کامیت
f5e2da429b

+ 5 - 0
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
  * @decap:  function pointer to decap rx frame in hw
  * @enmic: function pointer to enmic tx frame
  * @enmic: function pointer to enmic tx frame
  * @demic: function pointer to demic rx 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 {
 struct wlan_lmac_if_crypto_rx_ops {
@@ -472,6 +473,8 @@ struct wlan_lmac_if_crypto_rx_ops {
 					uint8_t tid, uint8_t keyid);
 					uint8_t tid, uint8_t keyid);
 	QDF_STATUS(*set_peer_wep_keys)(struct wlan_objmgr_vdev *vdev,
 	QDF_STATUS(*set_peer_wep_keys)(struct wlan_objmgr_vdev *vdev,
 					struct wlan_objmgr_peer *peer);
 					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) \
 #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)
 				(crypto_rx_ops->crypto_demic)
 #define WLAN_CRYPTO_RX_OPS_SET_PEER_WEP_KEYS(crypto_rx_ops) \
 #define WLAN_CRYPTO_RX_OPS_SET_PEER_WEP_KEYS(crypto_rx_ops) \
 				(crypto_rx_ops->set_peer_wep_keys)
 				(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_ */
 #endif /* end of _WLAN_CRYPTO_GLOBAL_DEF_H_ */

+ 23 - 5
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_crypto_key *key;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_lmac_if_tx_ops *tx_ops;
 	struct wlan_lmac_if_tx_ops *tx_ops;
+	struct wlan_lmac_if_rx_ops *rx_ops;
 	uint8_t macaddr[QDF_MAC_ADDR_SIZE] =
 	uint8_t macaddr[QDF_MAC_ADDR_SIZE] =
 			{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 			{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	QDF_STATUS status = QDF_STATUS_E_INVAL;
 	QDF_STATUS status = QDF_STATUS_E_INVAL;
 	struct wlan_objmgr_peer *peer = NULL;
 	struct wlan_objmgr_peer *peer = NULL;
 	uint8_t pdev_id;
 	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);
 	wlan_vdev_obj_lock(vdev);
 	qdf_mem_copy(macaddr, wlan_vdev_mlme_get_macaddr(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;
 		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)) {
 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
 		key = wlan_crypto_vdev_getkey(vdev, req_key->keyix);
 		key = wlan_crypto_vdev_getkey(vdev, req_key->keyix);
 		if (!key)
 		if (!key)
@@ -1365,10 +1380,13 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
 					sizeof(req_key->recviv));
 					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;
 	status = QDF_STATUS_SUCCESS;
@@ -3675,7 +3693,7 @@ exit:
  * Return: QDF_STATUS
  * Return: QDF_STATUS
  */
  */
 QDF_STATUS wlan_crypto_register_crypto_rx_ops(
 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_encap      = wlan_crypto_encap;
 	crypto_rx_ops->crypto_decap      = wlan_crypto_decap;
 	crypto_rx_ops->crypto_decap      = wlan_crypto_decap;
 	crypto_rx_ops->crypto_enmic      = wlan_crypto_enmic;
 	crypto_rx_ops->crypto_enmic      = wlan_crypto_enmic;

+ 14 - 0
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_ANTENNA          4
+#define WLAN_MGMT_TXRX_HOST_MAX_PN_LEN           8
 #define WLAN_INVALID_PER_CHAIN_RSSI             0xFF
 #define WLAN_INVALID_PER_CHAIN_RSSI             0xFF
 #define WLAN_INVALID_PER_CHAIN_SNR              0x80
 #define WLAN_INVALID_PER_CHAIN_SNR              0x80
 #define WLAN_NOISE_FLOOR_DBM_DEFAULT            -96
 #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
  * struct mgmt_rx_event_params - host mgmt header params
  * @chan_freq: channel frequency on which this frame is received
  * @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
  * @rx_params: pointer to other rx params
  *             (win specific, will be removed in phase 4)
  *             (win specific, will be removed in phase 4)
  * @reo_params: Pointer to MGMT Rx REO params
  * @reo_params: Pointer to MGMT Rx REO params
+ * @pn_params: Frame PN params
  */
  */
 struct mgmt_rx_event_params {
 struct mgmt_rx_event_params {
 	uint32_t    chan_freq;
 	uint32_t    chan_freq;
@@ -813,6 +826,7 @@ struct mgmt_rx_event_params {
 #ifdef WLAN_MGMT_RX_REO_SUPPORT
 #ifdef WLAN_MGMT_RX_REO_SUPPORT
 	struct mgmt_rx_reo_params *reo_params;
 	struct mgmt_rx_reo_params *reo_params;
 #endif
 #endif
+	struct frame_pn_params pn_params;
 };
 };
 
 
 #ifdef WLAN_MGMT_RX_REO_SUPPORT
 #ifdef WLAN_MGMT_RX_REO_SUPPORT

+ 24 - 0
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c

@@ -23,6 +23,8 @@
  *  southbound interface.
  *  southbound interface.
  */
  */
 
 
+#include <wmi_unified_param.h>
+
 #include "wlan_mgmt_txrx_tgt_api.h"
 #include "wlan_mgmt_txrx_tgt_api.h"
 #include "wlan_mgmt_txrx_utils_api.h"
 #include "wlan_mgmt_txrx_utils_api.h"
 #include "../../core/src/wlan_mgmt_txrx_main_i.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,
 				WLAN_SEQ_SEQ_SHIFT), mgmt_rx_params->rssi,
 				mgmt_rx_params->tsf_delta);
 				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))
 	if (simulation_frame_update(psoc, buf, mgmt_rx_params))
 		return QDF_STATUS_E_FAILURE;
 		return QDF_STATUS_E_FAILURE;
 
 

+ 14 - 0
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) 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
  * 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 wlan_lmac_if_set_umac_txops_registration_cb
 		(QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *));
 		(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
  * wlan_lmac_if_get_mgmt_txrx_rx_ops() - retrieve the mgmt rx_ops

+ 5 - 0
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)
 extern QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register)
 				(struct wlan_lmac_if_tx_ops *tx_ops);
 				(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
 #ifdef WLAN_FEATURE_SON
 /**
 /**
  * wlan_lmac_if_son_mod_register_rx_ops() - SON Module lmac_if rx_ops
  * 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);
 void wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops);
 #endif
 #endif
+
 #endif /* _WLAN_LMAC_IF_DEF_H_ */
 #endif /* _WLAN_LMAC_IF_DEF_H_ */

+ 25 - 0
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);
 				(struct wlan_lmac_if_tx_ops *tx_ops);
 qdf_export_symbol(wlan_lmac_if_umac_tx_ops_register);
 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
 static void
 tgt_vdev_mgr_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
 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_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);
 	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
 #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);
 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);

+ 34 - 0
wmi/inc/wmi_unified_api.h

@@ -1425,6 +1425,17 @@ QDF_STATUS
 wmi_unified_get_pn_send_cmd(wmi_unified_t wmi_hdl,
 wmi_unified_get_pn_send_cmd(wmi_unified_t wmi_hdl,
 			    struct peer_request_pn_param *pn_params);
 			    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_unified_p2p_go_set_beacon_ie_cmd() - set beacon IE for p2p go
  * @wmi_handle: wmi handle
  * @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,
 QDF_STATUS wmi_unified_extract_pn(wmi_unified_t wmi_hdl, void *evt_buf,
 			  struct wmi_host_get_pn_event *param);
 			  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
  * wmi_unified_send_periodic_chan_stats_config_cmd() - send periodic chan
  * stats cmd to fw
  * stats cmd to fw
@@ -2935,6 +2957,18 @@ QDF_STATUS wmi_unified_mgmt_rx_reo_filter_config_cmd(
 					struct mgmt_rx_reo_filter *filter);
 					struct mgmt_rx_reo_filter *filter);
 #endif
 #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_extract_vdev_roam_param() - extract vdev roam param from event
  * @wmi_handle: wmi handle
  * @wmi_handle: wmi handle

+ 29 - 0
wmi/inc/wmi_unified_param.h

@@ -3870,6 +3870,18 @@ struct peer_request_pn_param {
 	uint32_t key_type;
 	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
  * struct rtt_meas_req_params - RTT measurement request params
  * @req_id: Request id
  * @req_id: Request id
@@ -4927,6 +4939,7 @@ typedef enum {
 #ifdef WLAN_FEATURE_MCC_QUOTA
 #ifdef WLAN_FEATURE_MCC_QUOTA
 	wmi_resmgr_chan_time_quota_changed_eventid,
 	wmi_resmgr_chan_time_quota_changed_eventid,
 #endif
 #endif
+	wmi_peer_rx_pn_response_event_id,
 	wmi_events_max,
 	wmi_events_max,
 } wmi_conv_event_id;
 } wmi_conv_event_id;
 
 
@@ -5565,6 +5578,7 @@ typedef enum {
 #ifdef WLAN_FEATURE_11BE
 #ifdef WLAN_FEATURE_11BE
 	wmi_service_radar_found_chan_freq_eq_center_freq,
 	wmi_service_radar_found_chan_freq_eq_center_freq,
 #endif
 #endif
+	wmi_service_pn_replay_check_support,
 	wmi_services_max,
 	wmi_services_max,
 } wmi_conv_service_ids;
 } wmi_conv_service_ids;
 #define WMI_SERVICE_UNAVAILABLE 0xFFFF
 #define WMI_SERVICE_UNAVAILABLE 0xFFFF
@@ -7436,6 +7450,7 @@ enum wmi_host_fatal_condition_subtype_packet_log_config {
 #endif /* OL_ATH_SMART_LOGGING */
 #endif /* OL_ATH_SMART_LOGGING */
 
 
 #define GET_PN_MAX_LEN 16
 #define GET_PN_MAX_LEN 16
+#define GET_RX_PN_MAX_LEN 8
 
 
 /**
 /**
  * struct wmi_host_get_pn_event - PN event params
  * 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];
 	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
  * struct wmi_init_cmd_param - INIT command params
  * @target_resource_config: pointer to resource config
  * @target_resource_config: pointer to resource config

+ 8 - 0
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,
 QDF_STATUS (*extract_mgmt_rx_params)(wmi_unified_t wmi_handle, void *evt_buf,
 	struct mgmt_rx_event_params *hdr, uint8_t **bufp);
 	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,
 QDF_STATUS (*extract_vdev_stopped_param)(wmi_unified_t wmi_handle,
 		void *evt_buf, uint32_t *vdev_id);
 		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,
 QDF_STATUS (*extract_get_pn_data)(wmi_unified_t wmi_handle,
 				  void *evt_buf,
 				  void *evt_buf,
 				  struct wmi_host_get_pn_event *param);
 				  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
 #ifdef FEATURE_ANI_LEVEL_REQUEST
 QDF_STATUS (*send_ani_level_cmd)(wmi_unified_t wmi_handle, uint32_t *freqs,
 QDF_STATUS (*send_ani_level_cmd)(wmi_unified_t wmi_handle, uint32_t *freqs,
 				 uint8_t num_freqs);
 				 uint8_t num_freqs);

+ 35 - 0
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;
 	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
  *  wmi_unified_mgmt_cmd_send() - WMI mgmt cmd function
  *  @param wmi_handle      : handle to WMI.
  *  @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;
 	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
 #ifdef WLAN_FEATURE_DISA
 QDF_STATUS
 QDF_STATUS
 wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl, void *evt_buf,
 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
 #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
 QDF_STATUS
 wmi_extract_vdev_roam_param(wmi_unified_t wmi_handle, void *evt_buf,
 wmi_extract_vdev_roam_param(wmi_unified_t wmi_handle, void *evt_buf,
 			    wmi_host_roam_event *param)
 			    wmi_host_roam_event *param)

+ 124 - 0
wmi/src/wmi_unified_tlv.c

@@ -11584,6 +11584,51 @@ static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv(
 }
 }
 #endif
 #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
  * extract_vdev_roam_param_tlv() - extract vdev roam param from event
  * @wmi_handle: wmi handle
  * @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;
 	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
  * extract_fips_event_data_tlv() - extract fips event data
  * @wmi_handle: wmi handle
  * @wmi_handle: wmi handle
@@ -17411,6 +17528,7 @@ struct wmi_ops tlv_ops =  {
 	.extract_ready_event_params = extract_ready_event_params_tlv,
 	.extract_ready_event_params = extract_ready_event_params_tlv,
 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
 	.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
 	.extract_mgmt_rx_params = extract_mgmt_rx_params_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_roam_param = extract_vdev_roam_param_tlv,
 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
 	.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
 #ifdef FEATURE_WLAN_SCAN_PNO
 #ifdef FEATURE_WLAN_SCAN_PNO
@@ -17469,6 +17587,8 @@ struct wmi_ops tlv_ops =  {
 #endif
 #endif
 	.extract_get_pn_data = extract_get_pn_data_tlv,
 	.extract_get_pn_data = extract_get_pn_data_tlv,
 	.send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_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,
 	.send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv,
 #ifdef WLAN_FEATURE_DISA
 #ifdef WLAN_FEATURE_DISA
 	.send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv,
 	.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] =
 	event_ids[wmi_resmgr_chan_time_quota_changed_eventid] =
 			WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID;
 			WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID;
 #endif
 #endif
+	event_ids[wmi_peer_rx_pn_response_event_id] =
+		WMI_PEER_RX_PN_RESPONSE_EVENTID;
 }
 }
 
 
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
 #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_service[wmi_service_radar_found_chan_freq_eq_center_freq] =
 		WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ;
 		WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ;
 #endif
 #endif
+	wmi_service[wmi_service_pn_replay_check_support] =
+			WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT;
 }
 }
 
 
 /**
 /**