xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_regulation.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2020 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #include "phl_headers.h"
16 #include "phl_chnlplan.h"
17 #include "phl_country.h"
18 #include "phl_regulation_6g.h"
19 
20 extern const struct regulatory_domain_mapping rdmap[MAX_RD_MAP_NUM];
21 extern const struct chdef_2ghz chdef2g[MAX_CHDEF_2GHZ];
22 extern const struct chdef_5ghz chdef5g[MAX_CHDEF_5GHZ];
23 extern const struct country_domain_mapping cdmap[MAX_COUNTRY_NUM];
24 
25 /*
26  * @ Function description
27  *	Convert 2 ghz channels from bit definition and then fill to
28  *	struct rtw_regulation_channel *ch array[] and
29  *	*ch_cnt will also be calculated.
30  *
31  * @ parameter
32  *	*rg : internal regulatory information
33  *	*ch_cnt : final converted 2ghz channel numbers.
34  *	*rch : converted channels will be filled here.
35  *	ch : 2 ghz bit difinitions
36  *	passive : 2 ghz passive bit difinitions
37  *
38  */
_convert_ch2g(struct rtw_regulation * rg,u32 * ch_cnt,struct rtw_regulation_channel * rch,u16 ch,u16 passive)39 static void _convert_ch2g(struct rtw_regulation *rg, u32 *ch_cnt,
40 	struct rtw_regulation_channel *rch, u16 ch, u16 passive)
41 {
42 	u8 i = 0, property = 0;
43 	u32 shift = 0, cnt = 0;
44 
45 	PHL_INFO("[REGU], convert 2 ghz channels\n");
46 
47 	for (i = 0; i < MAX_CH_NUM_2GHZ; i++) {
48 		property = 0;
49 		shift = (1 << i);
50 		if (ch & shift) {
51 			rch[*ch_cnt].band = BAND_ON_24G;
52 			rch[*ch_cnt].channel = (u8)(i + 1);
53 
54 			if (passive & shift)
55 				property |= CH_PASSIVE;
56 
57 			rch[*ch_cnt].property = property;
58 			(*ch_cnt)++;
59 			PHL_INFO("[REGU], ch: %d%s\n", (i + 1),
60 			((property & CH_PASSIVE) ? ", passive" : " " ));
61 			cnt++;
62 		}
63 	}
64 
65 	PHL_INFO("[REGU], converted channels : %d\n", cnt);
66 }
67 
_chnlplan_update_2g(struct rtw_regulation * rg,const struct freq_plan * f)68 static enum rtw_regulation_status _chnlplan_update_2g(
69 		struct rtw_regulation *rg, const struct freq_plan *f)
70 {
71 	const struct chdef_2ghz *chdef = NULL;
72 	struct rtw_regulation_chplan_group *plan = NULL;
73 	u16 i = 0, ch = 0, passive = 0;
74 
75 	if (!f)
76 		return REGULATION_FAILURE;
77 
78 	if (f->regulation >= REGULATION_MAX)
79 		return REGULATION_FAILURE;
80 
81 	for (i = 0; i < MAX_CHDEF_2GHZ; i++) {
82 		if (f->ch_idx == chdef2g[i].idx) {
83 			chdef = &chdef2g[i];
84 			break;
85 		}
86 	}
87 
88 	if (!chdef)
89 		return REGULATION_FAILURE;
90 
91 	rg->ch_idx2g = f->ch_idx;
92 	rg->regulation_2g = f->regulation;
93 
94 	plan = &rg->chplan[FREQ_GROUP_2GHZ];
95 	plan->cnt = 0;
96 	ch = ((chdef->support_ch[1] << 8) | (chdef->support_ch[0]));
97 	passive = ((chdef->passive[1] << 8) | (chdef->passive[0]));
98 	_convert_ch2g(rg, &plan->cnt, plan->ch, ch, passive);
99 
100 	PHL_INFO("[REGU], 2 GHz, total channel = %d\n", plan->cnt);
101 
102 	return REGULATION_SUCCESS;
103 }
104 
_get_5ghz_ch_info(const struct chdef_5ghz * chdef,u8 group,u16 * ch,u16 * passive,u16 * dfs,u8 * max_num,u8 * ch_start)105 static void _get_5ghz_ch_info(const struct chdef_5ghz *chdef,
106 	u8 group, u16 *ch, u16 *passive, u16 *dfs, u8 *max_num, u8 *ch_start)
107 {
108 	switch (group) {
109 	case FREQ_GROUP_5GHZ_BAND1:
110 		*ch = chdef->support_ch_b1;
111 		*passive = chdef->passive_b1;
112 		*dfs = chdef->dfs_b1;
113 		*max_num = MAX_CH_NUM_BAND1;
114 		*ch_start = 36;
115 		break;
116 	case FREQ_GROUP_5GHZ_BAND2:
117 		*ch = chdef->support_ch_b2;
118 		*passive = chdef->passive_b2;
119 		*dfs = chdef->dfs_b2;
120 		*max_num = MAX_CH_NUM_BAND2;
121 		*ch_start = 52;
122 		break;
123 	case FREQ_GROUP_5GHZ_BAND3:
124 		*ch = ((chdef->support_ch_b3[1] << 8) |
125 			(chdef->support_ch_b3[0]));
126 		*passive = ((chdef->passive_b3[1] << 8) |
127 			(chdef->passive_b3[0]));
128 		*dfs = ((chdef->dfs_b3[1] << 8) |
129 			(chdef->dfs_b3[0])) ;
130 		*max_num = MAX_CH_NUM_BAND3;
131 		*ch_start = 100;
132 		break;
133 	case FREQ_GROUP_5GHZ_BAND4:
134 		*ch = chdef->support_ch_b4;
135 		*passive = chdef->passive_b4;
136 		*dfs = chdef->dfs_b4;
137 		*max_num = MAX_CH_NUM_BAND4;
138 		*ch_start = 149;
139 		break;
140 	default:
141 		*ch = 0;
142 		*passive = 0;
143 		*dfs = 0;
144 		*max_num = 0;
145 		*ch_start = 0;
146 		break;
147 	}
148 }
149 
150 /*
151  * @ Function description
152  *	Convert 5 ghz channels from bit definition and then fill to
153  *	struct rtw_regulation_channel *ch array[] and
154  *	*ch_cnt will also be calculated.
155  *
156  * @ parameter
157  *	band_5g : 1~4 (5g band-1 ~ 5g band-4)
158  *	*rg : internal regulatory information
159  *	*ch_cnt : final converted 2ghz channel numbers.
160  *	*rch : converted channels will be filled here.
161  *	ch : 5 ghz bnad channel bit difinitions
162  *	passive : 5 ghz band passive bit difinitions
163  *	dfs : 5 ghz band dfs bit difinitions
164  *	max_num : maximum channel numbers of the 5 ghz band.
165  *	ch_start : start channel index of the 5 ghz band.
166  */
_convert_ch5g(u8 band_5g,struct rtw_regulation * rg,u32 * ch_cnt,struct rtw_regulation_channel * rch,u16 ch,u16 passive,u16 dfs,u8 max_num,u8 ch_start)167 static void _convert_ch5g(u8 band_5g, struct rtw_regulation *rg,
168 			u32 *ch_cnt, struct rtw_regulation_channel *rch,
169 			u16 ch, u16 passive, u16 dfs, u8 max_num, u8 ch_start)
170 {
171 	u16 i = 0;
172 	u32 shift = 0;
173 	u8 property = 0;
174 	u32 cnt = 0;
175 
176 	PHL_INFO("[REGU], convert 5ghz band-%d channels, from %d, ch=0x%x, passive = 0x%x, dfs=0x%x \n",
177 			band_5g, ch_start, ch, passive, dfs);
178 
179 	for (i = 0; i < max_num; i++) {
180 		shift = (1 << i);
181 		if (ch & shift) {
182 			property = 0;
183 			rch[*ch_cnt].band = BAND_ON_5G;
184 			rch[*ch_cnt].channel = (u8)(ch_start + (i * 4));
185 
186 			if (passive & shift)
187 				property |= CH_PASSIVE;
188 			if (dfs & shift)
189 				property |= CH_DFS;
190 
191 			rch[*ch_cnt].property = property;
192 			PHL_INFO("[REGU], ch: %d%s%s \n",
193 				rch[*ch_cnt].channel,
194 				((property & CH_PASSIVE) ? ", passive" : ""),
195 				((property & CH_DFS) ? ", dfs" : ""));
196 			(*ch_cnt)++;
197 			cnt++;
198 		}
199 	}
200 
201 	PHL_INFO("[REGU], converted channels : %d\n", cnt);
202 }
203 
_chnlplan_update_5g(struct rtw_regulation * rg,const struct freq_plan * f)204 static enum rtw_regulation_status _chnlplan_update_5g(
205 		struct rtw_regulation *rg, const struct freq_plan *f)
206 {
207 	const struct chdef_5ghz *chdef = NULL;
208 	struct rtw_regulation_chplan_group *plan = NULL;
209 	u8 group = FREQ_GROUP_5GHZ_BAND1;
210 	u8 max_num = 0, ch_start = 0;
211 	u16 i = 0, ch = 0, passive = 0, dfs = 0;
212 	u32 total = 0;
213 
214 	if (!f)
215 		return REGULATION_FAILURE;
216 
217 	if (f->regulation >= REGULATION_MAX)
218 		return REGULATION_FAILURE;
219 
220 	for (i = 0; i < MAX_CHDEF_5GHZ; i++) {
221 		if (f->ch_idx == chdef5g[i].idx) {
222 			chdef = &chdef5g[i];
223 			break;
224 		}
225 	}
226 
227 	if (!chdef)
228 		return REGULATION_FAILURE;
229 
230 	rg->ch_idx5g = f->ch_idx;
231 	rg->regulation_5g = f->regulation;
232 
233 	for (i = 0; i < 4; i++) {
234 		group = (u8)(i + FREQ_GROUP_5GHZ_BAND1);
235 		plan = &rg->chplan[group];
236 		plan->cnt = 0;
237 		_get_5ghz_ch_info(chdef, group,
238 			&ch, &passive, &dfs, &max_num, &ch_start);
239 		_convert_ch5g((u8)(i + 1), rg, &plan->cnt, plan->ch,
240 			ch, passive, dfs, max_num, ch_start);
241 		total += plan->cnt;
242 	}
243 
244 	PHL_INFO("[REGU], 5 GHz, total channel = %d\n", total);
245 
246 	return REGULATION_SUCCESS;
247 }
248 
_regulatory_domain_update(struct rtw_regulation * rg,u8 did,enum regulation_rsn reason)249 static enum rtw_regulation_status _regulatory_domain_update(
250 		struct rtw_regulation *rg, u8 did, enum regulation_rsn reason)
251 {
252 	enum rtw_regulation_status status = REGULATION_SUCCESS;
253 	const struct freq_plan *plan_2g = NULL;
254 	const struct freq_plan *plan_5g = NULL;
255 
256 	plan_2g = &rdmap[did].freq_2g;
257 	plan_5g = &rdmap[did].freq_5g;
258 
259 	rg->domain.code = rdmap[did].domain_code;
260 	rg->domain.reason = reason;
261 
262 	status = _chnlplan_update_2g(rg, plan_2g);
263 		if (status != REGULATION_SUCCESS)
264 			return status;
265 	status = _chnlplan_update_5g(rg, plan_5g);
266 		if (status != REGULATION_SUCCESS)
267 			return status;
268 
269 	return status;
270 }
271 
_get_group_chplan(struct rtw_regulation * rg,struct rtw_regulation_chplan_group * group,struct rtw_regulation_chplan * plan)272 static void _get_group_chplan(struct rtw_regulation *rg,
273 			struct rtw_regulation_chplan_group *group,
274 			struct rtw_regulation_chplan *plan)
275 {
276 	u32 i = 0;
277 	u8 dfs = 0;
278 
279 	for (i = 0; i < group->cnt; i++) {
280 		dfs = ((group->ch[i].property & CH_DFS) ? 1 : 0);
281 
282 		if ((group->ch[i].channel) &&
283 			(!dfs || ((rg->capability & CAPABILITY_DFS) && dfs))) {
284 			plan->ch[plan->cnt].band =
285 				group->ch[i].band;
286 			plan->ch[plan->cnt].channel =
287 				group->ch[i].channel;
288 			plan->ch[plan->cnt].property =
289 				group->ch[i].property;
290 			plan->cnt++;
291 		}
292 	}
293 }
294 
_domain_index(u8 domain)295 static u8 _domain_index(u8 domain)
296 {
297 	u8 i = 0;
298 
299 	for (i = 0; i < MAX_RD_MAP_NUM; i++) {
300 		if (domain == rdmap[i].domain_code) {
301 			return i;
302 		}
303 	}
304 
305 	return MAX_RD_MAP_NUM;
306 }
307 
_get_chnlplan(struct rtw_regulation * rg,enum rtw_regulation_query type,struct rtw_regulation_chplan * plan)308 static enum rtw_regulation_status _get_chnlplan(struct rtw_regulation *rg,
309 				enum rtw_regulation_query type,
310 				struct rtw_regulation_chplan *plan)
311 {
312 	struct rtw_regulation_chplan_group *group = NULL;
313 
314 	if (rg->domain.code == INVALID_DOMAIN_CODE)
315 		return REGULATION_INVALID_DOMAIN;
316 
317 	plan->cnt = 0;
318 
319 	/* 2ghz */
320 	if (rg->capability & CAPABILITY_2GHZ) {
321 		if (type == REGULQ_CHPLAN_FULL ||
322 			type == REGULQ_CHPLAN_2GHZ_5GHZ ||
323 			type == REGULQ_CHPLAN_2GHZ) {
324 			group = &rg->chplan[FREQ_GROUP_2GHZ];
325 			_get_group_chplan(rg, group, plan);
326 		}
327 	}
328 
329 	/* 5ghz */
330 	if (rg->capability & CAPABILITY_5GHZ) {
331 		/* band1 */
332 		if (type == REGULQ_CHPLAN_FULL ||
333 			type == REGULQ_CHPLAN_2GHZ_5GHZ ||
334 			type == REGULQ_CHPLAN_5GHZ_ALL ||
335 			type == REGULQ_CHPLAN_5GHZ_BAND1) {
336 			group = &rg->chplan[FREQ_GROUP_5GHZ_BAND1];
337 			_get_group_chplan(rg, group, plan);
338 		}
339 		/* band2 */
340 		if (type == REGULQ_CHPLAN_FULL ||
341 			type == REGULQ_CHPLAN_2GHZ_5GHZ ||
342 			type == REGULQ_CHPLAN_5GHZ_ALL ||
343 			type == REGULQ_CHPLAN_5GHZ_BAND2) {
344 			group = &rg->chplan[FREQ_GROUP_5GHZ_BAND2];
345 			_get_group_chplan(rg, group, plan);
346 		}
347 		/* band3 */
348 		if (type == REGULQ_CHPLAN_FULL ||
349 			type == REGULQ_CHPLAN_2GHZ_5GHZ ||
350 			type == REGULQ_CHPLAN_5GHZ_ALL ||
351 			type == REGULQ_CHPLAN_5GHZ_BAND3) {
352 			group = &rg->chplan[FREQ_GROUP_5GHZ_BAND3];
353 			_get_group_chplan(rg, group, plan);
354 		}
355 		/* band4 */
356 		if (type == REGULQ_CHPLAN_FULL ||
357 			type == REGULQ_CHPLAN_2GHZ_5GHZ ||
358 			type == REGULQ_CHPLAN_5GHZ_ALL ||
359 			type == REGULQ_CHPLAN_5GHZ_BAND4) {
360 			group = &rg->chplan[FREQ_GROUP_5GHZ_BAND4];
361 			_get_group_chplan(rg, group, plan);
362 		}
363 	}
364 
365 #ifdef CONFIG_6GHZ
366 	regu_get_chnlplan_6g(rg, type, plan);
367 #endif
368 	return REGULATION_SUCCESS;
369 }
370 
_valid_property(u8 property,u8 reject)371 static bool _valid_property(u8 property, u8 reject)
372 {
373 	u8 i = 0;
374 
375 	/* accept all property */
376 	if (!reject)
377 		return true;
378 
379 	/* check if ch property rejected */
380 	for (i = 0; i < 8; i++) {
381 		if ((BIT(i) & property) & reject)
382 			return false;
383 	}
384 
385 	return true;
386 }
387 
_filter_chnlplan(void * d,struct rtw_regulation_chplan * plan,struct rtw_chlist * filter)388 static void _filter_chnlplan(void *d,
389 			struct rtw_regulation_chplan *plan,
390 			struct rtw_chlist *filter)
391 {
392 	struct rtw_regulation_chplan inplan = {0};
393 	u32 i = 0, j = 0, k = 0;
394 
395 	if (!d || !plan || !filter)
396 		return;
397 
398 	if (plan->cnt < filter->cnt)
399 		return;
400 
401 	_os_mem_cpy(d, &inplan, plan, sizeof(struct rtw_regulation_chplan));
402 
403 	/*
404 	 * generate output chplan
405 	 * ex: filter : {1, 6}, inplan : {1, 6, 6, 11}, ouput => {1, 6, 6}
406 	 */
407 	plan->cnt = 0;
408 	for (i = 0; i < filter->cnt; i++) {
409 		for (j = 0; j < inplan.cnt; j++) {
410 			if ((filter->ch[i].band == inplan.ch[j].band) &&
411 				(filter->ch[i].ch == inplan.ch[j].channel)) {
412 				plan->ch[k].band = inplan.ch[j].band;
413 				plan->ch[k].channel = inplan.ch[j].channel;
414 				plan->ch[k].property = inplan.ch[j].property;
415 				k++;
416 				plan->cnt++;
417 			}
418 		}
419 	}
420 }
421 
_regulation_valid(void * phl)422 static bool _regulation_valid(void *phl)
423 {
424 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
425 	struct rtw_regulation *rg = NULL;
426 	void *d = NULL;
427 	bool valid = false;
428 
429 	if (!phl)
430 		return false;
431 
432 	rg = &phl_info->regulation;
433 	if (!rg->init)
434 		return false;
435 
436 	d = phl_to_drvpriv(phl_info);
437 	_os_spinlock(d, &rg->lock, _bh, NULL);
438 	valid = rg->valid;
439 	_os_spinunlock(d, &rg->lock, _bh, NULL);
440 
441 	return valid;
442 }
443 
_query_channel(struct rtw_regulation * rg,enum band_type band,u16 channel,struct rtw_regulation_channel * ch)444 static bool _query_channel(struct rtw_regulation *rg,
445 			enum band_type band, u16 channel,
446 			struct rtw_regulation_channel *ch)
447 {
448 	struct rtw_regulation_chplan_group *plan = NULL;
449 	u32 i = 0, j = 0;
450 
451 	if ((BAND_2GHZ(band) && !(rg->capability & CAPABILITY_2GHZ)) ||
452 		(BAND_5GHZ(band) && !(rg->capability & CAPABILITY_5GHZ)) ||
453 		(BAND_6GHZ(band) && !(rg->capability & CAPABILITY_6GHZ)))
454 		return false;
455 
456 	for (i = FREQ_GROUP_2GHZ; i < FREQ_GROUP_MAX; i++) {
457 		plan = &rg->chplan[i];
458 		for (j = 0; j < plan->cnt; j++) {
459 			if (channel == plan->ch[j].channel) {
460 				ch->band = plan->ch[j].band;
461 				ch->channel = plan->ch[j].channel;
462 				ch->property = plan->ch[j].property;
463 				return true;
464 			}
465 		}
466 	}
467 
468 	return false;
469 }
470 
_display_chplan(struct rtw_regulation_chplan * plan)471 static void _display_chplan(struct rtw_regulation_chplan *plan)
472 {
473 	u32 i = 0;
474 
475 	for (i = 0; i < plan->cnt; i++) {
476 		PHL_INFO("[REGU], %d, %shz: ch %d%s%s%s\n", (i + 1),
477 			((plan->ch[i].band == BAND_ON_24G) ? "2g" :
478 			((plan->ch[i].band == BAND_ON_5G) ? "5g" :
479 			((plan->ch[i].band == BAND_ON_6G) ? "6g" : ""))),
480 			(plan->ch[i].channel),
481 			((plan->ch[i].property & CH_PASSIVE) ?
482 						", passive" : ""),
483 			((plan->ch[i].property & CH_DFS) ? ", dfs" : ""),
484 			((plan->ch[i].property & CH_PSC) ? ", psc" : ""));
485 	}
486 }
487 
_phl_regulation_send_msg(struct phl_info_t * phl_info,u8 evt_id)488 static void _phl_regulation_send_msg(struct phl_info_t *phl_info, u8 evt_id)
489 {
490 	struct phl_msg msg = {0};
491 	msg.inbuf = NULL;
492 	msg.inlen = 0;
493 	msg.band_idx = HW_BAND_0;
494 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_REGU);
495 	SET_MSG_EVT_ID_FIELD(msg.msg_id, evt_id);
496 
497 	if (RTW_PHL_STATUS_SUCCESS != phl_msg_hub_send(phl_info, NULL, &msg))
498 		PHL_ERR("[REGULATION] sending message failed (evt_id: %u) \n", evt_id);
499 }
500 
_history_log(struct rtw_regulation * rg,u8 domain,u8 reason)501 static void _history_log(struct rtw_regulation *rg, u8 domain, u8 reason)
502 {
503 	rg->history[rg->history_cnt].code = domain;
504 	rg->history[rg->history_cnt].reason = reason;
505 	rg->history_cnt++;
506 	if (rg->history_cnt >= MAX_HISTORY_NUM)
507 		rg->history_cnt = 0;
508 }
509 
510 
_get_5ghz_udef_ch_info(struct rtw_user_def_chplan * udef,u8 group,u16 * ch,u16 * passive,u16 * dfs,u8 * max_num,u8 * ch_start)511 static void _get_5ghz_udef_ch_info(struct rtw_user_def_chplan *udef,
512 	u8 group, u16 *ch, u16 *passive, u16 *dfs, u8 *max_num, u8 *ch_start)
513 {
514 	switch (group) {
515 	case FREQ_GROUP_5GHZ_BAND1:
516 		*ch = (u16)udef->ch5g & 0xf;
517 		*passive = (u16)udef->passive5g & 0xf;
518 		*dfs = (u16)udef->dfs5g & 0xf;
519 		*max_num = MAX_CH_NUM_BAND1;
520 		*ch_start = 36;
521 		break;
522 	case FREQ_GROUP_5GHZ_BAND2:
523 		*ch = (u16)((udef->ch5g & 0xf0) >> 4);
524 		*passive = (u16)((udef->passive5g & 0xf0) >> 4);
525 		*dfs = (u16)((udef->dfs5g & 0xf0) >> 4);
526 		*max_num = MAX_CH_NUM_BAND2;
527 		*ch_start = 52;
528 		break;
529 	case FREQ_GROUP_5GHZ_BAND3:
530 		*ch = (u16)((udef->ch5g & 0xfff00) >> 8);
531 		*passive = (u16)((udef->passive5g & 0xfff00) >> 8);
532 		*dfs = (u16)((udef->dfs5g & 0xfff00) >> 8);
533 		*max_num = MAX_CH_NUM_BAND3;
534 		*ch_start = 100;
535 		break;
536 	case FREQ_GROUP_5GHZ_BAND4:
537 		*ch = (u16)((udef->ch5g & 0xff00000) >> 20);
538 		*passive = (u16)((udef->passive5g & 0xff00000) >> 20);
539 		*dfs = (u16)((udef->dfs5g & 0xff00000) >> 20);
540 		*max_num = MAX_CH_NUM_BAND4;
541 		*ch_start = 149;
542 		break;
543 	default:
544 		*ch = 0;
545 		*passive = 0;
546 		*dfs = 0;
547 		*max_num = 0;
548 		*ch_start = 0;
549 		break;
550 	}
551 }
552 
553 /*
554  * @ Function description
555  *	Reset regulatory info for non-specific country
556  */
_reset_for_non_specific_country(struct rtw_regulation * rg)557 static void _reset_for_non_specific_country(struct rtw_regulation *rg)
558 {
559 	/* reset country */
560 	rg->country[0] = 0;
561 	rg->country[1] = 0;
562 
563 	/* reset TPO */
564 	rg->tpo = TPO_NA;
565 
566 	/* default support all */
567 	rg->support_mode |= (SUPPORT_11B | SUPPORT_11G | SUPPORT_11N |
568 				SUPPORT_11A | SUPPORT_11AC | SUPPORT_11AX);
569 }
570 
571 /*
572  * @ Function description
573  *	Set user defined channel plans
574  *
575  * @ parameter
576  *	struct rtw_user_def_chplan *udef : user defined channels, bit definition
577  *
578  * @ return :
579  *	true : if set successfully
580  *	false : failed to set
581  *
582  */
rtw_phl_set_user_def_chplan(void * phl,struct rtw_user_def_chplan * udef)583 bool rtw_phl_set_user_def_chplan(void *phl, struct rtw_user_def_chplan *udef)
584 {
585 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
586 	struct rtw_regulation *rg = NULL;
587 	struct rtw_regulation_chplan_group *plan = NULL;
588 	u8 max_num = 0, ch_start = 0;
589 	u16 ch = 0, passive = 0, dfs = 0;
590 	u8 group = FREQ_GROUP_5GHZ_BAND1;
591 	void *d = NULL;
592 	u32 i = 0;
593 
594 	if (!phl || !udef)
595 		return false;
596 
597 	rg = &phl_info->regulation;
598 	if (!rg->init)
599 		return false;
600 
601 	if (rg->domain.code != RSVD_DOMAIN) {
602 		PHL_INFO("[REGU], Only reserved domain can set udef channel plan \n");
603 		return false;
604 	}
605 
606 	PHL_INFO("[REGU], set udef channel plan, ch2g:0x%x, ch5g:0x%x\n",
607 			udef->ch2g, udef->ch5g);
608 
609 	d = phl_to_drvpriv(phl_info);
610 	_os_spinlock(d, &rg->lock, _bh, NULL);
611 
612 	rg->regulation_2g = (u8)udef->regulatory_idx;
613 	rg->regulation_5g = (u8)udef->regulatory_idx;
614 	rg->tpo = udef->tpo;
615 
616 	/* 2 ghz */
617 	plan = &rg->chplan[FREQ_GROUP_2GHZ];
618 	plan->cnt = 0;
619 	ch = udef->ch2g;
620 	passive = udef->passive2g;
621 	_convert_ch2g(rg, &plan->cnt, plan->ch, ch, passive);
622 
623 	PHL_INFO("[REGU], 2 GHz, total channel = %d\n", plan->cnt);
624 
625 	/* 5 ghz */
626 	for (i = 0; i < 4; i++) {
627 		group = (u8)(i + FREQ_GROUP_5GHZ_BAND1);
628 		plan = &rg->chplan[group];
629 		plan->cnt = 0;
630 		_get_5ghz_udef_ch_info(udef, group,
631 			&ch, &passive, &dfs, &max_num, &ch_start);
632 		_convert_ch5g((u8)(i + 1), rg, &plan->cnt, plan->ch,
633 			ch, passive, dfs, max_num, ch_start);
634 	}
635 
636 	_os_spinunlock(d, &rg->lock, _bh, NULL);
637 
638 	return true;
639 }
640 
641 
642 /*
643  * @ Function description
644  *	Check if domain is valid or not
645  *
646  * @ parameter
647  *	domain : domain code to query
648  *
649  * @ return :
650  *	true : if domain code exists in data base
651  *	false : invalid domain code
652  *
653  */
rtw_phl_valid_regulation_domain(u8 domain)654 bool rtw_phl_valid_regulation_domain(u8 domain)
655 {
656 	if (domain == RSVD_DOMAIN)
657 		return true;
658 
659 	if (_domain_index(domain) >= MAX_RD_MAP_NUM)
660 		return false;
661 
662 	return true;
663 }
664 
665 /*
666  * @ Function description
667  *	Set regulatory domain code
668  *
669  * @ parameter
670  *	phl : struct phl_info_t *
671  *	domain : domain code
672  *	reason : why
673  *
674  * @ return :
675  *	true : set domain successfully
676  *	false : set fail
677  *
678  */
rtw_phl_regulation_set_domain(void * phl,u8 domain,enum regulation_rsn reason)679 bool rtw_phl_regulation_set_domain(void *phl, u8 domain,
680 				       	enum regulation_rsn reason)
681 {
682 	enum rtw_regulation_status status = REGULATION_SUCCESS;
683 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
684 	struct rtw_regulation *rg = NULL;
685 	void *d = NULL;
686 	u8 did = MAX_RD_MAP_NUM;
687 
688 	PHL_INFO("[REGU], set domain code = 0x%x, reason = 0x%x\n",
689 			domain, reason);
690 
691 	if (!phl_info)
692 		return false;
693 
694 	rg = &phl_info->regulation;
695 	if (!rg->init)
696 		return false;
697 
698 	if (!rtw_phl_valid_regulation_domain(domain))
699 		return false;
700 
701 	did = _domain_index(domain);
702 
703 	d = phl_to_drvpriv(phl_info);
704 
705 	_os_spinlock(d, &rg->lock, _bh, NULL);
706 
707 	_history_log(rg, domain, reason);
708 
709 	if (domain == RSVD_DOMAIN) {
710 		rg->domain.code = RSVD_DOMAIN;
711 		rg->domain.reason = reason;
712 		status = REGULATION_SUCCESS;
713 	} else
714 		status = _regulatory_domain_update(rg, did, reason);
715 
716 	if (status == REGULATION_SUCCESS) {
717 		_reset_for_non_specific_country(rg);
718 		rg->valid = true;
719 	} else {
720 		rg->valid = false;
721 		rg->invalid_cnt++;
722 	}
723 	_os_spinunlock(d, &rg->lock, _bh, NULL);
724 
725 	PHL_INFO("[REGU], domain code update status = 0x%x\n", status);
726 
727 	if (status == REGULATION_SUCCESS) {
728 		_phl_regulation_send_msg(phl_info, MSG_EVT_REGU_SET_DOMAIN);
729 #ifdef CONFIG_6GHZ
730 		regu_set_domain_6g(phl, 0x7f, reason);
731 #endif
732 		return true;
733 	} else {
734 		return false;
735 	}
736 }
737 
738 /*
739  * @ Function description
740  *	Set regulation by 2bytes country code
741  *
742  * @ parameter
743  *	phl : struct phl_info_t *
744  *	country : 2 bytes char
745  *	reason : why
746  *
747  * @ return :
748  *	true : set country/domain successfully
749  *	false : set fail
750  *
751  */
rtw_phl_regulation_set_country(void * phl,char * country,enum regulation_rsn reason)752 bool rtw_phl_regulation_set_country(void *phl, char *country,
753 					enum regulation_rsn reason)
754 {
755 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
756 	struct rtw_regulation *rg = NULL;
757 	void *d = NULL;
758 	u32 i = 0;
759 
760 	PHL_INFO("[REGU], set country code = \"%c%c\", reason = 0x%x\n",
761 			country[0], country[1], reason);
762 
763 	if (!phl_info)
764 		return false;
765 
766 	d = phl_to_drvpriv(phl_info);
767 	rg = &phl_info->regulation;
768 	if (!rg->init)
769 		return false;
770 
771 	if (rg->domain.code == RSVD_DOMAIN)
772 		return false;
773 
774 	for (i = 0; i < MAX_COUNTRY_NUM; i++) {
775 		if (cdmap[i].char2[0] == country[0] &&
776 			cdmap[i].char2[1] == country[1] ) {
777 			if (!rtw_phl_regulation_set_domain(phl,
778 				cdmap[i].domain_code, reason))
779 				return false;
780 			_os_spinlock(d, &rg->lock, _bh, NULL);
781 			rg->country[0] = country[0];
782 			rg->country[1] = country[1];
783 			rg->tpo = cdmap[i].tpo;
784 			rg->support_mode = 0;
785 			if(cdmap[i].support & BIT(0))
786 				rg->support_mode |= (SUPPORT_11B | SUPPORT_11G | SUPPORT_11N);
787 			if(cdmap[i].support & BIT(1))
788 				rg->support_mode |= (SUPPORT_11A);
789 			if(cdmap[i].support & BIT(2))
790 				rg->support_mode |= (SUPPORT_11AC);
791 			if(cdmap[i].support & BIT(3))
792 				rg->support_mode |= (SUPPORT_11AX);
793 			_os_spinunlock(d, &rg->lock, _bh, NULL);
794 			return true;
795 		}
796 	}
797 
798 	PHL_INFO("[REGU], country mismatch !!\n");
799 	return false;
800 }
801 
802 /*
803  * @ Function description
804  *	Query current regulation channel plan
805  *
806  * @ parameter
807  *	phl : struct phl_info_t *
808  *	capability : enum rtw_regulation_capability
809  *
810  * @ return :
811  *	true : set capability successfully
812  *	false : set capability fail
813  *
814  */
rtw_phl_regulation_set_capability(void * phl,enum rtw_regulation_capability capability)815 bool rtw_phl_regulation_set_capability(void *phl,
816 		enum rtw_regulation_capability capability)
817 {
818 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
819 	struct rtw_regulation *rg = NULL;
820 	void *d = NULL;
821 
822 	PHL_INFO("[REGU], set capability = 0x%x \n", capability);
823 
824 	if (!phl_info)
825 		return false;
826 
827 	rg = &phl_info->regulation;
828 	if (!rg->init)
829 		return false;
830 
831 	d = phl_to_drvpriv(phl_info);
832 	_os_spinlock(d, &rg->lock, _bh, NULL);
833 	rg->capability = capability;
834 	_os_spinunlock(d, &rg->lock, _bh, NULL);
835 
836 	PHL_INFO("[REGU], set capability = 0x%x successfully !!\n",
837 			rg->capability);
838 	return true;
839 }
840 
841 /*
842  * @ Function description
843  *	Query current regulation channel plan
844  *
845  * @ parameter
846  *	phl : struct phl_info_t *
847  *	type : enum rtw_regulation_query, different query type
848  * 	filter : struct rtw_chlist *, used to filter regulation channels
849  *	plan : struct rtw_regulation_chplan *, query result will be filled here
850  *		- result will be the intersection of regulation channel plan and
851  *		   the filter channels.
852  *
853  * @ return :
854  *	true : regulation query successfully, caller can check result
855  *		by input parameter *plan.
856  *	false : regulation query fail
857  *
858  */
rtw_phl_regulation_query_chplan(void * phl,enum rtw_regulation_query type,struct rtw_chlist * filter,struct rtw_regulation_chplan * plan)859 bool rtw_phl_regulation_query_chplan(
860 			void *phl, enum rtw_regulation_query type,
861 			struct rtw_chlist *filter,
862 			struct rtw_regulation_chplan *plan)
863 {
864 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
865 	struct rtw_regulation *rg = NULL;
866 	enum rtw_regulation_status status = REGULATION_FAILURE;
867 	void *d = NULL;
868 
869 	if (!phl || !plan)
870 		return false;
871 
872 	if (!_regulation_valid(phl))
873 		return false;
874 
875 	rg = &phl_info->regulation;
876 	d = phl_to_drvpriv(phl_info);
877 
878 	_os_spinlock(d, &rg->lock, _bh, NULL);
879 	switch (type) {
880 	case REGULQ_CHPLAN_FULL:
881 	case REGULQ_CHPLAN_2GHZ:
882 	case REGULQ_CHPLAN_5GHZ_ALL:
883 	case REGULQ_CHPLAN_5GHZ_BAND1:
884 	case REGULQ_CHPLAN_5GHZ_BAND2:
885 	case REGULQ_CHPLAN_5GHZ_BAND3:
886 	case REGULQ_CHPLAN_5GHZ_BAND4:
887 	case REGULQ_CHPLAN_6GHZ_UNII5:
888 	case REGULQ_CHPLAN_6GHZ_UNII6:
889 	case REGULQ_CHPLAN_6GHZ_UNII7:
890 	case REGULQ_CHPLAN_6GHZ_UNII8:
891 	case REGULQ_CHPLAN_6GHZ:
892 	case REGULQ_CHPLAN_6GHZ_PSC:
893 	case REGULQ_CHPLAN_2GHZ_5GHZ:
894 		status = _get_chnlplan(rg, type, plan);
895 		if (filter)
896 			_filter_chnlplan(d, plan, filter);
897 		break;
898 	default:
899 		break;
900 	}
901 	_os_spinunlock(d, &rg->lock, _bh, NULL);
902 
903 	if (status == REGULATION_SUCCESS) {
904 		/* _display_chplan(plan); */
905 		return true;
906 	}
907 	else
908 		return false;
909 }
910 
911 /*
912  * @ Function description
913  *	Query specific regulation channel plan by domain code
914  *
915  * @ parameter
916  * 	domain : domain code
917  *	plan : struct rtw_regulation_chplan *, query result will be filled here
918  *
919  * @ return :
920  *	true : regulation query successfully, caller can check result
921  *		by input parameter *plan.
922  *	false : regulation query fail
923  *
924  */
rtw_phl_query_specific_chplan(void * phl,u8 domain,struct rtw_regulation_chplan * plan)925 bool rtw_phl_query_specific_chplan(void *phl, u8 domain,
926 			struct rtw_regulation_chplan *plan)
927 {
928 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
929 	const struct chdef_2ghz *chdef2 = NULL;
930 	const struct chdef_5ghz *chdef5 = NULL;
931 	struct rtw_regulation *rg = NULL;
932 	u8 did = MAX_RD_MAP_NUM;
933 	u8 idx2g = INVALID_CHDEF;
934 	u8 idx5g = INVALID_CHDEF;
935 	u16 i = 0, ch = 0, passive = 0, dfs = 0;
936 	u8 group = FREQ_GROUP_5GHZ_BAND1;
937 	u8 max_num = 0, ch_start = 0;
938 
939 	if (!plan)
940 		return false;
941 	plan->cnt = 0;
942 
943 	PHL_INFO("[REGU], query specific channel plan for domain : 0x%x!!\n",
944 			domain);
945 
946 	if (!rtw_phl_valid_regulation_domain(domain))
947 		return false;
948 
949 	/* find channel definition for 2 ghz & 5 ghz */
950 	did = _domain_index(domain);
951 	idx2g = rdmap[did].freq_2g.ch_idx;
952 	for (i = 0; i < MAX_CHDEF_2GHZ; i++) {
953 		if (idx2g == chdef2g[i].idx) {
954 			chdef2 = &chdef2g[i];
955 		}
956 	}
957 	idx5g = rdmap[did].freq_5g.ch_idx;
958 	for (i = 0; i < MAX_CHDEF_5GHZ; i++) {
959 		if (idx5g == chdef5g[i].idx) {
960 			chdef5 = &chdef5g[i];
961 		}
962 	}
963 
964 	/* when regulatory domain & capability is set, check regulatory capability setting first */
965 	if (_regulation_valid(phl)) {
966 		rg = &phl_info->regulation;
967 		if (!(rg->capability & CAPABILITY_2GHZ))
968 			chdef2 = NULL;
969 		if (!(rg->capability & CAPABILITY_5GHZ))
970 			chdef5 = NULL;
971 	}
972 
973 	/* 2ghz */
974 	if (chdef2) {
975 		ch = ((chdef2->support_ch[1] << 8) |
976 			(chdef2->support_ch[0]));
977 		passive = ((chdef2->passive[1] << 8) |
978 			(chdef2->passive[0]));
979 		_convert_ch2g(rg, &plan->cnt, plan->ch, ch, passive);
980 	}
981 
982 	/* 5ghz */
983 	if (chdef5) {
984 		for (i = 0; i < 4; i++) {
985 			group = (u8)(i + FREQ_GROUP_5GHZ_BAND1);
986 			_get_5ghz_ch_info(chdef5, group, &ch, &passive, &dfs,
987 						&max_num, &ch_start);
988 			_convert_ch5g((u8)(i + 1), rg, &plan->cnt, plan->ch,
989 				ch, passive, dfs, max_num, ch_start);
990 		}
991 	}
992 
993 	PHL_INFO("[REGU], query specific channel plan for domain : 0x%x, total channels : %d !!\n",
994 			domain, plan->cnt);
995 	_display_chplan(plan);
996 
997 	return true;
998 }
999 
1000 /*
1001  * @ Function description
1002  *	Query basic regulation info
1003  *
1004  * @ parameter
1005  * 	phl : struct phl_info_t *
1006  *	info : struct rtw_regulation_info *, query result will be filled here
1007  *
1008  * @ return :
1009  *	true : regulation query successfully, caller can check result
1010  *		by input parameter *info.
1011  *	false : regulation query fail
1012  *
1013  */
rtw_phl_query_regulation_info(void * phl,struct rtw_regulation_info * info)1014 bool rtw_phl_query_regulation_info(void *phl, struct rtw_regulation_info *info)
1015 {
1016 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1017 	struct rtw_regulation *rg = NULL;
1018 	void *d = NULL;
1019 
1020 	if (!phl || !info)
1021 		return false;
1022 
1023 	if (!_regulation_valid(phl))
1024 		return false;
1025 
1026 	rg = &phl_info->regulation;
1027 	d = phl_to_drvpriv(phl_info);
1028 
1029 	_os_spinlock(d, &rg->lock, _bh, NULL);
1030 
1031 	info->domain_code = (u8)rg->domain.code;
1032 	info->domain_reason = rg->domain.reason;
1033 	info->country[0] = rg->country[0];
1034 	info->country[1] = rg->country[1];
1035 	info->tpo = rg->tpo;
1036 	info->support_mode = rg->support_mode;
1037 	info->regulation_2g = rg->regulation_2g;
1038 	info->regulation_5g = rg->regulation_5g;
1039 	info->chplan_ver = REGULATION_CHPLAN_VERSION;
1040 	info->country_ver = REGULATION_COUNTRY_VERSION;
1041 	info->capability = rg->capability;
1042 
1043 	_os_spinunlock(d, &rg->lock, _bh, NULL);
1044 
1045 	return true;
1046 }
1047 
1048 /*
1049  * @ Function description
1050  *	Use the coutry code to query the corresponding
1051  *	domain code and properties
1052  *
1053  * @ parameter
1054  *	country : 2 bytes char
1055  *	country_chplan : pointer to structre of chplan's info
1056  *
1057  * @ return :
1058  *	true : successfully search the entry form cdmap
1059  *	false : country chplan query fail
1060  */
rtw_phl_query_country_chplan(char * country,struct rtw_regulation_country_chplan * country_chplan)1061 bool rtw_phl_query_country_chplan(char *country,
1062 	struct rtw_regulation_country_chplan* country_chplan)
1063 {
1064 	u32 i = 0;
1065 
1066 	PHL_INFO("[REGU], query country code = \"%c%c\"\n",
1067 			country[0], country[1]);
1068 
1069 	for (i = 0; i < MAX_COUNTRY_NUM; i++) {
1070 		if (cdmap[i].char2[0] == country[0] &&
1071 			cdmap[i].char2[1] == country[1] ) {
1072 			country_chplan->domain_code = cdmap[i].domain_code;
1073 			if(cdmap[i].support & BIT(0))
1074 				country_chplan->support_mode |= (SUPPORT_11B | SUPPORT_11G | SUPPORT_11N);
1075 			if(cdmap[i].support & BIT(1))
1076 				country_chplan->support_mode |= (SUPPORT_11A);
1077 			if(cdmap[i].support & BIT(2))
1078 				country_chplan->support_mode |= (SUPPORT_11AC);
1079 			if(cdmap[i].support & BIT(3))
1080 				country_chplan->support_mode |= (SUPPORT_11AX);
1081 			country_chplan->tpo = cdmap[i].tpo;
1082 			return true;
1083 		}
1084 	}
1085 	return false;
1086 }
1087 
rtw_phl_regulation_valid(void * phl)1088 bool rtw_phl_regulation_valid(void *phl)
1089 {
1090 	return _regulation_valid(phl);
1091 }
1092 
1093 /*
1094  * @ Function description
1095  *	Used to check if channel is in regulation channel list
1096  *
1097  * @ parameter
1098  * 	phl : struct phl_info_t *
1099  *	channel : channel to be checked
1100  *	reject : enum ch_property, ex: (CH_PASSIVE | CH_DFS)
1101  *
1102  * @ return :
1103  *	true : channel is in regulation list and not rejected
1104  *	false : query regulation failed or channel is not in regulation
1105  *		channel list
1106  */
rtw_phl_regulation_valid_channel(void * phl,enum band_type band,u16 channel,u8 reject)1107 bool rtw_phl_regulation_valid_channel(void *phl, enum band_type band,
1108 						u16 channel, u8 reject)
1109 {
1110 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1111 	struct rtw_regulation *rg = NULL;
1112 	struct rtw_regulation_channel ch = {0};
1113 	bool valid = false;
1114 	void *d = NULL;
1115 	u8 rej_property = reject;
1116 
1117 	if (!_regulation_valid(phl))
1118 		return false;
1119 
1120 	rg = &phl_info->regulation;
1121 	d = phl_to_drvpriv(phl_info);
1122 
1123 	_os_spinlock(d, &rg->lock, _bh, NULL);
1124 	if (_query_channel(rg, band, channel, &ch)) {
1125 		if (!(rg->capability & CAPABILITY_DFS))
1126 			rej_property |= CAPABILITY_DFS;
1127 		if (_valid_property(ch.property, rej_property))
1128 			valid = true;
1129 	}
1130 	_os_spinunlock(d, &rg->lock, _bh, NULL);
1131 
1132 	return valid;
1133 }
1134 
1135 /*
1136  * @ Function description
1137  *	Used to check if channel is a regulation DFS channel
1138  *
1139  * @ parameter
1140  * 	phl : struct phl_info_t *
1141  *	channel : channel to be checked
1142  *	dfs : result will be filled here
1143  *
1144  * @ return :
1145  *	true : regulation query successfully, caller can check result
1146  *		by input parameter *dfs.
1147  *	false : regulation fail
1148  *
1149  */
rtw_phl_regulation_dfs_channel(void * phl,enum band_type band,u16 channel,bool * dfs)1150 bool rtw_phl_regulation_dfs_channel(void *phl, enum band_type band,
1151 						u16 channel, bool *dfs)
1152 {
1153 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1154 	struct rtw_regulation *rg = NULL;
1155 	struct rtw_regulation_channel ch = {0};
1156 	void *d = NULL;
1157 	bool query = false;
1158 
1159 	if (!_regulation_valid(phl) || !dfs)
1160 		return false;
1161 
1162 	rg = &phl_info->regulation;
1163 	d = phl_to_drvpriv(phl_info);
1164 
1165 	_os_spinlock(d, &rg->lock, _bh, NULL);
1166 	if (_query_channel(rg, band, channel, &ch)) {
1167 		query = true;
1168 		if (ch.property & CH_DFS)
1169 			*dfs = true;
1170 		else
1171 			*dfs = false;
1172 	}
1173 	_os_spinunlock(d, &rg->lock, _bh, NULL);
1174 
1175 	return query;
1176 }
1177 
1178 /*
1179  * @ Function description
1180  *	Query regulation channel
1181  *
1182  * @ parameter
1183  * 	phl : struct phl_info_t *
1184  *	channel : channel for query
1185  *	ch : query result will be filled here
1186  *
1187  * @ return :
1188  *	true : regulation query successfully, caller can check result
1189  *		by input parameter *ch.
1190  *	false : regulation query fail
1191  *
1192  */
rtw_phl_regulation_query_ch(void * phl,enum band_type band,u8 channel,struct rtw_regulation_channel * ch)1193 bool rtw_phl_regulation_query_ch(void *phl, enum band_type band, u8 channel,
1194 					struct rtw_regulation_channel *ch)
1195 {
1196 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1197 	struct rtw_regulation *rg = NULL;
1198 	void *d = NULL;
1199 	bool query = false;
1200 
1201 	if (!_regulation_valid(phl) || !ch)
1202 		return false;
1203 
1204 	rg = &phl_info->regulation;
1205 	d = phl_to_drvpriv(phl_info);
1206 
1207 	_os_spinlock(d, &rg->lock, _bh, NULL);
1208 	if (_query_channel(rg, band, channel, ch))
1209 		query = true;
1210 	_os_spinunlock(d, &rg->lock, _bh, NULL);
1211 
1212 	return query;
1213 }
1214 
rtw_phl_get_domain_regulation_2g(u8 domain)1215 u8 rtw_phl_get_domain_regulation_2g(u8 domain)
1216 {
1217 	u8 did = MAX_RD_MAP_NUM;
1218 
1219 	if (!rtw_phl_valid_regulation_domain(domain))
1220 		return REGULATION_MAX;
1221 
1222 	did = _domain_index(domain);
1223 	if (did >= MAX_RD_MAP_NUM)
1224 		return REGULATION_MAX;
1225 
1226 	return rdmap[did].freq_2g.regulation;
1227 }
1228 
rtw_phl_get_domain_regulation_5g(u8 domain)1229 u8 rtw_phl_get_domain_regulation_5g(u8 domain)
1230 {
1231 	u8 did = MAX_RD_MAP_NUM;
1232 
1233 	if (!rtw_phl_valid_regulation_domain(domain))
1234 		return REGULATION_MAX;
1235 
1236 	did = _domain_index(domain);
1237 	if (did >= MAX_RD_MAP_NUM)
1238 		return REGULATION_MAX;
1239 
1240 	return rdmap[did].freq_5g.regulation;
1241 }
1242 
1243