qcacmn: Add support to cache peer capability info

Currently capability information and RX multicast broadcast
packet count of the connected peer is not getting
cached.
Add support to cache the capability info from assoc request and
RX multicast broadcast packets from FW.

Change-Id: I105e055b1e440852e8e6b508c25e45f79db2d062
CRs-Fixed: 2409521
diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h
index fe2e783..ef9db55 100644
--- a/os_if/linux/qca_vendor.h
+++ b/os_if/linux/qca_vendor.h
@@ -770,9 +770,10 @@
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC,
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH,
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD,
-#endif
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT,
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX =
diff --git a/target_if/cp_stats/src/target_if_mc_cp_stats.c b/target_if/cp_stats/src/target_if_mc_cp_stats.c
index 6886b30..c91f50a 100644
--- a/target_if/cp_stats/src/target_if_mc_cp_stats.c
+++ b/target_if/cp_stats/src/target_if_mc_cp_stats.c
@@ -43,6 +43,8 @@
 	ev->peer_stats = NULL;
 	qdf_mem_free(ev->peer_adv_stats);
 	ev->peer_adv_stats = NULL;
+	qdf_mem_free(ev->peer_extended_stats);
+	ev->peer_extended_stats = NULL;
 	qdf_mem_free(ev->cca_stats);
 	ev->cca_stats = NULL;
 	qdf_mem_free(ev->vdev_summary_stats);
@@ -86,6 +88,43 @@
 	return QDF_STATUS_SUCCESS;
 }
 
+static void target_if_cp_stats_extract_peer_extd_stats(
+	struct wmi_unified *wmi_hdl,
+	wmi_host_stats_event *stats_param,
+	struct stats_event *ev,
+	uint8_t *data)
+
+{
+	QDF_STATUS status;
+	uint32_t i;
+	wmi_host_peer_extd_stats peer_extd_stats;
+
+	if (!stats_param->num_peer_extd_stats)
+		return;
+
+	ev->peer_extended_stats =
+			qdf_mem_malloc(sizeof(*ev->peer_extended_stats) *
+				       stats_param->num_peer_extd_stats);
+	if (!ev->peer_extended_stats)
+		return;
+
+	ev->num_peer_extd_stats = stats_param->num_peer_extd_stats;
+
+	for (i = 0; i < ev->num_peer_extd_stats; i++) {
+		status = wmi_extract_peer_extd_stats(wmi_hdl, data, i,
+						     &peer_extd_stats);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			cp_stats_err("wmi_extract_peer_extd_stats failed");
+			continue;
+		}
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(
+			     &peer_extd_stats.peer_macaddr,
+			ev->peer_extended_stats[i].peer_macaddr);
+		ev->peer_extended_stats[i].rx_mc_bc_cnt =
+						peer_extd_stats.rx_mc_bc_cnt;
+	}
+}
+
 static QDF_STATUS target_if_cp_stats_extract_peer_stats(
 					struct wmi_unified *wmi_hdl,
 					wmi_host_stats_event *stats_param,
@@ -99,14 +138,14 @@
 	struct wmi_host_peer_adv_stats *peer_adv_stats;
 
 	/* Extract peer_stats */
-	ev->num_peer_stats = stats_param->num_peer_stats;
-	if (!ev->num_peer_stats)
+	if (!stats_param->num_peer_stats)
 		return QDF_STATUS_SUCCESS;
 
 	ev->peer_stats = qdf_mem_malloc(sizeof(*ev->peer_stats) *
-						ev->num_peer_stats);
+						stats_param->num_peer_stats);
 	if (!ev->peer_stats)
 		return QDF_STATUS_E_NOMEM;
+	ev->num_peer_stats = stats_param->num_peer_stats;
 
 	db2dbm_enabled = wmi_service_enabled(wmi_hdl,
 					     wmi_service_hw_db2dbm_support);
