xref: /wlan-dirver/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg.c (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
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 /**
361  * tgt_reg_chan_list_ext_update_handler() - Extended channel list update handler
362  * @handle: scn handle
363  * @event_buf: pointer to event buffer
364  * @len: buffer length
365  *
366  * Return: 0 on success
367  */
368 static int tgt_reg_chan_list_ext_update_handler(ol_scn_t handle,
369 						uint8_t *event_buf,
370 						uint32_t len)
371 {
372 	struct wlan_objmgr_psoc *psoc;
373 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
374 	struct cur_regulatory_info *reg_info;
375 	QDF_STATUS status;
376 	struct wmi_unified *wmi_handle;
377 	int ret_val = 0;
378 	uint32_t i;
379 
380 	TARGET_IF_ENTER();
381 
382 	psoc = target_if_get_psoc_from_scn_hdl(handle);
383 	if (!psoc) {
384 		target_if_err("psoc ptr is NULL");
385 		return -EINVAL;
386 	}
387 
388 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
389 	if (!reg_rx_ops) {
390 		target_if_err("reg_rx_ops is NULL");
391 		return -EINVAL;
392 	}
393 
394 	if (!reg_rx_ops->master_list_ext_handler) {
395 		target_if_err("master_list_ext_handler is NULL");
396 		return -EINVAL;
397 	}
398 
399 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
400 	if (!wmi_handle) {
401 		target_if_err("invalid wmi handle");
402 		return -EINVAL;
403 	}
404 
405 	reg_info = qdf_mem_malloc(sizeof(*reg_info));
406 	if (!reg_info)
407 		return -ENOMEM;
408 
409 	status = wmi_extract_reg_chan_list_ext_update_event(wmi_handle,
410 							    event_buf,
411 							    reg_info, len);
412 	if (!QDF_IS_STATUS_SUCCESS(status)) {
413 		target_if_err("Extraction of ext channel list event failed");
414 		ret_val = -EFAULT;
415 		goto clean;
416 	}
417 
418 	if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) {
419 		target_if_err_rl("phy_id %d is out of bounds",
420 				 reg_info->phy_id);
421 		ret_val = -EFAULT;
422 		goto clean;
423 	}
424 
425 	reg_info->psoc = psoc;
426 
427 	status = reg_rx_ops->master_list_ext_handler(reg_info);
428 	if (!QDF_IS_STATUS_SUCCESS(status)) {
429 		target_if_err("Failed to process master ext channel list handler");
430 		ret_val = -EFAULT;
431 	}
432 
433 clean:
434 	qdf_mem_free(reg_info->reg_rules_2g_ptr);
435 	qdf_mem_free(reg_info->reg_rules_5g_ptr);
436 
437 	for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) {
438 		qdf_mem_free(reg_info->reg_rules_6g_ap_ptr[i]);
439 		qdf_mem_free(reg_info->
440 			reg_rules_6g_client_ptr[i][REG_DEFAULT_CLIENT]);
441 		qdf_mem_free(reg_info->
442 			reg_rules_6g_client_ptr[i][REG_SUBORDINATE_CLIENT]);
443 	}
444 
445 	qdf_mem_free(reg_info);
446 
447 	TARGET_IF_EXIT();
448 
449 	return ret_val;
450 }
451 
452 /**
453  * tgt_if_regulatory_register_master_list_ext_handler() - Register extended
454  * master channel list event handler
455  * @psoc: Pointer to psoc
456  * @arg: Pointer to argument list
457  *
458  * Return: QDF_STATUS
459  */
460 static QDF_STATUS tgt_if_regulatory_register_master_list_ext_handler(
461 	struct wlan_objmgr_psoc *psoc, void *arg)
462 {
463 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
464 
465 	if (!wmi_handle)
466 		return QDF_STATUS_E_FAILURE;
467 
468 	return wmi_unified_register_event_handler(
469 			wmi_handle, wmi_reg_chan_list_cc_ext_event_id,
470 			tgt_reg_chan_list_ext_update_handler, WMI_RX_WORK_CTX);
471 }
472 
473 /**
474  * tgt_if_regulatory_unregister_master_list_ext_handler() - Unregister extended
475  * master channel list event handler
476  * @psoc: Pointer to psoc
477  * @arg: Pointer to argument list
478  *
479  * Return: QDF_STATUS
480  */
481 static QDF_STATUS tgt_if_regulatory_unregister_master_list_ext_handler(
482 	struct wlan_objmgr_psoc *psoc, void *arg)
483 {
484 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
485 
486 	if (!wmi_handle)
487 		return QDF_STATUS_E_FAILURE;
488 
489 	return wmi_unified_unregister_event_handler(
490 			wmi_handle, wmi_reg_chan_list_cc_ext_event_id);
491 }
492 
493 #ifdef CONFIG_AFC_SUPPORT
494 /**
495  * tgt_afc_event_handler() - Handler for AFC Event
496  * @handle: scn handle
497  * @event_buf: pointer to event buffer
498  * @len: buffer length
499  *
500  * Return: 0 on success
501  */
502 static int
503 tgt_afc_event_handler(ol_scn_t handle, uint8_t *event_buf, uint32_t len)
504 {
505 	struct wlan_objmgr_psoc *psoc;
506 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
507 	struct afc_regulatory_info *afc_info;
508 	QDF_STATUS status;
509 	struct wmi_unified *wmi_handle;
510 	int ret_val = 0;
511 
512 	TARGET_IF_ENTER();
513 
514 	psoc = target_if_get_psoc_from_scn_hdl(handle);
515 	if (!psoc) {
516 		target_if_err("psoc ptr is NULL");
517 		return -EINVAL;
518 	}
519 
520 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
521 	if (!reg_rx_ops) {
522 		target_if_err("reg_rx_ops is NULL");
523 		return -EINVAL;
524 	}
525 
526 	if (!reg_rx_ops->afc_event_handler) {
527 		target_if_err("afc_event_handler is NULL");
528 		return -EINVAL;
529 	}
530 
531 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
532 	if (!wmi_handle) {
533 		target_if_err("invalid wmi handle");
534 		return -EINVAL;
535 	}
536 
537 	afc_info = qdf_mem_malloc(sizeof(*afc_info));
538 	if (!afc_info)
539 		return -ENOMEM;
540 
541 	status = wmi_extract_afc_event(wmi_handle, event_buf, afc_info, len);
542 	if (!QDF_IS_STATUS_SUCCESS(status)) {
543 		target_if_err("Extraction of AFC event failed");
544 		ret_val = -EFAULT;
545 		goto clean;
546 	}
547 
548 	if (afc_info->phy_id >= PSOC_MAX_PHY_REG_CAP) {
549 		target_if_err_rl("phy_id %d is out of bounds",
550 				 afc_info->phy_id);
551 		ret_val = -EFAULT;
552 		goto clean;
553 	}
554 
555 	afc_info->psoc = psoc;
556 
557 	status = reg_rx_ops->afc_event_handler(afc_info);
558 	if (!QDF_IS_STATUS_SUCCESS(status)) {
559 		target_if_err("Failed to process AFC event handler");
560 		ret_val = -EFAULT;
561 		goto clean;
562 	}
563 
564 clean:
565 	qdf_mem_free(afc_info);
566 	TARGET_IF_EXIT();
567 
568 	return ret_val;
569 }
570 
571 /**
572  * tgt_if_regulatory_register_afc_event_handler() - Register AFC event
573  * handler
574  * @psoc: Pointer to psoc
575  * @arg: Pointer to argument list
576  *
577  * Return: QDF_STATUS
578  */
579 static QDF_STATUS tgt_if_regulatory_register_afc_event_handler(
580 	struct wlan_objmgr_psoc *psoc, void *arg)
581 {
582 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
583 
584 	if (!wmi_handle)
585 		return QDF_STATUS_E_FAILURE;
586 
587 	return wmi_unified_register_event_handler(
588 			wmi_handle, wmi_afc_event_id,
589 			tgt_afc_event_handler, WMI_RX_WORK_CTX);
590 }
591 
592 /**
593  * tgt_if_regulatory_unregister_afc_event_handler() - Unregister AFC event
594  * handler
595  * @psoc: Pointer to psoc
596  * @arg: Pointer to argument list
597  *
598  * Return: QDF_STATUS
599  */
600 static QDF_STATUS
601 tgt_if_regulatory_unregister_afc_event_handler(struct wlan_objmgr_psoc *psoc,
602 					       void *arg)
603 {
604 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
605 
606 	if (!wmi_handle)
607 		return QDF_STATUS_E_FAILURE;
608 
609 	return wmi_unified_unregister_event_handler(
610 			wmi_handle, wmi_afc_event_id);
611 }
612 #endif
613 #endif
614 
615 /**
616  * tgt_if_regulatory_set_country_code() - Set country code
617  * @psoc: Pointer to psoc
618  * @arg: Pointer to argument list
619  *
620  * Return: QDF_STATUS
621  */
622 static QDF_STATUS tgt_if_regulatory_set_country_code(
623 	struct wlan_objmgr_psoc *psoc, void *arg)
624 {
625 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
626 
627 	if (!wmi_handle)
628 		return QDF_STATUS_E_FAILURE;
629 
630 	return wmi_unified_set_country_cmd_send(wmi_handle, arg);
631 }
632 
633 /**
634  * tgt_if_regulatory_set_user_country_code() - Set user country code
635  * @psoc: Pointer to psoc
636  * @pdev_id: Pdev id
637  * @rd: Pointer to regdomain structure
638  *
639  * Return: QDF_STATUS
640  */
641 static QDF_STATUS tgt_if_regulatory_set_user_country_code(
642 	struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, struct cc_regdmn_s *rd)
643 {
644 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
645 
646 	if (!wmi_handle)
647 		return QDF_STATUS_E_FAILURE;
648 
649 	if (wmi_unified_set_user_country_code_cmd_send(
650 				wmi_handle, pdev_id, rd) != QDF_STATUS_SUCCESS
651 			) {
652 		target_if_err("Set user country code failed");
653 		return QDF_STATUS_E_FAILURE;
654 	}
655 
656 	return QDF_STATUS_SUCCESS;
657 }
658 
659 QDF_STATUS tgt_if_regulatory_modify_freq_range(struct wlan_objmgr_psoc *psoc)
660 {
661 	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
662 
663 	reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
664 	if (!reg_cap) {
665 		target_if_err("reg cap is NULL");
666 		return QDF_STATUS_E_FAILURE;
667 	}
668 
669 	if (!(reg_cap->wireless_modes & HOST_REGDMN_MODE_11A)) {
670 		reg_cap->low_5ghz_chan = 0;
671 		reg_cap->high_5ghz_chan = 0;
672 	}
673 
674 	if (!(reg_cap->wireless_modes &
675 	     (HOST_REGDMN_MODE_11B | HOST_REGDMN_MODE_PUREG))) {
676 		reg_cap->low_2ghz_chan = 0;
677 		reg_cap->high_2ghz_chan = 0;
678 	}
679 
680 	target_if_debug("phy_id = %d - low_2ghz_chan = %d high_2ghz_chan = %d low_5ghz_chan = %d high_5ghz_chan = %d",
681 			reg_cap->phy_id,
682 			reg_cap->low_2ghz_chan,
683 			reg_cap->high_2ghz_chan,
684 			reg_cap->low_5ghz_chan,
685 			reg_cap->high_5ghz_chan);
686 
687 	return QDF_STATUS_SUCCESS;
688 }
689 
690 #ifdef CONFIG_REG_CLIENT
691 /**
692  * tgt_if_regulatory_send_ctl_info() - Send CTL info to firmware
693  * @psoc: Pointer to psoc
694  * @params: Pointer to reg control params
695  *
696  * Return: QDF_STATUS
697  */
698 static QDF_STATUS
699 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc,
700 				struct reg_ctl_params *params)
701 {
702 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
703 
704 	if (!wmi_handle)
705 		return QDF_STATUS_E_FAILURE;
706 
707 	return wmi_unified_send_regdomain_info_to_fw_cmd(wmi_handle,
708 							 params->regd,
709 							 params->regd_2g,
710 							 params->regd_5g,
711 							 params->ctl_2g,
712 							 params->ctl_5g);
713 }
714 #else
715 static QDF_STATUS
716 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc,
717 				struct reg_ctl_params *params)
718 {
719 	return QDF_STATUS_SUCCESS;
720 }
721 #endif
722 
723 /**
724  * tgt_if_regulatory_get_phy_id_from_pdev_id() - Get phy_id from pdev_id
725  * @psoc: Pointer to psoc
726  * @pdev_id: Pdev id
727  * @phy_id: phy_id
728  *
729  * Return: QDF_STATUS
730  */
731 static QDF_STATUS tgt_if_regulatory_get_phy_id_from_pdev_id(
732 	struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *phy_id)
733 {
734 	struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle;
735 	uint8_t ret;
736 
737 	if (pdev_id >= WLAN_UMAC_MAX_PDEVS) {
738 		target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS");
739 		return QDF_STATUS_E_FAILURE;
740 	}
741 
742 	/* By default pdev_id and phy_id have one to one mapping */
743 	*phy_id = pdev_id;
744 
745 	if (!(tgt_if_handle &&
746 	      tgt_if_handle->info.is_pdevid_to_phyid_map))
747 		return QDF_STATUS_SUCCESS;
748 
749 	ret = tgt_if_handle->info.pdev_id_to_phy_id_map[pdev_id];
750 
751 	if (ret < PSOC_MAX_PHY_REG_CAP) {
752 		*phy_id = ret;
753 	} else {
754 		target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP");
755 		return QDF_STATUS_E_FAILURE;
756 	}
757 
758 	return QDF_STATUS_SUCCESS;
759 }
760 
761 /**
762  * tgt_if_regulatory_get_pdev_id_from_phy_id() - Get pdev_id for phy_id
763  * @psoc: Pointer to psoc
764  * @phy_id: Phy id
765  * @pdev_id: Pdev id
766  *
767  * Return: QDF_STATUS
768  */
769 static QDF_STATUS tgt_if_regulatory_get_pdev_id_from_phy_id(
770 	struct wlan_objmgr_psoc *psoc, uint8_t phy_id, uint8_t *pdev_id)
771 {
772 	struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle;
773 	uint8_t i;
774 
775 	if (phy_id >= PSOC_MAX_PHY_REG_CAP) {
776 		target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP");
777 		return QDF_STATUS_E_FAILURE;
778 	}
779 
780 	/* By default pdev_id and phy_id have one to one mapping */
781 	*pdev_id = phy_id;
782 
783 	if (!(tgt_if_handle &&
784 	      tgt_if_handle->info.is_pdevid_to_phyid_map))
785 		return QDF_STATUS_SUCCESS;
786 
787 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
788 		if (tgt_if_handle->info.pdev_id_to_phy_id_map[i] == phy_id)
789 			break;
790 	}
791 
792 	if (i < WLAN_UMAC_MAX_PDEVS) {
793 		*pdev_id = i;
794 	} else {
795 		target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS");
796 		return QDF_STATUS_E_FAILURE;
797 	}
798 
799 	return QDF_STATUS_SUCCESS;
800 }
801 
802 #ifdef CONFIG_BAND_6GHZ
803 static void target_if_register_master_ext_handler(
804 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
805 {
806 	reg_ops->register_master_ext_handler =
807 		tgt_if_regulatory_register_master_list_ext_handler;
808 
809 	reg_ops->unregister_master_ext_handler =
810 		tgt_if_regulatory_unregister_master_list_ext_handler;
811 }
812 
813 #ifdef CONFIG_AFC_SUPPORT
814 static void target_if_register_afc_event_handler(
815 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
816 {
817 	reg_ops->register_afc_event_handler =
818 		tgt_if_regulatory_register_afc_event_handler;
819 
820 	reg_ops->unregister_afc_event_handler =
821 		tgt_if_regulatory_unregister_afc_event_handler;
822 }
823 
824 static void target_if_register_acs_trigger_for_afc
825 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
826 {
827 	reg_ops->trigger_acs_for_afc = NULL;
828 }
829 #else
830 static void target_if_register_afc_event_handler(
831 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
832 {
833 }
834 
835 static void target_if_register_acs_trigger_for_afc
836 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
837 {
838 }
839 #endif
840 #else
841 static inline void
842 target_if_register_master_ext_handler(struct wlan_lmac_if_reg_tx_ops *reg_ops)
843 {
844 }
845 
846 static void target_if_register_afc_event_handler(
847 				struct wlan_lmac_if_reg_tx_ops *reg_ops)
848 {
849 }
850 
851 static void target_if_register_acs_trigger_for_afc
852 				(struct wlan_lmac_if_reg_tx_ops *reg_ops)
853 {
854 }
855 #endif
856 
857 static QDF_STATUS
858 tgt_if_regulatory_set_tpc_power(struct wlan_objmgr_psoc *psoc,
859 				uint8_t vdev_id,
860 				struct reg_tpc_power_info *param)
861 {
862 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
863 
864 	if (!wmi_handle)
865 		return QDF_STATUS_E_FAILURE;
866 
867 	return wmi_unified_send_set_tpc_power_cmd(wmi_handle, vdev_id, param);
868 }
869 
870 #ifdef CONFIG_AFC_SUPPORT
871 /**
872  * tgt_if_regulatory_send_afc_cmd() - Send AFC command to the FW
873  *
874  * @psoc: Pointer to psoc
875  * @pdev_id: Pdev id
876  * @param: Pointer to hold AFC indication.
877  *
878  * Return: QDF_STATUS_SUCCESS if WMI_AFC_CMD is sent, else QDF_STATUS_E_FAILURE
879  */
880 static QDF_STATUS
881 tgt_if_regulatory_send_afc_cmd(struct wlan_objmgr_psoc *psoc,
882 			       uint8_t pdev_id,
883 			       struct reg_afc_resp_rx_ind_info *param)
884 {
885 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
886 
887 	if (!wmi_handle)
888 		return QDF_STATUS_E_FAILURE;
889 
890 	return wmi_unified_send_afc_cmd(wmi_handle, pdev_id, param);
891 }
892 
893 static void
894 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops)
895 {
896 	reg_ops->send_afc_ind = tgt_if_regulatory_send_afc_cmd;
897 }
898 #else
899 static void
900 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops)
901 {
902 }
903 #endif
904 
905 /**
906  * tgt_if_regulatory_is_ext_tpc_supported() - Check if FW supports new
907  * WMI command for TPC power
908  *
909  * @psoc: Pointer to psoc
910  *
911  * Return: true if FW supports new WMI command for TPC, else false
912  */
913 static bool
914 tgt_if_regulatory_is_ext_tpc_supported(struct wlan_objmgr_psoc *psoc)
915 {
916 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
917 
918 	if (!wmi_handle)
919 		return false;
920 
921 	return wmi_service_enabled(wmi_handle,
922 				   wmi_service_ext_tpc_reg_support);
923 }
924 
925 QDF_STATUS target_if_regulatory_set_ext_tpc(struct wlan_objmgr_psoc *psoc)
926 {
927 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
928 
929 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
930 	if (!reg_rx_ops) {
931 		target_if_err("reg_rx_ops is NULL");
932 		return QDF_STATUS_E_FAILURE;
933 	}
934 
935 	if (reg_rx_ops->reg_set_ext_tpc_supported)
936 		reg_rx_ops->reg_set_ext_tpc_supported(
937 			psoc,
938 			tgt_if_regulatory_is_ext_tpc_supported(psoc));
939 
940 	return QDF_STATUS_SUCCESS;
941 }
942 
943 #if defined(CONFIG_BAND_6GHZ)
944 /**
945  * tgt_if_regulatory_is_lower_6g_edge_ch_supp() - Check if lower 6ghz
946  * edge channel (5935MHz) is supported
947  * @psoc: Pointer to psoc
948  *
949  * Return: true if channel is supported, else false
950  */
951 static bool
952 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc)
953 {
954 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
955 
956 	if (!wmi_handle)
957 		return false;
958 
959 	return wmi_service_enabled(wmi_handle,
960 				   wmi_service_lower_6g_edge_ch_supp);
961 }
962 
963 /**
964  * tgt_if_regulatory_is_upper_6g_edge_ch_disabled() - Check if upper
965  * 6ghz edge channel (7115MHz) is disabled
966  * @psoc: Pointer to psoc
967  *
968  * Return: true if channel is disabled, else false
969  */
970 static bool
971 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc)
972 {
973 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
974 
975 	if (!wmi_handle)
976 		return false;
977 
978 	return wmi_service_enabled(wmi_handle,
979 				   wmi_service_disable_upper_6g_edge_ch_supp);
980 }
981 
982 QDF_STATUS
983 target_if_reg_set_lower_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc)
984 {
985 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
986 
987 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
988 	if (!reg_rx_ops) {
989 		target_if_err("reg_rx_ops is NULL");
990 		return QDF_STATUS_E_FAILURE;
991 	}
992 
993 	if (reg_rx_ops->reg_set_lower_6g_edge_ch_supp)
994 		reg_rx_ops->reg_set_lower_6g_edge_ch_supp(
995 			psoc,
996 			tgt_if_regulatory_is_lower_6g_edge_ch_supp(psoc));
997 
998 	return QDF_STATUS_SUCCESS;
999 }
1000 
1001 QDF_STATUS
1002 target_if_reg_set_disable_upper_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc)
1003 {
1004 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1005 
1006 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1007 	if (!reg_rx_ops) {
1008 		target_if_err("reg_rx_ops is NULL");
1009 		return QDF_STATUS_E_FAILURE;
1010 	}
1011 
1012 	if (reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp)
1013 		reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp(
1014 			psoc,
1015 			tgt_if_regulatory_is_upper_6g_edge_ch_disabled(psoc));
1016 
1017 	return QDF_STATUS_SUCCESS;
1018 }
1019 #else
1020 static inline bool
1021 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc)
1022 {
1023 	return false;
1024 }
1025 
1026 static inline bool
1027 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc)
1028 {
1029 	return false;
1030 }
1031 #endif
1032 
1033 #if defined(CONFIG_AFC_SUPPORT)
1034 QDF_STATUS
1035 target_if_reg_set_afc_dev_type(struct wlan_objmgr_psoc *psoc,
1036 			       struct target_psoc_info *tgt_hdl)
1037 {
1038 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1039 	struct tgt_info *info;
1040 
1041 	if (!tgt_hdl) {
1042 		target_if_err("target_psoc_info is null");
1043 		return QDF_STATUS_E_FAILURE;
1044 	}
1045 
1046 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1047 	if (!reg_rx_ops) {
1048 		target_if_err("reg_rx_ops is NULL");
1049 		return QDF_STATUS_E_FAILURE;
1050 	}
1051 
1052 	info = (&tgt_hdl->info);
1053 
1054 	if (reg_rx_ops->reg_set_afc_dev_type)
1055 		reg_rx_ops->reg_set_afc_dev_type(
1056 			psoc,
1057 			info->service_ext2_param.afc_dev_type);
1058 
1059 	return QDF_STATUS_SUCCESS;
1060 }
1061 
1062 QDF_STATUS
1063 target_if_reg_get_afc_dev_type(struct wlan_objmgr_psoc *psoc,
1064 			       enum reg_afc_dev_deploy_type *reg_afc_dev_type)
1065 {
1066 	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
1067 
1068 	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
1069 	if (!reg_rx_ops) {
1070 		target_if_err("reg_rx_ops is NULL");
1071 		return QDF_STATUS_E_FAILURE;
1072 	}
1073 
1074 	if (reg_rx_ops->reg_get_afc_dev_type)
1075 		reg_rx_ops->reg_get_afc_dev_type(
1076 			psoc,
1077 			reg_afc_dev_type);
1078 
1079 	return QDF_STATUS_SUCCESS;
1080 }
1081 #endif
1082 
1083 /**
1084  * tgt_if_reg_is_chip_11be_cap() - Finds out if the hardware is capable
1085  * of 11BE. The capability bit is read from mac_phy_cap populated by the
1086  * FW per pdev.
1087  * @psoc: Pointer to psoc
1088  * @phy_id: phy_id
1089  *
1090  * Return: True if chip is 11BE capable, false otherwise.
1091  */
1092 #ifdef WLAN_FEATURE_11BE
1093 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc,
1094 					uint16_t phy_id)
1095 {
1096 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap;
1097 	struct target_psoc_info *tgt_hdl;
1098 	uint8_t pdev_id;
1099 	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
1100 
1101 	reg_tx_ops = target_if_regulatory_get_tx_ops(psoc);
1102 
1103 	if (!reg_tx_ops) {
1104 		target_if_err("reg_tx_ops is NULL");
1105 		return false;
1106 	}
1107 
1108 	if (reg_tx_ops->get_pdev_id_from_phy_id)
1109 		reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
1110 	else
1111 		pdev_id = phy_id;
1112 
1113 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
1114 	if (tgt_hdl) {
1115 		mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl);
1116 		if (!mac_phy_cap_arr)
1117 			return false;
1118 		mac_phy_cap = &mac_phy_cap_arr[pdev_id];
1119 		if (mac_phy_cap && mac_phy_cap->supports_11be)
1120 			return true;
1121 	}
1122 	return false;
1123 }
1124 #else
1125 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc,
1126 					uint16_t phy_id)
1127 {
1128 	return false;
1129 }
1130 #endif
1131 
1132 QDF_STATUS target_if_register_regulatory_tx_ops(
1133 		struct wlan_lmac_if_tx_ops *tx_ops)
1134 {
1135 	struct wlan_lmac_if_reg_tx_ops *reg_ops = &tx_ops->reg_ops;
1136 
1137 	reg_ops->register_master_handler =
1138 		tgt_if_regulatory_register_master_list_handler;
1139 
1140 	reg_ops->unregister_master_handler =
1141 		tgt_if_regulatory_unregister_master_list_handler;
1142 
1143 	target_if_register_master_ext_handler(reg_ops);
1144 
1145 	target_if_register_afc_event_handler(reg_ops);
1146 
1147 	reg_ops->set_country_code = tgt_if_regulatory_set_country_code;
1148 
1149 	reg_ops->fill_umac_legacy_chanlist = NULL;
1150 
1151 	reg_ops->set_country_failed = NULL;
1152 
1153 	target_if_register_acs_trigger_for_afc(reg_ops);
1154 
1155 	reg_ops->register_11d_new_cc_handler =
1156 		tgt_if_regulatory_register_11d_new_cc_handler;
1157 
1158 	reg_ops->unregister_11d_new_cc_handler =
1159 		tgt_if_regulatory_unregister_11d_new_cc_handler;
1160 
1161 	reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan;
1162 
1163 	reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan;
1164 
1165 	reg_ops->is_there_serv_ready_extn =
1166 		tgt_if_regulatory_is_there_serv_ready_extn;
1167 
1168 	reg_ops->set_user_country_code =
1169 		tgt_if_regulatory_set_user_country_code;
1170 
1171 	reg_ops->register_ch_avoid_event_handler =
1172 		tgt_if_regulatory_register_ch_avoid_event_handler;
1173 
1174 	reg_ops->unregister_ch_avoid_event_handler =
1175 		tgt_if_regulatory_unregister_ch_avoid_event_handler;
1176 
1177 	reg_ops->send_ctl_info = tgt_if_regulatory_send_ctl_info;
1178 
1179 	reg_ops->get_phy_id_from_pdev_id =
1180 			tgt_if_regulatory_get_phy_id_from_pdev_id;
1181 
1182 	reg_ops->get_pdev_id_from_phy_id =
1183 			tgt_if_regulatory_get_pdev_id_from_phy_id;
1184 
1185 	reg_ops->set_tpc_power = tgt_if_regulatory_set_tpc_power;
1186 
1187 	reg_ops->get_opclass_tbl_idx = NULL;
1188 
1189 	tgt_if_register_afc_callback(reg_ops);
1190 
1191 	reg_ops->is_chip_11be = tgt_if_reg_is_chip_11be_cap;
1192 
1193 	return QDF_STATUS_SUCCESS;
1194 }
1195