xref: /wlan-dirver/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.h (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
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_get_opclass_from_channe() - Print channels in op class.
88  * @country: Country code.
89  * @opclass: 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_type: 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_for_cur_hwmode() - Get details about the opclasses for
133  * the current hwmode.
134  * @pdev: Pointer to pdev.
135  * @reg_ap_cap: Pointer to reg_ap_cap.
136  * @n_opclasses: Pointer to number of opclasses.
137  * @max_supp_op_class: Maximum number of operating classes supported.
138  * @global_tbl_lookup: Whether to lookup global op class table.
139  * @max_chwidth: Max channel width supported by cur hwmode
140  * @is_80p80_supp: Bool to indicate if 80p80 is supported
141  * @in_6g_pwr_type: 6g power type which decides 6G channel list lookup.
142  *
143  * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE.
144  */
145 QDF_STATUS
146 reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev *pdev,
147 			       struct regdmn_ap_cap_opclass_t *reg_ap_cap,
148 			       uint8_t *n_opclasses,
149 			       uint8_t max_supp_op_class,
150 			       bool global_tbl_lookup,
151 			       enum phy_ch_width max_chwidth,
152 			       bool is_80p80_supp,
153 			       enum supported_6g_pwr_types in_6g_pwr_mode);
154 /**
155  * reg_is_5ghz_op_class() - Check if the input opclass is a 5GHz opclass.
156  * @country: Country code.
157  * @op_class: Operating class.
158  *
159  * Return: Return true if input the opclass is a 5GHz opclass,
160  * else return false.
161  */
162 bool reg_is_5ghz_op_class(const uint8_t *country, uint8_t op_class);
163 
164 /**
165  * reg_is_2ghz_op_class() - Check if the input opclass is a 2.4GHz opclass.
166  * @country: Country code.
167  * @op_class: Operating class.
168  *
169  * Return: Return true if input the opclass is a 2.4GHz opclass,
170  * else return false.
171  */
172 bool reg_is_2ghz_op_class(const uint8_t *country, uint8_t op_class);
173 
174 #ifdef CONFIG_CHAN_FREQ_API
175 
176 /**
177  * reg_freq_width_to_chan_op_class() - convert frequency to oper class,
178  *                                     channel
179  * @pdev: pdev pointer
180  * @freq: channel frequency in mhz
181  * @chan_width: channel width
182  * @global_tbl_lookup: whether to lookup global op class tbl
183  * @behav_limit: behavior limit
184  * @op_class: operating class
185  * @chan_num: channel number
186  *
187  * Return: Void.
188  */
189 void reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
190 				     qdf_freq_t freq,
191 				     uint16_t chan_width,
192 				     bool global_tbl_lookup,
193 				     uint16_t behav_limit,
194 				     uint8_t *op_class,
195 				     uint8_t *chan_num);
196 
197 /**
198  * reg_freq_width_to_chan_op_class_auto() - convert frequency to operating
199  * class,channel after fixing up the global_tbl_lookup and behav_limit
200  * for 6G frequencies.
201  * @pdev: pdev pointer
202  * @freq: channel frequency in mhz
203  * @chan_width: channel width
204  * @global_tbl_lookup: whether to lookup global op class tbl
205  * @behav_limit: behavior limit
206  * @op_class: operating class
207  * @chan_num: channel number
208  *
209  * Return: Void.
210  */
211 void reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev,
212 					  qdf_freq_t freq,
213 					  uint16_t chan_width,
214 					  bool global_tbl_lookup,
215 					  uint16_t behav_limit,
216 					  uint8_t *op_class,
217 					  uint8_t *chan_num);
218 
219 /**
220  * reg_freq_to_chan_op_class() - convert frequency to oper class,
221  *                                   channel
222  * @pdev: pdev pointer
223  * @freq: channel frequency in mhz
224  * @global_tbl_lookup: whether to lookup global op class tbl
225  * @behav_limit: behavior limit
226  * @op_class: operating class
227  * @chan_num: channel number
228  *
229  * Return: Void.
230  */
231 void reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
232 			       qdf_freq_t freq,
233 			       bool global_tbl_lookup,
234 			       uint16_t behav_limit,
235 			       uint8_t *op_class,
236 			       uint8_t *chan_num);
237 
238 /**
239  * reg_is_freq_in_country_opclass() - check for frequency in (tbl, oper class)
240  *
241  * @pdev: pdev pointer
242  * @country: country from country IE
243  * @op_class: operating class
244  * @chan_freq: channel frequency in mhz
245  *
246  * Return: bool
247  */
248 bool reg_is_freq_in_country_opclass(struct wlan_objmgr_pdev *pdev,
249 				    const uint8_t country[3],
250 				    uint8_t op_class,
251 				    qdf_freq_t chan_freq);
252 #endif
253 
254 /**
255  * reg_get_op_class_width() - get oper class width
256  *
257  * @pdev: pdev pointer
258  * @global_tbl_lookup: whether to lookup global op class tbl
259  * @op_class: operating class
260  * Return: uint16
261  */
262 uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
263 				uint8_t op_class,
264 				bool global_tbl_lookup);
265 
266 #ifdef HOST_OPCLASS_EXT
267 /**
268  * reg_country_chan_opclass_to_freq() - Convert channel number to frequency
269  * based on country code and op class
270  * @pdev: pdev object.
271  * @country: country code.
272  * @chan: IEEE Channel Number.
273  * @op_class: Opclass.
274  * @strict: flag to find channel from matched operating class code.
275  *
276  * Look up (channel, operating class) pair in country operating class tables
277  * and return the channel frequency.
278  * If not found and "strict" flag is false, try to get frequency (Mhz) by
279  * channel number only.
280  *
281  * Return: Channel center frequency else return 0.
282  */
283 qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
284 					    const uint8_t country[3],
285 					    uint8_t chan, uint8_t op_class,
286 					    bool strict);
287 #endif
288 
289 /**
290  * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency
291  * @chan: IEEE Channel Number.
292  * @op_class: Opclass.
293  * @global_tbl_lookup: Global table lookup.
294  *
295  * Return: Channel center frequency else return 0.
296  */
297 uint16_t reg_chan_opclass_to_freq(uint8_t chan,
298 				  uint8_t op_class,
299 				  bool global_tbl_lookup);
300 
301 /**
302  * reg_chan_opclass_to_freq_auto() - Convert channel number and opclass to
303  * frequency after fixing global_tbl_lookup
304  * @chan: IEEE Channel Number.
305  * @op_class: Opclass.
306  * @global_tbl_lookup: Global table lookup.
307  *
308  * Return: Channel center frequency else return 0.
309  */
310 qdf_freq_t reg_chan_opclass_to_freq_auto(uint8_t chan, uint8_t op_class,
311 					 bool global_tbl_lookup);
312 
313 #else
314 
315 static inline uint16_t reg_dmn_get_chanwidth_from_opclass(
316 		uint8_t *country, uint8_t channel, uint8_t opclass)
317 {
318 	return 0;
319 }
320 
321 static inline uint16_t reg_dmn_set_curr_opclasses(
322 		uint8_t num_classes, uint8_t *class)
323 {
324 	return 0;
325 }
326 
327 static inline uint16_t reg_dmn_get_curr_opclasses(
328 		uint8_t *num_classes, uint8_t *class)
329 {
330 	return 0;
331 }
332 
333 static inline uint16_t reg_dmn_get_opclass_from_channel(
334 		uint8_t *country, uint8_t channel, uint8_t offset)
335 {
336 	return 0;
337 }
338 
339 static inline
340 uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country,
341 					    qdf_freq_t freq,
342 					    uint16_t ch_width,
343 					    uint16_t behav_limit)
344 {
345 	return 0;
346 }
347 
348 static inline
349 uint8_t reg_get_band_cap_from_op_class(const uint8_t *country,
350 				       uint8_t num_of_opclass,
351 				       const uint8_t *opclass)
352 {
353 	return 0;
354 }
355 
356 static inline void reg_dmn_print_channels_in_opclass(uint8_t *country,
357 						     uint8_t op_class)
358 {
359 }
360 
361 static inline
362 QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
363 				   struct regdmn_ap_cap_opclass_t *reg_ap_cap,
364 				   uint8_t *n_opclasses,
365 				   uint8_t max_supp_op_class,
366 				   bool global_tbl_lookup,
367 				   enum supported_6g_pwr_types in_6g_pwr_mode)
368 {
369 	return QDF_STATUS_E_FAILURE;
370 }
371 
372 static inline
373 bool reg_is_5ghz_op_class(const uint8_t *country, uint8_t op_class)
374 {
375 	return false;
376 }
377 
378 static inline
379 bool reg_is_2ghz_op_class(const uint8_t *country, uint8_t op_class)
380 {
381 	return false;
382 }
383 
384 static inline QDF_STATUS
385 reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev *pdev,
386 			       struct regdmn_ap_cap_opclass_t *reg_ap_cap,
387 			       uint8_t *n_opclasses,
388 			       uint8_t max_supp_op_class,
389 			       bool global_tbl_lookup,
390 			       enum phy_ch_width max_ch_width,
391 			       bool is_80p80_supp,
392 			       enum supported_6g_pwr_types in_6g_pwr_mode)
393 {
394 	return QDF_STATUS_E_FAILURE;
395 }
396 
397 #ifdef CONFIG_CHAN_FREQ_API
398 
399 static inline void
400 reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
401 				qdf_freq_t freq,
402 				uint16_t chan_width,
403 				bool global_tbl_lookup,
404 				uint16_t behav_limit,
405 				uint8_t *op_class,
406 				uint8_t *chan_num)
407 {
408 }
409 
410 static inline void
411 reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev,
412 				     qdf_freq_t freq,
413 				     uint16_t chan_width,
414 				     bool global_tbl_lookup,
415 				     uint16_t behav_limit,
416 				     uint8_t *op_class,
417 				     uint8_t *chan_num)
418 {
419 }
420 
421 static inline void
422 reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev,
423 			  qdf_freq_t freq,
424 			  bool global_tbl_lookup,
425 			  uint16_t behav_limit,
426 			  uint8_t *op_class,
427 			  uint8_t *chan_num)
428 {
429 }
430 
431 static inline bool
432 reg_is_freq_in_country_opclass(struct wlan_objmgr_pdev *pdev,
433 			       const uint8_t country[3],
434 			       uint8_t op_class,
435 			       uint16_t chan_freq)
436 {
437 	return false;
438 }
439 
440 #endif
441 
442 static inline uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
443 					      uint8_t op_class,
444 					      bool global_tbl_lookup)
445 {
446 	return 0;
447 }
448 
449 #ifdef HOST_OPCLASS_EXT
450 static inline
451 qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
452 					    const uint8_t country[3],
453 					    uint8_t chan, uint8_t op_class,
454 					    bool strict)
455 {
456 	return 0;
457 }
458 #endif
459 
460 static inline uint16_t
461 reg_chan_opclass_to_freq(uint8_t chan,
462 			 uint8_t op_class,
463 			 bool global_tbl_lookup)
464 {
465 	return 0;
466 }
467 
468 static inline qdf_freq_t
469 reg_chan_opclass_to_freq_auto(uint8_t chan, uint8_t op_class,
470 			      bool global_tbl_lookup)
471 {
472 	return 0;
473 }
474 #endif
475 
476 /**
477  * reg_dmn_get_chanwidth_from_opclass_auto()- Get channel width for the
478  * given channel and opclass. If not found then search it in the global
479  * op class.
480  * @country - Country
481  * @channel - Channel for which channel spacing is required
482  * @opclass - Opclass to search from.
483  *
484  * Return: valid channel spacing if found. If not found then
485  * return 0.
486  */
487 uint16_t reg_dmn_get_chanwidth_from_opclass_auto(uint8_t *country,
488 						 uint8_t channel,
489 						 uint8_t opclass);
490 
491 #ifdef CONFIG_AFC_SUPPORT
492 
493 /**
494  * reg_dmn_get_6g_opclasses_and_channels()- Get the following from the
495  * operating class table for 6Ghz band: number of operating classes, list of
496  * opclasses, list channel sizes, list of channel lists.
497  * @p_frange_lst: Pointer to frequency range list (AFC)
498  * @pdev: Pointer to pdev.
499  * @num_opclasses: Pointer to number of operating classes. This is the number
500  * of elements in the list array arguments
501  * @opclas_lst: Pointer to pointer to memory of list of opclasses
502  * @chansize_lst: Pointer to pointer to memory of list of channel sizes
503  * @channel_lists: Array of pointers to pointer to memory of list of channels
504  *
505  * Return: QDF_STATUS
506  * NOTE:- All memory allocations done by this function should be freed by the
507  *        caller. The caller may use the function
508  *        'reg_dmn_free_6g_opclasses_and_channels' to free the allocations.
509  */
510 
511 QDF_STATUS reg_dmn_get_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
512 						 struct wlan_afc_frange_list *p_frange_lst,
513 						 uint8_t *num_opclasses,
514 						 uint8_t **opclass_lst,
515 						 uint8_t **chansize_lst,
516 						 uint8_t **channel_lists[]);
517 
518 /**
519  * reg_dmn_free_6g_opclasses_and_channels()- Free the memory allocated by
520  * the pointers and arrays indicated by the arguments.
521  * @pdev: Pointer to pdev.
522  * @num_opclasses: Number of operating classes. This is the number of
523  * elements in the 'channel_lists' array.
524  * @opclas_lst: Pointer to memory of list of opclasses
525  * @chansize_lst: Pointer to memory of list of channel sizes
526  * @channel_lists: Array of pointers to memory of list of channels
527  *
528  * Return: void
529  */
530 void reg_dmn_free_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
531 					    uint8_t num_opclasses,
532 					    uint8_t *opclass_lst,
533 					    uint8_t *chansize_lst,
534 					    uint8_t *channel_lists[]);
535 #endif
536 #endif
537