@@ -127,6 +166,9 @@
 							TGT_NOISE_FLOOR_DBM;
 	}
 
+	target_if_cp_stats_extract_peer_extd_stats(wmi_hdl, stats_param, ev,
+						   data);
+
 	/* Extract peer_adv_stats */
 	ev->num_peer_adv_stats = stats_param->num_peer_adv_stats;
 	if (!ev->num_peer_adv_stats)
@@ -540,7 +582,7 @@
 	case TYPE_CONNECTION_TX_POWER:
 		return WMI_REQUEST_PDEV_STAT;
 	case TYPE_PEER_STATS:
-		return WMI_REQUEST_PEER_STAT;
+		return WMI_REQUEST_PEER_STAT | WMI_REQUEST_PEER_EXTD_STAT;
 	case TYPE_STATION_STATS:
 		return (WMI_REQUEST_AP_STAT   |
 			WMI_REQUEST_PEER_STAT |
diff --git a/umac/cp_stats/core/src/wlan_cp_stats_defs.h b/umac/cp_stats/core/src/wlan_cp_stats_defs.h
index dcad1b2..4381cfa 100644
--- a/umac/cp_stats/core/src/wlan_cp_stats_defs.h
+++ b/umac/cp_stats/core/src/wlan_cp_stats_defs.h
@@ -88,6 +88,7 @@
  * @peer_obj: pointer to peer
  * @peer_stats: pointer to ic/mc specific stats
  * @peer_adv_stats: pointer to peer adv stats
+ * @peer_extd_stats: Pointer to peer extended stats
  * @peer_comp_priv_obj[]: component's private object pointers
  * @peer_cp_stats_lock:	lock to protect object
  */
@@ -95,6 +96,7 @@
 	struct wlan_objmgr_peer  *peer_obj;
 	void                     *peer_stats;
 	void                     *peer_adv_stats;
+	void                     *peer_extd_stats;
 	void *peer_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS];
 	qdf_spinlock_t peer_cp_stats_lock;
 };
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h
index b5138e8..357b862 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h
@@ -238,6 +238,28 @@
 };
 
 /**
+ * struct peer_extd_stats - Peer extension statistics
+ * @peer_macaddr: peer MAC address
+ * @rx_duration: lower 32 bits of rx duration in microseconds
+ * @peer_tx_bytes: Total TX bytes (including dot11 header) sent to peer
+ * @peer_rx_bytes: Total RX bytes (including dot11 header) received from peer
+ * @last_tx_rate_code: last TX ratecode
+ * @last_tx_power: TX power used by peer - units are 0.5 dBm
+ * @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames
+ * corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a
+ * valid data
+ */
+struct peer_extd_stats {
+	uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
+	uint32_t rx_duration;
+	uint32_t peer_tx_bytes;
+	uint32_t peer_rx_bytes;
+	uint32_t last_tx_rate_code;
+	int32_t last_tx_power;
+	uint32_t rx_mc_bc_cnt;
+};
+
+/**
  * struct peer_mc_cp_stats - peer specific stats
  * @tx_rate: tx rate
  * @rx_rate: rx rate
@@ -303,6 +325,8 @@
  * @peer_stats: if populated array indicating peer stats
  * @peer_adv_stats: if populated, indicates peer adv (extd2) stats
  * @num_peer_adv_stats: number of peer adv (extd2) stats
+ * @num_peer_extd_stats: Num peer extended stats
+ * @peer_extended_stats: Peer extended stats
  * @cca_stats: if populated indicates congestion stats
  * @num_summary_stats: number of summary stats
  * @vdev_summary_stats: if populated indicates array of summary stats per vdev
@@ -320,6 +344,8 @@
 	struct peer_mc_cp_stats *peer_stats;
 	uint32_t num_peer_adv_stats;
 	struct peer_adv_mc_cp_stats *peer_adv_stats;
+	uint32_t num_peer_extd_stats;
+	struct peer_extd_stats *peer_extended_stats;
 	struct congestion_stats_event *cca_stats;
 	uint32_t num_summary_stats;
 	struct summary_stats_event *vdev_summary_stats;
diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c
index 03dcc74..edad12c 100644
--- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c
+++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c
@@ -115,6 +115,7 @@
 	struct stats_event *ev;
 	struct peer_mc_cp_stats *peer_mc_stats;
 	struct peer_cp_stats *peer_cp_stats_priv;
+	struct peer_extd_stats *peer_extd_mc_stats;
 
 	if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) {
 		cp_stats_err("ignore self peer: %pM",
@@ -133,6 +134,10 @@
 	ev = arg;
 	ev->peer_stats[ev->num_peer_stats] = *peer_mc_stats;
 	ev->num_peer_stats++;
+
+	peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats;
+	ev->peer_extended_stats[ev->num_peer_extd_stats] = *peer_extd_mc_stats;
+	ev->num_peer_extd_stats++;
 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
 }
 
@@ -147,6 +152,7 @@
 	struct wlan_objmgr_vdev *vdev;
 	struct wlan_objmgr_peer *peer = NULL;
 	struct peer_mc_cp_stats *peer_mc_stats;
+	struct peer_extd_stats *peer_mc_extd_stats;
 	struct peer_cp_stats *peer_cp_stats_priv;
 	void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie);
 
@@ -172,6 +178,12 @@
 		if (!ev.peer_stats)
 			goto end;
 
+		ev.peer_extended_stats =
+			qdf_mem_malloc(sizeof(*ev.peer_extended_stats) *
+				       peer_count);
+		if (!ev.peer_extended_stats)
+			goto end;
+
 		wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP,
 						  peer_rssi_iterator, &ev,
 						  true, WLAN_CP_STATS_ID);
@@ -194,9 +206,20 @@
 			goto end;
 
 		ev.num_peer_stats = 1;
+
+		ev.peer_extended_stats =
+			qdf_mem_malloc(sizeof(*ev.peer_extended_stats));
+		if (!ev.peer_extended_stats)
+			goto end;
+
+		ev.num_peer_extd_stats = 1;
+
 		wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
 		peer_mc_stats = peer_cp_stats_priv->peer_stats;
 		*ev.peer_stats = *peer_mc_stats;
+
+		peer_mc_extd_stats = peer_cp_stats_priv->peer_extd_stats;
+		*ev.peer_extended_stats = *peer_mc_extd_stats;
 		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
 	}
 
@@ -299,8 +322,7 @@
 		peer_mc_stats->rx_rate = peer_stats->rx_rate;
 	if (peer_stats->peer_rssi)
 		peer_mc_stats->peer_rssi = peer_stats->peer_rssi;
-
-	cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%u",
+	cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%d",
 		       peer_mc_stats->peer_macaddr, peer_mc_stats->tx_rate,
 		       peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi);
 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
@@ -312,6 +334,103 @@
 	return status;
 }
 
+static QDF_STATUS
+tgt_mc_cp_stats_update_peer_extd_stats(
+				struct wlan_objmgr_psoc *psoc,
+				struct peer_extd_stats *peer_extended_stats)
+{
+	uint8_t *peer_mac_addr;
+	struct wlan_objmgr_peer *peer;
+	struct peer_extd_stats *peer_extd_mc_stats;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct peer_cp_stats *peer_cp_stats_priv;
+
+	if (!peer_extended_stats)
+		return QDF_STATUS_E_INVAL;
+
+	peer_mac_addr = peer_extended_stats->peer_macaddr;
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
+					   WLAN_CP_STATS_ID);
+	if (!peer) {
+		cp_stats_err("peer is null");
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
+	if (!peer_cp_stats_priv) {
+		cp_stats_err("peer_cp_stats_priv is null");
+		status = QDF_STATUS_E_EXISTS;
+		goto end;
+	}
+
+	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
+	peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats;
+	if (!peer_extd_mc_stats) {
+		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+		cp_stats_err("No peer_extd_mc_stats");
+		status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+	qdf_mem_copy(peer_extd_mc_stats->peer_macaddr,
+		     peer_extended_stats->peer_macaddr,
+		     QDF_MAC_ADDR_SIZE);
+	if (peer_extended_stats->rx_mc_bc_cnt)
+		peer_extd_mc_stats->rx_mc_bc_cnt =
+					peer_extended_stats->rx_mc_bc_cnt;
+	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
+
+	cp_stats_debug("peer_mac=%pM, rx_mc_bc_cnt=%u",
+		       peer_extended_stats->peer_macaddr,
+		       peer_extended_stats->rx_mc_bc_cnt);
+
+end:
+		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
+
+	return status;
+}
+
+static void tgt_mc_cp_stats_extract_peer_extd_stats(
+						struct wlan_objmgr_psoc *psoc,
+						struct stats_event *ev)
+{
+	uint32_t i, selected;
+	QDF_STATUS status;
+	struct request_info last_req = {0};
+
+	status = ucfg_mc_cp_stats_get_pending_req(psoc,
+						  TYPE_PEER_STATS,
+						  &last_req);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
+		return;
+	}
+
+	selected = ev->num_peer_extd_stats;
+	for (i = 0; i < ev->num_peer_extd_stats; i++) {
+		status = tgt_mc_cp_stats_update_peer_extd_stats(
+						psoc,
+						&ev->peer_extended_stats[i]);
+		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+		    !qdf_mem_cmp(ev->peer_stats[i].peer_macaddr,
+				 last_req.peer_mac_addr,
+				 QDF_MAC_ADDR_SIZE)) {
+			/* mac is specified, but failed to update the peer */
+			if (QDF_IS_STATUS_ERROR(status))
+				return;
+
+			selected = i;
+		}
+	}
+
+	/* no matched peer */
+	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
+	    selected == ev->num_peer_extd_stats) {
+		cp_stats_err("peer not found stats");
+		return;
+	}
+}
+
 static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
 					       struct stats_event *ev,
 					       bool is_station_stats)
