1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC:wlan_cp_stats_mc_tgt_api.c
22  *
23  * This file provide API definitions to update control plane statistics received
24  * from southbound interface
25  */
26 
27 #include "wlan_cp_stats_mc_defs.h"
28 #include "target_if_cp_stats.h"
29 #include "wlan_cp_stats_tgt_api.h"
30 #include "wlan_cp_stats_ucfg_api.h"
31 #include "wlan_cp_stats_mc_tgt_api.h"
32 #include <wlan_cp_stats_mc_ucfg_api.h>
33 #include <wlan_cp_stats_utils_api.h>
34 #include "../../core/src/wlan_cp_stats_defs.h"
35 #include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
36 #include "son_api.h"
37 #include "wlan_policy_mgr_api.h"
38 
tgt_mc_cp_stats_is_last_event(struct stats_event * ev,enum stats_req_type stats_type)39 static bool tgt_mc_cp_stats_is_last_event(struct stats_event *ev,
40 					  enum stats_req_type stats_type)
41 {
42 	bool is_last_event;
43 
44 	if (IS_MSB_SET(ev->last_event)) {
45 		is_last_event = IS_LSB_SET(ev->last_event);
46 	} else {
47 		if (stats_type == TYPE_CONNECTION_TX_POWER)
48 			is_last_event = true;
49 		else
50 			is_last_event = !!ev->peer_stats;
51 	}
52 
53 	if (is_last_event)
54 		cp_stats_debug("Last stats event");
55 
56 	return is_last_event;
57 }
58 
59 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
60 static void
tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)61 tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
62 {
63 	rx_ops->cp_stats_rx_ops.process_infra_stats_event =
64 				tgt_mc_cp_stats_process_infra_stats_event;
65 }
66 #else
67 static void
tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)68 tgt_cp_stats_register_infra_cp_stats_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
69 {
70 }
71 #endif
72 
73 #ifdef WLAN_FEATURE_BIG_DATA_STATS
74 static void
tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)75 tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
76 {
77 	rx_ops->cp_stats_rx_ops.process_big_data_stats_event =
78 			tgt_mc_cp_stats_process_big_data_stats_event;
79 }
80 
81 static QDF_STATUS
send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops,struct wlan_objmgr_psoc * psoc,struct request_info * req)82 send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops *tx_ops,
83 			struct wlan_objmgr_psoc *psoc,
84 			struct request_info *req)
85 {
86 	if (!tx_ops->send_req_big_data_stats) {
87 		cp_stats_err("could not get send_req_big_data_stats");
88 		return QDF_STATUS_E_NULL_VALUE;
89 	}
90 
91 	return tx_ops->send_req_big_data_stats(psoc, req);
92 }
93 #else
94 static void
tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)95 tgt_cp_stats_register_big_data_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
96 {}
97 
98 static QDF_STATUS
send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops,struct wlan_objmgr_psoc * psoc,struct request_info * req)99 send_big_data_stats_req(struct wlan_lmac_if_cp_stats_tx_ops *tx_ops,
100 			struct wlan_objmgr_psoc *psoc,
101 			struct request_info *req)
102 {
103 	return QDF_STATUS_SUCCESS;
104 }
105 #endif
106 
tgt_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)107 void tgt_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
108 {
109 	rx_ops->cp_stats_rx_ops.process_stats_event =
110 					tgt_mc_cp_stats_process_stats_event;
111 	tgt_cp_stats_register_infra_cp_stats_rx_ops(rx_ops);
112 	tgt_cp_stats_register_big_data_rx_ops(rx_ops);
113 }
114 
tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc * psoc,struct stats_event * ev,bool is_station_stats)115 static void tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc *psoc,
116 					struct stats_event *ev,
117 					bool is_station_stats)
118 {
119 	int32_t max_pwr = 0;
120 	uint8_t pdev_id;
121 	uint8_t mac_id = 0;
122 	QDF_STATUS status;
123 	struct wlan_objmgr_pdev *pdev;
124 	struct request_info last_req = {0};
125 	struct wlan_objmgr_vdev *vdev = NULL;
126 	struct pdev_mc_cp_stats *pdev_mc_stats;
127 	struct pdev_cp_stats *pdev_cp_stats_priv;
128 
129 	if (!ev->pdev_stats)
130 		return;
131 
132 	if (is_station_stats)
133 		status = ucfg_mc_cp_stats_get_pending_req(psoc,
134 					TYPE_STATION_STATS, &last_req);
135 	else
136 		status = ucfg_mc_cp_stats_get_pending_req(psoc,
137 					TYPE_CONNECTION_TX_POWER, &last_req);
138 
139 	if (QDF_IS_STATUS_ERROR(status)) {
140 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
141 		goto end;
142 	}
143 
144 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
145 						    WLAN_CP_STATS_ID);
146 	if (!vdev) {
147 		cp_stats_err("vdev is null");
148 		goto end;
149 	}
150 
151 	pdev = wlan_vdev_get_pdev(vdev);
152 	if (!pdev) {
153 		cp_stats_err("pdev is null");
154 		goto end;
155 	}
156 
157 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
158 	if (pdev_id >= ev->num_pdev_stats) {
159 		cp_stats_err("pdev_id: %d invalid", pdev_id);
160 		goto end;
161 	}
162 
163 	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
164 	if (!pdev_cp_stats_priv) {
165 		cp_stats_err("pdev_cp_stats_priv is null");
166 		goto end;
167 	}
168 
169 	mac_id = policy_mgr_mode_get_macid_by_vdev_id(psoc, last_req.vdev_id);
170 
171 	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
172 	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
173 	if (!is_station_stats &&
174 	    pdev_mc_stats->max_pwr != ev->pdev_stats[pdev_id].max_pwr)
175 		wlan_son_deliver_tx_power(vdev,
176 					  ev->pdev_stats[pdev_id].max_pwr);
177 	if (mac_id == ev->mac_seq_num)
178 		max_pwr = pdev_mc_stats->max_pwr =
179 			ev->pdev_stats[pdev_id].max_pwr;
180 
181 	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
182 
183 end:
184 	if (vdev)
185 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
186 }
187 
peer_rssi_iterator(struct wlan_objmgr_pdev * pdev,void * peer,void * arg)188 static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev,
189 			       void *peer, void *arg)
190 {
191 	struct stats_event *ev;
192 	struct peer_mc_cp_stats *peer_mc_stats;
193 	struct peer_cp_stats *peer_cp_stats_priv;
194 	struct peer_extd_stats *peer_extd_mc_stats;
195 
196 	if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) {
197 		cp_stats_debug("ignore self peer: "QDF_MAC_ADDR_FMT,
198 			       QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer)));
199 		return;
200 	}
201 
202 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
203 	if (!peer_cp_stats_priv) {
204 		cp_stats_err("peer cp stats object is null");
205 		return;
206 	}
207 
208 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
209 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
210 	ev = arg;
211 	ev->peer_stats[ev->num_peer_stats] = *peer_mc_stats;
212 	ev->num_peer_stats++;
213 
214 	peer_extd_mc_stats = peer_mc_stats->extd_stats;
215 	ev->peer_extended_stats[ev->num_peer_extd_stats] = *peer_extd_mc_stats;
216 	ev->num_peer_extd_stats++;
217 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
218 }
219 
220 static void
tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc * psoc,struct request_info * last_req)221 tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc,
222 				      struct request_info *last_req)
223 {
224 	uint8_t *mac_addr;
225 	uint16_t peer_count;
226 	struct stats_event ev = {0};
227 	struct wlan_objmgr_pdev *pdev;
228 	struct wlan_objmgr_vdev *vdev;
229 	struct wlan_objmgr_peer *peer = NULL;
230 	struct peer_mc_cp_stats *peer_mc_stats;
231 	struct peer_extd_stats *peer_mc_extd_stats;
232 	struct peer_cp_stats *peer_cp_stats_priv;
233 	void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie);
234 
235 	get_peer_rssi_cb = last_req->u.get_peer_rssi_cb;
236 	if (!get_peer_rssi_cb) {
237 		cp_stats_debug("get_peer_rssi_cb is null");
238 		return;
239 	}
240 
241 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
242 						    WLAN_CP_STATS_ID);
243 	if (!vdev) {
244 		cp_stats_err("vdev is null");
245 		goto end;
246 	}
247 
248 	mac_addr = last_req->peer_mac_addr;
249 	if (QDF_IS_ADDR_BROADCAST(mac_addr)) {
250 		pdev = wlan_vdev_get_pdev(vdev);
251 		peer_count = wlan_pdev_get_peer_count(pdev);
252 		ev.peer_stats = qdf_mem_malloc(sizeof(*ev.peer_stats) *
253 								peer_count);
254 		if (!ev.peer_stats)
255 			goto end;
256 
257 		ev.peer_extended_stats =
258 			qdf_mem_malloc(sizeof(*ev.peer_extended_stats) *
259 				       peer_count);
260 		if (!ev.peer_extended_stats)
261 			goto end;
262 
263 		wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP,
264 						  peer_rssi_iterator, &ev,
265 						  true, WLAN_CP_STATS_ID);
266 	} else {
267 		peer = wlan_objmgr_get_peer(psoc, last_req->pdev_id,
268 					    mac_addr, WLAN_CP_STATS_ID);
269 		if (!peer) {
270 			cp_stats_debug("peer[" QDF_MAC_ADDR_FMT "] is null",
271 				       QDF_MAC_ADDR_REF(mac_addr));
272 			goto end;
273 		}
274 
275 		peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
276 		if (!peer_cp_stats_priv) {
277 			cp_stats_err("peer cp stats object is null");
278 			goto end;
279 		}
280 
281 		ev.peer_stats = qdf_mem_malloc(sizeof(*ev.peer_stats));
282 		if (!ev.peer_stats)
283 			goto end;
284 
285 		ev.num_peer_stats = 1;
286 
287 		ev.peer_extended_stats =
288 			qdf_mem_malloc(sizeof(*ev.peer_extended_stats));
289 		if (!ev.peer_extended_stats)
290 			goto end;
291 
292 		ev.num_peer_extd_stats = 1;
293 
294 		wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
295 		peer_mc_stats = peer_cp_stats_priv->peer_stats;
296 		*ev.peer_stats = *peer_mc_stats;
297 
298 		peer_mc_extd_stats = peer_mc_stats->extd_stats;
299 		*ev.peer_extended_stats = *peer_mc_extd_stats;
300 		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
301 	}
302 
303 end:
304 	get_peer_rssi_cb(&ev, last_req->cookie);
305 
306 	ucfg_mc_cp_stats_free_stats_resources(&ev);
307 
308 	if (vdev)
309 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
310 	if (peer)
311 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
312 }
313 
314 static QDF_STATUS
tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc * psoc,struct peer_adv_mc_cp_stats * peer_adv_stats,uint32_t size)315 tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc *psoc,
316 				      struct peer_adv_mc_cp_stats
317 				      *peer_adv_stats, uint32_t size)
318 {
319 	uint8_t *peer_mac_addr;
320 	struct wlan_objmgr_peer *peer;
321 	struct peer_mc_cp_stats *peer_mc_stats;
322 	struct peer_adv_mc_cp_stats *peer_adv_mc_stats;
323 	QDF_STATUS status = QDF_STATUS_SUCCESS;
324 	struct peer_cp_stats *peer_cp_stats_priv;
325 
326 	if (!peer_adv_stats)
327 		return QDF_STATUS_E_INVAL;
328 
329 	peer_mac_addr = peer_adv_stats->peer_macaddr;
330 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
331 					   WLAN_CP_STATS_ID);
332 	if (!peer) {
333 		cp_stats_debug("peer is null");
334 		return QDF_STATUS_E_EXISTS;
335 	}
336 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
337 	if (!peer_cp_stats_priv) {
338 		cp_stats_err("peer_cp_stats_priv is null");
339 		status = QDF_STATUS_E_EXISTS;
340 		goto end;
341 	}
342 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
343 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
344 	peer_adv_mc_stats = peer_mc_stats->adv_stats;
345 
346 	qdf_mem_copy(peer_adv_mc_stats->peer_macaddr,
347 		     peer_adv_stats->peer_macaddr,
348 		     QDF_MAC_ADDR_SIZE);
349 	if (peer_adv_stats->fcs_count)
350 		peer_adv_mc_stats->fcs_count = peer_adv_stats->fcs_count;
351 	if (peer_adv_stats->rx_bytes)
352 		peer_adv_mc_stats->rx_bytes = peer_adv_stats->rx_bytes;
353 	if (peer_adv_stats->rx_count)
354 		peer_adv_mc_stats->rx_count = peer_adv_stats->rx_count;
355 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
356 
357 end:
358 	if (peer)
359 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
360 
361 	return status;
362 }
363 
364 static QDF_STATUS
tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc * psoc,struct peer_mc_cp_stats * peer_stats)365 tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc,
366 				  struct peer_mc_cp_stats *peer_stats)
367 {
368 	uint8_t *peer_mac_addr;
369 	struct wlan_objmgr_peer *peer;
370 	struct peer_mc_cp_stats *peer_mc_stats;
371 	QDF_STATUS status = QDF_STATUS_SUCCESS;
372 	struct peer_cp_stats *peer_cp_stats_priv;
373 
374 	if (!peer_stats)
375 		return QDF_STATUS_E_INVAL;
376 
377 	peer_mac_addr = peer_stats->peer_macaddr;
378 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
379 				    WLAN_CP_STATS_ID);
380 	if (!peer) {
381 		cp_stats_debug("peer is null");
382 		return QDF_STATUS_E_EXISTS;
383 	}
384 
385 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
386 	if (!peer_cp_stats_priv) {
387 		cp_stats_err("peer_cp_stats_priv is null");
388 		status = QDF_STATUS_E_EXISTS;
389 		goto end;
390 	}
391 
392 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
393 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
394 	qdf_mem_copy(peer_mc_stats->peer_macaddr,
395 		     peer_stats->peer_macaddr,
396 		     QDF_MAC_ADDR_SIZE);
397 	if (peer_stats->tx_rate)
398 		peer_mc_stats->tx_rate = peer_stats->tx_rate;
399 	if (peer_stats->rx_rate)
400 		peer_mc_stats->rx_rate = peer_stats->rx_rate;
401 	if (peer_stats->peer_rssi)
402 		peer_mc_stats->peer_rssi = peer_stats->peer_rssi;
403 	cp_stats_nofl_debug("PEER STATS: peer_mac="QDF_MAC_ADDR_FMT", tx_rate=%u, rx_rate=%u, peer_rssi=%d",
404 			    QDF_MAC_ADDR_REF(peer_mc_stats->peer_macaddr),
405 			    peer_mc_stats->tx_rate,
406 			    peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi);
407 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
408 
409 end:
410 	if (peer)
411 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
412 
413 	return status;
414 }
415 
416 static QDF_STATUS
tgt_mc_cp_stats_update_peer_extd_stats(struct wlan_objmgr_psoc * psoc,struct peer_extd_stats * peer_extended_stats)417 tgt_mc_cp_stats_update_peer_extd_stats(
418 				struct wlan_objmgr_psoc *psoc,
419 				struct peer_extd_stats *peer_extended_stats)
420 {
421 	uint8_t *peer_mac_addr;
422 	struct wlan_objmgr_peer *peer;
423 	struct peer_mc_cp_stats *peer_mc_stats;
424 	struct peer_extd_stats *peer_extd_mc_stats;
425 	QDF_STATUS status = QDF_STATUS_SUCCESS;
426 	struct peer_cp_stats *peer_cp_stats_priv;
427 
428 	if (!peer_extended_stats)
429 		return QDF_STATUS_E_INVAL;
430 
431 	peer_mac_addr = peer_extended_stats->peer_macaddr;
432 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
433 					   WLAN_CP_STATS_ID);
434 	if (!peer) {
435 		cp_stats_debug("peer is null");
436 		return QDF_STATUS_E_EXISTS;
437 	}
438 
439 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
440 	if (!peer_cp_stats_priv) {
441 		cp_stats_err("peer_cp_stats_priv is null");
442 		status = QDF_STATUS_E_EXISTS;
443 		goto end;
444 	}
445 
446 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
447 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
448 	peer_extd_mc_stats = peer_mc_stats->extd_stats;
449 	if (!peer_extd_mc_stats) {
450 		wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
451 		cp_stats_err("No peer_extd_mc_stats");
452 		status = QDF_STATUS_E_INVAL;
453 		goto end;
454 	}
455 	qdf_mem_copy(peer_extd_mc_stats->peer_macaddr,
456 		     peer_extended_stats->peer_macaddr,
457 		     QDF_MAC_ADDR_SIZE);
458 	if (peer_extended_stats->rx_mc_bc_cnt)
459 		peer_extd_mc_stats->rx_mc_bc_cnt =
460 					peer_extended_stats->rx_mc_bc_cnt;
461 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
462 
463 	cp_stats_debug("peer_mac="QDF_MAC_ADDR_FMT", rx_mc_bc_cnt=%u",
464 		       QDF_MAC_ADDR_REF(peer_extended_stats->peer_macaddr),
465 		       peer_extended_stats->rx_mc_bc_cnt);
466 
467 end:
468 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
469 
470 	return status;
471 }
472 
tgt_mc_cp_stats_extract_peer_extd_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)473 static void tgt_mc_cp_stats_extract_peer_extd_stats(
474 						struct wlan_objmgr_psoc *psoc,
475 						struct stats_event *ev)
476 {
477 	uint32_t i, selected;
478 	QDF_STATUS status;
479 	struct request_info last_req = {0};
480 
481 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
482 						  TYPE_PEER_STATS,
483 						  &last_req);
484 
485 	if (QDF_IS_STATUS_ERROR(status)) {
486 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
487 		return;
488 	}
489 
490 	selected = ev->num_peer_extd_stats;
491 	for (i = 0; i < ev->num_peer_extd_stats; i++) {
492 		status = tgt_mc_cp_stats_update_peer_extd_stats(
493 						psoc,
494 						&ev->peer_extended_stats[i]);
495 
496 		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
497 		    !qdf_mem_cmp(ev->peer_extended_stats[i].peer_macaddr,
498 				 last_req.peer_mac_addr,
499 				 QDF_MAC_ADDR_SIZE)) {
500 			/* mac is specified, but failed to update the peer */
501 			if (QDF_IS_STATUS_ERROR(status))
502 				return;
503 
504 			selected = i;
505 		}
506 	}
507 
508 	/* no matched peer */
509 	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
510 	    selected == ev->num_peer_extd_stats) {
511 		cp_stats_rl_err("peer not found stats");
512 		return;
513 	}
514 }
515 
tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev,bool is_station_stats)516 static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
517 					       struct stats_event *ev,
518 					       bool is_station_stats)
519 {
520 	uint32_t i;
521 	QDF_STATUS status;
522 	struct request_info last_req = {0};
523 	bool pending = false;
524 	uint32_t selected;
525 
526 	if (is_station_stats)
527 		status = ucfg_mc_cp_stats_get_pending_req(psoc,
528 							  TYPE_STATION_STATS,
529 							  &last_req);
530 	else
531 		status = ucfg_mc_cp_stats_get_pending_req(psoc,
532 							  TYPE_PEER_STATS,
533 							  &last_req);
534 
535 	if (QDF_IS_STATUS_ERROR(status)) {
536 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
537 		return;
538 	}
539 
540 	if (!ev->peer_stats)
541 		goto extd2_stats;
542 
543 	selected = ev->num_peer_stats;
544 	for (i = 0; i < ev->num_peer_stats; i++) {
545 		status = tgt_mc_cp_stats_update_peer_stats(psoc,
546 							   &ev->peer_stats[i]);
547 		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
548 		    !qdf_mem_cmp(ev->peer_stats[i].peer_macaddr,
549 				 last_req.peer_mac_addr,
550 				 QDF_MAC_ADDR_SIZE)) {
551 			/* mac is specified, but failed to update the peer */
552 			if (QDF_IS_STATUS_ERROR(status))
553 				return;
554 
555 			selected = i;
556 		}
557 	}
558 
559 	/* no matched peer */
560 	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
561 	    selected == ev->num_peer_stats)
562 		cp_stats_debug("peer not found for stats");
563 
564 extd2_stats:
565 
566 	if (!ev->peer_adv_stats)
567 		goto complete;
568 
569 	selected = ev->num_peer_adv_stats;
570 	for (i = 0; i < ev->num_peer_adv_stats; i++) {
571 		status = tgt_mc_cp_stats_update_peer_adv_stats(
572 						psoc, &ev->peer_adv_stats[i],
573 						ev->num_peer_adv_stats);
574 		if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
575 		    !qdf_mem_cmp(ev->peer_adv_stats[i].peer_macaddr,
576 				 last_req.peer_mac_addr,
577 				 QDF_MAC_ADDR_SIZE)) {
578 			/* mac is specified, but failed to update the peer */
579 			if (QDF_IS_STATUS_ERROR(status))
580 				return;
581 
582 			selected = i;
583 		}
584 	}
585 
586 	/* no matched peer */
587 	if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
588 	    selected == ev->num_peer_adv_stats)
589 		cp_stats_debug("peer not found for extd stats");
590 
591 complete:
592 	if (is_station_stats)
593 		return;
594 
595 	tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev);
596 	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_PEER_STATS)) {
597 		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS,
598 						   &last_req, &pending);
599 		if (pending && last_req.u.get_peer_rssi_cb)
600 			tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req);
601 	}
602 }
603 
604 #ifdef WLAN_FEATURE_MIB_STATS
tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)605 static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc,
606 					      struct stats_event *ev)
607 {
608 	QDF_STATUS status;
609 	struct request_info last_req = {0};
610 	bool pending = false;
611 
612 	if (!ev->mib_stats) {
613 		cp_stats_debug("no mib stats");
614 		return;
615 	}
616 
617 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
618 						  TYPE_MIB_STATS, &last_req);
619 
620 	if (QDF_IS_STATUS_ERROR(status)) {
621 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
622 		return;
623 	}
624 
625 	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_MIB_STATS)) {
626 		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_MIB_STATS,
627 						   &last_req, &pending);
628 		if (last_req.u.get_mib_stats_cb && pending)
629 			last_req.u.get_mib_stats_cb(ev, last_req.cookie);
630 	}
631 }
632 #else
tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)633 static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc,
634 					      struct stats_event *ev)
635 {
636 }
637 #endif
638 
639 static void
tgt_mc_cp_stats_extract_peer_stats_info_ext(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)640 tgt_mc_cp_stats_extract_peer_stats_info_ext(struct wlan_objmgr_psoc *psoc,
641 					    struct stats_event *ev)
642 {
643 	QDF_STATUS status;
644 	struct request_info last_req = {0};
645 	bool pending = false;
646 
647 	if (!ev->peer_stats_info_ext || ev->num_peer_stats_info_ext == 0) {
648 		cp_stats_debug("no peer_stats_info_ext");
649 		return;
650 	}
651 
652 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
653 						  TYPE_PEER_STATS_INFO_EXT,
654 						  &last_req);
655 	if (QDF_IS_STATUS_ERROR(status)) {
656 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
657 		return;
658 	}
659 
660 	ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS_INFO_EXT,
661 					   &last_req, &pending);
662 	if (last_req.u.get_peer_stats_cb && pending) {
663 		last_req.u.get_peer_stats_cb(ev, last_req.cookie);
664 		last_req.u.get_peer_stats_cb = NULL;
665 	}
666 }
667 
668 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
669 #ifdef WLAN_SUPPORT_TWT
670 static void
tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc * psoc,struct infra_cp_stats_event * ev)671 tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
672 					struct infra_cp_stats_event *ev)
673 {
674 	QDF_STATUS status;
675 	get_infra_cp_stats_cb resp_cb = NULL;
676 	void *context = NULL;
677 
678 	status = wlan_cp_stats_infra_cp_get_context(psoc, &resp_cb, &context);
679 	if (QDF_IS_STATUS_ERROR(status)) {
680 		cp_stats_err("ucfg_get_infra_cp_stats_context failed");
681 		return;
682 	}
683 
684 	cp_stats_debug("num_twt_infra_cp_stats = %d action %d",
685 		       ev->num_twt_infra_cp_stats, ev->action);
686 
687 	if (resp_cb)
688 		resp_cb(ev, context);
689 }
690 #else
691 static void
tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc * psoc,struct infra_cp_stats_event * ev)692 tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
693 					struct infra_cp_stats_event *ev)
694 {
695 }
696 #endif
697 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
698 
699 #ifdef WLAN_FEATURE_MEDIUM_ASSESS
700 static void
tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)701 tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
702 					 struct stats_event *ev)
703 {
704 	QDF_STATUS status;
705 	uint8_t i, index;
706 	struct request_info last_req = {0};
707 	struct medium_assess_data data[WLAN_UMAC_MAX_RP_PID] = { {0} };
708 	bool is_last_event = tgt_mc_cp_stats_is_last_event(ev,
709 					TYPE_CONGESTION_STATS);
710 
711 	if (!(ev->num_pdev_stats || ev->num_pdev_extd_stats)) {
712 		cp_stats_err("no congestion sta for pdev");
713 		return;
714 	}
715 
716 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
717 						  TYPE_CONGESTION_STATS,
718 						  &last_req);
719 	if (QDF_IS_STATUS_ERROR(status)) {
720 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
721 		return;
722 	}
723 
724 	for (i = 0; (i < ev->num_pdev_stats) && (i < WLAN_UMAC_MAX_RP_PID);
725 	     i++){
726 		index = ev->pdev_stats[i].pdev_id;
727 		if (index >= WLAN_UMAC_MAX_RP_PID) {
728 			cp_stats_err("part1 pdev id error");
729 			continue;
730 		}
731 		data[index].part1_valid = true;
732 		data[index].cycle_count = ev->pdev_stats[i].cycle_count;
733 		data[index].rx_clear_count = ev->pdev_stats[i].rx_clear_count;
734 		data[index].tx_frame_count = ev->pdev_stats[i].tx_frame_count;
735 	}
736 
737 	for (i = 0; (i < ev->num_pdev_extd_stats) && (i < WLAN_UMAC_MAX_RP_PID);
738 	     i++){
739 		index = ev->pdev_extd_stats[i].pdev_id;
740 		if (index >= WLAN_UMAC_MAX_RP_PID) {
741 			cp_stats_err("part2 pdev id error");
742 			continue;
743 		}
744 		data[index].part2_valid = true;
745 		data[index].my_rx_count = ev->pdev_extd_stats[i].my_rx_count;
746 	}
747 
748 	if (last_req.u.congestion_notif_cb)
749 		last_req.u.congestion_notif_cb(last_req.vdev_id, data,
750 						is_last_event);
751 
752 }
753 #else
754 static void
tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)755 tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
756 					 struct stats_event *ev)
757 {
758 }
759 #endif
760 
761 #ifdef WLAN_FEATURE_11BE_MLO
762 static void
update_ml_vdev_id_from_stats_event(struct request_info * req,uint8_t * vdev_id)763 update_ml_vdev_id_from_stats_event(struct request_info *req,
764 				   uint8_t *vdev_id)
765 {
766 	if (!req->ml_vdev_info.ml_vdev_count) {
767 		*vdev_id = req->vdev_id;
768 		return;
769 	}
770 
771 	if (*vdev_id == WLAN_UMAC_VDEV_ID_MAX ||
772 	    *vdev_id >= WLAN_MAX_VDEVS) {
773 		cp_stats_err("Invalid vdev[%u] sent by firmware", *vdev_id);
774 		*vdev_id = WLAN_UMAC_VDEV_ID_MAX;
775 	}
776 }
777 #else
778 static inline void
update_ml_vdev_id_from_stats_event(struct request_info * req,uint8_t * vdev_id)779 update_ml_vdev_id_from_stats_event(struct request_info *req,
780 				   uint8_t *vdev_id)
781 {
782 	*vdev_id = req->vdev_id;
783 }
784 #endif
785 
tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)786 static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc,
787 						  struct stats_event *ev)
788 {
789 	struct wlan_objmgr_vdev *vdev;
790 	struct vdev_mc_cp_stats *vdev_mc_stats;
791 	struct vdev_cp_stats *vdev_cp_stats_priv;
792 
793 	if (!ev->cca_stats)
794 		return;
795 
796 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
797 						    ev->cca_stats->vdev_id,
798 						    WLAN_CP_STATS_ID);
799 	if (!vdev) {
800 		cp_stats_err("vdev is null");
801 		return;
802 	}
803 
804 	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
805 	if (!vdev_cp_stats_priv) {
806 		cp_stats_err("vdev cp stats object is null");
807 		goto end;
808 	}
809 
810 	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
811 	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
812 	vdev_mc_stats->cca.congestion =  ev->cca_stats->congestion;
813 	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
814 
815 end:
816 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
817 }
818 
819 static void
tgt_mc_cp_stats_extract_pmf_bcn_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)820 tgt_mc_cp_stats_extract_pmf_bcn_stats(struct wlan_objmgr_psoc *psoc,
821 				      struct stats_event *ev)
822 {
823 	QDF_STATUS status;
824 	struct request_info last_req = {0};
825 	struct wlan_objmgr_vdev *vdev;
826 	struct vdev_mc_cp_stats *vdev_mc_stats;
827 	struct vdev_cp_stats *vdev_cp_stats_priv;
828 
829 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
830 						  TYPE_STATION_STATS,
831 						  &last_req);
832 	if (QDF_IS_STATUS_ERROR(status)) {
833 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
834 		return;
835 	}
836 
837 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
838 						    WLAN_CP_STATS_ID);
839 	if (!vdev) {
840 		cp_stats_err("vdev is null");
841 		return;
842 	}
843 
844 	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
845 	if (!vdev_cp_stats_priv) {
846 		cp_stats_err("vdev cp stats object is null");
847 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
848 		return;
849 	}
850 
851 	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
852 	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
853 
854 	if (ev->bcn_protect_stats.pmf_bcn_stats_valid)
855 		vdev_mc_stats->pmf_bcn_stats = ev->bcn_protect_stats;
856 
857 	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
858 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
859 }
860 
tgt_mc_cp_stats_extract_vdev_summary_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)861 static void tgt_mc_cp_stats_extract_vdev_summary_stats(
862 					struct wlan_objmgr_psoc *psoc,
863 					struct stats_event *ev)
864 {
865 	uint8_t i, vdev_id = WLAN_INVALID_VDEV_ID;
866 	QDF_STATUS status;
867 	struct wlan_objmgr_peer *peer = NULL;
868 	struct request_info last_req = {0};
869 	struct wlan_objmgr_vdev *vdev;
870 	struct peer_mc_cp_stats *peer_mc_stats;
871 	struct vdev_mc_cp_stats *vdev_mc_stats;
872 	struct peer_cp_stats *peer_cp_stats_priv;
873 	struct vdev_cp_stats *vdev_cp_stats_priv;
874 
875 	if (!ev->vdev_summary_stats)
876 		return;
877 
878 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
879 						 TYPE_STATION_STATS,
880 						 &last_req);
881 	if (QDF_IS_STATUS_ERROR(status)) {
882 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
883 		return;
884 	}
885 
886 	for (i = 0; i < ev->num_summary_stats; i++) {
887 		vdev_id = ev->vdev_summary_stats[i].vdev_id;
888 		update_ml_vdev_id_from_stats_event(&last_req, &vdev_id);
889 		if (ev->vdev_summary_stats[i].vdev_id == vdev_id)
890 			break;
891 	}
892 
893 	if (i == ev->num_summary_stats) {
894 		cp_stats_debug("vdev_id %d not found", vdev_id);
895 		return;
896 	}
897 
898 	if (vdev_id == WLAN_INVALID_VDEV_ID)
899 		return;
900 
901 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
902 						    WLAN_CP_STATS_ID);
903 	if (!vdev) {
904 		cp_stats_err("vdev is null");
905 		return;
906 	}
907 
908 	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
909 	if (!vdev_cp_stats_priv) {
910 		cp_stats_err("vdev cp stats object is null");
911 		goto end;
912 	}
913 
914 	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
915 	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
916 	qdf_mem_copy(&vdev_mc_stats->vdev_summary_stats,
917 		     &ev->vdev_summary_stats[i].stats,
918 		     sizeof(vdev_mc_stats->vdev_summary_stats));
919 
920 	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
921 
922 	peer = wlan_objmgr_get_peer(psoc, last_req.pdev_id,
923 				    last_req.peer_mac_addr, WLAN_CP_STATS_ID);
924 	if (!peer) {
925 		cp_stats_debug("peer is null "QDF_MAC_ADDR_FMT,
926 				QDF_MAC_ADDR_REF(last_req.peer_mac_addr));
927 		goto end;
928 	}
929 
930 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
931 	if (!peer_cp_stats_priv) {
932 		cp_stats_err("peer cp stats object is null");
933 		goto end;
934 	}
935 
936 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
937 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
938 	peer_mc_stats->peer_rssi = ev->vdev_summary_stats[i].stats.rssi;
939 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
940 
941 end:
942 	if (peer)
943 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
944 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
945 }
946 
tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)947 static void tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(
948 					struct wlan_objmgr_psoc *psoc,
949 					struct stats_event *ev)
950 {
951 	uint8_t i, j, vdev_id;
952 	QDF_STATUS status;
953 	struct request_info last_req = {0};
954 	struct wlan_objmgr_vdev *vdev;
955 	struct vdev_mc_cp_stats *vdev_mc_stats;
956 	struct vdev_cp_stats *vdev_cp_stats_priv;
957 
958 	if (!ev->vdev_chain_rssi)
959 		return;
960 
961 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
962 						  TYPE_STATION_STATS,
963 						  &last_req);
964 	if (QDF_IS_STATUS_ERROR(status)) {
965 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
966 		return;
967 	}
968 
969 	for (i = 0; i < ev->num_chain_rssi_stats; i++) {
970 		vdev_id = ev->vdev_chain_rssi[i].vdev_id;
971 		update_ml_vdev_id_from_stats_event(&last_req, &vdev_id);
972 		if (ev->vdev_chain_rssi[i].vdev_id != vdev_id)
973 			continue;
974 
975 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
976 							    WLAN_CP_STATS_ID);
977 		if (!vdev) {
978 			cp_stats_err("vdev is null");
979 			return;
980 		}
981 
982 		vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
983 		if (!vdev_cp_stats_priv) {
984 			cp_stats_err("vdev cp stats object is null");
985 			wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
986 			return;
987 		}
988 
989 		wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
990 		vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
991 		for (j = 0; j < MAX_NUM_CHAINS; j++) {
992 			vdev_mc_stats->chain_rssi[j] =
993 					ev->vdev_chain_rssi[i].chain_rssi[j];
994 		}
995 		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
996 
997 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
998 	}
999 }
1000 
1001 static void
tgt_mc_cp_stats_extract_vdev_extd_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)1002 tgt_mc_cp_stats_extract_vdev_extd_stats(struct wlan_objmgr_psoc *psoc,
1003 					struct stats_event *ev)
1004 {
1005 	uint8_t i, vdev_id;
1006 	QDF_STATUS status;
1007 	struct request_info last_req = {0};
1008 	struct wlan_objmgr_vdev *vdev;
1009 	struct vdev_mc_cp_stats *vdev_mc_stats;
1010 	struct vdev_cp_stats *vdev_cp_stats_priv;
1011 
1012 	if (!ev->vdev_extd_stats)
1013 		return;
1014 
1015 	status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS,
1016 						  &last_req);
1017 	if (QDF_IS_STATUS_ERROR(status)) {
1018 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
1019 		return;
1020 	}
1021 
1022 	for (i = 0; i < ev->num_vdev_extd_stats; i++) {
1023 		vdev_id = ev->vdev_extd_stats[i].vdev_id;
1024 
1025 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1026 							    WLAN_CP_STATS_ID);
1027 		if (!vdev) {
1028 			cp_stats_err("vdev is null");
1029 			return;
1030 		}
1031 
1032 		vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
1033 		if (!vdev_cp_stats_priv) {
1034 			cp_stats_err("vdev cp stats object is null");
1035 			wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1036 			return;
1037 		}
1038 
1039 		wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
1040 		vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
1041 		qdf_mem_copy(&vdev_mc_stats->vdev_extd_stats,
1042 			     &ev->vdev_extd_stats[i],
1043 			     sizeof(vdev_mc_stats->vdev_extd_stats));
1044 
1045 		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
1046 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1047 	}
1048 }
1049 
1050 static QDF_STATUS
tgt_send_vdev_mc_cp_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev,struct request_info * last_req)1051 tgt_send_vdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
1052 			  struct stats_event *ev,
1053 			  struct request_info *last_req)
1054 {
1055 	struct wlan_objmgr_vdev *vdev;
1056 	struct vdev_mc_cp_stats *vdev_mc_stats;
1057 	struct vdev_cp_stats *vdev_cp_stats_priv;
1058 
1059 	if (!ev || !last_req)
1060 		return QDF_STATUS_E_NULL_VALUE;
1061 
1062 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
1063 						    WLAN_CP_STATS_ID);
1064 	if (!vdev) {
1065 		cp_stats_err("vdev object is null");
1066 		return QDF_STATUS_E_NULL_VALUE;
1067 	}
1068 
1069 	vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
1070 	if (!vdev_cp_stats_priv) {
1071 		cp_stats_err("vdev cp stats object is null");
1072 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1073 		return QDF_STATUS_E_NULL_VALUE;
1074 	}
1075 
1076 	wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
1077 	vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
1078 	ev->vdev_summary_stats[0].vdev_id = last_req->vdev_id;
1079 	ev->vdev_summary_stats[0].stats = vdev_mc_stats->vdev_summary_stats;
1080 	ev->vdev_chain_rssi[0].vdev_id = last_req->vdev_id;
1081 	qdf_mem_copy(ev->vdev_chain_rssi[0].chain_rssi,
1082 		     vdev_mc_stats->chain_rssi,
1083 		     sizeof(vdev_mc_stats->chain_rssi));
1084 	ev->tx_rate_flags = vdev_mc_stats->tx_rate_flags;
1085 
1086 	ev->bcn_protect_stats = vdev_mc_stats->pmf_bcn_stats;
1087 
1088 	qdf_mem_copy(&ev->vdev_extd_stats[0],
1089 		     &vdev_mc_stats->vdev_extd_stats,
1090 		     sizeof(vdev_mc_stats->vdev_extd_stats));
1091 
1092 	wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
1093 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1094 
1095 	return QDF_STATUS_SUCCESS;
1096 }
1097 
1098 static QDF_STATUS
tgt_send_peer_mc_cp_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev,struct request_info * last_req)1099 tgt_send_peer_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
1100 			  struct stats_event *ev,
1101 			  struct request_info *last_req)
1102 {
1103 	struct wlan_objmgr_peer *peer;
1104 	struct peer_mc_cp_stats *peer_mc_stats;
1105 	struct peer_cp_stats *peer_cp_stats_priv;
1106 
1107 	if (!ev || !last_req)
1108 		return QDF_STATUS_E_NULL_VALUE;
1109 
1110 	peer = wlan_objmgr_get_peer(psoc, last_req->pdev_id,
1111 				    last_req->peer_mac_addr, WLAN_CP_STATS_ID);
1112 	if (!peer) {
1113 		cp_stats_debug("peer object is null");
1114 		return QDF_STATUS_E_NULL_VALUE;
1115 	}
1116 
1117 	peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
1118 	if (!peer_cp_stats_priv) {
1119 		cp_stats_err("peer cp stats object is null");
1120 		wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
1121 		return QDF_STATUS_E_NULL_VALUE;
1122 	}
1123 
1124 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
1125 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
1126 	/*
1127 	 * The linkspeed returned by fw is in kbps so convert
1128 	 * it in units of 100kbps which is expected by UMAC
1129 	 */
1130 	ev->tx_rate = peer_mc_stats->tx_rate / 100;
1131 	ev->rx_rate = peer_mc_stats->rx_rate / 100;
1132 
1133 	if (peer_mc_stats->adv_stats) {
1134 		ev->num_peer_adv_stats = 1;
1135 		qdf_mem_copy(ev->peer_adv_stats,
1136 			     peer_mc_stats->adv_stats,
1137 			     sizeof(*peer_mc_stats->adv_stats));
1138 	}
1139 
1140 	wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
1141 	wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
1142 
1143 	return QDF_STATUS_SUCCESS;
1144 }
1145 
1146 static QDF_STATUS
tgt_send_pdev_mc_cp_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev,struct request_info * last_req)1147 tgt_send_pdev_mc_cp_stats(struct wlan_objmgr_psoc *psoc,
1148 			  struct stats_event *ev,
1149 			  struct request_info *last_req)
1150 {
1151 	struct wlan_objmgr_pdev *pdev;
1152 	struct wlan_objmgr_vdev *vdev = NULL;
1153 	struct pdev_mc_cp_stats *pdev_mc_stats;
1154 	struct pdev_cp_stats *pdev_cp_stats_priv;
1155 	int pdev_id;
1156 
1157 	if (!ev || !last_req)
1158 		return QDF_STATUS_E_NULL_VALUE;
1159 
1160 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req->vdev_id,
1161 						    WLAN_CP_STATS_ID);
1162 	if (!vdev) {
1163 		cp_stats_err("vdev is null");
1164 		return QDF_STATUS_E_NULL_VALUE;
1165 	}
1166 
1167 	pdev = wlan_vdev_get_pdev(vdev);
1168 	if (!pdev) {
1169 		cp_stats_err("pdev is null");
1170 		goto end;
1171 	}
1172 
1173 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1174 	if (pdev_id != last_req->pdev_id) {
1175 		cp_stats_err("pdev_id: %d invalid", pdev_id);
1176 		goto end;
1177 	}
1178 
1179 	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
1180 	if (!pdev_cp_stats_priv) {
1181 		cp_stats_err("pdev_cp_stats_priv is null");
1182 		goto end;
1183 	}
1184 
1185 	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
1186 	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
1187 	qdf_mem_copy(ev->pdev_stats,
1188 		     pdev_mc_stats,
1189 		     sizeof(*pdev_mc_stats));
1190 	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
1191 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1192 
1193 	return QDF_STATUS_SUCCESS;
1194 
1195 end:
1196 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1197 	return QDF_STATUS_E_NULL_VALUE;
1198 }
1199 
1200 static QDF_STATUS
tgt_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev * vdev,int * dbm)1201 tgt_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, int *dbm)
1202 {
1203 	struct wlan_objmgr_pdev *pdev;
1204 	struct pdev_mc_cp_stats *pdev_mc_stats;
1205 	struct pdev_cp_stats *pdev_cp_stats_priv;
1206 	struct vdev_mc_cp_stats *vdev_mc_stats;
1207 	struct vdev_cp_stats *vdev_cp_stat;
1208 	uint32_t vdev_power = 0;
1209 
1210 	vdev_cp_stat = wlan_cp_stats_get_vdev_stats_obj(vdev);
1211 	if (vdev_cp_stat) {
1212 		wlan_cp_stats_vdev_obj_lock(vdev_cp_stat);
1213 		vdev_mc_stats = vdev_cp_stat->vdev_stats;
1214 		vdev_power = vdev_mc_stats->vdev_extd_stats.vdev_tx_power;
1215 		wlan_cp_stats_vdev_obj_unlock(vdev_cp_stat);
1216 		if (vdev_power) {
1217 			*dbm = vdev_power;
1218 			return QDF_STATUS_SUCCESS;
1219 		}
1220 	}
1221 
1222 	pdev = wlan_vdev_get_pdev(vdev);
1223 	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
1224 	if (!pdev_cp_stats_priv) {
1225 		cp_stats_err("pdev cp stats object is null");
1226 		return QDF_STATUS_E_NULL_VALUE;
1227 	}
1228 
1229 	wlan_cp_stats_pdev_obj_lock(pdev_cp_stats_priv);
1230 	pdev_mc_stats = pdev_cp_stats_priv->pdev_stats;
1231 	*dbm = pdev_mc_stats->max_pwr;
1232 	wlan_cp_stats_pdev_obj_unlock(pdev_cp_stats_priv);
1233 
1234 	return QDF_STATUS_SUCCESS;
1235 }
1236 
1237 static void
tgt_mc_cp_stats_extract_vdev_and_extd_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)1238 tgt_mc_cp_stats_extract_vdev_and_extd_stats(struct wlan_objmgr_psoc *psoc,
1239 					    struct stats_event *ev)
1240 {
1241 	QDF_STATUS status;
1242 	struct request_info last_req = {0};
1243 	bool pending = false;
1244 	int32_t max_pwr = 0;
1245 	struct wlan_objmgr_vdev *vdev = NULL;
1246 
1247 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
1248 						  TYPE_CONNECTION_TX_POWER,
1249 						  &last_req);
1250 	if (QDF_IS_STATUS_ERROR(status)) {
1251 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
1252 		return;
1253 	}
1254 
1255 	if (ev->pdev_stats)
1256 		tgt_mc_cp_stats_extract_tx_power(psoc, ev, false);
1257 	else if (ev->vdev_extd_stats)
1258 		tgt_mc_cp_stats_extract_vdev_extd_stats(psoc, ev);
1259 
1260 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
1261 						    WLAN_CP_STATS_ID);
1262 	if (!vdev) {
1263 		cp_stats_err("vdev is null");
1264 		return;
1265 	}
1266 	tgt_mc_cp_stats_get_tx_power(vdev, &max_pwr);
1267 
1268 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
1269 
1270 	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_CONNECTION_TX_POWER)) {
1271 		ucfg_mc_cp_stats_reset_pending_req(psoc,
1272 						   TYPE_CONNECTION_TX_POWER,
1273 						   &last_req,
1274 						   &pending);
1275 		if (last_req.u.get_tx_power_cb && pending)
1276 			last_req.u.get_tx_power_cb(max_pwr, last_req.cookie);
1277 	}
1278 }
1279 
1280 static void
tgt_mc_cp_stats_send_raw_station_stats(struct wlan_objmgr_psoc * psoc,struct request_info * last_req)1281 tgt_mc_cp_stats_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
1282 				       struct request_info *last_req)
1283 {
1284 	/* station_stats to be given to userspace thread */
1285 	struct stats_event info = {0};
1286 	void (*get_station_stats_cb)(struct stats_event *info, void *cookie);
1287 	QDF_STATUS status;
1288 
1289 	get_station_stats_cb = last_req->u.get_station_stats_cb;
1290 	if (!get_station_stats_cb) {
1291 		cp_stats_err("callback is null");
1292 		return;
1293 	}
1294 
1295 	info.num_summary_stats = 1;
1296 	info.num_chain_rssi_stats = 1;
1297 	info.num_vdev_extd_stats = 1;
1298 	info.vdev_summary_stats = qdf_mem_malloc(
1299 					sizeof(*info.vdev_summary_stats));
1300 	info.vdev_chain_rssi = qdf_mem_malloc(sizeof(*info.vdev_chain_rssi));
1301 
1302 	info.vdev_extd_stats = qdf_mem_malloc(sizeof(*info.vdev_extd_stats));
1303 
1304 	if (!info.vdev_summary_stats || !info.vdev_chain_rssi ||
1305 	    !info.vdev_extd_stats)
1306 		goto end;
1307 
1308 	status = tgt_send_vdev_mc_cp_stats(psoc, &info, last_req);
1309 	if (QDF_IS_STATUS_ERROR(status)) {
1310 		cp_stats_err("tgt_send_vdev_mc_cp_stats failed");
1311 		goto end;
1312 	}
1313 
1314 	info.peer_adv_stats = qdf_mem_malloc(sizeof(*info.peer_adv_stats));
1315 	if (!info.peer_adv_stats)
1316 		goto end;
1317 
1318 	status = tgt_send_peer_mc_cp_stats(psoc, &info, last_req);
1319 	if (QDF_IS_STATUS_ERROR(status)) {
1320 		cp_stats_err("tgt_send_peer_mc_cp_stats failed");
1321 		goto end;
1322 	}
1323 
1324 	info.num_pdev_stats = 1;
1325 	info.pdev_stats = qdf_mem_malloc(sizeof(*info.pdev_stats));
1326 	if (!info.pdev_stats)
1327 		goto end;
1328 
1329 	status = tgt_send_pdev_mc_cp_stats(psoc, &info, last_req);
1330 	if (QDF_IS_STATUS_ERROR(status)) {
1331 		cp_stats_err("tgt_send_pdev_mc_cp_stats failed");
1332 		goto end;
1333 	}
1334 end:
1335 	get_station_stats_cb(&info, last_req->cookie);
1336 
1337 	ucfg_mc_cp_stats_free_stats_resources(&info);
1338 }
1339 
1340 #ifdef WLAN_FEATURE_11BE_MLO
1341 static void
tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc * psoc,struct request_info * last_req)1342 tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
1343 						 struct request_info *last_req)
1344 {
1345 	uint8_t i;
1346 
1347 	if (!last_req->ml_vdev_info.ml_vdev_count) {
1348 		cp_stats_nofl_debug("Invoking get_station_cb for vdev_id[%d]",
1349 				    last_req->vdev_id);
1350 		tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
1351 		return;
1352 	}
1353 
1354 	for (i = 0; i < last_req->ml_vdev_info.ml_vdev_count; i++) {
1355 		last_req->vdev_id = last_req->ml_vdev_info.ml_vdev_id[i];
1356 		qdf_mem_copy(last_req->peer_mac_addr,
1357 			     &(last_req->ml_peer_mac_addr[i][0]),
1358 			     QDF_MAC_ADDR_SIZE);
1359 		cp_stats_nofl_debug("Invoking get_station_cb for ml vdev_id[%d]",
1360 				    last_req->vdev_id);
1361 		tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
1362 	}
1363 }
1364 #else
1365 static void
tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc * psoc,struct request_info * last_req)1366 tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
1367 						 struct request_info *last_req)
1368 {
1369 	tgt_mc_cp_stats_send_raw_station_stats(psoc, last_req);
1370 }
1371 #endif
1372 
tgt_mc_cp_stats_extract_station_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)1373 static void tgt_mc_cp_stats_extract_station_stats(
1374 				struct wlan_objmgr_psoc *psoc,
1375 				struct stats_event *ev)
1376 {
1377 	QDF_STATUS status;
1378 	struct request_info last_req = {0};
1379 	bool pending = false;
1380 
1381 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
1382 						  TYPE_STATION_STATS,
1383 						  &last_req);
1384 	if (QDF_IS_STATUS_ERROR(status)) {
1385 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
1386 		return;
1387 	}
1388 
1389 	tgt_mc_cp_stats_extract_tx_power(psoc, ev, true);
1390 	tgt_mc_cp_stats_extract_peer_stats(psoc, ev, true);
1391 	tgt_mc_cp_stats_extract_vdev_summary_stats(psoc, ev);
1392 	tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(psoc, ev);
1393 	tgt_mc_cp_stats_extract_pmf_bcn_stats(psoc, ev);
1394 	tgt_mc_cp_stats_extract_vdev_extd_stats(psoc, ev);
1395 
1396 	/*
1397 	 * PEER stats are the last stats sent for get_station statistics.
1398 	 * reset type_map bit for station stats .
1399 	 */
1400 	if (tgt_mc_cp_stats_is_last_event(ev, TYPE_STATION_STATS)) {
1401 		ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS,
1402 						   &last_req,
1403 						   &pending);
1404 		if (pending && last_req.u.get_station_stats_cb)
1405 			tgt_mc_cp_stats_prepare_n_send_raw_station_stats(
1406 							psoc, &last_req);
1407 	}
1408 }
1409 
tgt_mc_cp_send_lost_link_stats(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)1410 static void tgt_mc_cp_send_lost_link_stats(struct wlan_objmgr_psoc *psoc,
1411 					   struct stats_event *ev)
1412 {
1413 	struct psoc_cp_stats *psoc_cp_stats_priv;
1414 
1415 	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
1416 	if (psoc_cp_stats_priv && psoc_cp_stats_priv->legacy_stats_cb)
1417 		psoc_cp_stats_priv->legacy_stats_cb(ev);
1418 }
1419 
1420 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
tgt_mc_cp_stats_process_infra_stats_event(struct wlan_objmgr_psoc * psoc,struct infra_cp_stats_event * infra_event)1421 QDF_STATUS tgt_mc_cp_stats_process_infra_stats_event(
1422 				struct wlan_objmgr_psoc *psoc,
1423 				struct infra_cp_stats_event *infra_event)
1424 {
1425 	if (!infra_event)
1426 		return QDF_STATUS_E_NULL_VALUE;
1427 
1428 	tgt_mc_infra_cp_stats_extract_twt_stats(psoc, infra_event);
1429 
1430 	return QDF_STATUS_SUCCESS;
1431 }
1432 #endif
1433 
tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc * psoc,struct stats_event * ev)1434 QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc,
1435 					       struct stats_event *ev)
1436 {
1437 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_CONNECTION_TX_POWER))
1438 		tgt_mc_cp_stats_extract_vdev_and_extd_stats(psoc, ev);
1439 
1440 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS))
1441 		tgt_mc_cp_stats_extract_peer_stats(psoc, ev, false);
1442 
1443 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_STATION_STATS))
1444 		tgt_mc_cp_stats_extract_station_stats(psoc, ev);
1445 
1446 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_MIB_STATS))
1447 		tgt_mc_cp_stats_extract_mib_stats(psoc, ev);
1448 
1449 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_PEER_STATS_INFO_EXT))
1450 		tgt_mc_cp_stats_extract_peer_stats_info_ext(psoc, ev);
1451 
1452 	if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_CONGESTION_STATS))
1453 		tgt_mc_cp_stats_extract_congestion_stats(psoc, ev);
1454 
1455 	tgt_mc_cp_stats_extract_cca_stats(psoc, ev);
1456 
1457 	tgt_mc_cp_send_lost_link_stats(psoc, ev);
1458 	return QDF_STATUS_SUCCESS;
1459 }
1460 
1461 #ifdef WLAN_FEATURE_BIG_DATA_STATS
1462 QDF_STATUS
tgt_mc_cp_stats_process_big_data_stats_event(struct wlan_objmgr_psoc * psoc,struct big_data_stats_event * ev)1463 tgt_mc_cp_stats_process_big_data_stats_event(struct wlan_objmgr_psoc *psoc,
1464 					     struct big_data_stats_event *ev)
1465 {
1466 	QDF_STATUS status;
1467 	struct request_info last_req = {0};
1468 	bool pending = false;
1469 
1470 	if (!ev) {
1471 		cp_stats_err("invalid data");
1472 		return QDF_STATUS_E_INVAL;
1473 	}
1474 
1475 	status = ucfg_mc_cp_stats_get_pending_req(psoc,
1476 						  TYPE_BIG_DATA_STATS,
1477 						  &last_req);
1478 	if (QDF_IS_STATUS_ERROR(status)) {
1479 		cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
1480 		return QDF_STATUS_E_FAILURE;
1481 	}
1482 
1483 	ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_BIG_DATA_STATS,
1484 					   &last_req, &pending);
1485 
1486 	if (last_req.u.get_big_data_stats_cb && pending) {
1487 		last_req.u.get_big_data_stats_cb(ev, last_req.cookie);
1488 		last_req.u.get_big_data_stats_cb = NULL;
1489 	} else {
1490 		cp_stats_err("callback to send big data stats not found");
1491 		return QDF_STATUS_E_FAILURE;
1492 	}
1493 
1494 	return QDF_STATUS_SUCCESS;
1495 }
1496 #endif
1497 
tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc * psoc,uint32_t reason,struct wake_lock_stats * stats,uint32_t * unspecified_wake_count)1498 QDF_STATUS tgt_mc_cp_stats_inc_wake_lock_stats(struct wlan_objmgr_psoc *psoc,
1499 					       uint32_t reason,
1500 					       struct wake_lock_stats *stats,
1501 					       uint32_t *unspecified_wake_count)
1502 {
1503 	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
1504 
1505 	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
1506 	if (!tx_ops || !tx_ops->inc_wake_lock_stats)
1507 		return QDF_STATUS_E_NULL_VALUE;
1508 
1509 	tx_ops->inc_wake_lock_stats(reason, stats, unspecified_wake_count);
1510 
1511 	return QDF_STATUS_SUCCESS;
1512 }
1513 
tgt_send_mc_cp_stats_req(struct wlan_objmgr_psoc * psoc,enum stats_req_type type,struct request_info * req)1514 QDF_STATUS tgt_send_mc_cp_stats_req(struct wlan_objmgr_psoc *psoc,
1515 				    enum stats_req_type type,
1516 				    struct request_info *req)
1517 {
1518 	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
1519 	QDF_STATUS status;
1520 
1521 	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
1522 	if (!tx_ops) {
1523 		cp_stats_err("could not get tx_ops");
1524 		return QDF_STATUS_E_NULL_VALUE;
1525 	}
1526 
1527 	switch (type) {
1528 	case TYPE_PEER_STATS_INFO_EXT:
1529 		if (!tx_ops->send_req_peer_stats) {
1530 			cp_stats_err("could not get send_req_peer_stats");
1531 			return QDF_STATUS_E_NULL_VALUE;
1532 		}
1533 		status = tx_ops->send_req_peer_stats(psoc, req);
1534 		break;
1535 	case TYPE_BIG_DATA_STATS:
1536 		status = send_big_data_stats_req(tx_ops, psoc, req);
1537 		break;
1538 	default:
1539 		if (!tx_ops->send_req_stats) {
1540 			cp_stats_err("could not get send_req_stats");
1541 			return QDF_STATUS_E_NULL_VALUE;
1542 		}
1543 		status = tx_ops->send_req_stats(psoc, type, req);
1544 	}
1545 
1546 	return status;
1547 }
1548 
tgt_set_pdev_stats_update_period(struct wlan_objmgr_psoc * psoc,uint8_t pdev_id,uint32_t val)1549 QDF_STATUS tgt_set_pdev_stats_update_period(struct wlan_objmgr_psoc *psoc,
1550 					    uint8_t pdev_id, uint32_t val)
1551 {
1552 	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
1553 	QDF_STATUS status;
1554 
1555 	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
1556 	if (!tx_ops || !tx_ops->set_pdev_stats_update_period) {
1557 		cp_stats_err("could not get tx_ops");
1558 		return QDF_STATUS_E_NULL_VALUE;
1559 	}
1560 	status = tx_ops->set_pdev_stats_update_period(psoc, pdev_id, val);
1561 
1562 	return status;
1563 }
1564 
1565