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