@@ -397,6 +516,7 @@
 	if (is_station_stats)
 		return;
 
+	tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev);
 	tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req);
 	ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS);
 }
diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c
index def4b8c..409c4d8 100644
--- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c
+++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c
@@ -88,10 +88,19 @@
 	peer_cs->peer_adv_stats = qdf_mem_malloc(sizeof
 						 (struct peer_adv_mc_cp_stats));
 	if (!peer_cs->peer_adv_stats) {
-		cp_stats_err("malloc failed");
 		qdf_mem_free(peer_cs->peer_stats);
 		return QDF_STATUS_E_NOMEM;
 	}
+
+	peer_cs->peer_extd_stats =
+			qdf_mem_malloc(sizeof(struct peer_extd_stats));
+	if (!peer_cs->peer_extd_stats) {
+		qdf_mem_free(peer_cs->peer_stats);
+		peer_cs->peer_stats = NULL;
+		qdf_mem_free(peer_cs->peer_adv_stats);
+		peer_cs->peer_adv_stats = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -99,8 +108,11 @@
 {
 	qdf_mem_free(peer_cs->peer_adv_stats);
 	peer_cs->peer_adv_stats = NULL;
+	qdf_mem_free(peer_cs->peer_extd_stats);
+	peer_cs->peer_extd_stats = NULL;
 	qdf_mem_free(peer_cs->peer_stats);
 	peer_cs->peer_stats = NULL;
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -568,6 +580,7 @@
 	qdf_mem_free(ev->cca_stats);
 	qdf_mem_free(ev->vdev_summary_stats);
 	qdf_mem_free(ev->vdev_chain_rssi);
+	qdf_mem_free(ev->peer_extended_stats);
 	qdf_mem_zero(ev, sizeof(*ev));
 }
 
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index daf37a8..69df9b0 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -4083,6 +4083,8 @@
  * @num_pdev_ext_stats: number of pdev ext stats event structures
  * @num_vdev_stats: number of vdev stats
  * @num_peer_stats: number of peer stats event structures 0 or max peers
+ * @num_peer_extd_stats: number of peer extended stats event structures 0
+ * or max peers
  * @num_bcnflt_stats: number of beacon filter stats
  * @num_chan_stats: number of channel stats
  * @pdev_id: device id for the radio
@@ -4097,6 +4099,7 @@
 	uint32_t num_pdev_ext_stats;
 	uint32_t num_vdev_stats;
 	uint32_t num_peer_stats;
+	uint32_t num_peer_extd_stats;
 	uint32_t num_bcnflt_stats;
 	uint32_t num_chan_stats;
 	uint32_t pdev_id;
@@ -4119,7 +4122,10 @@
  * @atf_tokens_utilized: atf tokens utilized
  * @num_mu_tx_blacklisted: Blacklisted MU Tx count
  * @sgi_count: sgi count of the peer
- * @reserved: for future use
+ * @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames
+ * corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a
+ * valid data
+ * @rx_retry_cnt: Number of rx retries received from current station
  */
 typedef struct {
 	wmi_host_mac_addr peer_macaddr;
@@ -4133,7 +4139,8 @@
 	uint32_t atf_tokens_utilized;
 	uint32_t num_mu_tx_blacklisted;
 	uint32_t sgi_count;
-	uint32_t reserved[2];
+	uint32_t rx_mc_bc_cnt;
+	uint32_t rx_retry_cnt;
 } wmi_host_peer_extd_stats;
 
 /**
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index 2ed7493..4332382 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -8341,6 +8341,9 @@
 	case WMI_REQUEST_BCN_STAT:
 		stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
 		break;
+	case WMI_REQUEST_PEER_EXTD_STAT:
+		stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT;
+		break;
 
 	case WMI_REQUEST_PEER_EXTD2_STAT:
 		stats_param->stats_id |= WMI_HOST_REQUEST_PEER_ADV_STATS;
@@ -8377,6 +8380,7 @@
 	stats_param->num_pdev_ext_stats = 0;
 	stats_param->num_vdev_stats = ev->num_vdev_stats;
 	stats_param->num_peer_stats = ev->num_peer_stats;
+	stats_param->num_peer_extd_stats = ev->num_peer_extd_stats;
 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
 	stats_param->num_chan_stats = ev->num_chan_stats;
 	stats_param->num_bcn_stats = ev->num_bcn_stats;
@@ -8821,7 +8825,37 @@
 		void *evt_buf, uint32_t index,
 		wmi_host_peer_extd_stats *peer_extd_stats)
 {
+	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
+	wmi_stats_event_fixed_param *ev_param;
+	uint8_t *data;
+
+	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
+	ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
+	data = (uint8_t *)param_buf->data;
+	if (!data)
+		return QDF_STATUS_E_FAILURE;
+
+	if (index < ev_param->num_peer_extd_stats) {
+		wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data +
+			(ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) +
+			(ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) +
+			(ev_param->num_peer_stats * sizeof(wmi_peer_stats)) +
+			(ev_param->num_bcnflt_stats *
+			sizeof(wmi_bcnfilter_stats_t)) +
+			(ev_param->num_chan_stats * sizeof(wmi_chan_stats)) +
+			(ev_param->num_mib_stats * sizeof(wmi_mib_stats)) +
+			(ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) +
+			(index * sizeof(wmi_peer_extd_stats)));
+
+		qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats));
+		qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr,
+			     sizeof(wmi_mac_addr));
+
+		peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt;
+	}
+
 	return QDF_STATUS_SUCCESS;
+
 }
 
 /**