1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
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: reg_opclass.h
22 * This file provides prototypes of the regulatory opclass functions
23 */
24
25 #ifndef __REG_OPCLASS_H__
26 #define __REG_OPCLASS_H__
27
28 #ifdef CONFIG_AFC_SUPPORT
29 #include <wlan_reg_afc.h>
30 #endif
31
32 #define OPCLS_132 132
33
34 #ifdef HOST_OPCLASS
35 /**
36 * reg_dmn_get_chanwidth_from_opclass() - Get channel width from opclass.
37 * @country: Country code
38 * @channel: Channel number
39 * @opclass: Operating class
40 *
41 * Return: Channel width
42 */
43 uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel,
44 uint8_t opclass);
45
46 /**
47 * reg_dmn_get_opclass_from_channel() - Get operating class from channel.
48 * @country: Country code.
49 * @channel: Channel number.
50 * @offset: Operating class offset.
51 *
52 * Return: Error code.
53 */
54 uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel,
55 uint8_t offset);
56
57 /**
58 * reg_dmn_get_opclass_from_freq_width() - Get operating class from frequency
59 * @country: Country code.
60 * @freq: Channel center frequency.
61 * @ch_width: Channel width.
62 * @behav_limit: Behaviour limit.
63 *
64 * Return: Error code.
65 */
66 uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country,
67 qdf_freq_t freq,
68 uint16_t ch_width,
69 uint16_t behav_limit);
70
71 /**
72 * reg_get_band_cap_from_op_class() - Return band capability bitmap
73 * @country: Pointer to Country code.
74 * @num_of_opclass: Number of Operating class.
75 * @opclass: Pointer to opclass.
76 *
77 * Return supported band bitmap based on the input operating class list
78 * provided.
79 *
80 * Return: Return supported band capability
81 */
82 uint8_t reg_get_band_cap_from_op_class(const uint8_t *country,
83 uint8_t num_of_opclass,
84 const uint8_t *opclass);
85
86 /**
87 * reg_dmn_print_channels_in_opclass() - Print channels in op class.
88 * @country: Country code.
89 * @op_class: opclass.
90 *
91 * Return: Void.
92 */
93 void reg_dmn_print_channels_in_opclass(uint8_t *country, uint8_t op_class);
94
95 /**
96 * reg_dmn_set_curr_opclasses() - Set current operating class
97 * @num_classes: Number of classes
98 * @class: Pointer to operating class.
99 *
100 * Return: Error code.
101 */
102 uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class);
103
104 /**
105 * reg_dmn_get_curr_opclasses() - Get current supported operating classes.
106 * @num_classes: Number of classes.
107 * @class: Pointer to operating class.
108 *
109 * Return: Error code.
110 */
111 uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class);
112
113 /**
114 * reg_get_opclass_details() - Get details about the current opclass table.
115 * @pdev: Pointer to pdev.
116 * @reg_ap_cap: Pointer to reg_ap_cap.
117 * @n_opclasses: Pointer to number of opclasses.
118 * @max_supp_op_class: Maximum number of operating classes supported.
119 * @global_tbl_lookup: Whether to lookup global op class table.
120 * @in_6g_pwr_mode: 6g power type which decides 6G channel list lookup.
121 *
122 * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE.
123 */
124 QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
125 struct regdmn_ap_cap_opclass_t *reg_ap_cap,
126 uint8_t *n_opclasses,
127 uint8_t max_supp_op_class,
128 bool global_tbl_lookup,
129 enum supported_6g_pwr_types in_6g_pwr_mode);
130
131 /**
132 * reg_get_opclass_from_map() - Get opclass from map.
133 * @map: Pointer to pointer to regdmn_ap_cap_opclass_t.
134 * @is_global_op_table_needed: Whether to lookup global op class table.
135 *
136 * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE.
137 */
138 QDF_STATUS reg_get_opclass_from_map(const struct reg_dmn_op_class_map_t **map,
139 bool is_global_op_table_needed);
140
141 /**
142 * reg_get_opclass_for_cur_hwmode() - Get details about the opclasses for
143 * the current hwmode.
144 * @pdev: Pointer to pdev.
145 * @reg_ap_cap: Pointer to reg_ap_cap.
146 * @n_opclasses: Pointer to number of opclasses.
147 * @max_supp_op_class: Maximum number of operating classes supported.
148 * @global_tbl_lookup: Whether to lookup global op class table.
149 * @max_chwidth: Max channel width supported by cur hwmode
150 * @is_80p80_supp: Bool to indicate if 80p80 is supported
151 * @in_6g_pwr_mode: 6g power type which decides 6G channel list lookup.
152 *
153 * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE.
154 */
155 QDF_STATUS
156 reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev *pdev,
157 struct regdmn_ap_cap_opclass_t *reg_ap_cap,
158 uint8_t *n_opclasses,
159 uint8_t max_supp_op_class,
160 bool global_tbl_lookup,
161 enum phy_ch_width max_chwidth,
162 bool is_80p80_supp,
163 enum supported_6g_pwr_types in_6g_pwr_mode);
164
165 /**
166 * reg_is_5ghz_op_class() - Check if the input opclass is a 5GHz opclass.
167 * @country: Country code.
168 * @op_class: Operating class.
169 *
170 * Return: Return true if input the opclass is a 5GHz opclass,
171 * else return false.
172 */
173 bool reg_is_5ghz_op_class(const uint8_t *country, uint8_t op_class);
174
175 /**
176 * reg_is_2ghz_op_class() - Check if the input opclass is a 2.4GHz opclass.
177 * @country: Country code.
178 * @op_class: Operating class.
179 *
180 * Return: Return true if input the opclass is a 2.4GHz opclass,
181 * else return false.
182 */
183 bool reg_is_2ghz_op_class(const uint8_t *country, uint8_t op_class);
184
185 #ifdef CONFIG_CHAN_FREQ_API
186
187 /**
188 * reg_freq_width_to_chan_op_class() - convert frequency to oper class,
189 * channel
190 * @pdev: pdev pointer
191 * @freq: channel frequency in mhz
192 * @chan_width: channel width
193 * @global_tbl_lookup: whether to lookup global op class tbl
194 * @behav_limit: behavior limit
195 * @op_class: operating class
196 * @chan_num: channel number
197 *
198 * Return: Void.
199 */
200 void reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
201 qdf_freq_t freq,
202 uint16_t chan_width,
203 bool global_tbl_lookup,
204 uint16_t behav_limit,
205 uint8_t *op_class,
206 uint8_t *chan_num);
207
208 /**
209 * reg_freq_width_to_chan_op_class_auto() - convert frequency to operating
210 * class,channel after fixing up the global_tbl_lookup and behav_limit
211 * for 6G frequencies.
212 * @pdev: pdev pointer
213 * @freq: channel frequency in mhz
214 * @chan_width: channel width
215 * @global_tbl_lookup: whether to lookup global op class tbl
216 * @behav_limit: behavior limit
217 * @op_class: operating class
218 * @chan_num: channel number
219 *
220 * Return: Void.
221 */
222 void reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev,
223 qdf_freq_t freq,
224 uint16_t chan_width,
225 bool global_tbl_lookup,
226 uint16_t behav_limit,
227 uint8_t *op_class,
228 uint8_t *chan_num);
229
230 /**
231 * reg_freq_to_chan_op_class() - convert frequency to oper class,
232 * channel
233 * @pdev: pdev pointer
234 * @freq: channel frequency in mhz
235 * @global_tbl_lookup: whether to lookup global op class tbl
236 * @behav_limit: behavior limit
237 * @op_class: operating class
238 * @chan_num: channel number
239 *
240 * Return: Void.
241 */
242 void reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
243 qdf_freq_t freq,
244 bool global_tbl_lookup,
245 uint16_t behav_limit,
246 uint8_t *op_class,
247 uint8_t *chan_num);
248
249 /**
250 * reg_is_freq_in_country_opclass() - check for frequency in (tbl, oper class)
251 *
252 * @pdev: pdev pointer
253 * @country: country from country IE
254 * @op_class: operating class
255 * @chan_freq: channel frequency in mhz
256 *
257 * Return: bool
258 */
259 bool reg_is_freq_in_country_opclass(struct wlan_objmgr_pdev *pdev,
260 const uint8_t country[3],
261 uint8_t op_class,
262 qdf_freq_t chan_freq);
263 #endif
264
265 /**
266 * reg_get_op_class_width() - get oper class width
267 *
268 * @pdev: pdev pointer
269 * @global_tbl_lookup: whether to lookup global op class tbl
270 * @op_class: operating class
271 * Return: uint16
272 */
273 uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
274 uint8_t op_class,
275 bool global_tbl_lookup);
276
277 #ifdef HOST_OPCLASS_EXT
278 /**
279 * reg_country_chan_opclass_to_freq() - Convert channel number to frequency
280 * based on country code and op class
281 * @pdev: pdev object.
282 * @country: country code.
283 * @chan: IEEE Channel Number.
284 * @op_class: Opclass.
285 * @strict: flag to find channel from matched operating class code.
286 *
287 * Look up (channel, operating class) pair in country operating class tables
288 * and return the channel frequency.
289 * If not found and "strict" flag is false, try to get frequency (Mhz) by
290 * channel number only.
291 *
292 * Return: Channel center frequency else return 0.
293 */
294 qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
295 const uint8_t country[3],
296 uint8_t chan, uint8_t op_class,
297 bool strict);
298 #endif
299
300 /**
301 * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency
302 * @chan: IEEE Channel Number.
303 * @op_class: Opclass.
304 * @global_tbl_lookup: Global table lookup.
305 *
306 * Return: Channel center frequency else return 0.
307 */
308 uint16_t reg_chan_opclass_to_freq(uint8_t chan,
309 uint8_t op_class,
310 bool global_tbl_lookup);
311
312 /**
313 * reg_chan_opclass_to_freq_auto() - Convert channel number and opclass to
314 * frequency after fixing global_tbl_lookup
315 * @chan: IEEE Channel Number.
316 * @op_class: Opclass.
317 * @global_tbl_lookup: Global table lookup.
318 *
319 * Return: Channel center frequency else return 0.
320 */
321 qdf_freq_t reg_chan_opclass_to_freq_auto(uint8_t chan, uint8_t op_class,
322 bool global_tbl_lookup);
323
324 #else
325
reg_dmn_get_chanwidth_from_opclass(uint8_t * country,uint8_t channel,uint8_t opclass)326 static inline uint16_t reg_dmn_get_chanwidth_from_opclass(
327 uint8_t *country, uint8_t channel, uint8_t opclass)
328 {
329 return 0;
330 }
331
reg_dmn_set_curr_opclasses(uint8_t num_classes,uint8_t * class)332 static inline uint16_t reg_dmn_set_curr_opclasses(
333 uint8_t num_classes, uint8_t *class)
334 {
335 return 0;
336 }
337
reg_dmn_get_curr_opclasses(uint8_t * num_classes,uint8_t * class)338 static inline uint16_t reg_dmn_get_curr_opclasses(
339 uint8_t *num_classes, uint8_t *class)
340 {
341 return 0;
342 }
343
reg_dmn_get_opclass_from_channel(uint8_t * country,uint8_t channel,uint8_t offset)344 static inline uint16_t reg_dmn_get_opclass_from_channel(
345 uint8_t *country, uint8_t channel, uint8_t offset)
346 {
347 return 0;
348 }
349
350 static inline
reg_dmn_get_opclass_from_freq_width(uint8_t * country,qdf_freq_t freq,uint16_t ch_width,uint16_t behav_limit)351 uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country,
352 qdf_freq_t freq,
353 uint16_t ch_width,
354 uint16_t behav_limit)
355 {
356 return 0;
357 }
358
359 static inline
reg_get_band_cap_from_op_class(const uint8_t * country,uint8_t num_of_opclass,const uint8_t * opclass)360 uint8_t reg_get_band_cap_from_op_class(const uint8_t *country,
361 uint8_t num_of_opclass,
362 const uint8_t *opclass)
363 {
364 return 0;
365 }
366
reg_dmn_print_channels_in_opclass(uint8_t * country,uint8_t op_class)367 static inline void reg_dmn_print_channels_in_opclass(uint8_t *country,
368 uint8_t op_class)
369 {
370 }
371
372 static inline
reg_get_opclass_details(struct wlan_objmgr_pdev * pdev,struct regdmn_ap_cap_opclass_t * reg_ap_cap,uint8_t * n_opclasses,uint8_t max_supp_op_class,bool global_tbl_lookup,enum supported_6g_pwr_types in_6g_pwr_mode)373 QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
374 struct regdmn_ap_cap_opclass_t *reg_ap_cap,
375 uint8_t *n_opclasses,
376 uint8_t max_supp_op_class,
377 bool global_tbl_lookup,
378 enum supported_6g_pwr_types in_6g_pwr_mode)
379 {
380 return QDF_STATUS_E_FAILURE;
381 }
382
383 static inline
384 QDF_STATUS reg_get_opclass_from_map(const struct reg_dmn_op_class_map_t **map,
385 bool is_global_op_table_needed);
386 {
387 return QDF_STATUS_E_FAILURE;
388 }
389
390 static inline
reg_is_5ghz_op_class(const uint8_t * country,uint8_t op_class)391 bool reg_is_5ghz_op_class(const uint8_t *country, uint8_t op_class)
392 {
393 return false;
394 }
395
396 static inline
reg_is_2ghz_op_class(const uint8_t * country,uint8_t op_class)397 bool reg_is_2ghz_op_class(const uint8_t *country, uint8_t op_class)
398 {
399 return false;
400 }
401
402 static inline QDF_STATUS
reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev * pdev,struct regdmn_ap_cap_opclass_t * reg_ap_cap,uint8_t * n_opclasses,uint8_t max_supp_op_class,bool global_tbl_lookup,enum phy_ch_width max_ch_width,bool is_80p80_supp,enum supported_6g_pwr_types in_6g_pwr_mode)403 reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev *pdev,
404 struct regdmn_ap_cap_opclass_t *reg_ap_cap,
405 uint8_t *n_opclasses,
406 uint8_t max_supp_op_class,
407 bool global_tbl_lookup,
408 enum phy_ch_width max_ch_width,
409 bool is_80p80_supp,
410 enum supported_6g_pwr_types in_6g_pwr_mode)
411 {
412 return QDF_STATUS_E_FAILURE;
413 }
414
415 #ifdef CONFIG_CHAN_FREQ_API
416
417 static inline void
reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev * pdev,qdf_freq_t freq,uint16_t chan_width,bool global_tbl_lookup,uint16_t behav_limit,uint8_t * op_class,uint8_t * chan_num)418 reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
419 qdf_freq_t freq,
420 uint16_t chan_width,
421 bool global_tbl_lookup,
422 uint16_t behav_limit,
423 uint8_t *op_class,
424 uint8_t *chan_num)
425 {
426 }
427
428 static inline void
reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev * pdev,qdf_freq_t freq,uint16_t chan_width,bool global_tbl_lookup,uint16_t behav_limit,uint8_t * op_class,uint8_t * chan_num)429 reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev,
430 qdf_freq_t freq,
431 uint16_t chan_width,
432 bool global_tbl_lookup,
433 uint16_t behav_limit,
434 uint8_t *op_class,
435 uint8_t *chan_num)
436 {
437 }
438
439 static inline void
reg_freq_to_chan_op_class(struct wlan_objmgr_pdev * pdev,qdf_freq_t freq,bool global_tbl_lookup,uint16_t behav_limit,uint8_t * op_class,uint8_t * chan_num)440 reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
441 qdf_freq_t freq,
442 bool global_tbl_lookup,
443 uint16_t behav_limit,
444 uint8_t *op_class,
445 uint8_t *chan_num)
446 {
447 }
448
449 static inline bool
reg_is_freq_in_country_opclass(struct wlan_objmgr_pdev * pdev,const uint8_t country[3],uint8_t op_class,uint16_t chan_freq)450 reg_is_freq_in_country_opclass(struct wlan_objmgr_pdev *pdev,
451 const uint8_t country[3],
452 uint8_t op_class,
453 uint16_t chan_freq)
454 {
455 return false;
456 }
457
458 #endif
459
reg_get_op_class_width(struct wlan_objmgr_pdev * pdev,uint8_t op_class,bool global_tbl_lookup)460 static inline uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
461 uint8_t op_class,
462 bool global_tbl_lookup)
463 {
464 return 0;
465 }
466
467 #ifdef HOST_OPCLASS_EXT
468 static inline
reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev * pdev,const uint8_t country[3],uint8_t chan,uint8_t op_class,bool strict)469 qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
470 const uint8_t country[3],
471 uint8_t chan, uint8_t op_class,
472 bool strict)
473 {
474 return 0;
475 }
476 #endif
477
478 static inline uint16_t
reg_chan_opclass_to_freq(uint8_t chan,uint8_t op_class,bool global_tbl_lookup)479 reg_chan_opclass_to_freq(uint8_t chan,
480 uint8_t op_class,
481 bool global_tbl_lookup)
482 {
483 return 0;
484 }
485
486 static inline qdf_freq_t
reg_chan_opclass_to_freq_auto(uint8_t chan,uint8_t op_class,bool global_tbl_lookup)487 reg_chan_opclass_to_freq_auto(uint8_t chan, uint8_t op_class,
488 bool global_tbl_lookup)
489 {
490 return 0;
491 }
492 #endif
493
494 /**
495 * reg_dmn_get_chanwidth_from_opclass_auto() - Get channel width for the
496 * given channel and opclass. If not found then search it in the global
497 * op class.
498 * @country: Country
499 * @channel: Channel for which channel spacing is required
500 * @opclass: Opclass to search from.
501 *
502 * Return: valid channel spacing if found. If not found then
503 * return 0.
504 */
505 uint16_t reg_dmn_get_chanwidth_from_opclass_auto(uint8_t *country,
506 uint8_t channel,
507 uint8_t opclass);
508
509 #ifdef CONFIG_AFC_SUPPORT
510
511 /**
512 * reg_dmn_get_6g_opclasses_and_channels() - Get the following from the
513 * operating class table for 6Ghz band: number of operating classes, list of
514 * opclasses, list channel sizes, list of channel lists.
515 * @p_frange_lst: Pointer to frequency range list (AFC)
516 * @pdev: Pointer to pdev.
517 * @num_opclasses: Pointer to number of operating classes. This is the number
518 * of elements in the list array arguments
519 * @opclass_lst: Pointer to pointer to memory of list of opclasses
520 * @chansize_lst: Pointer to pointer to memory of list of channel sizes
521 * @channel_lists: Array of pointers to pointer to memory of list of channels
522 *
523 * Return: QDF_STATUS
524 * NOTE:- All memory allocations done by this function should be freed by the
525 * caller. The caller may use the function
526 * 'reg_dmn_free_6g_opclasses_and_channels' to free the allocations.
527 */
528
529 QDF_STATUS reg_dmn_get_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
530 struct wlan_afc_frange_list *p_frange_lst,
531 uint8_t *num_opclasses,
532 uint8_t **opclass_lst,
533 uint8_t **chansize_lst,
534 uint8_t **channel_lists[]);
535
536 /**
537 * reg_dmn_free_6g_opclasses_and_channels() - Free the memory allocated by
538 * the pointers and arrays indicated by the arguments.
539 * @pdev: Pointer to pdev.
540 * @num_opclasses: Number of operating classes. This is the number of
541 * elements in the 'channel_lists' array.
542 * @opclass_lst: Pointer to memory of list of opclasses
543 * @chansize_lst: Pointer to memory of list of channel sizes
544 * @channel_lists: Array of pointers to memory of list of channels
545 *
546 * Return: void
547 */
548 void reg_dmn_free_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
549 uint8_t num_opclasses,
550 uint8_t *opclass_lst,
551 uint8_t *chansize_lst,
552 uint8_t *channel_lists[]);
553 #endif
554
555 #ifndef CONFIG_REG_CLIENT
556 /**
557 * reg_enable_disable_opclass_chans() - Disable or enable the input 20 MHz
558 * operating channels in the radio's current channel list
559 * @pdev: Pointer to pdev
560 * @is_disable: Boolean to disable or enable the channels
561 * @opclass: Operating class. Only 20MHz opclasses are supported.
562 * @ieee_chan_list: Pointer to ieee_chan_list
563 * @chan_list_size: Size of ieee_chan_list
564 * @global_tbl_lookup: Whether to lookup global op class table
565 *
566 * Return - Return QDF_STATUS
567 */
568 QDF_STATUS reg_enable_disable_opclass_chans(struct wlan_objmgr_pdev *pdev,
569 bool is_disable, uint8_t opclass,
570 uint8_t *ieee_chan_list,
571 uint8_t chan_list_size,
572 bool global_tbl_lookup);
573 #endif
574 #endif
575