xref: /wlan-driver/qcacld-3.0/components/wmi/src/wmi_unified_mc_cp_stats_tlv.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name #include "osdep.h"
19*5113495bSYour Name #include "wmi.h"
20*5113495bSYour Name #include "wmi_unified_priv.h"
21*5113495bSYour Name #include "wmi_unified_param.h"
22*5113495bSYour Name 
23*5113495bSYour Name /**
24*5113495bSYour Name  * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event
25*5113495bSYour Name  * buffer
26*5113495bSYour Name  * @wmi_handle: wmi handle
27*5113495bSYour Name  * @evt_buf: pointer to event buffer
28*5113495bSYour Name  * @index: Index into vdev stats
29*5113495bSYour Name  * @rssi_stats: Pointer to hold rssi stats
30*5113495bSYour Name  *
31*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
32*5113495bSYour Name  */
33*5113495bSYour Name static QDF_STATUS
extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t index,struct wmi_host_per_chain_rssi_stats * rssi_stats)34*5113495bSYour Name extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
35*5113495bSYour Name 			       uint32_t index,
36*5113495bSYour Name 			       struct wmi_host_per_chain_rssi_stats *rssi_stats)
37*5113495bSYour Name {
38*5113495bSYour Name 	uint8_t *data;
39*5113495bSYour Name 	wmi_rssi_stats *fw_rssi_stats;
40*5113495bSYour Name 	wmi_per_chain_rssi_stats *rssi_event;
41*5113495bSYour Name 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
42*5113495bSYour Name 
43*5113495bSYour Name 	if (!evt_buf) {
44*5113495bSYour Name 		wmi_err("evt_buf is null");
45*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
46*5113495bSYour Name 	}
47*5113495bSYour Name 
48*5113495bSYour Name 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
49*5113495bSYour Name 	rssi_event = param_buf->chain_stats;
50*5113495bSYour Name 
51*5113495bSYour Name 	if (index >= rssi_event->num_per_chain_rssi_stats) {
52*5113495bSYour Name 		wmi_err("Invalid index: %u", index);
53*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
54*5113495bSYour Name 	}
55*5113495bSYour Name 
56*5113495bSYour Name 	data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE;
57*5113495bSYour Name 	fw_rssi_stats = &((wmi_rssi_stats *)data)[index];
58*5113495bSYour Name 	if (fw_rssi_stats->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS)
59*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
60*5113495bSYour Name 
61*5113495bSYour Name 	rssi_stats->vdev_id = fw_rssi_stats->vdev_id;
62*5113495bSYour Name 	qdf_mem_copy(rssi_stats->rssi_avg_beacon,
63*5113495bSYour Name 		     fw_rssi_stats->rssi_avg_beacon,
64*5113495bSYour Name 		     sizeof(fw_rssi_stats->rssi_avg_beacon));
65*5113495bSYour Name 	qdf_mem_copy(rssi_stats->rssi_avg_data,
66*5113495bSYour Name 		     fw_rssi_stats->rssi_avg_data,
67*5113495bSYour Name 		     sizeof(fw_rssi_stats->rssi_avg_data));
68*5113495bSYour Name 	qdf_mem_copy(&rssi_stats->peer_macaddr,
69*5113495bSYour Name 		     &fw_rssi_stats->peer_macaddr,
70*5113495bSYour Name 		     sizeof(fw_rssi_stats->peer_macaddr));
71*5113495bSYour Name 
72*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
73*5113495bSYour Name }
74*5113495bSYour Name 
75*5113495bSYour Name /**
76*5113495bSYour Name  * extract_peer_adv_stats_tlv() - extract adv peer stats from event
77*5113495bSYour Name  * @wmi_handle: wmi handle
78*5113495bSYour Name  * @evt_buf: pointer to event buffer
79*5113495bSYour Name  * @peer_adv_stats: Pointer to hold adv peer stats
80*5113495bSYour Name  *
81*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
82*5113495bSYour Name  */
extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct wmi_host_peer_adv_stats * peer_adv_stats)83*5113495bSYour Name static QDF_STATUS extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle,
84*5113495bSYour Name 					     void *evt_buf,
85*5113495bSYour Name 					     struct wmi_host_peer_adv_stats
86*5113495bSYour Name 					     *peer_adv_stats)
87*5113495bSYour Name {
88*5113495bSYour Name 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
89*5113495bSYour Name 	wmi_peer_extd2_stats *adv_stats;
90*5113495bSYour Name 	int i;
91*5113495bSYour Name 
92*5113495bSYour Name 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
93*5113495bSYour Name 
94*5113495bSYour Name 	adv_stats = param_buf->peer_extd2_stats;
95*5113495bSYour Name 	if (!adv_stats) {
96*5113495bSYour Name 		wmi_debug("no peer_adv stats in event buffer");
97*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
98*5113495bSYour Name 	}
99*5113495bSYour Name 
100*5113495bSYour Name 	for (i = 0; i < param_buf->num_peer_extd2_stats; i++) {
101*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&adv_stats[i].peer_macaddr,
102*5113495bSYour Name 					   peer_adv_stats[i].peer_macaddr);
103*5113495bSYour Name 		peer_adv_stats[i].fcs_count = adv_stats[i].rx_fcs_err;
104*5113495bSYour Name 		peer_adv_stats[i].rx_bytes =
105*5113495bSYour Name 				(uint64_t)adv_stats[i].rx_bytes_u32 <<
106*5113495bSYour Name 				WMI_LOWER_BITS_SHIFT_32 |
107*5113495bSYour Name 				adv_stats[i].rx_bytes_l32;
108*5113495bSYour Name 		peer_adv_stats[i].rx_count = adv_stats[i].rx_mpdus;
109*5113495bSYour Name 	}
110*5113495bSYour Name 
111*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
112*5113495bSYour Name }
113*5113495bSYour Name 
114*5113495bSYour Name #ifdef WLAN_FEATURE_MIB_STATS
115*5113495bSYour Name /**
116*5113495bSYour Name  * extract_mib_stats_tlv() - extract mib stats from event
117*5113495bSYour Name  * @wmi_handle: wmi handle
118*5113495bSYour Name  * @evt_buf: pointer to event buffer
119*5113495bSYour Name  * @mib_stats: pointer to hold mib stats
120*5113495bSYour Name  *
121*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
122*5113495bSYour Name  */
extract_mib_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct mib_stats_metrics * mib_stats)123*5113495bSYour Name static QDF_STATUS extract_mib_stats_tlv(wmi_unified_t wmi_handle,
124*5113495bSYour Name 					void *evt_buf,
125*5113495bSYour Name 					struct mib_stats_metrics
126*5113495bSYour Name 					*mib_stats)
127*5113495bSYour Name {
128*5113495bSYour Name 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
129*5113495bSYour Name 	wmi_stats_event_fixed_param *ev_param;
130*5113495bSYour Name 	uint8_t *data;
131*5113495bSYour Name 	wmi_mib_stats *ev;
132*5113495bSYour Name 	wmi_mib_extd_stats *ev_extd;
133*5113495bSYour Name 
134*5113495bSYour Name 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
135*5113495bSYour Name 	ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
136*5113495bSYour Name 	data = (uint8_t *)param_buf->data;
137*5113495bSYour Name 
138*5113495bSYour Name 	ev = (wmi_mib_stats *)(data +
139*5113495bSYour Name 	      ev_param->num_pdev_stats * sizeof(wmi_pdev_stats) +
140*5113495bSYour Name 	      ev_param->num_vdev_stats * sizeof(wmi_vdev_stats) +
141*5113495bSYour Name 	      ev_param->num_peer_stats * sizeof(wmi_peer_stats) +
142*5113495bSYour Name 	      ev_param->num_bcnflt_stats *
143*5113495bSYour Name 	      sizeof(wmi_bcnfilter_stats_t) +
144*5113495bSYour Name 	      ev_param->num_chan_stats * sizeof(wmi_chan_stats));
145*5113495bSYour Name 
146*5113495bSYour Name 	qdf_mem_zero(mib_stats, sizeof(*mib_stats));
147*5113495bSYour Name 
148*5113495bSYour Name 	mib_stats->mib_counters.tx_frags =
149*5113495bSYour Name 		ev->tx_mpdu_grp_frag_cnt;
150*5113495bSYour Name 	mib_stats->mib_counters.group_tx_frames =
151*5113495bSYour Name 		ev->tx_msdu_grp_frm_cnt;
152*5113495bSYour Name 	mib_stats->mib_counters.failed_cnt = ev->tx_msdu_fail_cnt;
153*5113495bSYour Name 	mib_stats->mib_counters.rx_frags = ev->rx_mpdu_frag_cnt;
154*5113495bSYour Name 	mib_stats->mib_counters.group_rx_frames =
155*5113495bSYour Name 		ev->rx_msdu_grp_frm_cnt;
156*5113495bSYour Name 	mib_stats->mib_counters.fcs_error_cnt =
157*5113495bSYour Name 		ev->rx_mpdu_fcs_err;
158*5113495bSYour Name 	mib_stats->mib_counters.tx_frames =
159*5113495bSYour Name 		ev->tx_msdu_frm_cnt;
160*5113495bSYour Name 	mib_stats->mib_mac_statistics.retry_cnt =
161*5113495bSYour Name 		ev->tx_msdu_retry_cnt;
162*5113495bSYour Name 	mib_stats->mib_mac_statistics.frame_dup_cnt =
163*5113495bSYour Name 		ev->rx_frm_dup_cnt;
164*5113495bSYour Name 	mib_stats->mib_mac_statistics.rts_success_cnt =
165*5113495bSYour Name 		ev->tx_rts_success_cnt;
166*5113495bSYour Name 	mib_stats->mib_mac_statistics.rts_fail_cnt =
167*5113495bSYour Name 		ev->tx_rts_fail_cnt;
168*5113495bSYour Name 
169*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_tx_frag_cnt =
170*5113495bSYour Name 		 ev->tx_Qos_mpdu_grp_frag_cnt;
171*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_retry_cnt =
172*5113495bSYour Name 		ev->tx_Qos_msdu_retry_UP;
173*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_failed_cnt =
174*5113495bSYour Name 		ev->tx_Qos_msdu_fail_UP;
175*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_frame_dup_cnt =
176*5113495bSYour Name 		ev->rx_Qos_frm_dup_cnt_UP;
177*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_rts_success_cnt =
178*5113495bSYour Name 		ev->tx_Qos_rts_success_cnt_UP;
179*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_rts_fail_cnt =
180*5113495bSYour Name 		ev->tx_Qos_rts_fail_cnt_UP;
181*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_rx_frag_cnt =
182*5113495bSYour Name 		ev->rx_Qos_mpdu_frag_cnt_UP;
183*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_tx_frame_cnt =
184*5113495bSYour Name 		ev->tx_Qos_msdu_frm_cnt_UP;
185*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_discarded_frame_cnt =
186*5113495bSYour Name 		ev->rx_Qos_msdu_discard_cnt_UP;
187*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_mpdu_rx_cnt =
188*5113495bSYour Name 		ev->rx_Qos_mpdu_cnt;
189*5113495bSYour Name 	mib_stats->mib_qos_counters.qos_retries_rx_cnt =
190*5113495bSYour Name 		ev->rx_Qos_mpdu_retryBit_cnt;
191*5113495bSYour Name 
192*5113495bSYour Name 	mib_stats->mib_rsna_stats.tkip_icv_err =
193*5113495bSYour Name 		ev->rsna_TKIP_icv_err_cnt;
194*5113495bSYour Name 	mib_stats->mib_rsna_stats.tkip_replays =
195*5113495bSYour Name 		ev->rsna_TKIP_replay_err_cnt;
196*5113495bSYour Name 	mib_stats->mib_rsna_stats.ccmp_decrypt_err =
197*5113495bSYour Name 		ev->rsna_CCMP_decrypt_err_cnt;
198*5113495bSYour Name 	mib_stats->mib_rsna_stats.ccmp_replays =
199*5113495bSYour Name 		ev->rsna_CCMP_replay_err_cnt;
200*5113495bSYour Name 
201*5113495bSYour Name 	mib_stats->mib_counters_group3.tx_ampdu_cnt =
202*5113495bSYour Name 		ev->tx_ampdu_cnt;
203*5113495bSYour Name 	mib_stats->mib_counters_group3.tx_mpdus_in_ampdu_cnt =
204*5113495bSYour Name 		ev->tx_mpdu_cnt_in_ampdu;
205*5113495bSYour Name 	mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt =
206*5113495bSYour Name 		ev->tx_octets_in_ampdu.upload.high;
207*5113495bSYour Name 	mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt =
208*5113495bSYour Name 		mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt << 32;
209*5113495bSYour Name 	mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt +=
210*5113495bSYour Name 		ev->tx_octets_in_ampdu.upload.low;
211*5113495bSYour Name 
212*5113495bSYour Name 	mib_stats->mib_counters_group3.ampdu_rx_cnt =
213*5113495bSYour Name 		ev->rx_ampdu_cnt;
214*5113495bSYour Name 	mib_stats->mib_counters_group3.mpdu_in_rx_ampdu_cnt =
215*5113495bSYour Name 		ev->rx_mpdu_cnt_in_ampdu;
216*5113495bSYour Name 	mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt =
217*5113495bSYour Name 		ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_high;
218*5113495bSYour Name 	mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt =
219*5113495bSYour Name 		mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt << 32;
220*5113495bSYour Name 	mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt +=
221*5113495bSYour Name 		ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_low;
222*5113495bSYour Name 
223*5113495bSYour Name 	if (ev_param->num_mib_extd_stats) {
224*5113495bSYour Name 		ev_extd = (wmi_mib_extd_stats *)((uint8_t *)ev +
225*5113495bSYour Name 			   ev_param->num_mib_stats * sizeof(wmi_mib_stats) +
226*5113495bSYour Name 			   ev_param->num_bcn_stats * sizeof(wmi_bcn_stats) +
227*5113495bSYour Name 			   ev_param->num_peer_extd_stats *
228*5113495bSYour Name 			   sizeof(wmi_peer_extd_stats));
229*5113495bSYour Name 		mib_stats->mib_mac_statistics.multi_retry_cnt =
230*5113495bSYour Name 			ev_extd->tx_msdu_multi_retry_cnt;
231*5113495bSYour Name 		mib_stats->mib_mac_statistics.tx_ack_fail_cnt =
232*5113495bSYour Name 			ev_extd->tx_ack_fail_cnt;
233*5113495bSYour Name 
234*5113495bSYour Name 		mib_stats->mib_qos_counters.qos_multi_retry_cnt =
235*5113495bSYour Name 			ev_extd->tx_qos_msdu_multi_retry_up;
236*5113495bSYour Name 		mib_stats->mib_qos_counters.tx_qos_ack_fail_cnt_up =
237*5113495bSYour Name 			ev_extd->tx_qos_ack_fail_cnt_up;
238*5113495bSYour Name 
239*5113495bSYour Name 		mib_stats->mib_rsna_stats.cmac_icv_err =
240*5113495bSYour Name 			ev_extd->rsna_cmac_icv_err_cnt;
241*5113495bSYour Name 		mib_stats->mib_rsna_stats.cmac_replays =
242*5113495bSYour Name 			ev_extd->rsna_cmac_replay_err_cnt;
243*5113495bSYour Name 
244*5113495bSYour Name 		mib_stats->mib_counters_group3.rx_ampdu_deli_crc_err_cnt =
245*5113495bSYour Name 			ev_extd->rx_ampdu_deli_crc_err_cnt;
246*5113495bSYour Name 	}
247*5113495bSYour Name 
248*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
249*5113495bSYour Name }
250*5113495bSYour Name 
wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops * ops)251*5113495bSYour Name static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops)
252*5113495bSYour Name {
253*5113495bSYour Name 	ops->extract_mib_stats = extract_mib_stats_tlv;
254*5113495bSYour Name }
255*5113495bSYour Name #else
wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops * ops)256*5113495bSYour Name static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops)
257*5113495bSYour Name {
258*5113495bSYour Name }
259*5113495bSYour Name #endif /* WLAN_FEATURE_MIB_STATS */
260*5113495bSYour Name 
261*5113495bSYour Name /**
262*5113495bSYour Name  * send_request_peer_stats_info_cmd_tlv() - WMI request peer stats function
263*5113495bSYour Name  * @wmi_handle: handle to WMI.
264*5113495bSYour Name  * @param: pointer to hold peer stats request parameter
265*5113495bSYour Name  *
266*5113495bSYour Name  * Return: QDF_STATUS
267*5113495bSYour Name  */
268*5113495bSYour Name static QDF_STATUS
send_request_peer_stats_info_cmd_tlv(wmi_unified_t wmi_handle,struct peer_stats_request_params * param)269*5113495bSYour Name send_request_peer_stats_info_cmd_tlv(wmi_unified_t wmi_handle,
270*5113495bSYour Name 				     struct peer_stats_request_params *param)
271*5113495bSYour Name {
272*5113495bSYour Name 	int32_t ret;
273*5113495bSYour Name 	wmi_request_peer_stats_info_cmd_fixed_param *cmd;
274*5113495bSYour Name 	wmi_buf_t buf;
275*5113495bSYour Name 	uint16_t len = sizeof(wmi_request_peer_stats_info_cmd_fixed_param);
276*5113495bSYour Name 
277*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
278*5113495bSYour Name 	if (!buf)
279*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
280*5113495bSYour Name 
281*5113495bSYour Name 	cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)wmi_buf_data(buf);
282*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
283*5113495bSYour Name 		   WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param,
284*5113495bSYour Name 		   WMITLV_GET_STRUCT_TLVLEN(
285*5113495bSYour Name 				  wmi_request_peer_stats_info_cmd_fixed_param));
286*5113495bSYour Name 	cmd->request_type = param->request_type;
287*5113495bSYour Name 	cmd->vdev_id = param->vdev_id;
288*5113495bSYour Name 	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac_addr, &cmd->peer_macaddr);
289*5113495bSYour Name 	cmd->reset_after_request = param->reset_after_request;
290*5113495bSYour Name 
291*5113495bSYour Name 	wmi_debug("PEER STATS REQ VDEV_ID:%d PEER:"QDF_MAC_ADDR_FMT" TYPE:%d RESET:%d",
292*5113495bSYour Name 		 cmd->vdev_id, QDF_MAC_ADDR_REF(param->peer_mac_addr),
293*5113495bSYour Name 		 cmd->request_type,
294*5113495bSYour Name 		 cmd->reset_after_request);
295*5113495bSYour Name 
296*5113495bSYour Name 	wmi_mtrace(WMI_REQUEST_PEER_STATS_INFO_CMDID, cmd->vdev_id, 0);
297*5113495bSYour Name 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
298*5113495bSYour Name 				   WMI_REQUEST_PEER_STATS_INFO_CMDID);
299*5113495bSYour Name 	if (ret) {
300*5113495bSYour Name 		wmi_err("Failed to send peer stats request to fw =%d", ret);
301*5113495bSYour Name 		wmi_buf_free(buf);
302*5113495bSYour Name 	}
303*5113495bSYour Name 
304*5113495bSYour Name 	return qdf_status_from_os_return(ret);
305*5113495bSYour Name }
306*5113495bSYour Name 
307*5113495bSYour Name /**
308*5113495bSYour Name  * extract_peer_stats_count_tlv() - extract peer stats count from event
309*5113495bSYour Name  * @wmi_handle: wmi handle
310*5113495bSYour Name  * @evt_buf: pointer to event buffer
311*5113495bSYour Name  * @stats_param: Pointer to hold stats count
312*5113495bSYour Name  *
313*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
314*5113495bSYour Name  */
315*5113495bSYour Name static QDF_STATUS
extract_peer_stats_count_tlv(wmi_unified_t wmi_handle,void * evt_buf,wmi_host_stats_event * stats_param)316*5113495bSYour Name extract_peer_stats_count_tlv(wmi_unified_t wmi_handle, void *evt_buf,
317*5113495bSYour Name 			     wmi_host_stats_event *stats_param)
318*5113495bSYour Name {
319*5113495bSYour Name 	WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
320*5113495bSYour Name 	wmi_peer_stats_info_event_fixed_param *ev_param;
321*5113495bSYour Name 
322*5113495bSYour Name 	param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
323*5113495bSYour Name 	if (!param_buf)
324*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
325*5113495bSYour Name 
326*5113495bSYour Name 	ev_param = param_buf->fixed_param;
327*5113495bSYour Name 	if (!ev_param)
328*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
329*5113495bSYour Name 
330*5113495bSYour Name 	if (!param_buf->num_peer_stats_info ||
331*5113495bSYour Name 	    param_buf->num_peer_stats_info < ev_param->num_peers) {
332*5113495bSYour Name 		wmi_err_rl("actual num of peers stats info: %d is less than provided peers: %d",
333*5113495bSYour Name 			   param_buf->num_peer_stats_info, ev_param->num_peers);
334*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
335*5113495bSYour Name 	}
336*5113495bSYour Name 
337*5113495bSYour Name 	if (!stats_param)
338*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
339*5113495bSYour Name 
340*5113495bSYour Name 	stats_param->num_peer_stats_info_ext = ev_param->num_peers;
341*5113495bSYour Name 
342*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
343*5113495bSYour Name }
344*5113495bSYour Name 
dump_peer_stats_info(wmi_peer_stats_info * stats)345*5113495bSYour Name static void dump_peer_stats_info(wmi_peer_stats_info *stats)
346*5113495bSYour Name {
347*5113495bSYour Name 	u_int8_t mac[6];
348*5113495bSYour Name 	int i;
349*5113495bSYour Name 
350*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac);
351*5113495bSYour Name 	wmi_debug("mac "QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac));
352*5113495bSYour Name 	wmi_debug("tx_bytes %d %d tx_packets %d %d tx_retries %d tx_failed %d",
353*5113495bSYour Name 		 stats->tx_bytes.low_32,
354*5113495bSYour Name 		 stats->tx_bytes.high_32,
355*5113495bSYour Name 		 stats->tx_packets.low_32,
356*5113495bSYour Name 		 stats->tx_packets.high_32,
357*5113495bSYour Name 		 stats->tx_retries, stats->tx_failed);
358*5113495bSYour Name 	wmi_debug("rx_bytes %d %d rx_packets %d %d",
359*5113495bSYour Name 		 stats->rx_bytes.low_32,
360*5113495bSYour Name 		 stats->rx_bytes.high_32,
361*5113495bSYour Name 		 stats->rx_packets.low_32,
362*5113495bSYour Name 		 stats->rx_packets.high_32);
363*5113495bSYour Name 	wmi_debug("tx_rate_code %x rx_rate_code %x tx_rate %x rx_rate %x peer_rssi %d tx_succeed %d",
364*5113495bSYour Name 		 stats->last_tx_rate_code,
365*5113495bSYour Name 		 stats->last_rx_rate_code,
366*5113495bSYour Name 		 stats->last_tx_bitrate_kbps,
367*5113495bSYour Name 		 stats->last_rx_bitrate_kbps,
368*5113495bSYour Name 		 stats->peer_rssi, stats->tx_succeed);
369*5113495bSYour Name 	for (i = 0; i < WMI_MAX_CHAINS; i++)
370*5113495bSYour Name 		wmi_debug("chain%d_rssi %d", i, stats->peer_rssi_per_chain[i]);
371*5113495bSYour Name }
372*5113495bSYour Name 
373*5113495bSYour Name /**
374*5113495bSYour Name  * extract_peer_tx_pkt_per_mcs_tlv() - extract peer tx packets per MCS
375*5113495bSYour Name  * from event
376*5113495bSYour Name  * @wmi_handle: wmi handle
377*5113495bSYour Name  * @evt_buf: pointer to event buffer
378*5113495bSYour Name  * @index: Index into vdev stats
379*5113495bSYour Name  * @peer_stats_info: Pointer to hold peer stats info
380*5113495bSYour Name  *
381*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
382*5113495bSYour Name  */
383*5113495bSYour Name static QDF_STATUS
extract_peer_tx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t index,wmi_host_peer_stats_info * peer_stats_info)384*5113495bSYour Name extract_peer_tx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle, void *evt_buf,
385*5113495bSYour Name 				uint32_t index,
386*5113495bSYour Name 				wmi_host_peer_stats_info *peer_stats_info)
387*5113495bSYour Name {
388*5113495bSYour Name 	WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
389*5113495bSYour Name 	int i, j;
390*5113495bSYour Name 
391*5113495bSYour Name 	param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
392*5113495bSYour Name 
393*5113495bSYour Name 	if (index + peer_stats_info->num_tx_rate_counts <=
394*5113495bSYour Name 					param_buf->num_tx_rate_counts) {
395*5113495bSYour Name 		peer_stats_info->tx_pkt_per_mcs =
396*5113495bSYour Name 			qdf_mem_malloc(
397*5113495bSYour Name 			peer_stats_info->num_tx_rate_counts * sizeof(uint32_t));
398*5113495bSYour Name 
399*5113495bSYour Name 		if (!peer_stats_info->tx_pkt_per_mcs)
400*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
401*5113495bSYour Name 		wmi_debug("Tx rate counts");
402*5113495bSYour Name 		for (j = 0, i = index; j < peer_stats_info->num_tx_rate_counts;
403*5113495bSYour Name 		     j++, i++) {
404*5113495bSYour Name 			peer_stats_info->tx_pkt_per_mcs[j] =
405*5113495bSYour Name 						param_buf->tx_rate_counts[i];
406*5113495bSYour Name 			wmi_nofl_debug("MCS [%d] %d", j,
407*5113495bSYour Name 				       peer_stats_info->tx_pkt_per_mcs[j]);
408*5113495bSYour Name 		}
409*5113495bSYour Name 	} else {
410*5113495bSYour Name 		wmi_err("invalid idx %d curr peer tx_rate_counts %d total tx_rate_count %d",
411*5113495bSYour Name 			index, peer_stats_info->num_tx_rate_counts,
412*5113495bSYour Name 			param_buf->num_tx_rate_counts);
413*5113495bSYour Name 	}
414*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
415*5113495bSYour Name }
416*5113495bSYour Name 
417*5113495bSYour Name /**
418*5113495bSYour Name  * extract_peer_rx_pkt_per_mcs_tlv() - extract peer rx rpackets per MCS
419*5113495bSYour Name  * from event
420*5113495bSYour Name  * @wmi_handle: wmi handle
421*5113495bSYour Name  * @evt_buf: pointer to event buffer
422*5113495bSYour Name  * @index: Index into vdev stats
423*5113495bSYour Name  * @peer_stats_info: Pointer to hold peer stats info
424*5113495bSYour Name  *
425*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
426*5113495bSYour Name  */
427*5113495bSYour Name static QDF_STATUS
extract_peer_rx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t index,wmi_host_peer_stats_info * peer_stats_info)428*5113495bSYour Name extract_peer_rx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle, void *evt_buf,
429*5113495bSYour Name 				uint32_t index,
430*5113495bSYour Name 				wmi_host_peer_stats_info *peer_stats_info)
431*5113495bSYour Name {
432*5113495bSYour Name 	WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
433*5113495bSYour Name 	int i, j;
434*5113495bSYour Name 
435*5113495bSYour Name 	param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
436*5113495bSYour Name 
437*5113495bSYour Name 	if (index + peer_stats_info->num_rx_rate_counts <=
438*5113495bSYour Name 					param_buf->num_rx_rate_counts) {
439*5113495bSYour Name 		peer_stats_info->rx_pkt_per_mcs =
440*5113495bSYour Name 			qdf_mem_malloc(
441*5113495bSYour Name 			peer_stats_info->num_rx_rate_counts * sizeof(uint32_t));
442*5113495bSYour Name 
443*5113495bSYour Name 		if (!peer_stats_info->rx_pkt_per_mcs)
444*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
445*5113495bSYour Name 		wmi_debug("Rx rate counts");
446*5113495bSYour Name 		for (j = 0, i = index; j < peer_stats_info->num_rx_rate_counts;
447*5113495bSYour Name 		     j++, i++) {
448*5113495bSYour Name 			peer_stats_info->rx_pkt_per_mcs[j] =
449*5113495bSYour Name 						param_buf->rx_rate_counts[i];
450*5113495bSYour Name 			wmi_nofl_debug("MCS [%d] %d", j,
451*5113495bSYour Name 				       peer_stats_info->rx_pkt_per_mcs[j]);
452*5113495bSYour Name 		}
453*5113495bSYour Name 	} else {
454*5113495bSYour Name 		wmi_err("invalid idx %d curr peer rx_rate_counts %d total rx_rate_count %d",
455*5113495bSYour Name 			index, peer_stats_info->num_rx_rate_counts,
456*5113495bSYour Name 			param_buf->num_rx_rate_counts);
457*5113495bSYour Name 	}
458*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
459*5113495bSYour Name }
460*5113495bSYour Name 
461*5113495bSYour Name /**
462*5113495bSYour Name  * extract_peer_stats_info_tlv() - extract peer stats info from event
463*5113495bSYour Name  * @wmi_handle: wmi handle
464*5113495bSYour Name  * @evt_buf: pointer to event buffer
465*5113495bSYour Name  * @index: Index into vdev stats
466*5113495bSYour Name  * @peer_stats_info: Pointer to hold peer stats info
467*5113495bSYour Name  *
468*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
469*5113495bSYour Name  */
470*5113495bSYour Name static QDF_STATUS
extract_peer_stats_info_tlv(wmi_unified_t wmi_handle,void * evt_buf,uint32_t index,wmi_host_peer_stats_info * peer_stats_info)471*5113495bSYour Name extract_peer_stats_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
472*5113495bSYour Name 			    uint32_t index,
473*5113495bSYour Name 			    wmi_host_peer_stats_info *peer_stats_info)
474*5113495bSYour Name {
475*5113495bSYour Name 	WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
476*5113495bSYour Name 	wmi_peer_stats_info_event_fixed_param *ev_param;
477*5113495bSYour Name 
478*5113495bSYour Name 	param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf;
479*5113495bSYour Name 	ev_param = param_buf->fixed_param;
480*5113495bSYour Name 
481*5113495bSYour Name 	if (index < ev_param->num_peers) {
482*5113495bSYour Name 		wmi_peer_stats_info *ev = &param_buf->peer_stats_info[index];
483*5113495bSYour Name 		int i;
484*5113495bSYour Name 
485*5113495bSYour Name 		dump_peer_stats_info(ev);
486*5113495bSYour Name 
487*5113495bSYour Name 		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr,
488*5113495bSYour Name 					   peer_stats_info->peer_macaddr.bytes);
489*5113495bSYour Name 		peer_stats_info->tx_packets = ev->tx_packets.low_32;
490*5113495bSYour Name 		peer_stats_info->tx_bytes = ev->tx_bytes.high_32;
491*5113495bSYour Name 		peer_stats_info->tx_bytes <<= 32;
492*5113495bSYour Name 		peer_stats_info->tx_bytes += ev->tx_bytes.low_32;
493*5113495bSYour Name 		peer_stats_info->rx_packets = ev->rx_packets.low_32;
494*5113495bSYour Name 		peer_stats_info->rx_bytes = ev->rx_bytes.high_32;
495*5113495bSYour Name 		peer_stats_info->rx_bytes <<= 32;
496*5113495bSYour Name 		peer_stats_info->rx_bytes += ev->rx_bytes.low_32;
497*5113495bSYour Name 		peer_stats_info->tx_retries = ev->tx_retries;
498*5113495bSYour Name 		peer_stats_info->tx_failed = ev->tx_failed;
499*5113495bSYour Name 		peer_stats_info->tx_succeed = ev->tx_succeed;
500*5113495bSYour Name 		peer_stats_info->peer_rssi = ev->peer_rssi;
501*5113495bSYour Name 		peer_stats_info->last_tx_bitrate_kbps =
502*5113495bSYour Name 						ev->last_tx_bitrate_kbps;
503*5113495bSYour Name 		peer_stats_info->last_tx_rate_code = ev->last_tx_rate_code;
504*5113495bSYour Name 		peer_stats_info->last_rx_bitrate_kbps =
505*5113495bSYour Name 						ev->last_rx_bitrate_kbps;
506*5113495bSYour Name 		peer_stats_info->last_rx_rate_code = ev->last_rx_rate_code;
507*5113495bSYour Name 		for (i = 0; i < WMI_MAX_CHAINS; i++)
508*5113495bSYour Name 			peer_stats_info->peer_rssi_per_chain[i] =
509*5113495bSYour Name 						     ev->peer_rssi_per_chain[i];
510*5113495bSYour Name 		peer_stats_info->num_tx_rate_counts = ev->num_tx_rate_counts;
511*5113495bSYour Name 		peer_stats_info->num_rx_rate_counts = ev->num_rx_rate_counts;
512*5113495bSYour Name 	}
513*5113495bSYour Name 
514*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
515*5113495bSYour Name }
516*5113495bSYour Name 
517*5113495bSYour Name #ifdef WLAN_FEATURE_BIG_DATA_STATS
518*5113495bSYour Name /**
519*5113495bSYour Name  * extract_big_data_stats_tlv() - extract big data from event
520*5113495bSYour Name  * @wmi_handle: wmi handle
521*5113495bSYour Name  * @evt_buf: pointer to event buffer
522*5113495bSYour Name  * @stats: Pointer to hold big data stats
523*5113495bSYour Name  *
524*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
525*5113495bSYour Name  */
526*5113495bSYour Name static QDF_STATUS
extract_big_data_stats_tlv(wmi_unified_t wmi_handle,void * evt_buf,struct big_data_stats_event * stats)527*5113495bSYour Name extract_big_data_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
528*5113495bSYour Name 			   struct big_data_stats_event *stats)
529*5113495bSYour Name {
530*5113495bSYour Name 	WMI_VDEV_SEND_BIG_DATA_P2_EVENTID_param_tlvs *param_buf;
531*5113495bSYour Name 	wmi_vdev_send_big_data_p2_event_fixed_param *event;
532*5113495bSYour Name 	wmi_big_data_dp_stats_tlv_param *dp_stats_param_buf;
533*5113495bSYour Name 
534*5113495bSYour Name 	param_buf = (WMI_VDEV_SEND_BIG_DATA_P2_EVENTID_param_tlvs *)evt_buf;
535*5113495bSYour Name 	if (!param_buf) {
536*5113495bSYour Name 		wmi_err("invalid buffer");
537*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
538*5113495bSYour Name 	}
539*5113495bSYour Name 
540*5113495bSYour Name 	event = param_buf->fixed_param;
541*5113495bSYour Name 	if (!event) {
542*5113495bSYour Name 		wmi_err("invalid fixed param");
543*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
544*5113495bSYour Name 	}
545*5113495bSYour Name 
546*5113495bSYour Name 	dp_stats_param_buf = param_buf->big_data_dp_stats;
547*5113495bSYour Name 	if (!dp_stats_param_buf) {
548*5113495bSYour Name 		wmi_err("invalid dp stats param");
549*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
550*5113495bSYour Name 	}
551*5113495bSYour Name 
552*5113495bSYour Name 	stats->vdev_id = event->vdev_id;
553*5113495bSYour Name 	stats->ani_level = event->ani_level;
554*5113495bSYour Name 	stats->tsf_out_of_sync = event->tsf_out_of_sync;
555*5113495bSYour Name 
556*5113495bSYour Name 	stats->last_data_tx_pwr = dp_stats_param_buf->last_data_tx_pwr;
557*5113495bSYour Name 	stats->target_power_dsss = dp_stats_param_buf->target_power_dsss;
558*5113495bSYour Name 	stats->target_power_ofdm = dp_stats_param_buf->target_power_ofdm;
559*5113495bSYour Name 	stats->last_tx_data_rix = dp_stats_param_buf->last_tx_data_rix;
560*5113495bSYour Name 	stats->last_tx_data_rate_kbps =
561*5113495bSYour Name 		dp_stats_param_buf->last_tx_data_rate_kbps;
562*5113495bSYour Name 
563*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
564*5113495bSYour Name }
565*5113495bSYour Name #endif
566*5113495bSYour Name 
567*5113495bSYour Name #ifdef WLAN_FEATURE_BIG_DATA_STATS
568*5113495bSYour Name static void
wmi_attach_big_data_stats_handler(struct wmi_ops * ops)569*5113495bSYour Name wmi_attach_big_data_stats_handler(struct wmi_ops *ops)
570*5113495bSYour Name {
571*5113495bSYour Name 	ops->extract_big_data_stats = extract_big_data_stats_tlv;
572*5113495bSYour Name }
573*5113495bSYour Name #else
574*5113495bSYour Name static void
wmi_attach_big_data_stats_handler(struct wmi_ops * ops)575*5113495bSYour Name wmi_attach_big_data_stats_handler(struct wmi_ops *ops)
576*5113495bSYour Name {}
577*5113495bSYour Name #endif
578*5113495bSYour Name 
wmi_mc_cp_stats_attach_tlv(wmi_unified_t wmi_handle)579*5113495bSYour Name void wmi_mc_cp_stats_attach_tlv(wmi_unified_t wmi_handle)
580*5113495bSYour Name {
581*5113495bSYour Name 	struct wmi_ops *ops = wmi_handle->ops;
582*5113495bSYour Name 
583*5113495bSYour Name 	ops->extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv;
584*5113495bSYour Name 	ops->extract_peer_adv_stats = extract_peer_adv_stats_tlv;
585*5113495bSYour Name 	wmi_cp_stats_attach_mib_stats_tlv(ops);
586*5113495bSYour Name 	ops->send_request_peer_stats_info_cmd =
587*5113495bSYour Name 		send_request_peer_stats_info_cmd_tlv;
588*5113495bSYour Name 	ops->extract_peer_stats_count = extract_peer_stats_count_tlv;
589*5113495bSYour Name 	ops->extract_peer_stats_info = extract_peer_stats_info_tlv;
590*5113495bSYour Name 	wmi_handle->ops->extract_peer_tx_pkt_per_mcs =
591*5113495bSYour Name 					extract_peer_tx_pkt_per_mcs_tlv;
592*5113495bSYour Name 	wmi_handle->ops->extract_peer_rx_pkt_per_mcs =
593*5113495bSYour Name 					extract_peer_rx_pkt_per_mcs_tlv;
594*5113495bSYour Name 	wmi_attach_big_data_stats_handler(ops);
595*5113495bSYour Name }
596