xref: /wlan-dirver/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg.c (revision 2888b71da71bce103343119fa1b31f4a0cee07c8)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  *
6  * Permission to use, copy, modify, and/or distribute this software for
7  * any purpose with or without fee is hereby granted, provided that the
8  * above copyright notice and this permission notice appear in all
9  * copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18  * PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /**
22  * DOC: target_if_reg.c
23  * This file contains regulatory target interfaces.
24  */
25 
26 #include <wmi_unified_api.h>
27 #include <reg_services_public_struct.h>
28 #include <wlan_reg_tgt_api.h>
29 #include <target_if.h>
30 #include <target_if_reg.h>
31 #include <wmi_unified_reg_api.h>
32 #include <qdf_platform.h>
33 #include <target_if_reg_11d.h>
34 #include <target_if_reg_lte.h>
35 #include <wlan_reg_ucfg_api.h>
36 
37 /**
38  * get_chan_list_cc_event_id() - Get chan_list_cc event i
39  *
40  * Return: Event id
41  */
42 static inline uint32_t get_chan_list_cc_event_id(void)
43 {
44 	return wmi_reg_chan_list_cc_event_id;
45 }
46 
47 /**
48  * tgt_if_regulatory_is_regdb_offloaded() - Check if regdb is offloaded
49  * @psoc: Pointer to psoc
50  *
51  * Return: true if regdb if offloaded, else false
52  */
53 static bool tgt_if_regulatory_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc)
54 {
55 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
56 
57 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
58 
59 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
60 	if (!reg_rx_ops) {
61 		target_if_err("reg_rx_ops is NULL");
62 		return false;
63 	}
64 
65 	if (!wmi_handle)
66 		return false;
67 
68 	if (reg_rx_ops->reg_ignore_fw_reg_offload_ind &&
69 	    reg_rx_ops->reg_ignore_fw_reg_offload_ind(psoc)) {
70 		target_if_debug("User disabled regulatory offload from ini");
71 		return 0;
72 	}
73 
74 	return wmi_service_enabled(wmi_handle, wmi_service_regulatory_db);
75 }
76 
77 /**
78  * tgt_if_regulatory_is_6ghz_supported() - Check if 6ghz is supported
79  * @psoc: Pointer to psoc
80  *
81  * Return: true if regdb if offloaded, else false
82  */
83 static bool tgt_if_regulatory_is_6ghz_supported(struct wlan_objmgr_psoc *psoc)
84 {
85 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
86 
87 	if (!wmi_handle)
88 		return false;
89 
90 	return wmi_service_enabled(wmi_handle, wmi_service_6ghz_support);
91 }
92 
93 /**
94  * tgt_if_regulatory_is_5dot9_ghz_supported() - Check if 5.9ghz is supported
95  * @psoc: Pointer to psoc
96  *
97  * Return: true if regdb if offloaded, else false
98  */
99 static bool
100 tgt_if_regulatory_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc)
101 {
102 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
103 
104 	if (!wmi_handle)
105 		return false;
106 
107 	return wmi_service_enabled(wmi_handle, wmi_service_5dot9_ghz_support);
108 }
109 
110 /**
111  * tgt_if_regulatory_is_there_serv_ready_extn() - Check for service ready
112  * extension
113  * @psoc: Pointer to psoc object
114  *
115  * Return: true if service ready extension is present, else false.
116  */
117 static bool tgt_if_regulatory_is_there_serv_ready_extn(
118 		struct wlan_objmgr_psoc *psoc)
119 {
120 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
121 
122 	if (!wmi_handle)
123 		return false;
124 
125 	return wmi_service_enabled(wmi_handle, wmi_service_ext_msg);
126 }
127 
128 /**
129  * target_if_regulatory_get_rx_ops() - Get regdb rx ops
130  * @psoc: Pointer to psoc object
131  *
132  * Return: Reg rx_ops
133  */
134 struct wlan_lmac_if_reg_rx_ops *
135 target_if_regulatory_get_rx_ops(struct wlan_objmgr_psoc *psoc)
136 {
137 	struct wlan_lmac_if_rx_ops *rx_ops;
138 
139 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
140 	if (!rx_ops) {
141 		target_if_err("rx_ops is NULL");
142 		return NULL;
143 	}
144 
145 	return &rx_ops->reg_rx_ops;
146 }
147 
148 struct wlan_lmac_if_reg_tx_ops *
149 target_if_regulatory_get_tx_ops(struct wlan_objmgr_psoc *psoc)
150 {
151 	struct wlan_lmac_if_tx_ops *tx_ops;
152 
153 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
154 	if (!tx_ops) {
155 		target_if_err("tx_ops is NULL");
156 		return NULL;
157 	}
158 
159 	return &tx_ops->reg_ops;
160 }
161 
162 QDF_STATUS target_if_reg_set_offloaded_info(struct wlan_objmgr_psoc *psoc)
163 {
164 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
165 
166 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
167 	if (!reg_rx_ops) {
168 		target_if_err("reg_rx_ops is NULL");
169 		return QDF_STATUS_E_FAILURE;
170 	}
171 
172 	if (reg_rx_ops->reg_set_regdb_offloaded)
173 		reg_rx_ops->reg_set_regdb_offloaded(
174 				psoc,
175 				tgt_if_regulatory_is_regdb_offloaded(psoc));
176 
177 	if (reg_rx_ops->reg_set_11d_offloaded)
178 		reg_rx_ops->reg_set_11d_offloaded(
179 				psoc, tgt_if_regulatory_is_11d_offloaded(psoc));
180 
181 	return QDF_STATUS_SUCCESS;
182 }
183 
184 QDF_STATUS target_if_reg_set_6ghz_info(struct wlan_objmgr_psoc *psoc)
185 {
186 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
187 
188 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
189 	if (!reg_rx_ops) {
190 		target_if_err("reg_rx_ops is NULL");
191 		return QDF_STATUS_E_FAILURE;
192 	}
193 
194 	if (reg_rx_ops->reg_set_6ghz_supported)
195 		reg_rx_ops->reg_set_6ghz_supported(
196 			psoc,
197 			tgt_if_regulatory_is_6ghz_supported(psoc));
198 
199 	return QDF_STATUS_SUCCESS;
200 }
201 
202 QDF_STATUS target_if_reg_set_5dot9_ghz_info(struct wlan_objmgr_psoc *psoc)
203 {
204 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
205 
206 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
207 	if (!reg_rx_ops) {
208 		target_if_err("reg_rx_ops is NULL");
209 		return QDF_STATUS_E_FAILURE;
210 	}
211 
212 	if (reg_rx_ops->reg_set_5dot9_ghz_supported)
213 		reg_rx_ops->reg_set_5dot9_ghz_supported(
214 			psoc,
215 			tgt_if_regulatory_is_5dot9_ghz_supported(psoc));
216 
217 	return QDF_STATUS_SUCCESS;
218 }
219 
220 bool
221 target_if_reg_is_reg_cc_ext_event_host_supported(struct wlan_objmgr_psoc *psoc)
222 {
223 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
224 	bool reg_ext_cc_supp = false;
225 
226 	reg_tx_ops = target_if_regulatory_get_tx_ops(psoc);
227 	if (!reg_tx_ops) {
228 		target_if_err("reg_tx_ops is NULL");
229 		return reg_ext_cc_supp;
230 	}
231 
232 	if (reg_tx_ops->register_master_ext_handler)
233 		reg_ext_cc_supp = true;
234 
235 	return reg_ext_cc_supp;
236 }
237 
238 /**
239  * tgt_reg_chan_list_update_handler() - Channel list update handler
240  * @handle: scn handle
241  * @event_buf: pointer to event buffer
242  * @len: buffer length
243  *
244  * Return: 0 on success
245  */
246 static int tgt_reg_chan_list_update_handler(ol_scn_t handle, uint8_t *event_buf,
247 					    uint32_t len)
248 {
249 	struct wlan_objmgr_psoc *psoc;
250 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
251 	struct cur_regulatory_info *reg_info;
252 	QDF_STATUS status;
253 	struct wmi_unified *wmi_handle;
254 	int ret_val = 0;
255 
256 	TARGET_IF_ENTER();
257 
258 	psoc = target_if_get_psoc_from_scn_hdl(handle);
259 	if (!psoc) {
260 		target_if_err("psoc ptr is NULL");
261 		return -EINVAL;
262 	}
263 
264 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
265 	if (!reg_rx_ops) {
266 		target_if_err("reg_rx_ops is NULL");
267 		return -EINVAL;
268 	}
269 
270 	if (!reg_rx_ops->master_list_handler) {
271 		target_if_err("master_list_handler is NULL");
272 		return -EINVAL;
273 	}
274 
275 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
276 	if (!wmi_handle) {
277 		target_if_err("invalid wmi handle");
278 		return -EINVAL;
279 	}
280 
281 	reg_info = qdf_mem_malloc(sizeof(*reg_info));
282 	if (!reg_info)
283 		return -ENOMEM;
284 
285 	if (wmi_extract_reg_chan_list_update_event(wmi_handle,
286 						   event_buf, reg_info, len)
287 	    != QDF_STATUS_SUCCESS) {
288 		target_if_err("Extraction of channel list event failed");
289 		ret_val = -EFAULT;
290 		goto clean;
291 	}
292 
293 	if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) {
294 		target_if_err_rl("phy_id %d is out of bounds",
295 				 reg_info->phy_id);
296 		ret_val = -EFAULT;
297 		goto clean;
298 	}
299 
300 	reg_info->psoc = psoc;
301 
302 	status = reg_rx_ops->master_list_handler(reg_info);
303 	if (status != QDF_STATUS_SUCCESS) {
304 		target_if_err("Failed to process master channel list handler");
305 		ret_val = -EFAULT;
306 	}
307 
308 clean:
309 	qdf_mem_free(reg_info->reg_rules_2g_ptr);
310 	qdf_mem_free(reg_info->reg_rules_5g_ptr);
311 	qdf_mem_free(reg_info);
312 
313 	TARGET_IF_EXIT();
314 
315 	return ret_val;
316 }
317 
318 /**
319  * tgt_if_regulatory_register_master_list_handler() - Register master channel
320  * list
321  * @psoc: Pointer to psoc
322  * @arg: Pointer to argument list
323  *
324  * Return: QDF_STATUS
325  */
326 static QDF_STATUS tgt_if_regulatory_register_master_list_handler(
327 	struct wlan_objmgr_psoc *psoc, void *arg)
328 {
329 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
330 
331 	if (!wmi_handle)
332 		return QDF_STATUS_E_FAILURE;
333 
334 	return wmi_unified_register_event_handler(
335 			wmi_handle, wmi_reg_chan_list_cc_event_id,
336 			tgt_reg_chan_list_update_handler, WMI_RX_WORK_CTX);
337 }
338 
339 /**
340  * tgt_if_regulatory_unregister_master_list_handler() - Unregister master
341  * channel list
342  * @psoc: Pointer to psoc
343  * @arg: Pointer to argument list
344  *
345  * Return: QDF_STATUS
346  */
347 static QDF_STATUS tgt_if_regulatory_unregister_master_list_handler(
348 	struct wlan_objmgr_psoc *psoc, void *arg)
349 {
350 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
351 
352 	if (!wmi_handle)
353 		return QDF_STATUS_E_FAILURE;
354 
355 	return wmi_unified_unregister_event_handler(
356 			wmi_handle, wmi_reg_chan_list_cc_event_id);
357 }
358 
359 #ifdef CONFIG_BAND_6GHZ
360 #ifdef CONFIG_REG_CLIENT
361 /**
362  * tgt_mem_free_fcc_rules() - Free regulatory fcc rules
363  * @reg_info: Pointer to regulatory info
364  *
365  */
366 static void tgt_reg_mem_free_fcc_rules(struct cur_regulatory_info *reg_info)
367 {
368 	qdf_mem_free(reg_info->fcc_rules_ptr);
369 }
370 #else
371 static void tgt_reg_mem_free_fcc_rules(struct cur_regulatory_info *reg_info)
372 {
373 }
374 #endif
375 
376 /**
377  * tgt_reg_chan_list_ext_update_handler() - Extended channel list update handler
378  * @handle: scn handle
379  * @event_buf: pointer to event buffer
380  * @len: buffer length
381  *
382  * Return: 0 on success
383  */
384 static int tgt_reg_chan_list_ext_update_handler(ol_scn_t handle,
385 						uint8_t *event_buf,
386 						uint32_t len)
387 {
388 	struct wlan_objmgr_psoc *psoc;
389 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
390 	struct cur_regulatory_info *reg_info;
391 	QDF_STATUS status;
392 	struct wmi_unified *wmi_handle;
393 	int ret_val = 0;
394 	uint32_t i;
395 
396 	TARGET_IF_ENTER();
397 
398 	psoc = target_if_get_psoc_from_scn_hdl(handle);
399 	if (!psoc) {
400 		target_if_err("psoc ptr is NULL");
401 		return -EINVAL;
402 	}
403 
404 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
405 	if (!reg_rx_ops) {
406 		target_if_err("reg_rx_ops is NULL");
407 		return -EINVAL;
408 	}
409 
410 	if (!reg_rx_ops->master_list_ext_handler) {
411 		target_if_err("master_list_ext_handler is NULL");
412 		return -EINVAL;
413 	}
414 
415 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
416 	if (!wmi_handle) {
417 		target_if_err("invalid wmi handle");
418 		return -EINVAL;
419 	}
420 
421 	reg_info = qdf_mem_malloc(sizeof(*reg_info));
422 	if (!reg_info)
423 		return -ENOMEM;
424 
425 	status = wmi_extract_reg_chan_list_ext_update_event(wmi_handle,
426 							    event_buf,
427 							    reg_info, len);
428 	if (!QDF_IS_STATUS_SUCCESS(status)) {
429 		target_if_err("Extraction of ext channel list event failed");
430 		ret_val = -EFAULT;
431 		goto clean;
432 	}
433 
434 	if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) {
435 		target_if_err_rl("phy_id %d is out of bounds",
436 				 reg_info->phy_id);
437 		ret_val = -EFAULT;
438 		goto clean;
439 	}
440 
441 	reg_info->psoc = psoc;
442 
443 	status = reg_rx_ops->master_list_ext_handler(reg_info);
444 	if (!QDF_IS_STATUS_SUCCESS(status)) {
445 		target_if_err("Failed to process master ext channel list handler");
446 		ret_val = -EFAULT;
447 	}
448 
449 clean:
450 	qdf_mem_free(reg_info->reg_rules_2g_ptr);
451 	qdf_mem_free(reg_info->reg_rules_5g_ptr);
452 	tgt_reg_mem_free_fcc_rules(reg_info);
453 
454 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
455 		qdf_mem_free(reg_info->reg_rules_6g_ap_ptr[i]);
456 		qdf_mem_free(reg_info->
457 			reg_rules_6g_client_ptr[i][REG_DEFAULT_CLIENT]);
458 		qdf_mem_free(reg_info->
459 			reg_rules_6g_client_ptr[i][REG_SUBORDINATE_CLIENT]);
460 	}
461 
462 	qdf_mem_free(reg_info);
463 
464 	TARGET_IF_EXIT();
465 
466 	return ret_val;
467 }
468 
469 /**
470  * tgt_if_regulatory_register_master_list_ext_handler() - Register extended
471  * master channel list event handler
472  * @psoc: Pointer to psoc
473  * @arg: Pointer to argument list
474  *
475  * Return: QDF_STATUS
476  */
477 static QDF_STATUS tgt_if_regulatory_register_master_list_ext_handler(
478 	struct wlan_objmgr_psoc *psoc, void *arg)
479 {
480 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
481 
482 	if (!wmi_handle)
483 		return QDF_STATUS_E_FAILURE;
484 
485 	return wmi_unified_register_event_handler(
486 			wmi_handle, wmi_reg_chan_list_cc_ext_event_id,
487 			tgt_reg_chan_list_ext_update_handler, WMI_RX_WORK_CTX);
488 }
489 
490 /**
491  * tgt_if_regulatory_unregister_master_list_ext_handler() - Unregister extended
492  * master channel list event handler
493  * @psoc: Pointer to psoc
494  * @arg: Pointer to argument list
495  *
496  * Return: QDF_STATUS
497  */
498 static QDF_STATUS tgt_if_regulatory_unregister_master_list_ext_handler(
499 	struct wlan_objmgr_psoc *psoc, void *arg)
500 {
501 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
502 
503 	if (!wmi_handle)
504 		return QDF_STATUS_E_FAILURE;
505 
506 	return wmi_unified_unregister_event_handler(
507 			wmi_handle, wmi_reg_chan_list_cc_ext_event_id);
508 }
509 
510 #ifdef CONFIG_AFC_SUPPORT
511 /**
512  * tgt_afc_event_handler() - Handler for AFC Event
513  * @handle: scn handle
514  * @event_buf: pointer to event buffer
515  * @len: buffer length
516  *
517  * Return: 0 on success
518  */
519 static int
520 tgt_afc_event_handler(ol_scn_t handle, uint8_t *event_buf, uint32_t len)
521 {
522 	struct wlan_objmgr_psoc *psoc;
523 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
524 	struct afc_regulatory_info *afc_info;
525 	QDF_STATUS status;
526 	struct wmi_unified *wmi_handle;
527 	int ret_val = 0;
528 
529 	TARGET_IF_ENTER();
530 
531 	psoc = target_if_get_psoc_from_scn_hdl(handle);
532 	if (!psoc) {
533 		target_if_err("psoc ptr is NULL");
534 		return -EINVAL;
535 	}
536 
537 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
538 	if (!reg_rx_ops) {
539 		target_if_err("reg_rx_ops is NULL");
540 		return -EINVAL;
541 	}
542 
543 	if (!reg_rx_ops->afc_event_handler) {
544 		target_if_err("afc_event_handler is NULL");
545 		return -EINVAL;
546 	}
547 
548 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
549 	if (!wmi_handle) {
550 		target_if_err("invalid wmi handle");
551 		return -EINVAL;
552 	}
553 
554 	afc_info = qdf_mem_malloc(sizeof(*afc_info));
555 	if (!afc_info)
556 		return -ENOMEM;
557 
558 	status = wmi_extract_afc_event(wmi_handle, event_buf, afc_info, len);
559 	if (!QDF_IS_STATUS_SUCCESS(status)) {
560 		target_if_err("Extraction of AFC event failed");
561 		ret_val = -EFAULT;
562 		goto clean;
563 	}
564 
565 	if (afc_info->phy_id >= PSOC_MAX_PHY_REG_CAP) {
566 		target_if_err_rl("phy_id %d is out of bounds",
567 				 afc_info->phy_id);
568 		ret_val = -EFAULT;
569 		goto clean;
570 	}
571 
572 	afc_info->psoc = psoc;
573 
574 	status = reg_rx_ops->afc_event_handler(afc_info);
575 	if (!QDF_IS_STATUS_SUCCESS(status)) {
576 		target_if_err("Failed to process AFC event handler");
577 		ret_val = -EFAULT;
578 		goto clean;
579 	}
580 
581 clean:
582 	qdf_mem_free(afc_info);
583 	TARGET_IF_EXIT();
584 
585 	return ret_val;
586 }
587 
588 /**
589  * tgt_if_regulatory_register_afc_event_handler() - Register AFC event
590  * handler
591  * @psoc: Pointer to psoc
592  * @arg: Pointer to argument list
593  *
594  * Return: QDF_STATUS
595  */
596 static QDF_STATUS tgt_if_regulatory_register_afc_event_handler(
597 	struct wlan_objmgr_psoc *psoc, void *arg)
598 {
599 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
600 
601 	if (!wmi_handle)
602 		return QDF_STATUS_E_FAILURE;
603 
604 	return wmi_unified_register_event_handler(
605 			wmi_handle, wmi_afc_event_id,
606 			tgt_afc_event_handler, WMI_RX_WORK_CTX);
607 }
608 
609 /**
610  * tgt_if_regulatory_unregister_afc_event_handler() - Unregister AFC event
611  * handler
612  * @psoc: Pointer to psoc
613  * @arg: Pointer to argument list
614  *
615  * Return: QDF_STATUS
616  */
617 static QDF_STATUS
618 tgt_if_regulatory_unregister_afc_event_handler(struct wlan_objmgr_psoc *psoc,
619 					       void *arg)
620 {
621 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
622 
623 	if (!wmi_handle)
624 		return QDF_STATUS_E_FAILURE;
625 
626 	return wmi_unified_unregister_event_handler(
627 			wmi_handle, wmi_afc_event_id);
628 }
629 #endif
630 #endif
631 
632 /**
633  * tgt_if_regulatory_set_country_code() - Set country code
634  * @psoc: Pointer to psoc
635  * @arg: Pointer to argument list
636  *
637  * Return: QDF_STATUS
638  */
639 static QDF_STATUS tgt_if_regulatory_set_country_code(
640 	struct wlan_objmgr_psoc *psoc, void *arg)
641 {
642 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
643 
644 	if (!wmi_handle)
645 		return QDF_STATUS_E_FAILURE;
646 
647 	return wmi_unified_set_country_cmd_send(wmi_handle, arg);
648 }
649 
650 /**
651  * tgt_if_regulatory_set_user_country_code() - Set user country code
652  * @psoc: Pointer to psoc
653  * @pdev_id: Pdev id
654  * @rd: Pointer to regdomain structure
655  *
656  * Return: QDF_STATUS
657  */
658 static QDF_STATUS tgt_if_regulatory_set_user_country_code(
659 	struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, struct cc_regdmn_s *rd)
660 {
661 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
662 
663 	if (!wmi_handle)
664 		return QDF_STATUS_E_FAILURE;
665 
666 	if (wmi_unified_set_user_country_code_cmd_send(
667 				wmi_handle, pdev_id, rd) != QDF_STATUS_SUCCESS
668 			) {
669 		target_if_err("Set user country code failed");
670 		return QDF_STATUS_E_FAILURE;
671 	}
672 
673 	return QDF_STATUS_SUCCESS;
674 }
675 
676 QDF_STATUS tgt_if_regulatory_modify_freq_range(struct wlan_objmgr_psoc *psoc)
677 {
678 	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
679 
680 	reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
681 	if (!reg_cap) {
682 		target_if_err("reg cap is NULL");
683 		return QDF_STATUS_E_FAILURE;
684 	}
685 
686 	if (!(reg_cap->wireless_modes & HOST_REGDMN_MODE_11A)) {
687 		reg_cap->low_5ghz_chan = 0;
688 		reg_cap->high_5ghz_chan = 0;
689 	}
690 
691 	if (!(reg_cap->wireless_modes &
692 	     (HOST_REGDMN_MODE_11B | HOST_REGDMN_MODE_PUREG))) {
693 		reg_cap->low_2ghz_chan = 0;
694 		reg_cap->high_2ghz_chan = 0;
695 	}
696 
697 	target_if_debug("phy_id = %d - low_2ghz_chan = %d high_2ghz_chan = %d low_5ghz_chan = %d high_5ghz_chan = %d",
698 			reg_cap->phy_id,
699 			reg_cap->low_2ghz_chan,
700 			reg_cap->high_2ghz_chan,
701 			reg_cap->low_5ghz_chan,
702 			reg_cap->high_5ghz_chan);
703 
704 	return QDF_STATUS_SUCCESS;
705 }
706 
707 #ifdef CONFIG_REG_CLIENT
708 /**
709  * tgt_if_regulatory_send_ctl_info() - Send CTL info to firmware
710  * @psoc: Pointer to psoc
711  * @params: Pointer to reg control params
712  *
713  * Return: QDF_STATUS
714  */
715 static QDF_STATUS
716 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc,
717 				struct reg_ctl_params *params)
718 {
719 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
720 
721 	if (!wmi_handle)
722 		return QDF_STATUS_E_FAILURE;
723 
724 	return wmi_unified_send_regdomain_info_to_fw_cmd(wmi_handle,
725 							 params->regd,
726 							 params->regd_2g,
727 							 params->regd_5g,
728 							 params->ctl_2g,
729 							 params->ctl_5g);
730 }
731 #else
732 static QDF_STATUS
733 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc,
734 				struct reg_ctl_params *params)
735 {
736 	return QDF_STATUS_SUCCESS;
737 }
738 #endif
739 
740 /**
741  * tgt_if_regulatory_get_phy_id_from_pdev_id() - Get phy_id from pdev_id
742  * @psoc: Pointer to psoc
743  * @pdev_id: Pdev id
744  * @phy_id: phy_id
745  *
746  * Return: QDF_STATUS
747  */
748 static QDF_STATUS tgt_if_regulatory_get_phy_id_from_pdev_id(
749 	struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *phy_id)
750 {
751 	struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle;
752 	uint8_t ret;
753 
754 	if (pdev_id >= WLAN_UMAC_MAX_PDEVS) {
755 		target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS");
756 		return QDF_STATUS_E_FAILURE;
757 	}
758 
759 	/* By default pdev_id and phy_id have one to one mapping */
760 	*phy_id = pdev_id;
761 
762 	if (!(tgt_if_handle &&
763 	      tgt_if_handle->info.is_pdevid_to_phyid_map))
764 		return QDF_STATUS_SUCCESS;
765 
766 	ret = tgt_if_handle->info.pdev_id_to_phy_id_map[pdev_id];
767 
768 	if (ret < PSOC_MAX_PHY_REG_CAP) {
769 		*phy_id = ret;
770 	} else {
771 		target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP");
772 		return QDF_STATUS_E_FAILURE;
773 	}
774 
775 	return QDF_STATUS_SUCCESS;
776 }
777 
778 /**
779  * tgt_if_regulatory_get_pdev_id_from_phy_id() - Get pdev_id for phy_id
780  * @psoc: Pointer to psoc
781  * @phy_id: Phy id
782  * @pdev_id: Pdev id
783  *
784  * Return: QDF_STATUS
785  */
786 static QDF_STATUS tgt_if_regulatory_get_pdev_id_from_phy_id(
787 	struct wlan_objmgr_psoc *psoc, uint8_t phy_id, uint8_t *pdev_id)
788 {
789 	struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle;
790 	uint8_t i;
791 
792 	if (phy_id >= PSOC_MAX_PHY_REG_CAP) {
793 		target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP");
794 		return QDF_STATUS_E_FAILURE;
795 	}
796 
797 	/* By default pdev_id and phy_id have one to one mapping */
798 	*pdev_id = phy_id;
799 
800 	if (!(tgt_if_handle &&
801 	      tgt_if_handle->info.is_pdevid_to_phyid_map))
802 		return QDF_STATUS_SUCCESS;
803 
804 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
805 		if (tgt_if_handle->info.pdev_id_to_phy_id_map[i] == phy_id)
806 			break;
807 	}
808 
809 	if (i < WLAN_UMAC_MAX_PDEVS) {
810 		*pdev_id = i;
811 	} else {
812 		target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS");
813 		return QDF_STATUS_E_FAILURE;
814 	}
815 
816 	return QDF_STATUS_SUCCESS;
817 }
818 
819 #ifdef CONFIG_BAND_6GHZ
820 static void target_if_register_master_ext_handler(
821 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
822 {
823 	reg_ops->register_master_ext_handler =
824 		tgt_if_regulatory_register_master_list_ext_handler;
825 
826 	reg_ops->unregister_master_ext_handler =
827 		tgt_if_regulatory_unregister_master_list_ext_handler;
828 }
829 
830 #ifdef CONFIG_AFC_SUPPORT
831 static void target_if_register_afc_event_handler(
832 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
833 {
834 	reg_ops->register_afc_event_handler =
835 		tgt_if_regulatory_register_afc_event_handler;
836 
837 	reg_ops->unregister_afc_event_handler =
838 		tgt_if_regulatory_unregister_afc_event_handler;
839 }
840 
841 static void target_if_register_acs_trigger_for_afc
842 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
843 {
844 	reg_ops->trigger_acs_for_afc = NULL;
845 }
846 #else
847 static void target_if_register_afc_event_handler(
848 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
849 {
850 }
851 
852 static void target_if_register_acs_trigger_for_afc
853 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
854 {
855 }
856 #endif
857 #else
858 static inline void
859 target_if_register_master_ext_handler(struct wlan_lmac_if_reg_tx_ops *reg_ops)
860 {
861 }
862 
863 static void target_if_register_afc_event_handler(
864 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
865 {
866 }
867 
868 static void target_if_register_acs_trigger_for_afc
869 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
870 {
871 }
872 #endif
873 
874 static QDF_STATUS
875 tgt_if_regulatory_set_tpc_power(struct wlan_objmgr_psoc *psoc,
876 				uint8_t vdev_id,
877 				struct reg_tpc_power_info *param)
878 {
879 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
880 
881 	if (!wmi_handle)
882 		return QDF_STATUS_E_FAILURE;
883 
884 	return wmi_unified_send_set_tpc_power_cmd(wmi_handle, vdev_id, param);
885 }
886 
887 #ifdef CONFIG_AFC_SUPPORT
888 /**
889  * tgt_if_regulatory_send_afc_cmd() - Send AFC command to the FW
890  *
891  * @psoc: Pointer to psoc
892  * @pdev_id: Pdev id
893  * @param: Pointer to hold AFC indication.
894  *
895  * Return: QDF_STATUS_SUCCESS if WMI_AFC_CMD is sent, else QDF_STATUS_E_FAILURE
896  */
897 static QDF_STATUS
898 tgt_if_regulatory_send_afc_cmd(struct wlan_objmgr_psoc *psoc,
899 			       uint8_t pdev_id,
900 			       struct reg_afc_resp_rx_ind_info *param)
901 {
902 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
903 
904 	if (!wmi_handle)
905 		return QDF_STATUS_E_FAILURE;
906 
907 	return wmi_unified_send_afc_cmd(wmi_handle, pdev_id, param);
908 }
909 
910 static void
911 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops)
912 {
913 	reg_ops->send_afc_ind = tgt_if_regulatory_send_afc_cmd;
914 }
915 #else
916 static void
917 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops)
918 {
919 }
920 #endif
921 
922 /**
923  * tgt_if_regulatory_is_ext_tpc_supported() - Check if FW supports new
924  * WMI command for TPC power
925  *
926  * @psoc: Pointer to psoc
927  *
928  * Return: true if FW supports new WMI command for TPC, else false
929  */
930 static bool
931 tgt_if_regulatory_is_ext_tpc_supported(struct wlan_objmgr_psoc *psoc)
932 {
933 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
934 
935 	if (!wmi_handle)
936 		return false;
937 
938 	return wmi_service_enabled(wmi_handle,
939 				   wmi_service_ext_tpc_reg_support);
940 }
941 
942 QDF_STATUS target_if_regulatory_set_ext_tpc(struct wlan_objmgr_psoc *psoc)
943 {
944 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
945 
946 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
947 	if (!reg_rx_ops) {
948 		target_if_err("reg_rx_ops is NULL");
949 		return QDF_STATUS_E_FAILURE;
950 	}
951 
952 	if (reg_rx_ops->reg_set_ext_tpc_supported)
953 		reg_rx_ops->reg_set_ext_tpc_supported(
954 			psoc,
955 			tgt_if_regulatory_is_ext_tpc_supported(psoc));
956 
957 	return QDF_STATUS_SUCCESS;
958 }
959 
960 #if defined(CONFIG_BAND_6GHZ)
961 /**
962  * tgt_if_regulatory_is_lower_6g_edge_ch_supp() - Check if lower 6ghz
963  * edge channel (5935MHz) is supported
964  * @psoc: Pointer to psoc
965  *
966  * Return: true if channel is supported, else false
967  */
968 static bool
969 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc)
970 {
971 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
972 
973 	if (!wmi_handle)
974 		return false;
975 
976 	return wmi_service_enabled(wmi_handle,
977 				   wmi_service_lower_6g_edge_ch_supp);
978 }
979 
980 /**
981  * tgt_if_regulatory_is_upper_6g_edge_ch_disabled() - Check if upper
982  * 6ghz edge channel (7115MHz) is disabled
983  * @psoc: Pointer to psoc
984  *
985  * Return: true if channel is disabled, else false
986  */
987 static bool
988 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc)
989 {
990 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
991 
992 	if (!wmi_handle)
993 		return false;
994 
995 	return wmi_service_enabled(wmi_handle,
996 				   wmi_service_disable_upper_6g_edge_ch_supp);
997 }
998 
999 QDF_STATUS
1000 target_if_reg_set_lower_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc)
1001 {
1002 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1003 
1004 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1005 	if (!reg_rx_ops) {
1006 		target_if_err("reg_rx_ops is NULL");
1007 		return QDF_STATUS_E_FAILURE;
1008 	}
1009 
1010 	if (reg_rx_ops->reg_set_lower_6g_edge_ch_supp)
1011 		reg_rx_ops->reg_set_lower_6g_edge_ch_supp(
1012 			psoc,
1013 			tgt_if_regulatory_is_lower_6g_edge_ch_supp(psoc));
1014 
1015 	return QDF_STATUS_SUCCESS;
1016 }
1017 
1018 QDF_STATUS
1019 target_if_reg_set_disable_upper_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc)
1020 {
1021 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1022 
1023 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1024 	if (!reg_rx_ops) {
1025 		target_if_err("reg_rx_ops is NULL");
1026 		return QDF_STATUS_E_FAILURE;
1027 	}
1028 
1029 	if (reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp)
1030 		reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp(
1031 			psoc,
1032 			tgt_if_regulatory_is_upper_6g_edge_ch_disabled(psoc));
1033 
1034 	return QDF_STATUS_SUCCESS;
1035 }
1036 #else
1037 static inline bool
1038 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc)
1039 {
1040 	return false;
1041 }
1042 
1043 static inline bool
1044 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc)
1045 {
1046 	return false;
1047 }
1048 #endif
1049 
1050 #if defined(CONFIG_AFC_SUPPORT)
1051 QDF_STATUS
1052 target_if_reg_set_afc_dev_type(struct wlan_objmgr_psoc *psoc,
1053 			       struct target_psoc_info *tgt_hdl)
1054 {
1055 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1056 	struct tgt_info *info;
1057 
1058 	if (!tgt_hdl) {
1059 		target_if_err("target_psoc_info is null");
1060 		return QDF_STATUS_E_FAILURE;
1061 	}
1062 
1063 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1064 	if (!reg_rx_ops) {
1065 		target_if_err("reg_rx_ops is NULL");
1066 		return QDF_STATUS_E_FAILURE;
1067 	}
1068 
1069 	info = (&tgt_hdl->info);
1070 
1071 	if (reg_rx_ops->reg_set_afc_dev_type)
1072 		reg_rx_ops->reg_set_afc_dev_type(
1073 			psoc,
1074 			info->service_ext2_param.afc_dev_type);
1075 
1076 	return QDF_STATUS_SUCCESS;
1077 }
1078 
1079 QDF_STATUS
1080 target_if_reg_get_afc_dev_type(struct wlan_objmgr_psoc *psoc,
1081 			       enum reg_afc_dev_deploy_type *reg_afc_dev_type)
1082 {
1083 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1084 
1085 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1086 	if (!reg_rx_ops) {
1087 		target_if_err("reg_rx_ops is NULL");
1088 		return QDF_STATUS_E_FAILURE;
1089 	}
1090 
1091 	if (reg_rx_ops->reg_get_afc_dev_type)
1092 		reg_rx_ops->reg_get_afc_dev_type(
1093 			psoc,
1094 			reg_afc_dev_type);
1095 
1096 	return QDF_STATUS_SUCCESS;
1097 }
1098 #endif
1099 
1100 /**
1101  * tgt_if_reg_is_chip_11be_cap() - Finds out if the hardware is capable
1102  * of 11BE. The capability bit is read from mac_phy_cap populated by the
1103  * FW per pdev.
1104  * @psoc: Pointer to psoc
1105  * @phy_id: phy_id
1106  *
1107  * Return: True if chip is 11BE capable, false otherwise.
1108  */
1109 #ifdef WLAN_FEATURE_11BE
1110 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc,
1111 					uint16_t phy_id)
1112 {
1113 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap;
1114 	struct target_psoc_info *tgt_hdl;
1115 	uint8_t pdev_id;
1116 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
1117 
1118 	reg_tx_ops = target_if_regulatory_get_tx_ops(psoc);
1119 
1120 	if (!reg_tx_ops) {
1121 		target_if_err("reg_tx_ops is NULL");
1122 		return false;
1123 	}
1124 
1125 	if (reg_tx_ops->get_pdev_id_from_phy_id)
1126 		reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
1127 	else
1128 		pdev_id = phy_id;
1129 
1130 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
1131 	if (tgt_hdl) {
1132 		mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl);
1133 		if (!mac_phy_cap_arr)
1134 			return false;
1135 		mac_phy_cap = &mac_phy_cap_arr[pdev_id];
1136 		if (mac_phy_cap && mac_phy_cap->supports_11be)
1137 			return true;
1138 	}
1139 	return false;
1140 }
1141 #else
1142 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc,
1143 					uint16_t phy_id)
1144 {
1145 	return false;
1146 }
1147 #endif
1148 
1149 QDF_STATUS target_if_register_regulatory_tx_ops(
1150 		struct wlan_lmac_if_tx_ops *tx_ops)
1151 {
1152 	struct wlan_lmac_if_reg_tx_ops *reg_ops = &tx_ops->reg_ops;
1153 
1154 	reg_ops->register_master_handler =
1155 		tgt_if_regulatory_register_master_list_handler;
1156 
1157 	reg_ops->unregister_master_handler =
1158 		tgt_if_regulatory_unregister_master_list_handler;
1159 
1160 	target_if_register_master_ext_handler(reg_ops);
1161 
1162 	target_if_register_afc_event_handler(reg_ops);
1163 
1164 	reg_ops->set_country_code = tgt_if_regulatory_set_country_code;
1165 
1166 	reg_ops->fill_umac_legacy_chanlist = NULL;
1167 
1168 	reg_ops->set_country_failed = NULL;
1169 
1170 	target_if_register_acs_trigger_for_afc(reg_ops);
1171 
1172 	reg_ops->register_11d_new_cc_handler =
1173 		tgt_if_regulatory_register_11d_new_cc_handler;
1174 
1175 	reg_ops->unregister_11d_new_cc_handler =
1176 		tgt_if_regulatory_unregister_11d_new_cc_handler;
1177 
1178 	reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan;
1179 
1180 	reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan;
1181 
1182 	reg_ops->is_there_serv_ready_extn =
1183 		tgt_if_regulatory_is_there_serv_ready_extn;
1184 
1185 	reg_ops->set_user_country_code =
1186 		tgt_if_regulatory_set_user_country_code;
1187 
1188 	reg_ops->register_ch_avoid_event_handler =
1189 		tgt_if_regulatory_register_ch_avoid_event_handler;
1190 
1191 	reg_ops->unregister_ch_avoid_event_handler =
1192 		tgt_if_regulatory_unregister_ch_avoid_event_handler;
1193 
1194 	reg_ops->send_ctl_info = tgt_if_regulatory_send_ctl_info;
1195 
1196 	reg_ops->get_phy_id_from_pdev_id =
1197 			tgt_if_regulatory_get_phy_id_from_pdev_id;
1198 
1199 	reg_ops->get_pdev_id_from_phy_id =
1200 			tgt_if_regulatory_get_pdev_id_from_phy_id;
1201 
1202 	reg_ops->set_tpc_power = tgt_if_regulatory_set_tpc_power;
1203 
1204 	reg_ops->get_opclass_tbl_idx = NULL;
1205 
1206 	tgt_if_register_afc_callback(reg_ops);
1207 
1208 	reg_ops->is_chip_11be = tgt_if_reg_is_chip_11be_cap;
1209 
1210 	return QDF_STATUS_SUCCESS;
1211 }
1212