xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mgmt_txrx/src/target_if_mgmt_txrx_rx_reo.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
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 #include <wlan_mlo_mgr_setup.h>
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 	uint8_t grp_id;
171 
172 	if (!psoc) {
173 		mgmt_rx_reo_err("psoc is null");
174 		return QDF_STATUS_E_NULL_VALUE;
175 	}
176 
177 	if (!num_active_hw_links) {
178 		mgmt_rx_reo_err("Pointer to num_active_hw_links is null");
179 		return QDF_STATUS_E_NULL_VALUE;
180 	}
181 
182 	if (!mlo_psoc_get_grp_id(psoc, &grp_id)) {
183 		mgmt_rx_reo_err("Failed to get valid MLO Group id");
184 		return QDF_STATUS_E_INVAL;
185 	}
186 
187 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(psoc);
188 
189 	if (!low_level_ops) {
190 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
191 		return QDF_STATUS_E_NULL_VALUE;
192 	}
193 
194 	qdf_assert_always(low_level_ops->implemented);
195 
196 	*num_active_hw_links = low_level_ops->get_num_links(grp_id);
197 
198 	return QDF_STATUS_SUCCESS;
199 }
200 
201 /**
202  * target_if_mgmt_rx_reo_get_valid_hw_link_bitmap() - Get valid MLO HW link
203  * bitmap
204  * @psoc: Pointer to psoc object
205  * @valid_hw_link_bitmap: Pointer to valid MLO HW link bitmap
206  *
207  * Get valid MLO HW link bitmap from the MLO global shared memory arena.
208  *
209  * Return: QDF_STATUS
210  */
211 QDF_STATUS
212 target_if_mgmt_rx_reo_get_valid_hw_link_bitmap(struct wlan_objmgr_psoc *psoc,
213 					       uint16_t *valid_hw_link_bitmap)
214 {
215 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
216 	uint8_t grp_id;
217 
218 	if (!psoc) {
219 		mgmt_rx_reo_err("psoc is null");
220 		return QDF_STATUS_E_NULL_VALUE;
221 	}
222 
223 	if (!valid_hw_link_bitmap) {
224 		mgmt_rx_reo_err("Pointer to valid_hw_link_bitmap is null");
225 		return QDF_STATUS_E_NULL_VALUE;
226 	}
227 
228 	if (!mlo_psoc_get_grp_id(psoc, &grp_id)) {
229 		mgmt_rx_reo_err("Failed to get valid MLO Group id");
230 		return QDF_STATUS_E_INVAL;
231 	}
232 
233 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(psoc);
234 
235 	if (!low_level_ops) {
236 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
237 		return QDF_STATUS_E_NULL_VALUE;
238 	}
239 
240 	qdf_assert_always(low_level_ops->implemented);
241 
242 	*valid_hw_link_bitmap = low_level_ops->get_valid_link_bitmap(grp_id);
243 
244 	return QDF_STATUS_SUCCESS;
245 }
246 
247 /**
248  * target_if_mgmt_rx_reo_read_snapshot_raw() - Read raw value of management
249  * rx-reorder snapshot
250  * @snapshot_address: snapshot address
251  * @mgmt_rx_reo_snapshot_low: Pointer to lower 32 bits of snapshot value
252  * @mgmt_rx_reo_snapshot_high: Pointer to higher 32 bits of snapshot value
253  * @snapshot_version: snapshot version
254  *
255  * Read raw value of management rx-reorder snapshots.
256  *
257  * Return: QDF_STATUS
258  */
259 static QDF_STATUS
260 target_if_mgmt_rx_reo_read_snapshot_raw
261 			(struct mgmt_rx_reo_shared_snapshot *snapshot_address,
262 			 uint32_t *mgmt_rx_reo_snapshot_low,
263 			 uint32_t *mgmt_rx_reo_snapshot_high,
264 			 uint8_t snapshot_version,
265 			 struct mgmt_rx_reo_shared_snapshot *raw_snapshot)
266 {
267 	uint32_t prev_snapshot_low;
268 	uint32_t prev_snapshot_high;
269 	uint32_t cur_snapshot_low;
270 	uint32_t cur_snapshot_high;
271 	uint8_t retry_count = 0;
272 
273 	if (snapshot_version == 1) {
274 		*mgmt_rx_reo_snapshot_low =
275 				snapshot_address->mgmt_rx_reo_snapshot_low;
276 		*mgmt_rx_reo_snapshot_high =
277 				snapshot_address->mgmt_rx_reo_snapshot_high;
278 		raw_snapshot->mgmt_rx_reo_snapshot_low =
279 						*mgmt_rx_reo_snapshot_low;
280 		raw_snapshot->mgmt_rx_reo_snapshot_high =
281 						*mgmt_rx_reo_snapshot_high;
282 		return QDF_STATUS_SUCCESS;
283 	}
284 
285 	prev_snapshot_low = snapshot_address->mgmt_rx_reo_snapshot_low;
286 	prev_snapshot_high = snapshot_address->mgmt_rx_reo_snapshot_high;
287 	raw_snapshot->mgmt_rx_reo_snapshot_low = prev_snapshot_low;
288 	raw_snapshot->mgmt_rx_reo_snapshot_high = prev_snapshot_high;
289 
290 	for (; retry_count < (MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT - 1);
291 	     retry_count++) {
292 		cur_snapshot_low = snapshot_address->mgmt_rx_reo_snapshot_low;
293 		cur_snapshot_high = snapshot_address->mgmt_rx_reo_snapshot_high;
294 
295 		raw_snapshot[retry_count + 1].mgmt_rx_reo_snapshot_low =
296 							cur_snapshot_low;
297 		raw_snapshot[retry_count + 1].mgmt_rx_reo_snapshot_high =
298 							cur_snapshot_high;
299 
300 		if (prev_snapshot_low == cur_snapshot_low &&
301 		    prev_snapshot_high == cur_snapshot_high)
302 			break;
303 
304 		prev_snapshot_low = cur_snapshot_low;
305 		prev_snapshot_high = cur_snapshot_high;
306 	}
307 
308 	qdf_assert_always(retry_count !=
309 			  (MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT - 1));
310 
311 	*mgmt_rx_reo_snapshot_low = cur_snapshot_low;
312 	*mgmt_rx_reo_snapshot_high = cur_snapshot_high;
313 
314 	return QDF_STATUS_SUCCESS;
315 }
316 
317 /**
318  * target_if_mgmt_rx_reo_read_snapshot() - Read management rx-reorder snapshot
319  * @pdev: pdev pointer
320  * @snapshot_info: Snapshot info
321  * @id: Snapshot ID
322  * @snapshot_value: Pointer to snapshot value
323  *
324  * Read management rx-reorder snapshots from target.
325  *
326  * Return: QDF_STATUS
327  */
328 static QDF_STATUS
329 target_if_mgmt_rx_reo_read_snapshot(
330 			struct wlan_objmgr_pdev *pdev,
331 			struct mgmt_rx_reo_snapshot_info *snapshot_info,
332 			enum mgmt_rx_reo_shared_snapshot_id id,
333 			struct mgmt_rx_reo_snapshot_params *snapshot_value,
334 			struct mgmt_rx_reo_shared_snapshot (*raw_snapshot)
335 			[MGMT_RX_REO_SNAPSHOT_B2B_READ_SWAR_RETRY_LIMIT])
336 {
337 	bool snapshot_valid;
338 	uint16_t mgmt_pkt_ctr;
339 	uint32_t global_timestamp;
340 	uint32_t mgmt_rx_reo_snapshot_low;
341 	uint32_t mgmt_rx_reo_snapshot_high;
342 	uint8_t retry_count;
343 	QDF_STATUS status;
344 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
345 	struct mgmt_rx_reo_shared_snapshot *snapshot_address;
346 	uint8_t snapshot_version;
347 
348 	if (!snapshot_info) {
349 		mgmt_rx_reo_err("Mgmt Rx REO snapshot info null");
350 		return QDF_STATUS_E_INVAL;
351 	}
352 
353 	snapshot_address = snapshot_info->address;
354 	if (!snapshot_address) {
355 		mgmt_rx_reo_err("Mgmt Rx REO snapshot address null");
356 		return QDF_STATUS_E_INVAL;
357 	}
358 
359 	snapshot_version = snapshot_info->version;
360 
361 	if (!snapshot_value) {
362 		mgmt_rx_reo_err("Mgmt Rx REO snapshot null");
363 		return QDF_STATUS_E_INVAL;
364 	}
365 
366 	qdf_mem_zero(snapshot_value, sizeof(*snapshot_value));
367 
368 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(
369 				wlan_pdev_get_psoc(pdev));
370 
371 	if (!low_level_ops) {
372 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
373 		return QDF_STATUS_E_FAILURE;
374 	}
375 
376 	/* Make sure that function pointers are populated */
377 	qdf_assert_always(low_level_ops->implemented);
378 
379 	switch (id) {
380 	case MGMT_RX_REO_SHARED_SNAPSHOT_MAC_HW:
381 	case MGMT_RX_REO_SHARED_SNAPSHOT_FW_CONSUMED:
382 	case MGMT_RX_REO_SHARED_SNAPSHOT_FW_FORWARDED:
383 		retry_count = 0;
384 		for (; retry_count < MGMT_RX_REO_SNAPSHOT_READ_RETRY_LIMIT;
385 		     retry_count++) {
386 			status = target_if_mgmt_rx_reo_read_snapshot_raw
387 					(snapshot_address,
388 					 &mgmt_rx_reo_snapshot_low,
389 					 &mgmt_rx_reo_snapshot_high,
390 					 snapshot_version,
391 					 raw_snapshot[retry_count]);
392 
393 			if (QDF_IS_STATUS_ERROR(status)) {
394 				mgmt_rx_reo_err("Failed to read snapshot %d",
395 						id);
396 				return QDF_STATUS_E_FAILURE;
397 			}
398 
399 			snapshot_valid = low_level_ops->snapshot_is_valid(
400 						mgmt_rx_reo_snapshot_low,
401 						snapshot_version);
402 
403 			if (!snapshot_valid) {
404 				mgmt_rx_reo_info("Invalid REO snapshot value");
405 				snapshot_value->valid = false;
406 				snapshot_value->mgmt_pkt_ctr =
407 					low_level_ops->snapshot_get_mgmt_pkt_ctr
408 					(mgmt_rx_reo_snapshot_low,
409 					 snapshot_version);
410 				snapshot_value->global_timestamp =
411 				low_level_ops->snapshot_get_global_timestamp
412 					(mgmt_rx_reo_snapshot_low,
413 					 mgmt_rx_reo_snapshot_high,
414 					 snapshot_version);
415 				snapshot_value->retry_count = retry_count + 1;
416 				return QDF_STATUS_SUCCESS;
417 			}
418 
419 			if (low_level_ops->snapshot_is_consistent
420 						(mgmt_rx_reo_snapshot_low,
421 						 mgmt_rx_reo_snapshot_high,
422 						 snapshot_version)) {
423 				global_timestamp =
424 				    low_level_ops->snapshot_get_global_timestamp
425 						(mgmt_rx_reo_snapshot_low,
426 						 mgmt_rx_reo_snapshot_high,
427 						 snapshot_version);
428 				mgmt_pkt_ctr =
429 					low_level_ops->snapshot_get_mgmt_pkt_ctr
430 						(mgmt_rx_reo_snapshot_low,
431 						 snapshot_version);
432 				break;
433 			}
434 			mgmt_rx_reo_info("Inconsistent snapshot %d, version=%u, low=0x%x, high=0x%x, retry=%u",
435 					 id, snapshot_version,
436 					 mgmt_rx_reo_snapshot_low,
437 					 mgmt_rx_reo_snapshot_high,
438 					 retry_count);
439 		}
440 
441 		if (retry_count == MGMT_RX_REO_SNAPSHOT_READ_RETRY_LIMIT) {
442 			mgmt_rx_reo_err("Read retry limit, id = %d, ver = %u",
443 					id, snapshot_version);
444 			snapshot_value->valid = false;
445 			snapshot_value->mgmt_pkt_ctr = 0xFFFF;
446 			snapshot_value->global_timestamp = 0xFFFFFFFF;
447 			snapshot_value->retry_count = retry_count;
448 			qdf_assert_always(0);
449 			return QDF_STATUS_E_FAILURE;
450 		}
451 
452 		snapshot_value->valid = true;
453 		snapshot_value->mgmt_pkt_ctr = mgmt_pkt_ctr;
454 		snapshot_value->global_timestamp = global_timestamp;
455 		snapshot_value->retry_count = retry_count + 1;
456 		status = QDF_STATUS_SUCCESS;
457 		break;
458 
459 	default:
460 		mgmt_rx_reo_err("Invalid snapshot id %d", id);
461 		status = QDF_STATUS_E_INVAL;
462 		break;
463 	}
464 
465 	return status;
466 }
467 
468 /**
469  * target_if_mgmt_rx_reo_get_snapshot_info() - Get information related to
470  * management rx-reorder snapshot
471  * @pdev: Pointer to pdev object
472  * @id: Snapshot ID
473  * @snapshot_info: Pointer to snapshot info
474  *
475  * Return: QDF_STATUS
476  */
477 static QDF_STATUS
478 target_if_mgmt_rx_reo_get_snapshot_info
479 			(struct wlan_objmgr_pdev *pdev,
480 			 enum mgmt_rx_reo_shared_snapshot_id id,
481 			 struct mgmt_rx_reo_snapshot_info *snapshot_info)
482 {
483 	struct wlan_lmac_if_mgmt_rx_reo_low_level_ops *low_level_ops;
484 	int8_t link_id;
485 	int8_t snapshot_version;
486 	uint8_t grp_id;
487 	struct wlan_objmgr_psoc *psoc;
488 
489 	if (!pdev) {
490 		mgmt_rx_reo_err("pdev is null");
491 		return QDF_STATUS_E_NULL_VALUE;
492 	}
493 
494 	psoc = wlan_pdev_get_psoc(pdev);
495 	if (!psoc) {
496 		mgmt_rx_reo_err("psoc is null");
497 		return QDF_STATUS_E_NULL_VALUE;
498 	}
499 
500 	if (id >= MGMT_RX_REO_SHARED_SNAPSHOT_MAX) {
501 		mgmt_rx_reo_err("Mgmt RX REO snapshot id invalid %d", id);
502 		return QDF_STATUS_E_INVAL;
503 	}
504 
505 	if (!snapshot_info) {
506 		mgmt_rx_reo_err("Ref to mgmt RX REO snapshot info is null");
507 		return QDF_STATUS_E_NULL_VALUE;
508 	}
509 
510 	if (!mlo_psoc_get_grp_id(psoc, &grp_id)) {
511 		mgmt_rx_reo_err("Failed to get valid MLO Group id");
512 		return QDF_STATUS_E_INVAL;
513 	}
514 
515 	low_level_ops = target_if_get_mgmt_rx_reo_low_level_ops(psoc);
516 
517 	if (!low_level_ops) {
518 		mgmt_rx_reo_err("Low level ops of MGMT Rx REO is null");
519 		return QDF_STATUS_E_FAILURE;
520 	}
521 
522 	qdf_assert_always(low_level_ops->implemented);
523 
524 	link_id = wlan_get_mlo_link_id_from_pdev(pdev);
525 	qdf_assert_always(link_id >= 0);
526 
527 	snapshot_info->address =
528 			low_level_ops->get_snapshot_address(grp_id,
529 							    link_id, id);
530 
531 	snapshot_version = low_level_ops->get_snapshot_version(grp_id, id);
532 	if (snapshot_version < 0) {
533 		mgmt_rx_reo_err("Invalid snapshot version %d MLO Group id %d",
534 				snapshot_version, grp_id);
535 		return QDF_STATUS_E_INVAL;
536 	}
537 
538 	snapshot_info->version = snapshot_version;
539 
540 	return QDF_STATUS_SUCCESS;
541 }
542 
543 /**
544  * target_if_mgmt_rx_reo_filter_config() - Configure MGMT Rx REO filter
545  * @pdev: Pointer to pdev objmgr
546  * @filter: Pointer to MGMT Rx REO filter
547  *
548  * Return: QDF_STATUS_SUCCESS for success or error code
549  */
550 static QDF_STATUS
551 target_if_mgmt_rx_reo_filter_config(
552 	struct wlan_objmgr_pdev *pdev,
553 	struct mgmt_rx_reo_filter *filter)
554 {
555 	QDF_STATUS status;
556 	struct wmi_unified *wmi_handle;
557 	uint8_t pdev_id;
558 
559 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
560 	if (!wmi_handle) {
561 		mgmt_rx_reo_err("Invalid WMI handle");
562 		return QDF_STATUS_E_INVAL;
563 	}
564 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
565 
566 	status = wmi_unified_mgmt_rx_reo_filter_config_cmd(wmi_handle, pdev_id,
567 							   filter);
568 	if (QDF_IS_STATUS_ERROR(status))
569 		mgmt_rx_reo_err("Unable to send MGMT Rx REO Filter config cmd");
570 
571 	return status;
572 }
573 
574 QDF_STATUS
575 target_if_mgmt_rx_reo_extract_reo_params(
576 	wmi_unified_t wmi_handle, void *evt_buf,
577 	struct mgmt_rx_event_params *params)
578 {
579 	struct wlan_objmgr_psoc *psoc;
580 
581 	if (!wmi_handle) {
582 		mgmt_rx_reo_err("wmi_handle is null");
583 		return QDF_STATUS_E_NULL_VALUE;
584 	}
585 
586 	psoc = target_if_get_psoc_from_scn_hdl(wmi_handle->scn_handle);
587 	if (!psoc) {
588 		mgmt_rx_reo_err("null psoc");
589 		return QDF_STATUS_E_NULL_VALUE;
590 	}
591 
592 	/* If REO feature is not enabled in FW, no need to extract REO params */
593 	if (!wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_MGMT_RX_REO_CAPABLE))
594 		return QDF_STATUS_SUCCESS;
595 
596 	if (!params) {
597 		mgmt_rx_reo_err("MGMT Rx event parameters is NULL");
598 		return QDF_STATUS_E_NULL_VALUE;
599 	}
600 
601 	return wmi_extract_mgmt_rx_reo_params(wmi_handle, evt_buf,
602 					      params->reo_params);
603 }
604 
605 QDF_STATUS
606 target_if_mgmt_rx_reo_tx_ops_register(
607 			struct wlan_lmac_if_mgmt_txrx_tx_ops *mgmt_txrx_tx_ops)
608 {
609 	struct wlan_lmac_if_mgmt_rx_reo_tx_ops *mgmt_rx_reo_tx_ops;
610 
611 	if (!mgmt_txrx_tx_ops) {
612 		mgmt_rx_reo_err("mgmt_txrx txops NULL");
613 		return QDF_STATUS_E_FAILURE;
614 	}
615 	mgmt_rx_reo_tx_ops = &mgmt_txrx_tx_ops->mgmt_rx_reo_tx_ops;
616 	mgmt_rx_reo_tx_ops->get_num_active_hw_links =
617 				target_if_mgmt_rx_reo_get_num_active_hw_links;
618 	mgmt_rx_reo_tx_ops->get_valid_hw_link_bitmap =
619 				target_if_mgmt_rx_reo_get_valid_hw_link_bitmap;
620 	mgmt_rx_reo_tx_ops->read_mgmt_rx_reo_snapshot =
621 				target_if_mgmt_rx_reo_read_snapshot;
622 	mgmt_rx_reo_tx_ops->get_mgmt_rx_reo_snapshot_info =
623 				target_if_mgmt_rx_reo_get_snapshot_info;
624 	mgmt_rx_reo_tx_ops->mgmt_rx_reo_filter_config =
625 					target_if_mgmt_rx_reo_filter_config;
626 
627 	return QDF_STATUS_SUCCESS;
628 }
629 
630 QDF_STATUS
631 target_if_mgmt_rx_reo_host_drop_handler(struct wlan_objmgr_pdev *pdev,
632 					struct mgmt_rx_event_params *params)
633 {
634 	struct wlan_lmac_if_mgmt_rx_reo_rx_ops *mgmt_rx_reo_rx_ops;
635 
636 	if (!pdev) {
637 		mgmt_rx_reo_err("pdev is null");
638 		return QDF_STATUS_E_NULL_VALUE;
639 	}
640 
641 	if (!params) {
642 		mgmt_rx_reo_err("mgmt rx event params are null");
643 		return QDF_STATUS_E_NULL_VALUE;
644 	}
645 
646 	mgmt_rx_reo_rx_ops = target_if_mgmt_rx_reo_get_rx_ops(
647 					wlan_pdev_get_psoc(pdev));
648 	if (!mgmt_rx_reo_rx_ops) {
649 		mgmt_rx_reo_err("rx_ops of MGMT Rx REO module is NULL");
650 		return QDF_STATUS_E_NULL_VALUE;
651 	}
652 
653 	return mgmt_rx_reo_rx_ops->host_drop_handler(pdev, params->reo_params);
654 }
655