xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mgmt_txrx/src/target_if_mgmt_txrx_rx_reo.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  *  DOC: target_if_mgmt_txrx_rx_reo.c
20  *  This file contains definitions of management rx re-ordering related APIs.
21  */
22 
23 #include <wlan_objmgr_psoc_obj.h>
24 #include <wlan_objmgr_pdev_obj.h>
25 #include <qdf_status.h>
26 #include <target_if.h>
27 #include <wlan_mgmt_txrx_rx_reo_public_structs.h>
28 #include <target_if_mgmt_txrx_rx_reo.h>
29 #include <wlan_lmac_if_api.h>
30 #include <init_deinit_lmac.h>
31 
32 /**
33  * target_if_mgmt_rx_reo_fw_consumed_event_handler() - WMI event handler to
34  * process MGMT Rx FW consumed event handler
35  * @scn: Pointer to scn object
36  * @data_buf: Pointer to event buffer
37  * @data_len: Length of event buffer
38  *
39  * Return: 0 for success, else failure
40  */
41 static int
42 target_if_mgmt_rx_reo_fw_consumed_event_handler(
43 	ol_scn_t scn, uint8_t *data, uint32_t datalen)
44 {
45 	struct wlan_objmgr_psoc *psoc;
46 	struct wlan_objmgr_pdev *pdev;
47 	struct wmi_unified *wmi_handle;
48 	QDF_STATUS status;
49 	struct mgmt_rx_reo_params params;
50 	struct wlan_lmac_if_mgmt_rx_reo_rx_ops *mgmt_rx_reo_rx_ops;
51 
52 	psoc = target_if_get_psoc_from_scn_hdl(scn);
53 	if (!psoc) {
54 		mgmt_rx_reo_err("null psoc");
55 		return -EINVAL;
56 	}
57 
58 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
59 	if (!wmi_handle) {
60 		mgmt_rx_reo_err("wmi_handle is NULL");
61 		return -EINVAL;
62 	}
63 
64 	status = wmi_extract_mgmt_rx_fw_consumed(wmi_handle, data, &params);
65 	if (QDF_IS_STATUS_ERROR(status)) {
66 		mgmt_rx_reo_err("Failed to extract mgmt rx params");
67 		return -EINVAL;
68 	}
69 
70 	mgmt_rx_reo_rx_ops = target_if_mgmt_rx_reo_get_rx_ops(psoc);
71 	if (!mgmt_rx_reo_rx_ops) {
72 		mgmt_rx_reo_err("rx_ops of MGMT Rx REO module is NULL");
73 		return -EINVAL;
74 	}
75 
76 	if (!mgmt_rx_reo_rx_ops->fw_consumed_event_handler) {
77 		mgmt_rx_reo_err("FW consumed event handler is NULL");
78 		return -EINVAL;
79 	}
80 
81 	/* Take the pdev reference */
82 	pdev = wlan_objmgr_get_pdev_by_id(psoc, params.pdev_id,
83 					  WLAN_MGMT_SB_ID);
84 	if (!pdev) {
85 		mgmt_rx_reo_err("Couldn't get pdev for pdev_id: %d"
86 				"on psoc: %pK", params.pdev_id, psoc);
87 		return -EINVAL;
88 	}
89 
90 	status = mgmt_rx_reo_rx_ops->fw_consumed_event_handler(pdev, &params);
91 	if (QDF_IS_STATUS_ERROR(status)) {
92 		mgmt_rx_reo_err("FW consumed event handling failed");
93 		wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
94 		return -EINVAL;
95 	}
96 
97 	wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
98 	return 0;
99 }
100 
101 QDF_STATUS
102 target_if_mgmt_rx_reo_register_event_handlers(struct wlan_objmgr_psoc *psoc)
103 {
104 	struct wmi_unified *wmi_handle;
105 	QDF_STATUS status;
106 
107 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
108 	if (!wmi_handle) {
109 		mgmt_rx_reo_err("Invalid WMI handle");
110 		return QDF_STATUS_E_INVAL;
111 	}
112 
113 	status = wmi_unified_register_event_handler(
114 			wmi_handle,
115 			wmi_mgmt_rx_fw_consumed_eventid,
116 			target_if_mgmt_rx_reo_fw_consumed_event_handler,
117 			WMI_RX_UMAC_CTX);
118 
119 	if (QDF_IS_STATUS_ERROR(status)) {
120 		mgmt_rx_reo_err("Register Rx FW consumed event cb errcode %d",
121 				status);
122 		if (status ==  QDF_STATUS_E_NOSUPPORT)
123 			status = QDF_STATUS_SUCCESS;
124 	}
125 
126 	return status;
127 }
128 
129 QDF_STATUS
130 target_if_mgmt_rx_reo_unregister_event_handlers(struct wlan_objmgr_psoc *psoc)
131 {
132 	struct wmi_unified *wmi_handle;
133 	QDF_STATUS status;
134 
135 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
136 	if (!wmi_handle) {
137 		mgmt_rx_reo_err("Invalid WMI handle");
138 		return QDF_STATUS_E_INVAL;
139 	}
140 
141 	status = wmi_unified_unregister_event_handler(
142 			wmi_handle,
143 			wmi_mgmt_rx_fw_consumed_eventid);
144 
145 	if (QDF_IS_STATUS_ERROR(status)) {
146 		mgmt_rx_reo_err("Unregister Rx FW consumed event cb errcode %d",
147 				status);
148 		if (status ==  QDF_STATUS_E_NOSUPPORT)
149 			status = QDF_STATUS_SUCCESS;
150 	}
151 
152 	return status;
153 }
154 
155 /**
156  * target_if_mgmt_rx_reo_get_num_active_hw_links() - Get number of active MLO HW
157  * links
158  * @psoc: Pointer to psoc object
159  * @num_active_hw_links: pointer to number of active MLO HW links
160  *
161  * Get number of active MLO HW links from the MLO global shared memory arena.
162  *
163  * Return: QDF_STATUS
164  */
165 static QDF_STATUS
166 target_if_mgmt_rx_reo_get_num_active_hw_links(struct wlan_objmgr_psoc *psoc,
167 					      int8_t *num_active_hw_links)
168 {
169 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
170 
171 	if (!psoc) {
172 		mgmt_rx_reo_err("psoc is null");
173 		return QDF_STATUS_E_NULL_VALUE;
174 	}
175 
176 	if (!num_active_hw_links) {
177 		mgmt_rx_reo_err("Pointer to num_active_hw_links is null");
178 		return QDF_STATUS_E_NULL_VALUE;
179 	}
180 
181 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(psoc);
182 
183 	if (!low_level_ops) {
184 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
185 		return QDF_STATUS_E_NULL_VALUE;
186 	}
187 
188 	qdf_assert_always(low_level_ops->implemented);
189 
190 	*num_active_hw_links = low_level_ops->get_num_links();
191 
192 	return QDF_STATUS_SUCCESS;
193 }
194 
195 /**
196  * target_if_mgmt_rx_reo_get_valid_hw_link_bitmap() - Get valid MLO HW link
197  * bitmap
198  * @psoc: Pointer to psoc object
199  * @valid_hw_link_bitmap: Pointer to valid MLO HW link bitmap
200  *
201  * Get valid MLO HW link bitmap from the MLO global shared memory arena.
202  *
203  * Return: QDF_STATUS
204  */
205 QDF_STATUS
206 target_if_mgmt_rx_reo_get_valid_hw_link_bitmap(struct wlan_objmgr_psoc *psoc,
207 					       uint16_t *valid_hw_link_bitmap)
208 {
209 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
210 
211 	if (!psoc) {
212 		mgmt_rx_reo_err("psoc is null");
213 		return QDF_STATUS_E_NULL_VALUE;
214 	}
215 
216 	if (!valid_hw_link_bitmap) {
217 		mgmt_rx_reo_err("Pointer to valid_hw_link_bitmap is null");
218 		return QDF_STATUS_E_NULL_VALUE;
219 	}
220 
221 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(psoc);
222 
223 	if (!low_level_ops) {
224 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
225 		return QDF_STATUS_E_NULL_VALUE;
226 	}
227 
228 	qdf_assert_always(low_level_ops->implemented);
229 
230 	*valid_hw_link_bitmap = low_level_ops->get_valid_link_bitmap();
231 
232 	return QDF_STATUS_SUCCESS;
233 }
234 
235 /**
236  * target_if_mgmt_rx_reo_read_snapshot_raw() - Read raw value of management
237  * rx-reorder snapshot
238  * @snapshot_address: snapshot address
239  * @mgmt_rx_reo_snapshot_low: Pointer to lower 32 bits of snapshot value
240  * @mgmt_rx_reo_snapshot_high: Pointer to higher 32 bits of snapshot value
241  * @snapshot_version: snapshot version
242  *
243  * Read raw value of management rx-reorder snapshots.
244  *
245  * Return: QDF_STATUS
246  */
247 static QDF_STATUS
248 target_if_mgmt_rx_reo_read_snapshot_raw
249 			(struct mgmt_rx_reo_shared_snapshot *snapshot_address,
250 			 uint32_t *mgmt_rx_reo_snapshot_low,
251 			 uint32_t *mgmt_rx_reo_snapshot_high,
252 			 uint8_t snapshot_version,
253 			 struct mgmt_rx_reo_shared_snapshot *raw_snapshot)
254 {
255 	uint32_t prev_snapshot_low;
256 	uint32_t prev_snapshot_high;
257 	uint32_t cur_snapshot_low;
258 	uint32_t cur_snapshot_high;
259 	uint8_t retry_count = 0;
260 
261 	if (snapshot_version == 1) {
262 		*mgmt_rx_reo_snapshot_low =
263 				snapshot_address->mgmt_rx_reo_snapshot_low;
264 		*mgmt_rx_reo_snapshot_high =
265 				snapshot_address->mgmt_rx_reo_snapshot_high;
266 		raw_snapshot->mgmt_rx_reo_snapshot_low =
267 						*mgmt_rx_reo_snapshot_low;
268 		raw_snapshot->mgmt_rx_reo_snapshot_high =
269 						*mgmt_rx_reo_snapshot_high;
270 		return QDF_STATUS_SUCCESS;
271 	}
272 
273 	prev_snapshot_low = snapshot_address->mgmt_rx_reo_snapshot_low;
274 	prev_snapshot_high = snapshot_address->mgmt_rx_reo_snapshot_high;
275 	raw_snapshot->mgmt_rx_reo_snapshot_low = prev_snapshot_low;
276 	raw_snapshot->mgmt_rx_reo_snapshot_high = prev_snapshot_high;
277 
278 	for (; retry_count < (MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT - 1);
279 	     retry_count++) {
280 		cur_snapshot_low = snapshot_address->mgmt_rx_reo_snapshot_low;
281 		cur_snapshot_high = snapshot_address->mgmt_rx_reo_snapshot_high;
282 
283 		raw_snapshot[retry_count + 1].mgmt_rx_reo_snapshot_low =
284 							cur_snapshot_low;
285 		raw_snapshot[retry_count + 1].mgmt_rx_reo_snapshot_high =
286 							cur_snapshot_high;
287 
288 		if (prev_snapshot_low == cur_snapshot_low &&
289 		    prev_snapshot_high == cur_snapshot_high)
290 			break;
291 
292 		prev_snapshot_low = cur_snapshot_low;
293 		prev_snapshot_high = cur_snapshot_high;
294 	}
295 
296 	qdf_assert_always(retry_count !=
297 			  (MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT - 1));
298 
299 	*mgmt_rx_reo_snapshot_low = cur_snapshot_low;
300 	*mgmt_rx_reo_snapshot_high = cur_snapshot_high;
301 
302 	return QDF_STATUS_SUCCESS;
303 }
304 
305 /**
306  * target_if_mgmt_rx_reo_read_snapshot() - Read management rx-reorder snapshot
307  * @pdev: pdev pointer
308  * @snapshot_info: Snapshot info
309  * @id: Snapshot ID
310  * @snapshot_value: Pointer to snapshot value
311  *
312  * Read management rx-reorder snapshots from target.
313  *
314  * Return: QDF_STATUS
315  */
316 static QDF_STATUS
317 target_if_mgmt_rx_reo_read_snapshot(
318 			struct wlan_objmgr_pdev *pdev,
319 			struct mgmt_rx_reo_snapshot_info *snapshot_info,
320 			enum mgmt_rx_reo_shared_snapshot_id id,
321 			struct mgmt_rx_reo_snapshot_params *snapshot_value,
322 			struct mgmt_rx_reo_shared_snapshot (*raw_snapshot)
323 			[MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT])
324 {
325 	bool snapshot_valid;
326 	uint16_t mgmt_pkt_ctr;
327 	uint32_t global_timestamp;
328 	uint32_t mgmt_rx_reo_snapshot_low;
329 	uint32_t mgmt_rx_reo_snapshot_high;
330 	uint8_t retry_count;
331 	QDF_STATUS status;
332 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
333 	struct mgmt_rx_reo_shared_snapshot *snapshot_address;
334 	uint8_t snapshot_version;
335 
336 	if (!snapshot_info) {
337 		mgmt_rx_reo_err("Mgmt Rx REO snapshot info null");
338 		return QDF_STATUS_E_INVAL;
339 	}
340 
341 	snapshot_address = snapshot_info->address;
342 	if (!snapshot_address) {
343 		mgmt_rx_reo_err("Mgmt Rx REO snapshot address null");
344 		return QDF_STATUS_E_INVAL;
345 	}
346 
347 	snapshot_version = snapshot_info->version;
348 
349 	if (!snapshot_value) {
350 		mgmt_rx_reo_err("Mgmt Rx REO snapshot null");
351 		return QDF_STATUS_E_INVAL;
352 	}
353 
354 	qdf_mem_zero(snapshot_value, sizeof(*snapshot_value));
355 
356 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(
357 				wlan_pdev_get_psoc(pdev));
358 
359 	if (!low_level_ops) {
360 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
361 		return QDF_STATUS_E_FAILURE;
362 	}
363 
364 	/* Make sure that function pointers are populated */
365 	qdf_assert_always(low_level_ops->implemented);
366 
367 	switch (id) {
368 	case MGMT_RX_REO_SHARED_SNAPSHOT_MAC_HW:
369 	case MGMT_RX_REO_SHARED_SNAPSHOT_FW_CONSUMED:
370 	case MGMT_RX_REO_SHARED_SNAPSHOT_FW_FORWARDED:
371 		retry_count = 0;
372 		for (; retry_count < MGMT_RX_REO_SNAPSHOT_READ_RETRY_LIMIT;
373 		     retry_count++) {
374 			status = target_if_mgmt_rx_reo_read_snapshot_raw
375 					(snapshot_address,
376 					 &mgmt_rx_reo_snapshot_low,
377 					 &mgmt_rx_reo_snapshot_high,
378 					 snapshot_version,
379 					 raw_snapshot[retry_count]);
380 
381 			if (QDF_IS_STATUS_ERROR(status)) {
382 				mgmt_rx_reo_err("Failed to read snapshot %d",
383 						id);
384 				return QDF_STATUS_E_FAILURE;
385 			}
386 
387 			snapshot_valid = low_level_ops->snapshot_is_valid(
388 						mgmt_rx_reo_snapshot_low,
389 						snapshot_version);
390 
391 			if (!snapshot_valid) {
392 				mgmt_rx_reo_info("Invalid REO snapshot value");
393 				snapshot_value->valid = false;
394 				snapshot_value->mgmt_pkt_ctr =
395 					low_level_ops->snapshot_get_mgmt_pkt_ctr
396 					(mgmt_rx_reo_snapshot_low,
397 					 snapshot_version);
398 				snapshot_value->global_timestamp =
399 				low_level_ops->snapshot_get_global_timestamp
400 					(mgmt_rx_reo_snapshot_low,
401 					 mgmt_rx_reo_snapshot_high,
402 					 snapshot_version);
403 				snapshot_value->retry_count = retry_count + 1;
404 				return QDF_STATUS_SUCCESS;
405 			}
406 
407 			if (low_level_ops->snapshot_is_consistent
408 						(mgmt_rx_reo_snapshot_low,
409 						 mgmt_rx_reo_snapshot_high,
410 						 snapshot_version)) {
411 				global_timestamp =
412 				    low_level_ops->snapshot_get_global_timestamp
413 						(mgmt_rx_reo_snapshot_low,
414 						 mgmt_rx_reo_snapshot_high,
415 						 snapshot_version);
416 				mgmt_pkt_ctr =
417 					low_level_ops->snapshot_get_mgmt_pkt_ctr
418 						(mgmt_rx_reo_snapshot_low,
419 						 snapshot_version);
420 				break;
421 			}
422 			mgmt_rx_reo_info("Inconsistent snapshot %d, version=%u, low=0x%x, high=0x%x, retry=%u",
423 					 id, snapshot_version,
424 					 mgmt_rx_reo_snapshot_low,
425 					 mgmt_rx_reo_snapshot_high,
426 					 retry_count);
427 		}
428 
429 		if (retry_count == MGMT_RX_REO_SNAPSHOT_READ_RETRY_LIMIT) {
430 			mgmt_rx_reo_err("Read retry limit, id = %d, ver = %u",
431 					id, snapshot_version);
432 			snapshot_value->valid = false;
433 			snapshot_value->mgmt_pkt_ctr = 0xFFFF;
434 			snapshot_value->global_timestamp = 0xFFFFFFFF;
435 			snapshot_value->retry_count = retry_count;
436 			qdf_assert_always(0);
437 			return QDF_STATUS_E_FAILURE;
438 		}
439 
440 		snapshot_value->valid = true;
441 		snapshot_value->mgmt_pkt_ctr = mgmt_pkt_ctr;
442 		snapshot_value->global_timestamp = global_timestamp;
443 		snapshot_value->retry_count = retry_count + 1;
444 		status = QDF_STATUS_SUCCESS;
445 		break;
446 
447 	default:
448 		mgmt_rx_reo_err("Invalid snapshot id %d", id);
449 		status = QDF_STATUS_E_INVAL;
450 		break;
451 	}
452 
453 	return status;
454 }
455 
456 /**
457  * target_if_mgmt_rx_reo_get_snapshot_info() - Get information related to
458  * management rx-reorder snapshot
459  * @pdev: Pointer to pdev object
460  * @id: Snapshot ID
461  * @snapshot_info: Pointer to snapshot info
462  *
463  * Return: QDF_STATUS
464  */
465 static QDF_STATUS
466 target_if_mgmt_rx_reo_get_snapshot_info
467 			(struct wlan_objmgr_pdev *pdev,
468 			 enum mgmt_rx_reo_shared_snapshot_id id,
469 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
470 {
471 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
472 	int8_t link_id;
473 	int8_t snapshot_version;
474 
475 	if (!pdev) {
476 		mgmt_rx_reo_err("pdev is null");
477 		return QDF_STATUS_E_NULL_VALUE;
478 	}
479 
480 	if (id >= MGMT_RX_REO_SHARED_SNAPSHOT_MAX) {
481 		mgmt_rx_reo_err("Mgmt RX REO snapshot id invalid %d", id);
482 		return QDF_STATUS_E_INVAL;
483 	}
484 
485 	if (!snapshot_info) {
486 		mgmt_rx_reo_err("Ref to mgmt RX REO snapshot info is null");
487 		return QDF_STATUS_E_NULL_VALUE;
488 	}
489 
490 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(
491 				wlan_pdev_get_psoc(pdev));
492 
493 	if (!low_level_ops) {
494 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
495 		return QDF_STATUS_E_FAILURE;
496 	}
497 
498 	qdf_assert_always(low_level_ops->implemented);
499 
500 	link_id = wlan_get_mlo_link_id_from_pdev(pdev);
501 	qdf_assert_always(link_id >= 0);
502 
503 	snapshot_info->address =
504 			low_level_ops->get_snapshot_address(link_id, id);
505 
506 	snapshot_version = low_level_ops->get_snapshot_version(id);
507 	if (snapshot_version < 0) {
508 		mgmt_rx_reo_err("Invalid snapshot version %d",
509 				snapshot_version);
510 		return QDF_STATUS_E_INVAL;
511 	}
512 
513 	snapshot_info->version = snapshot_version;
514 
515 	return QDF_STATUS_SUCCESS;
516 }
517 
518 /**
519  * target_if_mgmt_rx_reo_filter_config() - Configure MGMT Rx REO filter
520  * @pdev: Pointer to pdev objmgr
521  * @filter: Pointer to MGMT Rx REO filter
522  *
523  * Return: QDF_STATUS_SUCCESS for success or error code
524  */
525 static QDF_STATUS
526 target_if_mgmt_rx_reo_filter_config(
527 	struct wlan_objmgr_pdev *pdev,
528 	struct mgmt_rx_reo_filter *filter)
529 {
530 	QDF_STATUS status;
531 	struct wmi_unified *wmi_handle;
532 	uint8_t pdev_id;
533 
534 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
535 	if (!wmi_handle) {
536 		mgmt_rx_reo_err("Invalid WMI handle");
537 		return QDF_STATUS_E_INVAL;
538 	}
539 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
540 
541 	status = wmi_unified_mgmt_rx_reo_filter_config_cmd(wmi_handle, pdev_id,
542 							   filter);
543 	if (QDF_IS_STATUS_ERROR(status))
544 		mgmt_rx_reo_err("Unable to send MGMT Rx REO Filter config cmd");
545 
546 	return status;
547 }
548 
549 QDF_STATUS
550 target_if_mgmt_rx_reo_extract_reo_params(
551 	wmi_unified_t wmi_handle, void *evt_buf,
552 	struct mgmt_rx_event_params *params)
553 {
554 	struct wlan_objmgr_psoc *psoc;
555 
556 	if (!wmi_handle) {
557 		mgmt_rx_reo_err("wmi_handle is null");
558 		return QDF_STATUS_E_NULL_VALUE;
559 	}
560 
561 	psoc = target_if_get_psoc_from_scn_hdl(wmi_handle->scn_handle);
562 	if (!psoc) {
563 		mgmt_rx_reo_err("null psoc");
564 		return QDF_STATUS_E_NULL_VALUE;
565 	}
566 
567 	/* If REO feature is not enabled in FW, no need to extract REO params */
568 	if (!wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_MGMT_RX_REO_CAPABLE))
569 		return QDF_STATUS_SUCCESS;
570 
571 	if (!params) {
572 		mgmt_rx_reo_err("MGMT Rx event parameters is NULL");
573 		return QDF_STATUS_E_NULL_VALUE;
574 	}
575 
576 	return wmi_extract_mgmt_rx_reo_params(wmi_handle, evt_buf,
577 					      params->reo_params);
578 }
579 
580 QDF_STATUS
581 target_if_mgmt_rx_reo_tx_ops_register(
582 			struct wlan_lmac_if_mgmt_txrx_tx_ops *mgmt_txrx_tx_ops)
583 {
584 	struct wlan_lmac_if_mgmt_rx_reo_tx_ops *mgmt_rx_reo_tx_ops;
585 
586 	if (!mgmt_txrx_tx_ops) {
587 		mgmt_rx_reo_err("mgmt_txrx txops NULL");
588 		return QDF_STATUS_E_FAILURE;
589 	}
590 	mgmt_rx_reo_tx_ops = &mgmt_txrx_tx_ops->mgmt_rx_reo_tx_ops;
591 	mgmt_rx_reo_tx_ops->get_num_active_hw_links =
592 				target_if_mgmt_rx_reo_get_num_active_hw_links;
593 	mgmt_rx_reo_tx_ops->get_valid_hw_link_bitmap =
594 				target_if_mgmt_rx_reo_get_valid_hw_link_bitmap;
595 	mgmt_rx_reo_tx_ops->read_mgmt_rx_reo_snapshot =
596 				target_if_mgmt_rx_reo_read_snapshot;
597 	mgmt_rx_reo_tx_ops->get_mgmt_rx_reo_snapshot_info =
598 				target_if_mgmt_rx_reo_get_snapshot_info;
599 	mgmt_rx_reo_tx_ops->mgmt_rx_reo_filter_config =
600 					target_if_mgmt_rx_reo_filter_config;
601 
602 	return QDF_STATUS_SUCCESS;
603 }
604 
605 QDF_STATUS
606 target_if_mgmt_rx_reo_host_drop_handler(struct wlan_objmgr_pdev *pdev,
607 					struct mgmt_rx_event_params *params)
608 {
609 	struct wlan_lmac_if_mgmt_rx_reo_rx_ops *mgmt_rx_reo_rx_ops;
610 
611 	if (!pdev) {
612 		mgmt_rx_reo_err("pdev is null");
613 		return QDF_STATUS_E_NULL_VALUE;
614 	}
615 
616 	if (!params) {
617 		mgmt_rx_reo_err("mgmt rx event params are null");
618 		return QDF_STATUS_E_NULL_VALUE;
619 	}
620 
621 	mgmt_rx_reo_rx_ops = target_if_mgmt_rx_reo_get_rx_ops(
622 					wlan_pdev_get_psoc(pdev));
623 	if (!mgmt_rx_reo_rx_ops) {
624 		mgmt_rx_reo_err("rx_ops of MGMT Rx REO module is NULL");
625 		return QDF_STATUS_E_NULL_VALUE;
626 	}
627 
628 	return mgmt_rx_reo_rx_ops->host_drop_handler(pdev, params->reo_params);
629 }
630