1 /** @file mlan_cfp.c
2  *
3  *  @brief  This file provides WLAN client mode channel, frequency and power related code
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 /*************************************************************
12 Change Log:
13     04/16/2009: initial version
14 ************************************************************/
15 #include <mlan_api.h>
16 
17 /* Additional WMSDK header files */
18 #include <wmerrno.h>
19 #include <osa.h>
20 
21 /* Always keep this include at the end of all include files */
22 #include <mlan_remap_mem_operations.h>
23 /********************************************************
24     Local Variables
25 ********************************************************/
26 
27 /** 100mW */
28 #define WLAN_TX_PWR_DEFAULT 20
29 /** 100mW */
30 #define WLAN_TX_PWR_US_DEFAULT 20
31 /** 100mW */
32 #define WLAN_TX_PWR_JP_BG_DEFAULT 20
33 /** 200mW */
34 #define WLAN_TX_PWR_JP_A_DEFAULT 23
35 /** 100mW */
36 #define WLAN_TX_PWR_FR_100MW 20
37 /** 10mW */
38 #define WLAN_TX_PWR_FR_10MW 10
39 /** 100mW */
40 #define WLAN_TX_PWR_EMEA_DEFAULT 20
41 /** 200mW */
42 #define WLAN_TX_PWR_200MW 23
43 /** 2000mW */
44 #define WLAN_TX_PWR_CN_2000MW 33
45 #if defined(RW610)
46 /** 22dBm */
47 #define WLAN_TX_PWR_WW_DEFAULT 22
48 #else
49 /** 8dBm */
50 #define WLAN_TX_PWR_WW_DEFAULT 8
51 #endif
52 /** Region code mapping */
53 typedef struct _country_code_mapping
54 {
55     /** Region */
56     t_u8 country_code[COUNTRY_CODE_LEN];
57     /** Code for B/G CFP table */
58     t_u8 cfp_code_bg;
59     /** Code for A CFP table */
60     t_u8 cfp_code_a;
61 } country_code_mapping_t;
62 
63 static const country_code_mapping_t country_code_mapping[] = {
64     {"WW", 0x00, 0x00}, /* World Wide Safe */
65     {"US", 0x10, 0x10}, /* US FCC */
66     {"CA", 0x10, 0x20}, /* IC Canada */
67     {"SG", 0x10, 0x10}, /* Singapore */
68     {"EU", 0x30, 0x30}, /* ETSI */
69     {"AU", 0x30, 0x30}, /* Australia */
70     {"KR", 0x30, 0x30}, /* Republic Of Korea */
71     {"FR", 0x32, 0x32}, /* France */
72     {"JP", 0xFF, 0x40}, /* Japan */
73     {"CN", 0x30, 0x50}, /* China */
74 };
75 
76 #define COUNTRY_ID_US 0
77 #define COUNTRY_ID_JP 1
78 #define COUNTRY_ID_CN 2
79 #define COUNTRY_ID_EU 3
80 
81 typedef struct _oper_bw_chan
82 {
83     /*non-global operating class*/
84     t_u8 oper_class;
85     /*global operating class*/
86     t_u8 global_oper_class;
87     /*bandwidth 0-20M 1-40M 2-80M 3-160M*/
88     t_u8 bandwidth;
89     /*channel list*/
90     t_u8 channel_list[13];
91 } oper_bw_chan;
92 
93 /** oper class table for US*/
94 static oper_bw_chan oper_bw_chan_us[] = {
95     /** non-Global oper class, global oper class, bandwidth, channel list*/
96     {1, 115, 0, {36, 40, 44, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
97     {2, 118, 0, {52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
98     {3, 124, 0, {149, 153, 157, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
99     {4, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 0}},
100     {5, 125, 0, {149, 153, 157, 161, 165, 0, 0, 0, 0, 0, 0, 0, 0}},
101     {12, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0}},
102     {22, 116, 1, {36, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
103     {23, 119, 1, {52, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
104     {24, 122, 1, {100, 108, 116, 124, 132, 140, 0, 0, 0, 0, 0, 0, 0}},
105     {25, 126, 1, {149, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
106     {26, 126, 1, {149, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
107     {27, 117, 1, {40, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
108     {28, 120, 1, {56, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
109     {29, 123, 1, {104, 112, 120, 128, 136, 144, 0, 0, 0, 0, 0, 0, 0}},
110     {30, 127, 1, {153, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
111     {31, 127, 1, {153, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
112     {32, 83, 1, {1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0}},
113     {33, 84, 1, {5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0}},
114 #if CONFIG_11AC
115     {128, 128, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
116     {129, 129, 3, {50, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
117     {130, 130, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
118 #endif
119 };
120 
121 /** oper class table for EU*/
122 static oper_bw_chan oper_bw_chan_eu[] = {
123     /** non-global oper class,global oper class, bandwidth, channel list*/
124     {1, 115, 0, {36, 40, 44, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
125     {2, 118, 0, {52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
126     {3, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0, 0}},
127     {4, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
128     {5, 116, 1, {36, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
129     {6, 119, 1, {52, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
130     {7, 122, 1, {100, 108, 116, 124, 132, 0, 0, 0, 0, 0, 0, 0, 0}},
131     {8, 117, 1, {40, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
132     {9, 120, 1, {56, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
133     {10, 123, 1, {104, 112, 120, 128, 136, 0, 0, 0, 0, 0, 0, 0, 0}},
134     {11, 83, 1, {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0}},
135     {12, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0}},
136     {17, 125, 0, {149, 153, 157, 161, 165, 169, 0, 0, 0, 0, 0, 0, 0}},
137 #if CONFIG_11AC
138     {128, 128, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
139     {129, 129, 3, {50, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
140     {130, 130, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
141 #endif
142 };
143 
144 /** oper class table for Japan*/
145 static oper_bw_chan oper_bw_chan_jp[] = {
146     /** non-Global oper class,global oper class, bandwidth, channel list*/
147     {1, 115, 0, {34, 38, 42, 46, 36, 40, 44, 48, 0, 0, 0, 0, 0}},
148     {30, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
149     {31, 82, 0, {14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
150     {32, 118, 0, {52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
151     {33, 118, 0, {52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
152     {34, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0, 0}},
153     {35, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0, 0}},
154     {36, 116, 1, {36, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
155     {37, 119, 1, {52, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
156     {38, 119, 1, {52, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
157     {39, 122, 1, {100, 108, 116, 124, 132, 0, 0, 0, 0, 0, 0, 0, 0}},
158     {40, 122, 1, {100, 108, 116, 124, 132, 0, 0, 0, 0, 0, 0, 0, 0}},
159     {41, 117, 1, {40, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
160     {42, 120, 1, {56, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
161     {43, 120, 1, {56, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
162     {44, 123, 1, {104, 112, 120, 128, 136, 0, 0, 0, 0, 0, 0, 0, 0}},
163     {45, 123, 1, {104, 112, 120, 128, 136, 0, 0, 0, 0, 0, 0, 0, 0}},
164     {56, 83, 1, {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0}},
165     {57, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0}},
166     {58, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0, 0}},
167 #if CONFIG_11AC
168     {128, 128, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
169     {129, 129, 3, {50, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
170     {130, 130, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
171 #endif
172 };
173 
174 /** oper class table for China*/
175 static oper_bw_chan oper_bw_chan_cn[] = {
176     /** non-Global oper class,global oper class, bandwidth, channel list*/
177     {1, 115, 0, {36, 40, 44, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
178     {2, 118, 0, {52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
179     {3, 125, 0, {149, 153, 157, 161, 165, 0, 0, 0, 0, 0, 0, 0, 0}},
180     {4, 116, 1, {36, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
181     {5, 119, 1, {52, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
182     {6, 126, 1, {149, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
183     {7, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
184     {8, 83, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0}},
185     {9, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0}},
186 #if CONFIG_11AC
187     {128, 128, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
188     {129, 129, 3, {50, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
189     {130, 130, 2, {42, 58, 106, 122, 138, 155, 0, 0, 0, 0, 0, 0, 0}},
190 #endif
191 };
192 
193 /** Country code for ETSI */
194 static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = {
195     "AL", "AD", "AT", "AU", "BY", "BE", "BA", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "MK",
196     "DE", "GR", "HU", "IS", "IE", "IT", "KR", "LV", "LI", "LT", "LU", "MT", "MD", "MC", "ME", "NL",
197     "NO", "PL", "RO", "RU", "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NZ"};
198 
199 /**
200  * The structure for Channel-Frequency-Power table
201  */
202 typedef struct _cfp_table
203 {
204     /** Region or Code */
205     t_u8 code;
206     /** Frequency/Power */
207     const chan_freq_power_t *cfp;
208     /** No of CFP flag */
209     int cfp_no;
210 } cfp_table_t;
211 
212 /* Format { Channel, Frequency (MHz), MaxTxPower } */
213 /** Band: 'B/G', Region: USA FCC/Canada IC */
214 static const chan_freq_power_t channel_freq_power_US_BG[] = {
215     {1, 2412, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {2, 2417, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
216     {3, 2422, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {4, 2427, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
217     {5, 2432, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {6, 2437, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
218     {7, 2442, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {8, 2447, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
219     {9, 2452, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {10, 2457, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
220     {11, 2462, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}};
221 
222 /** Band: 'B/G', Region: Europe ETSI/China */
223 static const chan_freq_power_t channel_freq_power_EU_BG[] = {
224     {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},  {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
225     {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},  {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
226     {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},  {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
227     {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},  {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
228     {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},  {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
229     {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}, {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
230     {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}};
231 
232 /** Band: 'B/G', Region: France */
233 static const chan_freq_power_t channel_freq_power_FR_BG[] = {
234     {1, 2412, WLAN_TX_PWR_FR_100MW, (bool)MFALSE}, {2, 2417, WLAN_TX_PWR_FR_100MW, (bool)MFALSE},
235     {3, 2422, WLAN_TX_PWR_FR_100MW, (bool)MFALSE}, {4, 2427, WLAN_TX_PWR_FR_100MW, (bool)MFALSE},
236     {5, 2432, WLAN_TX_PWR_FR_100MW, (bool)MFALSE}, {6, 2437, WLAN_TX_PWR_FR_100MW, (bool)MFALSE},
237     {7, 2442, WLAN_TX_PWR_FR_100MW, (bool)MFALSE}, {8, 2447, WLAN_TX_PWR_FR_100MW, (bool)MFALSE},
238     {9, 2452, WLAN_TX_PWR_FR_100MW, (bool)MFALSE}, {10, 2457, WLAN_TX_PWR_FR_10MW, (bool)MFALSE},
239     {11, 2462, WLAN_TX_PWR_FR_10MW, (bool)MFALSE}, {12, 2467, WLAN_TX_PWR_FR_10MW, (bool)MFALSE},
240     {13, 2472, WLAN_TX_PWR_FR_10MW, (bool)MFALSE}};
241 
242 /** Band: 'B/G', Region: Japan */
243 static const chan_freq_power_t channel_freq_power_JPN40_BG[] = {{14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE}};
244 
245 /** Band : 'B/G', Region: Special */
246 static const chan_freq_power_t channel_freq_power_SPECIAL_BG[] = {
247     {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},  {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
248     {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},  {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
249     {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},  {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
250     {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},  {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
251     {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},  {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
252     {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE}, {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE},
253     {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE}, {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, (bool)MFALSE}};
254 
255 /** Band : 'B/G', Region: World Wide Safe */
256 static chan_freq_power_t channel_freq_power_WW_BG[] = {
257     {1, 2412, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},  {2, 2417, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
258     {3, 2422, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},  {4, 2427, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
259     {5, 2432, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},  {6, 2437, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
260     {7, 2442, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},  {8, 2447, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
261     {9, 2452, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},  {10, 2457, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
262     {11, 2462, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {12, 2467, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
263     {13, 2472, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}};
264 
265 /** Band : 'B/G', Region: Custom - Place holder for Max 14 channels (As defined in WWSM)*/
266 static chan_freq_power_t channel_freq_power_Custom_BG[] = {
267     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
268     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
269     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
270     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
271     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
272     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
273     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}};
274 
275 static uint8_t rf_radio_modes_group[] = {
276     0,  /* set the radio in power down mode */
277     /*1,   sets the radio in 5GHz band, 2X2 mode(path A+B) */
278     3,  /* sets the radio in 5GHz band, 1X1 mode(path A) */
279    /* 4,   sets the radio in 5GHz band, 1X1 mode(path B) */
280    /* 9,   sets the radio in 2.4GHz band, 2X2 mode(path A+B) */
281     11, /* sets the radio in 2.4GHz band, 1X1 mode(path A) */
282    /* 14, sets the radio in 2.4GHz band, 1X1 mode(path B)*/
283 };
284 
285 /**
286  * The 2.4GHz CFP tables
287  */
288 static cfp_table_t cfp_table_BG[] = {
289     {
290         0x00, /* World Wide Safe */
291         (chan_freq_power_t *)channel_freq_power_WW_BG,
292         (int)(sizeof(channel_freq_power_WW_BG) / sizeof(chan_freq_power_t)),
293     },
294     {
295         0x10, /* US FCC */
296         (const chan_freq_power_t *)channel_freq_power_US_BG,
297         (int)(sizeof(channel_freq_power_US_BG) / sizeof(chan_freq_power_t)),
298     },
299     {
300         0x20, /* CANADA IC */
301         (const chan_freq_power_t *)channel_freq_power_US_BG,
302         (int)(sizeof(channel_freq_power_US_BG) / sizeof(chan_freq_power_t)),
303     },
304     {
305         0x30, /* EU */
306         (const chan_freq_power_t *)channel_freq_power_EU_BG,
307         (int)(sizeof(channel_freq_power_EU_BG) / sizeof(chan_freq_power_t)),
308     },
309     {
310         0x32, /* FRANCE */
311         (const chan_freq_power_t *)channel_freq_power_FR_BG,
312         (int)(sizeof(channel_freq_power_FR_BG) / sizeof(chan_freq_power_t)),
313     },
314     {
315         0x40, /* JAPAN */
316         (const chan_freq_power_t *)channel_freq_power_JPN40_BG,
317         (int)(sizeof(channel_freq_power_JPN40_BG) / sizeof(chan_freq_power_t)),
318     },
319     {
320         0x50, /* China */
321         (const chan_freq_power_t *)channel_freq_power_EU_BG,
322         (int)(sizeof(channel_freq_power_EU_BG) / sizeof(chan_freq_power_t)),
323     },
324     {
325         0xff, /* Special */
326         (const chan_freq_power_t *)channel_freq_power_SPECIAL_BG,
327         (int)(sizeof(channel_freq_power_SPECIAL_BG) / sizeof(chan_freq_power_t)),
328     },
329     /* Add new region here */
330 };
331 
332 /** Number of the CFP tables for 2.4GHz */
333 #define MLAN_CFP_TABLE_SIZE_BG (sizeof(cfp_table_BG) / sizeof(cfp_table_t))
334 
335 #if CONFIG_5GHz_SUPPORT
336 /* Format { Channel, Frequency (MHz), MaxTxPower, DFS } */
337 /** Band: 'A', Region: USA FCC, Spain, France */
338 static const chan_freq_power_t channel_freq_power_A[] = {
339     {36, 5180, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},  {40, 5200, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
340     {44, 5220, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},  {48, 5240, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
341     {52, 5260, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},   {56, 5280, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
342     {60, 5300, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},   {64, 5320, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
343     {100, 5500, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {104, 5520, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
344     {108, 5540, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {112, 5560, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
345     {116, 5580, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {120, 5600, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
346     {124, 5620, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {128, 5640, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
347     {132, 5660, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {136, 5680, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
348     {140, 5700, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {144, 5720, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
349     {149, 5745, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {153, 5765, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
350     {157, 5785, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {161, 5805, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
351     {165, 5825, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
352 #if CONFIG_UNII4_BAND_SUPPORT
353     {169, 5845, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {173, 5865, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
354     {177, 5885, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
355 #endif
356 };
357 
358 /** Band: 'A', Region: Canada IC */
359 static const chan_freq_power_t channel_freq_power_CAN_A[] = {
360     {36, 5180, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},  {40, 5200, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
361     {44, 5220, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},  {48, 5240, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
362     {52, 5260, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},   {56, 5280, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
363     {60, 5300, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},   {64, 5320, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
364     {100, 5500, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {104, 5520, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
365     {108, 5540, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {112, 5560, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
366     {116, 5580, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {132, 5660, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
367     {136, 5680, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},  {140, 5700, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
368 #if CONFIG_11AC
369      {144, 5720, WLAN_TX_PWR_US_DEFAULT, (bool)MTRUE},
370 #endif
371     {149, 5745, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {153, 5765, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
372     {157, 5785, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}, {161, 5805, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE},
373     {165, 5825, WLAN_TX_PWR_US_DEFAULT, (bool)MFALSE}};
374 
375 /** Band: 'A', Region: Europe ETSI */
376 static const chan_freq_power_t channel_freq_power_EU_A[] = {
377     {36, 5180, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}, {40, 5200, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
378     {44, 5220, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}, {48, 5240, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
379     {52, 5260, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},  {56, 5280, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
380     {60, 5300, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},  {64, 5320, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
381     {100, 5500, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {104, 5520, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
382     {108, 5540, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {112, 5560, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
383     {116, 5580, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {120, 5600, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
384     {124, 5620, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {128, 5640, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
385     {132, 5660, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {136, 5680, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE},
386     {140, 5700, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MTRUE}, {149, 5745, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
387     {153, 5765, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}, {157, 5785, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE},
388     {161, 5805, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}, {165, 5825, WLAN_TX_PWR_EMEA_DEFAULT, (bool)MFALSE}};
389 
390 /** Band: 'A', Region: Japan */
391 static const chan_freq_power_t channel_freq_power_JPN_A[] = {
392     {36, 5180, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MFALSE}, {40, 5200, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MFALSE},
393     {44, 5220, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MFALSE}, {48, 5240, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MFALSE},
394     {52, 5260, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},  {56, 5280, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
395     {60, 5300, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},  {64, 5320, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
396     {100, 5500, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {104, 5520, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
397     {108, 5540, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {112, 5560, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
398     {116, 5580, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {120, 5600, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
399     {124, 5620, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {128, 5640, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
400     {132, 5660, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {136, 5680, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE},
401     {140, 5700, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}, {144, 5720, WLAN_TX_PWR_JP_A_DEFAULT, (bool)MTRUE}};
402 
403 /** Band: 'A', Region: China */
404 static const chan_freq_power_t channel_freq_power_CN_A[] = {
405     {36, 5180, WLAN_TX_PWR_200MW, MFALSE}, {40, 5200, WLAN_TX_PWR_200MW, MFALSE},
406     {44, 5220, WLAN_TX_PWR_200MW, MFALSE}, {48, 5240, WLAN_TX_PWR_200MW, MFALSE},
407     {52, 5260, WLAN_TX_PWR_200MW, MTRUE},  {56, 5280, WLAN_TX_PWR_200MW, MTRUE},
408     {60, 5300, WLAN_TX_PWR_200MW, MTRUE},  {64, 5320, WLAN_TX_PWR_200MW, MTRUE},
409     {149, 5745, WLAN_TX_PWR_CN_2000MW, MFALSE}, {153, 5765, WLAN_TX_PWR_CN_2000MW, MFALSE},
410     {157, 5785, WLAN_TX_PWR_CN_2000MW, MFALSE}, {161, 5805, WLAN_TX_PWR_CN_2000MW, MFALSE},
411     {165, 5825, WLAN_TX_PWR_CN_2000MW, MFALSE}};
412 
413 
414 /** Band: 'A', Region: World Wide Safe */
415 static chan_freq_power_t channel_freq_power_WW_A[] = {
416     {36, 5180, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {40, 5200, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
417     {44, 5220, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {48, 5240, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
418     {52, 5260, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},  {56, 5280, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
419     {60, 5300, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},  {64, 5320, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
420     {100, 5500, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {104, 5520, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
421     {108, 5540, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {112, 5560, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
422     {116, 5580, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {120, 5600, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
423     {124, 5620, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {128, 5640, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
424     {132, 5660, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {136, 5680, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
425     {140, 5700, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE}, {144, 5720, WLAN_TX_PWR_WW_DEFAULT, (bool)MTRUE},
426     {149, 5745, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {153, 5765, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
427     {157, 5785, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {161, 5805, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
428     {165, 5825, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}};
429 
430 /** Band: 'A', Region: Custom - Place holder for Max 25 channels (As defined in WWSM) */
431 static chan_freq_power_t channel_freq_power_Custom_A[] = {
432     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
433     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
434     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
435     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
436     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
437     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
438     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
439     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
440     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
441     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
442     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
443     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
444     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
445 #if CONFIG_UNII4_BAND_SUPPORT
446     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE}, {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
447     {0, 0, WLAN_TX_PWR_WW_DEFAULT, (bool)MFALSE},
448 #endif
449 };
450 
451 /** Band: 'A', Code: 1, Low band (5150-5250 MHz) channels */
452 static const chan_freq_power_t channel_freq_power_low_band[] = {
453     {36, 5180, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
454     {40, 5200, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
455     {44, 5220, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
456     {48, 5240, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
457 };
458 
459 /** Band: 'A', Code: 2, Lower middle band (5250-5350 MHz) channels */
460 static const chan_freq_power_t channel_freq_power_lower_middle_band[] = {
461     {52, 5260, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
462     {56, 5280, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
463     {60, 5300, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
464     {64, 5320, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
465 };
466 
467 /** Band: 'A', Code: 3, Upper middle band (5470-5725 MHz) channels */
468 static const chan_freq_power_t channel_freq_power_upper_middle_band[] = {
469     {100, 5500, WLAN_TX_PWR_DEFAULT, (bool)MTRUE}, {104, 5520, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
470     {108, 5540, WLAN_TX_PWR_DEFAULT, (bool)MTRUE}, {112, 5560, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
471     {116, 5580, WLAN_TX_PWR_DEFAULT, (bool)MTRUE}, {120, 5600, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
472     {124, 5620, WLAN_TX_PWR_DEFAULT, (bool)MTRUE}, {128, 5640, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
473     {132, 5660, WLAN_TX_PWR_DEFAULT, (bool)MTRUE}, {136, 5680, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
474     {140, 5700, WLAN_TX_PWR_DEFAULT, (bool)MTRUE},
475 };
476 
477 /** Band: 'A', Code: 4, High band (5725-5850 MHz) channels */
478 static const chan_freq_power_t channel_freq_power_high_band[] = {{149, 5745, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
479                                                                  {153, 5765, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
480                                                                  {157, 5785, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
481                                                                  {161, 5805, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
482                                                                  {165, 5825, WLAN_TX_PWR_DEFAULT, (bool)MFALSE}};
483 
484 /** Band: 'A', Code: 5, Low band (5150-5250 MHz) and
485  * High band (5725-5850 MHz) channels */
486 static const chan_freq_power_t channel_freq_power_low_high_band[] = {
487     {36, 5180, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},  {40, 5200, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
488     {44, 5220, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},  {48, 5240, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
489     {149, 5745, WLAN_TX_PWR_DEFAULT, (bool)MFALSE}, {153, 5765, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
490     {157, 5785, WLAN_TX_PWR_DEFAULT, (bool)MFALSE}, {161, 5805, WLAN_TX_PWR_DEFAULT, (bool)MFALSE},
491     {165, 5825, WLAN_TX_PWR_DEFAULT, (bool)MFALSE}};
492 
493 /**
494  * The 5GHz CFP tables
495  */
496 static cfp_table_t cfp_table_A[] = {
497     {
498         0x00, /* World Wide Safe*/
499         (chan_freq_power_t *)channel_freq_power_WW_A,
500         (int)(sizeof(channel_freq_power_WW_A) / sizeof(chan_freq_power_t)),
501     },
502     {
503         0x10, /* US FCC */
504         (const chan_freq_power_t *)channel_freq_power_A,
505         (int)(sizeof(channel_freq_power_A) / sizeof(chan_freq_power_t)),
506     },
507     {
508         0x20, /* CANADA IC */
509         (const chan_freq_power_t *)channel_freq_power_CAN_A,
510         (int)(sizeof(channel_freq_power_CAN_A) / sizeof(chan_freq_power_t)),
511     },
512     {
513         0x30, /* EU */
514         (const chan_freq_power_t *)channel_freq_power_EU_A,
515         (int)(sizeof(channel_freq_power_EU_A) / sizeof(chan_freq_power_t)),
516     },
517     {
518         0x32, /* FRANCE */
519         (const chan_freq_power_t *)channel_freq_power_A,
520         (int)(sizeof(channel_freq_power_A) / sizeof(chan_freq_power_t)),
521     },
522     {
523         0x40, /* JAPAN */
524         (const chan_freq_power_t *)channel_freq_power_JPN_A,
525         (int)((int)(sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t))),
526     },
527     {
528         0x50, /* China */
529         (const chan_freq_power_t *)channel_freq_power_CN_A,
530         (int)(sizeof(channel_freq_power_CN_A) / sizeof(chan_freq_power_t)),
531     },
532     {
533         0xff, /* Special */
534         (const chan_freq_power_t *)channel_freq_power_JPN_A,
535         (int)(sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t)),
536     },
537     {0x1, /* Low band (5150-5250 MHz) channels */
538      (const chan_freq_power_t *)channel_freq_power_low_band,
539      (int)(sizeof(channel_freq_power_low_band) / sizeof(chan_freq_power_t))},
540     {0x2, /* Lower middle band (5250-5350 MHz) channels */
541      (const chan_freq_power_t *)channel_freq_power_lower_middle_band,
542      (int)(sizeof(channel_freq_power_lower_middle_band) / sizeof(chan_freq_power_t))},
543     {0x3, /* Upper middle band (5470-5725 MHz) channels */
544      (const chan_freq_power_t *)channel_freq_power_upper_middle_band,
545      (int)(sizeof(channel_freq_power_upper_middle_band) / sizeof(chan_freq_power_t))},
546     {0x4, /* High band (5725-5850 MHz) channels */
547      (const chan_freq_power_t *)channel_freq_power_high_band,
548      (int)(sizeof(channel_freq_power_high_band) / sizeof(chan_freq_power_t))},
549     {0x5, /* Low band (5150-5250 MHz) and High band (5725-5850 MHz) channels */
550      (const chan_freq_power_t *)channel_freq_power_low_high_band,
551      (int)(sizeof(channel_freq_power_low_high_band) / sizeof(chan_freq_power_t))},
552     /* Add new region here */
553 };
554 
555 /** Number of the CFP tables for 5GHz */
556 #define MLAN_CFP_TABLE_SIZE_A (sizeof(cfp_table_A) / sizeof(cfp_table_t))
557 
558 #endif /* CONFIG_5GHz_SUPPORT */
559 
560 /********************************************************
561     Global Variables
562 ********************************************************/
563 /**
564  * The table to keep region code
565  */
566 t_u16 region_code_index[MRVDRV_MAX_REGION_CODE] = {0x00, 0x10, 0x20, 0x30, 0x32, 0x40, 0x41, 0x50, 0xfe, 0xff};
567 
568 /** The table to keep CFP code for A */
569 t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A] = {0x1, 0x2, 0x3, 0x4, 0x5};
570 
571 /**
572  * The rates supported for ad-hoc B mode
573  */
574 t_u8 AdhocRates_B[B_SUPPORTED_RATES] = {0x82, 0x84, 0x8b, 0x96, 0};
575 
576 /**
577  * The rates supported for ad-hoc G mode
578  */
579 t_u8 AdhocRates_G[G_SUPPORTED_RATES] = {0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0};
580 
581 /**
582  * The rates supported for ad-hoc BG mode
583  */
584 t_u8 AdhocRates_BG[BG_SUPPORTED_RATES] = {0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0};
585 
586 /**
587  * The rates supported in A mode for ad-hoc
588  */
589 t_u8 AdhocRates_A[A_SUPPORTED_RATES] = {0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0};
590 
591 /**
592  * The rates supported in A mode (used for BAND_A)
593  */
594 t_u8 SupportedRates_A[A_SUPPORTED_RATES] = {0x0c, 0x12, 0x18, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0};
595 
596 #if CONFIG_11N
597 /**
598  * The rates supported by the card
599  */
600 static t_u16 WlanDataRates[WLAN_SUPPORTED_RATES_EXT] = {
601     0x02,  0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90, 0x0D,
602     0x1A,  0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3,
603     0x10E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604     0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
605 #else
606 /**
607  * The rates supported by the card
608  */
609 t_u16 WlanDataRates[WLAN_SUPPORTED_RATES] = {0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60,
610                                              0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
614 #endif
615 
616 /**
617  * The rates supported in B mode
618  */
619 t_u8 SupportedRates_B[B_SUPPORTED_RATES] = {0x02, 0x04, 0x0b, 0x16, 0};
620 
621 /**
622  * The rates supported in G mode (BAND_G, BAND_G|BAND_GN)
623  */
624 t_u8 SupportedRates_G[G_SUPPORTED_RATES] = {0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0};
625 
626 /**
627  * The rates supported in BG mode (BAND_B|BAND_G, BAND_B|BAND_G|BAND_GN)
628  */
629 t_u8 SupportedRates_BG[BG_SUPPORTED_RATES] = {0x02, 0x04, 0x0b, 0x0c, 0x12, 0x16, 0x18,
630                                               0x24, 0x30, 0x48, 0x60, 0x6c, 0};
631 
632 /**
633  * The rates supported in N mode
634  */
635 t_u8 SupportedRates_N[N_SUPPORTED_RATES] = {0x02, 0x04, 0};
636 
637 #if CONFIG_11AX
638 #define MCS_NUM_AX 12
639 /**
640  * for MCS0/MCS1/MCS3/MCS4 have 4 additional DCM=1 value
641  * note: the value in the table is 2 multiplier of the actual rate
642  */
643 static t_u16 ax_mcs_rate_nss1[12][MCS_NUM_AX + 4] = {
644     {0x90, 0x48, 0x120, 0x90, 0x1B0, 0x240, 0x120, 0x360, 0x1B0, 0x481, 0x511, 0x5A1, 0x6C1, 0x781, 0x871,
645      0x962}, /*SG 160M*/
646     {0x88, 0x44, 0x110, 0x88, 0x198, 0x220, 0x110, 0x330, 0x198, 0x440, 0x4C9, 0x551, 0x661, 0x716, 0x7F9,
647      0x8DC}, /*MG 160M*/
648     {0x7A, 0x3D, 0xF5, 0x7A, 0x16F, 0x1EA, 0xF5, 0x2DF, 0x16F, 0x3D4, 0x44E, 0x4C9, 0x5BE, 0x661, 0x72D,
649      0x7F9}, /*LG 160M*/
650     {0x48, 0x24, 0x90, 0x48, 0xD8, 0x120, 0x90, 0x1B0, 0xD8, 0x240, 0x288, 0x2D0, 0x360, 0x3C0, 0x438,
651      0x4B0}, /*SG 80M*/
652     {0x44, 0x22, 0x88, 0x44, 0xCC, 0x110, 0x88, 0x198, 0xCC, 0x220, 0x264, 0x2A8, 0x330, 0x38B, 0x3FC,
653      0x46E},                                                                                                  /*MG 80M*/
654     {0x3D, 0x1E, 0x7A, 0x3D, 0xB7, 0xF5, 0x7A, 0x16F, 0xB7, 0x1EA, 0x227, 0x264, 0x2DF, 0x330, 0x396, 0x3FC}, /*LG 80M*/
655     {0x22, 0x11, 0x44, 0x22, 0x67, 0x89, 0x44, 0xCE, 0x67, 0x113, 0x135, 0x158, 0x19D, 0x1CA, 0x204, 0x23D},  /*SG 40M*/
656     {0x20, 0x10, 0x41, 0x20, 0x61, 0x82, 0x41, 0xC3, 0x61, 0x104, 0x124, 0x145, 0x186, 0x1B1, 0x1E7, 0x21D},  /*MG 40M*/
657     {0x1D, 0xE, 0x3A, 0x1D, 0x57, 0x75, 0x3A, 0xAF, 0x57, 0xEA, 0x107, 0x124, 0x15F, 0x186, 0x1B6, 0x1E7},    /*LG 40M*/
658     {0x11, 0x8, 0x22, 0x11, 0x33, 0x44, 0x22, 0x67, 0x33, 0x89, 0x9A, 0xAC, 0xCE, 0xE5, 0x102, 0x11E},        /*SG 20M*/
659     {0x10, 0x8, 0x20, 0x10, 0x30, 0x41, 0x20, 0x61, 0x30, 0x82, 0x92, 0xA2, 0xC3, 0xD8, 0xF3, 0x10E},         /*MG 20M*/
660     {0xE, 0x7, 0x1D, 0xE, 0x2B, 0x3A, 0x1D, 0x57, 0x2B, 0x75, 0x83, 0x92, 0xAF, 0xC3, 0xDB, 0xF3}             /*LG 20M*/
661 };
662 #endif
663 
664 /**
665  *  @brief This function finds the CFP in
666  *  		cfp_table_BG/A based on region/code and band parameter.
667  *
668  *  @param pmadapter  A pointer to mlan_adapter structure
669  *  @param region     The region code
670  *  @param band       The band
671  *  @param cfp_no     A pointer to CFP number
672  *
673  *  @return           A pointer to CFP
674  */
wlan_get_region_cfp_table(pmlan_adapter pmadapter,t_u8 region,t_u16 band,int * cfp_no)675 const chan_freq_power_t *wlan_get_region_cfp_table(pmlan_adapter pmadapter, t_u8 region, t_u16 band, int *cfp_no)
676 {
677     t_u32 i;
678     t_u8 cfp_bg;
679 #if CONFIG_5GHz_SUPPORT
680     t_u8 cfp_a;
681 #endif /* CONFIG_5GHz_SUPPORT */
682 
683     ENTER();
684 
685     cfp_bg = region;
686 #if CONFIG_5GHz_SUPPORT
687     cfp_a = region;
688 #endif /* CONFIG_5GHz_SUPPORT */
689     if (region == 0U || region == 0x40)
690     {
691         /* Invalid region code or Japan case, use CFP code */
692         cfp_bg = pmadapter->cfp_code_bg;
693 #if CONFIG_5GHz_SUPPORT
694         cfp_a = pmadapter->cfp_code_a;
695 #endif /* CONFIG_5GHz_SUPPORT */
696     }
697 
698     if ((band & (BAND_B | BAND_G | BAND_GN | BAND_GAC)) != 0U)
699     {
700 #ifdef OTP_CHANINFO
701         /* Return the FW cfp table for requested region code, if available.
702          * If region is not forced and the requested region code is different,
703          * simply return the corresponding pre-defined table.
704          */
705         if ((pmadapter->otp_region != MNULL) && (pmadapter->cfp_otp_bg != MNULL))
706         {
707             if (pmadapter->otp_region->force_reg != (t_u16)MFALSE ||
708                 (cfp_bg == (t_u8)pmadapter->otp_region->region_code))
709             {
710                 *cfp_no = (int)pmadapter->tx_power_table_bg_rows;
711                 LEAVE();
712                 return pmadapter->cfp_otp_bg;
713             }
714         }
715 #endif
716         for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++)
717         {
718             PRINTM(MINFO, "cfp_table_BG[%d].code=%d\n", i, cfp_table_BG[i].code);
719             /* Check if region/code matches for BG bands */
720             if (cfp_table_BG[i].code == cfp_bg)
721             {
722                 /* Select by band */
723                 *cfp_no = cfp_table_BG[i].cfp_no;
724                 LEAVE();
725                 return cfp_table_BG[i].cfp;
726             }
727         }
728     }
729 
730 #if CONFIG_5GHz_SUPPORT
731     if ((band & (BAND_A | BAND_AN | BAND_AAC)) != 0U)
732     {
733 #ifdef OTP_CHANINFO
734         /* Return the FW cfp table for requested region code */
735         if ((pmadapter->otp_region != MNULL) && (pmadapter->cfp_otp_a != MNULL))
736         {
737             if (pmadapter->otp_region->force_reg != (t_u16)MFALSE ||
738                 (cfp_a == (t_u8)pmadapter->otp_region->region_code))
739             {
740                 *cfp_no = (int)pmadapter->tx_power_table_a_rows;
741                 LEAVE();
742                 return pmadapter->cfp_otp_a;
743             }
744         }
745 #endif
746         for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++)
747         {
748             PRINTM(MINFO, "cfp_table_A[%d].code=%d\n", i, cfp_table_A[i].code);
749             /* Check if region/code matches for A bands */
750             if (cfp_table_A[i].code == cfp_a)
751             {
752                 /* Select by band */
753                 *cfp_no = cfp_table_A[i].cfp_no;
754                 LEAVE();
755                 return cfp_table_A[i].cfp;
756             }
757         }
758     }
759 #endif /* CONFIG_5GHz_SUPPORT */
760 
761     if (region == 0U)
762     {
763 #if CONFIG_5GHz_SUPPORT
764         PRINTM(MERROR, "Error Band[0x%x] or code[BG:%#x, A:%#x]\n", band, cfp_bg, cfp_a);
765 
766 #else
767         PRINTM(MERROR, "Error Band[0x%x] or code[BG:%#x]\n", band, cfp_bg);
768 #endif /* CONFIG_5GHz_SUPPORT */
769     }
770     else
771     {
772         PRINTM(MERROR, "Error Band[0x%x] or region[%#x]\n", band, region);
773     }
774 
775     LEAVE();
776     return MNULL;
777 }
778 
779 /********************************************************
780     Global Functions
781 ********************************************************/
782 /**
783  *  @brief This function converts region string to integer code
784  *
785  *  @param pmadapter        A pointer to mlan_adapter structure
786  *  @param country_code     Country string
787  *  @param cfp_bg           Pointer to buffer
788  *  @param cfp_a            Pointer to buffer
789  *
790  *  @return                 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
791  */
wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter,t_u8 * country_code,t_u8 * cfp_bg,t_u8 * cfp_a)792 mlan_status wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter, t_u8 *country_code, t_u8 *cfp_bg, t_u8 *cfp_a)
793 {
794     t_u8 i;
795 
796     ENTER();
797 
798     /* Look for code in mapping table */
799     for (i = 0; i < NELEMENTS(country_code_mapping); i++)
800     {
801         if (!__memcmp(pmadapter, country_code_mapping[i].country_code, country_code, COUNTRY_CODE_LEN - 1))
802         {
803             *cfp_bg = country_code_mapping[i].cfp_code_bg;
804             *cfp_a  = country_code_mapping[i].cfp_code_a;
805             LEAVE();
806             return MLAN_STATUS_SUCCESS;
807         }
808     }
809 
810     LEAVE();
811     return MLAN_STATUS_FAILURE;
812 }
813 
814 #ifdef SD8801
815 /**
816  *  @brief Use index to get the data rate
817  *
818  *  @param pmadapter   A pointer to mlan_adapter structure
819  *  @param index       The index of data rate
820  *  @param ht_info     HT info
821  *
822  *  @return            Data rate or 0
823  */
wlan_index_to_data_rate(pmlan_adapter pmadapter,t_u8 index,t_u8 ht_info)824 t_u32 wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index, t_u8 ht_info)
825 {
826 #if CONFIG_11N
827 #ifdef STREAM_2X2
828 #define MCS_NUM_SUPP 16
829     t_u16 mcs_num_supp              = MCS_NUM_SUPP;
830     t_u16 mcs_rate[4][MCS_NUM_SUPP] = {
831         {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e, 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6,
832          0x21c}, /*LG 40M*/
833         {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c, 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c,
834          0x258},                                                                                             /*SG 40M */
835         {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82, 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104},   /*LG 20M */
836         {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120}}; /*SG 20M */
837 #else
838 #define MCS_NUM_SUPP 8
839     t_u16 mcs_num_supp              = MCS_NUM_SUPP;
840     t_u16 mcs_rate[4][MCS_NUM_SUPP] = {{0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e},  /*LG 40M*/
841                                        {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}, /*SG 40M */
842                                        {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82},   /*LG 20M */
843                                        {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}};  /*SG 20M */
844 #endif
845 #endif
846     t_u32 rate = 0;
847 
848     ENTER();
849 
850 #if CONFIG_11N
851 #ifdef STREAM_2X2
852     if (pmadapter->hw_dev_mcs_support == HT_STREAM_MODE_1X1)
853         mcs_num_supp = 8;
854 #endif
855     if (ht_info & MBIT(0))
856     {
857         if (index == MLAN_RATE_BITMAP_MCS0)
858         {
859             if (ht_info & MBIT(2))
860                 rate = 0x0D; /* MCS 32 SGI rate */
861             else
862                 rate = 0x0C; /* MCS 32 LGI rate */
863         }
864         else if (index < mcs_num_supp)
865         {
866             if (ht_info & MBIT(1))
867             {
868                 if (ht_info & MBIT(2))
869                     rate = mcs_rate[1][index]; /* SGI, 40M */
870                 else
871                     rate = mcs_rate[0][index]; /* LGI, 40M */
872             }
873             else
874             {
875                 if (ht_info & MBIT(2))
876                     rate = mcs_rate[3][index]; /* SGI, 20M */
877                 else
878                     rate = mcs_rate[2][index]; /* LGI, 20M */
879             }
880         }
881         else
882             rate = WlanDataRates[0];
883     }
884     else
885 #endif /* ENABLE_802_11N */
886     {
887 #if CONFIG_11N
888         /* 11n non HT rates */
889         if (index >= WLAN_SUPPORTED_RATES_EXT)
890         {
891 #else
892         if (index >= WLAN_SUPPORTED_RATES)
893         {
894 #endif
895             index = 0;
896         }
897         rate = WlanDataRates[index];
898     }
899     LEAVE();
900     return rate;
901 }
902 #else
903 /**
904  *  @brief Use index to get the data rate
905  *
906  *  @param pmadapter        A pointer to mlan_adapter structure
907  *  @param index            The index of data rate
908  *  @param tx_rate_info     Tx rate info
909  *  @param ext_rate_info    Extend tx rate info
910  *  @return                 Data rate or 0
911  */
912 t_u32 wlan_index_to_data_rate(pmlan_adapter pmadapter,
913                               t_u8 index,
914                               t_u8 tx_rate_info
915 #if CONFIG_11AX
916                               ,
917                               t_u8 ext_rate_info
918 #endif
919 )
920 {
921 #if CONFIG_11N
922 #ifdef STREAM_2X2
923 #define MCS_NUM_SUPP 16U
924     t_u16 mcs_rate[4][MCS_NUM_SUPP] = {
925         {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e, 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6,
926          0x21c}, /*LG 40M*/
927         {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c, 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c,
928          0x258},                                                                                             /*SG 40M */
929         {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82, 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104},   /*LG 20M */
930         {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120}}; /*SG 20M */
931 #else
932 #define MCS_NUM_SUPP 8U
933     t_u16 mcs_rate[4][MCS_NUM_SUPP] = {{0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e},  /*LG 40M*/
934                                        {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}, /*SG 40M */
935                                        {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82},   /*LG 20M */
936                                        {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}};  /*SG 20M */
937 #endif
938 #endif
939 
940 #if CONFIG_11AC
941 #define MCS_NUM_AC 10
942     /* NSS 1. note: the value in the table is 2 multiplier of the actual rate
943      *              in other words, it is in the unit of 500 Kbs
944      */
945     t_u16 ac_mcs_rate_nss1[8][MCS_NUM_AC] = {
946         {0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D, 0x492, 0x57C, 0x618},  /* LG 160M*/
947         {0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492, 0x514, 0x618, 0x6C6}, /* SG 160M*/
948         {0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F, 0x249, 0x2BE, 0x30C},    /* LG 80M */
949         {0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249, 0x28A, 0x30C, 0x363},   /* SG 80M */
950         {0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x144, 0x168},       /* LG 40M */
951         {0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E, 0x12C, 0x168, 0x190},      /* SG 40M */
952         {0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C, 0x00},           /* LG 20M */
953         {0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE, 0x00},           /* SG 20M */
954     };
955 #ifdef STREAM_2X2
956     /* NSS 2. note: the value in the table is 2 multiplier of the actual rate */
957     t_u16 ac_mcs_rate_nss2[8][MCS_NUM_AC] = {
958         {0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A, 0x924, 0xAF8, 0xC30},  /*LG 160M*/
959         {0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924, 0xA28, 0xC30, 0xD8B}, /*SG 160M*/
960 
961         {0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D, 0x492, 0x57C, 0x618},  /*LG 80M*/
962         {0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492, 0x514, 0x618, 0x6C6}, /*SG 80M*/
963         {0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6, 0x21C, 0x288, 0x2D0},    /*LG 40M*/
964         {0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C, 0x258, 0x2D0, 0x320},    /*SG 40M*/
965         {0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104, 0x138, 0x00},        /*LG 20M*/
966         {0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121, 0x15B, 0x00},       /*SG 20M*/
967     };
968 #endif
969 #endif /* CONFIG_11AC */
970 
971     t_u32 rate     = 0;
972 #if (CONFIG_11AC) || (CONFIG_11AX)
973     t_u8 mcs_index = 0;
974 #endif
975 #if CONFIG_11AX
976     t_u8 he_dcm    = 0;
977     t_u8 stbc      = 0;
978 #endif
979     t_u8 bw        = 0;
980     t_u8 gi        = 0;
981     ENTER();
982 
983 #if CONFIG_11AC
984     if ((tx_rate_info & 0x3U) == (t_u8)MLAN_RATE_FORMAT_VHT)
985     {
986         /* VHT rate */
987         mcs_index = index & 0xFU;
988 
989         if (mcs_index > 9U)
990         {
991             mcs_index = 9U;
992         }
993 
994         /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
995         bw = (tx_rate_info & 0xCU) >> 2U;
996         /* LGI: gi =0, SGI: gi = 1 */
997         gi = (tx_rate_info & 0x10U) >> 4U;
998 #ifdef STREAM_2X2
999         if ((index >> 4) == 1)
1000         {
1001             /* NSS = 2 */
1002             rate = ac_mcs_rate_nss2[2 * (3 - bw) + gi][mcs_index];
1003         }
1004         else
1005 #endif
1006         {
1007             /* NSS = 1 */
1008             rate = ac_mcs_rate_nss1[2U * (3U - bw) + gi][mcs_index];
1009         }
1010     }
1011     else
1012 #endif
1013 #if CONFIG_11AX
1014         if ((mlan_rate_format)(tx_rate_info & 0x3U) == MLAN_RATE_FORMAT_HE)
1015     {
1016         /* HE rate */
1017         mcs_index = index & 0xF;
1018         he_dcm    = ext_rate_info & MBIT(0);
1019         if (mcs_index > MCS_NUM_AX - 1)
1020             mcs_index = MCS_NUM_AX - 1;
1021         /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
1022         bw = (tx_rate_info & (MBIT(3) | MBIT(2))) >> 2;
1023         /* BIT7:BIT4 0:0= 0.8us,0:1= 0.8us, 1:0=1.6us, 1:1=3.2us or 0.8us */
1024         gi = (tx_rate_info & MBIT(4)) >> 4 | (tx_rate_info & MBIT(7)) >> 6;
1025         /* STBC: BIT5 in tx rate info */
1026         stbc = (tx_rate_info & MBIT(5)) >> 5;
1027         if (gi > 3)
1028         {
1029             PRINTM(MERROR, "Invalid gi value");
1030             return 0;
1031         }
1032         if ((gi == 3) && stbc && he_dcm)
1033         {
1034             gi     = 0;
1035             stbc   = 0;
1036             he_dcm = 0;
1037         }
1038         /* map to gi 0:0.8us,1:1.6us 2:3.2us*/
1039         if (gi > 0)
1040             gi = gi - 1;
1041         switch (mcs_index)
1042         {
1043             case 0:
1044             case 1:
1045                 rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi][mcs_index * 2 + he_dcm];
1046                 break;
1047             case 2:
1048                 rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi][mcs_index * 2];
1049                 break;
1050             case 3:
1051             case 4:
1052                 rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi][mcs_index * 2 - 1 + he_dcm];
1053                 break;
1054             default:
1055                 rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi][mcs_index + 4];
1056                 break;
1057         }
1058     }
1059     else
1060 #endif
1061 #if CONFIG_11N
1062         if ((tx_rate_info & 0x3U) == (t_u8)MLAN_RATE_FORMAT_HT)
1063     {
1064         /* HT rate */
1065         /* 20M: bw=0, 40M: bw=1 */
1066         bw = (tx_rate_info & 0xCU) >> 2U;
1067         /* LGI: gi =0, SGI: gi = 1 */
1068         gi = (tx_rate_info & 0x10U) >> 4U;
1069         if (index == MLAN_RATE_BITMAP_MCS0)
1070         {
1071             if (gi == 1U)
1072             {
1073                 rate = 0x0D; /* MCS 32 SGI rate */
1074             }
1075             else
1076             {
1077                 rate = 0x0C; /* MCS 32 LGI rate */
1078             }
1079         }
1080         else if (index < MCS_NUM_SUPP)
1081         {
1082             if (bw <= 1U)
1083             {
1084                 rate = mcs_rate[2U * (1U - bw) + gi][index];
1085             }
1086             else
1087             {
1088                 rate = WlanDataRates[0];
1089             }
1090         }
1091         else
1092         {
1093             rate = WlanDataRates[0];
1094         }
1095     }
1096     else
1097 #endif /* CONFIG_11N */
1098     {
1099 #if CONFIG_11N
1100         /* 11n non HT rates */
1101         if (index >= WLAN_SUPPORTED_RATES_EXT)
1102         {
1103 #else
1104         if (index >= WLAN_SUPPORTED_RATES)
1105         {
1106 #endif
1107             index = 0;
1108         }
1109         rate = WlanDataRates[index];
1110     }
1111     LEAVE();
1112     return rate;
1113 }
1114 #endif
1115 
1116 /**
1117  *  @brief Get active data rates
1118  *
1119  *  @param pmpriv           A pointer to mlan_private structure
1120  *  @param bss_mode         The specified BSS mode (Infra/IBSS)
1121  *  @param config_bands     The specified band configuration
1122  *  @param rates            The buf to return the active rates
1123  *
1124  *  @return                 The number of Rates
1125  */
1126 t_u32 wlan_get_active_data_rates(mlan_private *pmpriv,
1127                                  mlan_bss_mode bss_mode,
1128                                  t_u16 config_bands,
1129                                  WLAN_802_11_RATES rates)
1130 {
1131     t_u32 k;
1132 
1133     ENTER();
1134 
1135     if (pmpriv->media_connected != MTRUE)
1136     {
1137         k = wlan_get_supported_rates(pmpriv, bss_mode, config_bands, rates);
1138     }
1139     else
1140     {
1141         k = wlan_copy_rates(rates, 0, pmpriv->curr_bss_params.data_rates, (int)pmpriv->curr_bss_params.num_of_rates);
1142     }
1143 
1144     LEAVE();
1145     return k;
1146 }
1147 
1148 #ifdef STA_SUPPORT
1149 /**
1150  *  @brief This function search through all the regions cfp table to find the channel,
1151  *            if the channel is found then gets the MIN txpower of the channel
1152  *            present in all the regions.
1153  *
1154  *  @param pmpriv       A pointer to mlan_private structure
1155  *  @param channel      Channel number.
1156  *
1157  *  @return             The Tx power
1158  */
1159 t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u8 channel)
1160 {
1161     t_u8 i        = 0;
1162     t_u8 j        = 0;
1163     t_u8 tx_power = 0;
1164     t_u32 cfp_no;
1165     const chan_freq_power_t *cfp = MNULL;
1166 #if CONFIG_5GHz_SUPPORT
1167     const chan_freq_power_t *cfp_a = MNULL;
1168     t_u32 cfp_no_a;
1169 #endif /* CONFIG_5GHz_SUPPORT */
1170 
1171     ENTER();
1172 
1173     for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++)
1174     {
1175         /* Get CFP */
1176         cfp    = cfp_table_BG[i].cfp;
1177         cfp_no = (t_u32)cfp_table_BG[i].cfp_no;
1178         /* Find matching channel and get Tx power */
1179         for (j = 0; j < cfp_no; j++)
1180         {
1181             if ((cfp + j)->channel == channel)
1182             {
1183                 if (tx_power != 0U)
1184                 {
1185                     tx_power = MIN(tx_power, (t_u8)((cfp + j)->max_tx_power));
1186                 }
1187                 else
1188                 {
1189                     tx_power = (t_u8)(cfp + j)->max_tx_power;
1190                 }
1191                 break;
1192             }
1193         }
1194     }
1195 
1196 #if CONFIG_5GHz_SUPPORT
1197     for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++)
1198     {
1199         /* Get CFP */
1200         cfp_a    = cfp_table_A[i].cfp;
1201         cfp_no_a = (t_u32)cfp_table_A[i].cfp_no;
1202         for (j = 0; j < cfp_no_a; j++)
1203         {
1204             if ((cfp_a + j)->channel == channel)
1205             {
1206                 if (tx_power != 0U)
1207                 {
1208                     tx_power = MIN(tx_power, (t_u8)((cfp_a + j)->max_tx_power));
1209                 }
1210                 else
1211                 {
1212                     tx_power = (t_u8)((cfp_a + j)->max_tx_power);
1213                 }
1214                 break;
1215             }
1216         }
1217     }
1218 #endif /* CONFIG_5GHz_SUPPORT */
1219 
1220     LEAVE();
1221     return tx_power;
1222 }
1223 
1224 /**
1225  *  @brief Get the channel frequency power info for a specific channel
1226  *
1227  *  @param pmadapter            A pointer to mlan_adapter structure
1228  *  @param band                 It can be BAND_A, BAND_G or BAND_B
1229  *  @param channel              The channel to search for
1230  *  @param region_channel       A pointer to region_chan_t structure
1231  *
1232  *  @return                     A pointer to chan_freq_power_t structure or MNULL if not found.
1233  */
1234 
1235 const chan_freq_power_t *wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter,
1236                                                           t_u16 band,
1237                                                           t_u16 channel,
1238                                                           region_chan_t *region_channel)
1239 {
1240     region_chan_t *rc;
1241     const chan_freq_power_t *cfp = MNULL;
1242     t_u8 i, j;
1243 
1244     ENTER();
1245 
1246     j = 0;
1247     while (cfp == MNULL && (j < MAX_REGION_CHANNEL_NUM))
1248     {
1249         bool continue_loop = MFALSE;
1250         rc                 = &region_channel[j];
1251 
1252         if (rc->valid == (t_u8)MFALSE || rc->pcfp == MNULL)
1253         {
1254             j++;
1255             continue;
1256         }
1257         switch (rc->band)
1258         {
1259             case BAND_A:
1260                 switch (band)
1261                 {
1262                     case BAND_AN:
1263                     case BAND_A | BAND_AN:
1264                     case BAND_A | BAND_AN | BAND_AAC:
1265                     case BAND_A: /* Matching BAND_A */
1266                         break;
1267 
1268                     default:
1269                         j++;
1270                         continue_loop = MTRUE;
1271                         break;
1272                 }
1273                 break;
1274             case BAND_B:
1275             case BAND_G:
1276                 switch (band)
1277                 {
1278                     case BAND_GN:
1279                     case BAND_B | BAND_G | BAND_GN:
1280                     case BAND_G | BAND_GN:
1281                     case BAND_GN | BAND_GAC:
1282                     case BAND_B | BAND_G | BAND_GN | BAND_GAC:
1283                     case BAND_G | BAND_GN | BAND_GAC:
1284                     case BAND_B | BAND_G:
1285                     case BAND_B: /* Matching BAND_B/G */
1286                     case BAND_G:
1287                         break;
1288                     default:
1289                         j++;
1290                         continue_loop = MTRUE;
1291                         break;
1292                 }
1293                 break;
1294             default:
1295                 j++;
1296                 continue_loop = MTRUE;
1297                 break;
1298         }
1299         if (continue_loop == MTRUE)
1300         {
1301             continue;
1302         }
1303         if (channel == FIRST_VALID_CHANNEL)
1304         {
1305             cfp = &rc->pcfp[0];
1306         }
1307         else
1308         {
1309             for (i = 0; i < rc->num_cfp; i++)
1310             {
1311                 if (rc->pcfp[i].channel == channel)
1312                 {
1313                     cfp = &rc->pcfp[i];
1314                     break;
1315                 }
1316             }
1317         }
1318         j++;
1319     }
1320 
1321     if (cfp == MNULL && channel != 0U)
1322     {
1323         PRINTM(MERROR,
1324                "wlan_get_cfp_by_band_and_channel(): cannot find "
1325                "cfp by band %d & channel %d\n",
1326                band, channel);
1327     }
1328 
1329     LEAVE();
1330     return cfp;
1331 }
1332 
1333 /**
1334  *  @brief Find the channel frequency power info for a specific channel
1335  *
1336  *  @param pmadapter    A pointer to mlan_adapter structure
1337  *  @param band         It can be BAND_A, BAND_G or BAND_B
1338  *  @param channel      The channel to search for
1339  *
1340  *  @return             A pointer to chan_freq_power_t structure or MNULL if not found.
1341  */
1342 const chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter *pmadapter, t_u16 band, t_u16 channel)
1343 {
1344     const chan_freq_power_t *cfp = MNULL;
1345 
1346     ENTER();
1347 
1348     /* Any station(s) with 11D enabled */
1349     if (wlan_count_priv_cond(pmadapter, wlan_11d_is_enabled, wlan_is_station) > 0)
1350     {
1351         cfp = wlan_get_cfp_by_band_and_channel(pmadapter, band, channel, pmadapter->universal_channel);
1352     }
1353     else
1354     {
1355         cfp = wlan_get_cfp_by_band_and_channel(pmadapter, band, channel, pmadapter->region_channel);
1356     }
1357 
1358     LEAVE();
1359     return cfp;
1360 }
1361 
1362 /**
1363  *  @brief Find the channel frequency power info for a specific frequency
1364  *
1365  *  @param pmadapter    A pointer to mlan_adapter structure
1366  *  @param band         It can be BAND_A, BAND_G or BAND_B
1367  *  @param freq         The frequency to search for
1368  *
1369  *  @return         Pointer to chan_freq_power_t structure; MNULL if not found
1370  */
1371 const chan_freq_power_t *wlan_find_cfp_by_band_and_freq(mlan_adapter *pmadapter, t_u16 band, t_u32 freq)
1372 {
1373     const chan_freq_power_t *cfp = MNULL;
1374     region_chan_t *rc;
1375     t_u8 i, j;
1376 
1377     ENTER();
1378 
1379     j = 0;
1380     while (cfp == MNULL && (j < MAX_REGION_CHANNEL_NUM))
1381     {
1382         bool continue_loop = MFALSE;
1383         rc                 = &pmadapter->region_channel[j];
1384 
1385         /* Any station(s) with 11D enabled */
1386         if (wlan_count_priv_cond(pmadapter, wlan_11d_is_enabled, wlan_is_station) > 0)
1387         {
1388             rc = &pmadapter->universal_channel[j];
1389         }
1390 
1391         if (rc->valid == 0U || rc->pcfp == MNULL)
1392         {
1393             j++;
1394             continue;
1395         }
1396         switch (rc->band)
1397         {
1398             case BAND_A:
1399                 switch (band)
1400                 {
1401                     case BAND_AN:
1402                     case BAND_A | BAND_AN:
1403                     case BAND_A | BAND_AN | BAND_AAC:
1404                     case BAND_A: /* Matching BAND_A */
1405                         break;
1406                     default:
1407                         j++;
1408                         continue_loop = MTRUE;
1409                         break;
1410                 }
1411                 break;
1412             case BAND_B:
1413             case BAND_G:
1414                 switch (band)
1415                 {
1416                     case BAND_GN:
1417                     case BAND_B | BAND_G | BAND_GN:
1418                     case BAND_G | BAND_GN:
1419                     case BAND_GN | BAND_GAC:
1420                     case BAND_B | BAND_G | BAND_GN | BAND_GAC:
1421                     case BAND_G | BAND_GN | BAND_GAC:
1422                     case BAND_B | BAND_G:
1423                     case BAND_B:
1424                     case BAND_G:
1425                         break;
1426                     default:
1427                         j++;
1428                         continue_loop = MTRUE;
1429                         break;
1430                 }
1431                 break;
1432             default:
1433                 j++;
1434                 continue_loop = MTRUE;
1435                 break;
1436         }
1437         if (continue_loop == MTRUE)
1438         {
1439             continue;
1440         }
1441         for (i = 0; i < rc->num_cfp; i++)
1442         {
1443             if (rc->pcfp[i].freq == freq)
1444             {
1445                 cfp = &rc->pcfp[i];
1446                 break;
1447             }
1448         }
1449         j++;
1450     }
1451 
1452     if (cfp == MNULL && freq != 0U)
1453     {
1454         PRINTM(MERROR,
1455                "wlan_find_cfp_by_band_and_freq(): cannot find cfp by "
1456                "band %d & freq %d\n",
1457                band, freq);
1458     }
1459 
1460     LEAVE();
1461     return cfp;
1462 }
1463 #endif /* STA_SUPPORT */
1464 
1465 /**
1466  *  @brief Check if Rate Auto
1467  *
1468  *  @param pmpriv               A pointer to mlan_private structure
1469  *
1470  *  @return                     MTRUE or MFALSE
1471  */
1472 bool wlan_is_rate_auto(mlan_private *pmpriv)
1473 {
1474     t_u32 i;
1475     int rate_num = 0;
1476 
1477     ENTER();
1478 
1479     for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates); i++)
1480     {
1481         if (pmpriv->bitmap_rates[i] != 0U)
1482         {
1483             rate_num++;
1484         }
1485     }
1486 
1487     LEAVE();
1488     if (rate_num > 1)
1489     {
1490         return MTRUE;
1491     }
1492     else
1493     {
1494         return MFALSE;
1495     }
1496 }
1497 
1498 /**
1499  *  @brief Covert Rate Bitmap to Rate index
1500  *
1501  *  @param pmadapter    Pointer to mlan_adapter structure
1502  *  @param rate_bitmap  Pointer to rate bitmap
1503  *  @param size         Size of the bitmap array
1504  *
1505  *  @return             Rate index
1506  */
1507 int wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 *rate_bitmap, int size)
1508 {
1509     int i;
1510 
1511     ENTER();
1512 
1513     for (i = 0; i < size * 8; i++)
1514     {
1515         if ((rate_bitmap[i / 16] & ((t_u32)1U << ((t_u32)i % 16U))) != 0U)
1516         {
1517             LEAVE();
1518             return i;
1519         }
1520     }
1521 
1522     LEAVE();
1523     return -1;
1524 }
1525 
1526 /**
1527  *  @brief Convert config_bands to B/G/A band
1528  *
1529  *  @param config_bands     The specified band configuration
1530  *
1531  *  @return                 BAND_B|BAND_G|BAND_A
1532  */
1533 t_u16 wlan_convert_config_bands(t_u16 config_bands)
1534 {
1535     t_u16 bands = 0;
1536     if (config_bands & BAND_B)
1537         bands |= BAND_B;
1538     if (config_bands & BAND_G || config_bands & BAND_GN
1539 #ifdef ENABLE_802_11AC
1540         || config_bands & BAND_GAC
1541 #endif
1542 #ifdef ENABLE_802_11AX
1543         || config_bands & BAND_GAX
1544 #endif
1545     )
1546         bands |= BAND_G;
1547     if (config_bands & BAND_A || config_bands & BAND_AN
1548 #ifdef ENABLE_802_11AC
1549         || config_bands & BAND_AAC
1550 #endif
1551 #ifdef ENABLE_802_11AX
1552         || config_bands & BAND_AAX
1553 #endif
1554     )
1555         bands |= BAND_A;
1556     return bands;
1557 }
1558 
1559 /**
1560  *  @brief Get supported data rates
1561  *
1562  *  @param pmpriv           A pointer to mlan_private structure
1563  *  @param bss_mode         The specified BSS mode (Infra/IBSS)
1564  *  @param config_bands     The specified band configuration
1565  *  @param rates            The buf to return the supported rates
1566  *
1567  *  @return                 The number of Rates
1568  */
1569 t_u32 wlan_get_supported_rates(mlan_private *pmpriv,
1570                                mlan_bss_mode bss_mode,
1571                                t_u16 config_bands,
1572                                WLAN_802_11_RATES rates)
1573 {
1574     t_u32 k     = 0;
1575     t_u16 bands = 0;
1576 
1577     ENTER();
1578 
1579     bands = wlan_convert_config_bands(config_bands);
1580     if (bss_mode == MLAN_BSS_MODE_INFRA)
1581     {
1582         /* Infra. mode */
1583         if (bands == BAND_B)
1584         {
1585             /* B only */
1586             k = wlan_copy_rates(rates, k, SupportedRates_B, sizeof(SupportedRates_B));
1587         }
1588         else if (bands == BAND_G)
1589         {
1590             /* G only */
1591             k = wlan_copy_rates(rates, k, SupportedRates_G, sizeof(SupportedRates_G));
1592         }
1593         else if (bands & (BAND_B | BAND_G))
1594         {
1595             /* BG only */
1596 #ifdef WIFI_DIRECT_SUPPORT
1597             if (pmpriv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
1598                 k = wlan_copy_rates(rates, k, SupportedRates_G, sizeof(SupportedRates_G));
1599             else
1600 #endif
1601                 k = wlan_copy_rates(rates, k, SupportedRates_BG, sizeof(SupportedRates_BG));
1602         }
1603         else if (bands & BAND_A)
1604         {
1605             /* support A */
1606             k = wlan_copy_rates(rates, k, SupportedRates_A, sizeof(SupportedRates_A));
1607         }
1608     }
1609     else
1610     {
1611         /* Adhoc. mode */
1612         if (bands == BAND_B)
1613         {
1614             /* B only */
1615             k = wlan_copy_rates(rates, k, AdhocRates_B, sizeof(AdhocRates_B));
1616         }
1617         else if (bands == BAND_G)
1618         {
1619             /* G only */
1620             k = wlan_copy_rates(rates, k, AdhocRates_G, sizeof(AdhocRates_G));
1621         }
1622         else if (bands & BAND_A)
1623         {
1624             /* support A */
1625             k = wlan_copy_rates(rates, k, AdhocRates_A, sizeof(AdhocRates_A));
1626         }
1627         else
1628         {
1629             k = wlan_copy_rates(rates, k, AdhocRates_BG, sizeof(AdhocRates_BG));
1630         }
1631     }
1632 
1633     LEAVE();
1634     return k;
1635 }
1636 
1637 /**
1638  *  @brief This function sets region table.
1639  *
1640  *  @param pmpriv  A pointer to mlan_private structure
1641  *  @param region  The region code
1642  *  @param band    The band
1643  *
1644  *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1645  */
1646 mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u16 band)
1647 {
1648     mlan_adapter *pmadapter = pmpriv->adapter;
1649     int i                   = 0;
1650     const chan_freq_power_t *cfp;
1651     int cfp_no;
1652 
1653     ENTER();
1654 
1655     (void)__memset(pmadapter, pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
1656 
1657     if ((band & (BAND_B | BAND_G | BAND_GN)) != 0U)
1658     {
1659         cfp = wlan_get_region_cfp_table(pmadapter, region, (BAND_G | BAND_B | BAND_GN), &cfp_no);
1660         if (cfp != MNULL)
1661         {
1662             pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no;
1663             pmadapter->region_channel[i].pcfp    = cfp;
1664         }
1665         else
1666         {
1667             PRINTM(MERROR, "wrong region code %#x in Band B-G\n", region);
1668             LEAVE();
1669             return MLAN_STATUS_FAILURE;
1670         }
1671         pmadapter->region_channel[i].valid  = (t_u8)MTRUE;
1672         pmadapter->region_channel[i].region = region;
1673         if ((band & BAND_GN) != 0U)
1674         {
1675             pmadapter->region_channel[i].band = BAND_G;
1676         }
1677         else
1678         {
1679             pmadapter->region_channel[i].band = (band & BAND_G) != 0U ? BAND_G : BAND_B;
1680         }
1681         i++;
1682     }
1683 #if CONFIG_5GHz_SUPPORT
1684     if ((band & (BAND_A | BAND_AN | BAND_AAC)) != 0U)
1685     {
1686         cfp = wlan_get_region_cfp_table(pmadapter, region, BAND_A, &cfp_no);
1687         if (cfp != MNULL)
1688         {
1689             pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no;
1690             pmadapter->region_channel[i].pcfp    = cfp;
1691         }
1692         else
1693         {
1694             PRINTM(MERROR, "wrong region code %#x in Band A\n", region);
1695             LEAVE();
1696             return MLAN_STATUS_FAILURE;
1697         }
1698         pmadapter->region_channel[i].valid  = (t_u8)MTRUE;
1699         pmadapter->region_channel[i].region = region;
1700         pmadapter->region_channel[i].band   = BAND_A;
1701     }
1702 #endif /* CONFIG_5GHz_SUPPORT */
1703 
1704     LEAVE();
1705     return MLAN_STATUS_SUCCESS;
1706 }
1707 
1708 /**
1709  *  @brief Get if radar detection is enabled or not on a certain channel
1710  *
1711  *  @param priv    Private driver information structure
1712  *  @param chnl Channel to determine radar detection requirements
1713  *
1714  *  @return
1715  *    - MTRUE if radar detection is required
1716  *    - MFALSE otherwise
1717  */
1718 t_bool wlan_get_cfp_radar_detect(mlan_private *priv, t_u8 chnl)
1719 {
1720     t_u8 i, j;
1721     t_bool required               = MFALSE;
1722     const chan_freq_power_t *pcfp = MNULL;
1723 
1724     ENTER();
1725 
1726     /* get the cfp table first */
1727     for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++)
1728     {
1729         if (priv->adapter->region_channel[i].band == BAND_A)
1730         {
1731             pcfp = priv->adapter->region_channel[i].pcfp;
1732             break;
1733         }
1734     }
1735 
1736     if (pcfp == MNULL)
1737     {
1738         /* This means operation in BAND-A is not support, we can just return
1739            false here, it's harmless */
1740         goto done;
1741     }
1742 
1743     /* get the radar detection requirements according to chan num */
1744     for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++)
1745     {
1746         if (pcfp[j].channel == chnl)
1747         {
1748             required = pcfp[j].passive_scan_or_radar_detect;
1749             break;
1750         }
1751     }
1752 
1753 done:
1754     LEAVE();
1755     return required;
1756 }
1757 
1758 /**
1759  *  @brief Get if scan type is passive or not on a certain channel for b/g band
1760  *
1761  *  @param priv    Private driver information structure
1762  *  @param chnl Channel to determine scan type
1763  *
1764  *  @return
1765  *    - MTRUE if scan type is passive
1766  *    - MFALSE otherwise
1767  */
1768 
1769 t_bool wlan_bg_scan_type_is_passive(mlan_private *priv, t_u8 chnl)
1770 {
1771     t_u8 i, j;
1772     t_bool passive                = MFALSE;
1773     const chan_freq_power_t *pcfp = MNULL;
1774 
1775     ENTER();
1776 
1777     /* get the cfp table first */
1778     for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++)
1779     {
1780         if ((priv->adapter->region_channel[i].band & (BAND_B | BAND_G)) != 0U)
1781         {
1782             pcfp = priv->adapter->region_channel[i].pcfp;
1783             break;
1784         }
1785     }
1786 
1787     if (pcfp == MNULL)
1788     {
1789         /* This means operation in BAND-B or BAND_G is not support, we can
1790            just return false here */
1791         goto done;
1792     }
1793 
1794     /* get the bg scan type according to chan num */
1795     for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++)
1796     {
1797         if (pcfp[j].channel == chnl)
1798         {
1799             passive = pcfp[j].passive_scan_or_radar_detect;
1800             break;
1801         }
1802     }
1803 
1804 done:
1805     LEAVE();
1806     return passive;
1807 }
1808 
1809 /**
1810  * @bried convert ht_info to rate_info
1811  *
1812  * @param ht_info	ht_info
1813  *
1814  * @return		rate_info
1815  */
1816 t_u8 wlan_convert_v14_rate_ht_info(t_u8 ht_info)
1817 {
1818     t_u8 rate_info = 0;
1819     rate_info      = ht_info & 0x01U;
1820     /* band */
1821     rate_info |= (ht_info & MBIT(1)) << 1;
1822     /* Short GI */
1823     rate_info |= (ht_info & MBIT(2)) << 1;
1824     return rate_info;
1825 }
1826 
1827 /**
1828  * @brief Validate if channel is in range of World Wide Safe Mode
1829  *
1830  * @param chan_num	Channel Number
1831  *
1832  * @return		Valid or Invalid
1833  */
1834 t_bool wlan_is_channel_valid(t_u8 chan_num)
1835 {
1836     t_bool valid = MFALSE;
1837     int i        = 0;
1838     chan_freq_power_t *cfp_wwsm;
1839     int cfp_no = 0;
1840 
1841     ENTER();
1842 
1843     cfp_wwsm = (chan_freq_power_t *)channel_freq_power_WW_BG;
1844     cfp_no   = (int)(sizeof(channel_freq_power_WW_BG) / sizeof(chan_freq_power_t));
1845 
1846     for (i = 0; i < cfp_no; i++)
1847     {
1848         /* Channel 0 is invalid */
1849         if (chan_num == 0U)
1850         {
1851             PRINTM(MERROR, "Invalid channel. Channel number can't be %d\r\n", chan_num);
1852             valid = MFALSE;
1853             break;
1854         }
1855 
1856         if (chan_num == cfp_wwsm[i].channel)
1857         {
1858             valid = MTRUE;
1859             break;
1860         }
1861     }
1862 
1863 #if CONFIG_5GHz_SUPPORT
1864     if (!valid)
1865     {
1866         cfp_wwsm = (chan_freq_power_t *)channel_freq_power_WW_A;
1867         cfp_no   = (int)(sizeof(channel_freq_power_WW_A) / sizeof(chan_freq_power_t));
1868 
1869         for (i = 0; i < cfp_no; i++)
1870         {
1871             /* Channel 0 is invalid */
1872             if (chan_num == 0U)
1873             {
1874                 PRINTM(MERROR, "Invalid channel. Channel number can't be %d\r\n", chan_num);
1875                 valid = MFALSE;
1876                 break;
1877             }
1878 
1879             if (chan_num == cfp_wwsm[i].channel)
1880             {
1881                 valid = MTRUE;
1882                 break;
1883             }
1884         }
1885     }
1886 #endif
1887 
1888     LEAVE();
1889     return valid;
1890 }
1891 
1892 /**
1893  * @brief Validate if channel is in range of region table
1894  *
1895  * @param priv    Private driver information structure
1896  * @param chan_num	Channel Number
1897  *
1898  * @return		Valid or Invalid
1899  */
1900 t_bool wlan_check_channel_by_region_table(mlan_private *pmpriv, t_u8 chan_num)
1901 {
1902     t_bool valid = MFALSE;
1903     int i        = 0;
1904     mlan_adapter *pmadapter = pmpriv->adapter;
1905     const chan_freq_power_t *cfp = pmadapter->region_channel[0].pcfp;
1906     int cfp_no  = pmadapter->region_channel[0].num_cfp;
1907 
1908     ENTER();
1909 
1910     if(NULL == cfp)
1911         return MFALSE;
1912 
1913     /* Channel 0 is invalid */
1914     if (chan_num == 0)
1915     {
1916         PRINTM(MERROR, "Invalid channel. Channel number can't be %d\r\n", chan_num);
1917         valid = MFALSE;
1918         return valid;
1919     }
1920 
1921     for (i = 0; i < cfp_no; i++)
1922     {
1923         if (chan_num == cfp[i].channel)
1924         {
1925             valid = MTRUE;
1926             break;
1927         }
1928     }
1929 
1930 #if CONFIG_5GHz_SUPPORT
1931     if (!valid)
1932     {
1933         cfp = pmadapter->region_channel[1].pcfp;
1934         cfp_no   = pmadapter->region_channel[1].num_cfp;
1935 
1936         if(NULL == cfp)
1937             return MFALSE;
1938 
1939         for (i = 0; i < cfp_no; i++)
1940         {
1941             if (chan_num == cfp[i].channel)
1942             {
1943                 valid = MTRUE;
1944                 break;
1945             }
1946         }
1947     }
1948 #endif
1949 
1950     LEAVE();
1951     return valid;
1952 }
1953 
1954 /**
1955  * @brief Validate if radio mode is in range of World Wide Safe Mode
1956  *
1957  * @param mode	radio mode
1958  *
1959  * @return		Valid or Invalid
1960  */
1961 t_bool wlan_is_radio_mode_valid(t_u8 mode)
1962 {
1963     t_bool valid = MFALSE;
1964     int i        = 0;
1965     int mode_num;
1966 
1967     ENTER();
1968     mode_num = (sizeof(rf_radio_modes_group) / sizeof(rf_radio_modes_group[0]));
1969 
1970     for (i = 0; i < mode_num; i++)
1971     {
1972         if (mode == rf_radio_modes_group[i])
1973         {
1974             valid = MTRUE;
1975             break;
1976         }
1977     }
1978 
1979     if (valid == MFALSE)
1980     {
1981         PRINTF("Invalid radio mode. Radio mode can't be %d\r\n", mode);
1982     }
1983     LEAVE();
1984     return valid;
1985 }
1986 
1987 /**
1988  * @brief Validate if channel and its frequency is in range of World Wide Safe Mode
1989  *
1990  * @param chan_num	Channel Number
1991  * @param chan_freq	Channel Frequency
1992  *
1993  * @return		Valid or Invalid
1994  */
1995 t_bool wlan_is_channel_and_freq_valid(mlan_adapter *pmadapter, t_u8 chan_num, t_u16 chan_freq)
1996 {
1997     t_bool valid = MFALSE;
1998     int i        = 0;
1999     const chan_freq_power_t *cfp;
2000     int cfp_no = 0;
2001 
2002     ENTER();
2003 
2004     cfp = wlan_get_region_cfp_table(pmadapter, pmadapter->region_code, (BAND_G | BAND_B | BAND_GN), &cfp_no);
2005 
2006     for (i = 0; i < cfp_no; i++)
2007     {
2008         /* Channel 0 is invalid */
2009         if (chan_num == 0U)
2010         {
2011             PRINTM(MERROR, "Invalid channel. Channel number can't be %d\r\n", chan_num);
2012             valid = MFALSE;
2013             break;
2014         }
2015 
2016         if (chan_num == cfp[i].channel)
2017         {
2018             /* Channel Number is valid. Now validate the corresponding frequency as well */
2019             if (chan_freq == cfp[i].freq)
2020             {
2021                 valid = MTRUE;
2022             }
2023             else
2024             {
2025                 PRINTM(MERROR, "Channel freq mismatch. Expected %d, Configured %d\r\n", cfp[i].freq, chan_freq);
2026                 valid = MFALSE;
2027             }
2028 
2029             break;
2030         }
2031     }
2032 
2033 #if CONFIG_5GHz_SUPPORT
2034     if (!valid)
2035     {
2036         cfp = wlan_get_region_cfp_table(pmadapter, pmadapter->region_code, BAND_A, &cfp_no);
2037 
2038         for (i = 0; i < cfp_no; i++)
2039         {
2040             /* Channel 0 is invalid */
2041             if (chan_num == 0U)
2042             {
2043                 PRINTM(MERROR, "Invalid channel. Channel number can't be %d\r\n", chan_num);
2044                 valid = MFALSE;
2045                 break;
2046             }
2047 
2048             if (chan_num == cfp[i].channel)
2049             {
2050                 /* Channel Number is valid. Now validate the corresponding frequency as well */
2051                 if (chan_freq == cfp[i].freq)
2052                 {
2053                     valid = MTRUE;
2054                 }
2055                 else
2056                 {
2057                     PRINTM(MERROR, "Channel freq mismatch. Expected %d, Configured %d\r\n", cfp[i].freq,
2058                            chan_freq);
2059                     valid = MFALSE;
2060                 }
2061 
2062                 break;
2063             }
2064         }
2065     }
2066 #endif
2067 
2068     LEAVE();
2069     return valid;
2070 }
2071 
2072 /**
2073  * @brief Set Custom CFP Table
2074  *
2075  * @param chanlist	Channel List Config
2076  * @param cfp_no_bg	A pointer to the number of CFP entries for Band BG
2077  * @param cfp_no_a	A pointer to the number of CFP entries for Band A
2078  *
2079  * @return              MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2080  */
2081 #if CONFIG_5GHz_SUPPORT
2082 mlan_status wlan_set_custom_cfp_table(wifi_chanlist_t *chanlist, t_u8 *cfp_no_bg, t_u8 *cfp_no_a)
2083 #else
2084 mlan_status wlan_set_custom_cfp_table(wifi_chanlist_t *chanlist, t_u8 *cfp_no_bg)
2085 #endif
2086 {
2087     t_u8 i      = 0;
2088     t_u8 idx_bg = 0;
2089     *cfp_no_bg  = 0;
2090 
2091 #if CONFIG_5GHz_SUPPORT
2092     t_u8 idx_a = 0;
2093     *cfp_no_a  = 0;
2094 #endif
2095 
2096     ENTER();
2097 
2098     for (i = 0; i < chanlist->num_chans; i++)
2099     {
2100         if ((chanlist->chan_info[i].chan_num <= MAX_CHANNELS_BG) &&
2101             (idx_bg < (sizeof(channel_freq_power_Custom_BG) / sizeof(chan_freq_power_t))))
2102         {
2103             channel_freq_power_Custom_BG[idx_bg].channel = chanlist->chan_info[i].chan_num;
2104             channel_freq_power_Custom_BG[idx_bg].freq    = chanlist->chan_info[i].chan_freq;
2105             channel_freq_power_Custom_BG[idx_bg].passive_scan_or_radar_detect =
2106                 chanlist->chan_info[i].passive_scan_or_radar_detect;
2107             idx_bg++;
2108             *cfp_no_bg = idx_bg;
2109         }
2110 #if CONFIG_5GHz_SUPPORT
2111         else if ((chanlist->chan_info[i].chan_num > MAX_CHANNELS_BG) &&
2112                  (idx_a < (sizeof(channel_freq_power_Custom_A) / sizeof(chan_freq_power_t))))
2113         {
2114             channel_freq_power_Custom_A[idx_a].channel = chanlist->chan_info[i].chan_num;
2115             channel_freq_power_Custom_A[idx_a].freq    = chanlist->chan_info[i].chan_freq;
2116             channel_freq_power_Custom_A[idx_a].passive_scan_or_radar_detect =
2117                 chanlist->chan_info[i].passive_scan_or_radar_detect;
2118             idx_a++;
2119             *cfp_no_a = idx_a;
2120         }
2121 #endif
2122         else
2123         {
2124 #if CONFIG_5GHz_SUPPORT
2125             PRINTM(MERROR, "Error in configuring custom CFP table. ch %d, idx_bg %d, idx_a %d\r\n",
2126                    chanlist->chan_info[i].chan_num, idx_bg, idx_a);
2127 #else
2128             PRINTM(MERROR, "Error in configuring custom CFP table. ch %d, idx_bg %d\r\n", chanlist->chan_info[i].chan_num,
2129                    idx_bg);
2130 #endif
2131             return MLAN_STATUS_FAILURE;
2132         }
2133     }
2134 
2135     LEAVE();
2136     return MLAN_STATUS_SUCCESS;
2137 }
2138 
2139 /**
2140  *  @brief This function sets custom region table.
2141  *
2142  *  @param pmpriv 	A pointer to mlan_private structure
2143  *  @param cfp_no_bg	Number of CFP entries for Band BG
2144  *  @param cfp_no_a	Number of CFP entries for Band A
2145  *
2146  *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2147  */
2148 #if CONFIG_5GHz_SUPPORT
2149 void wlan_set_custom_regiontable(mlan_private *pmpriv, t_u8 cfp_no_bg, t_u8 cfp_no_a)
2150 #else
2151 void wlan_set_custom_regiontable(mlan_private *pmpriv, t_u8 cfp_no_bg)
2152 #endif
2153 {
2154     mlan_adapter *pmadapter = pmpriv->adapter;
2155     int i                   = 0;
2156 
2157     ENTER();
2158 
2159     if (cfp_no_bg != 0U)
2160     {
2161         pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no_bg;
2162         pmadapter->region_channel[i].pcfp    = channel_freq_power_Custom_BG;
2163     }
2164 
2165     i++;
2166 
2167 #if CONFIG_5GHz_SUPPORT
2168     if (cfp_no_a != 0U)
2169     {
2170         pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no_a;
2171         pmadapter->region_channel[i].pcfp    = channel_freq_power_Custom_A;
2172     }
2173 #endif
2174 
2175     LEAVE();
2176 }
2177 
2178 /**
2179  *  @brief This function gets the list of configured active channels.
2180  *
2181  *  @param pmpriv 	A pointer to mlan_private structure
2182  *  @param chan_list	A pointer to the channel list
2183  *  @param num_chans	A pointer to the number of active channels
2184  *  @param acs_band  ACS band info     0: get 2.4G channel list
2185  *                                     1: get 5G channel list
2186  */
2187 void wlan_get_active_channel_list(mlan_private *pmpriv, t_u8 *chan_list, t_u8 *num_chans, t_u16 acs_band)
2188 {
2189     mlan_adapter *pmadapter = pmpriv->adapter;
2190     int i                   = 0;
2191     int j                   = 0;
2192     const chan_freq_power_t *cfp;
2193     int cfp_no;
2194 
2195     ENTER();
2196 
2197     *num_chans = 0;
2198 
2199     if (acs_band == 0)
2200     {
2201         cfp    = pmadapter->region_channel[i].pcfp;
2202         cfp_no = pmadapter->region_channel[i].num_cfp;
2203         for (j = 0; j < cfp_no; j++)
2204         {
2205             if ((!(cfp[j].dynamic.flags & NXP_CHANNEL_DISABLED)) && (!cfp[j].passive_scan_or_radar_detect))
2206             {
2207                 *(chan_list++) = cfp[j].channel;
2208                 *num_chans     = *num_chans + 1;
2209             }
2210         }
2211     }
2212     if (acs_band == 1)
2213     {
2214 #if CONFIG_5GHz_SUPPORT
2215         i      = 1;
2216         cfp    = pmadapter->region_channel[i].pcfp;
2217         cfp_no = (int)pmadapter->region_channel[i].num_cfp;
2218 
2219         for (j = 0; j < cfp_no; j++)
2220         {
2221             if ((!(cfp[j].dynamic.flags & NXP_CHANNEL_DISABLED)) && (!cfp[j].passive_scan_or_radar_detect))
2222             {
2223                 *(chan_list++) = (t_u8)cfp[j].channel;
2224                 *num_chans     = *num_chans + 1U;
2225             }
2226         }
2227 
2228 #endif
2229     }
2230 }
2231 
2232 #ifdef OTP_CHANINFO
2233 /**
2234  *  @brief	Update CFP tables and power tables from FW
2235  *
2236  *  @param priv		Private driver information structure
2237  *  @param buf		Pointer to the buffer holding TLV data
2238  *					from 0x242 command response.
2239  *  @param buf_left	bufsize
2240  *
2241  *  @return
2242  *    None
2243  */
2244 void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
2245 {
2246     mlan_adapter *pmadapter = pmpriv->adapter;
2247     mlan_callbacks *pcb     = (mlan_callbacks *)&pmadapter->callbacks;
2248     MrvlIEtypesHeader_t *head;
2249     t_u16 tlv;
2250     t_u16 tlv_buf_len;
2251     t_u16 tlv_buf_left;
2252     t_u16 i;
2253     int k               = 0, rows, cols;
2254     t_u16 max_tx_pwr_bg = WLAN_TX_PWR_DEFAULT;
2255 #if CONFIG_5GHz_SUPPORT
2256     t_u16 max_tx_pwr_a = WLAN_TX_PWR_DEFAULT;
2257 #endif
2258     t_u8 *tlv_buf;
2259     t_u8 *data;
2260     t_u8 *tmp;
2261     mlan_status ret;
2262 
2263     ENTER();
2264 
2265     if (buf == MNULL)
2266     {
2267         PRINTM(MERROR, "CFP table update failed!\n");
2268         goto out;
2269     }
2270     if (pmadapter->otp_region != MNULL)
2271     {
2272         wlan_free_fw_cfp_tables(pmadapter);
2273     }
2274 
2275     pmadapter->tx_power_table_bg_rows = FW_CFP_TABLE_MAX_ROWS_BG;
2276     pmadapter->tx_power_table_bg_cols = FW_CFP_TABLE_MAX_COLS_BG;
2277 #if CONFIG_5GHz_SUPPORT
2278     pmadapter->tx_power_table_a_rows = FW_CFP_TABLE_MAX_ROWS_A;
2279     pmadapter->tx_power_table_a_cols = FW_CFP_TABLE_MAX_COLS_A;
2280 #endif
2281     tlv_buf      = (t_u8 *)buf;
2282     tlv_buf_left = buf_left;
2283 
2284     while (tlv_buf_left >= sizeof(*head))
2285     {
2286         head        = (MrvlIEtypesHeader_t *)(void *)tlv_buf;
2287         tlv         = wlan_le16_to_cpu(head->type);
2288         tlv_buf_len = wlan_le16_to_cpu(head->len);
2289 
2290         if (tlv_buf_left < (sizeof(*head) + tlv_buf_len))
2291         {
2292             break;
2293         }
2294         data = (t_u8 *)head + sizeof(*head);
2295 
2296         switch (tlv)
2297         {
2298             case TLV_TYPE_REGION_INFO:
2299                 /* Skip adding fw region info if it already exists or
2300                  * if this TLV has no set data
2301                  */
2302                 if (*data == 0U)
2303                 {
2304                     break;
2305                 }
2306                 if (pmadapter->otp_region != MNULL)
2307                 {
2308                     break;
2309                 }
2310 
2311                 ret = pcb->moal_malloc(pmadapter->pmoal_handle, sizeof(otp_region_info_t), MLAN_MEM_DEF,
2312                                        (t_u8 **)(void **)&pmadapter->otp_region);
2313 
2314                 if (ret != MLAN_STATUS_SUCCESS || (pmadapter->otp_region == MNULL))
2315                 {
2316                     PRINTM(MERROR,
2317                            "Memory allocation for the otp region"
2318                            " info struct failed!\n");
2319                     break;
2320                 }
2321                 /* Save region info values from OTP in the otp_region
2322                  * structure
2323                  */
2324                 (void)__memcpy(pmadapter, pmadapter->otp_region, data, sizeof(otp_region_info_t));
2325 
2326                 data += sizeof(otp_region_info_t);
2327                 /* Get pre-defined cfp tables corresponding to the region code
2328                  * in OTP
2329                  */
2330                 for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++)
2331                 {
2332                     if (cfp_table_BG[i].code == pmadapter->otp_region->region_code)
2333                     {
2334                         max_tx_pwr_bg = (cfp_table_BG[i].cfp)->max_tx_power;
2335                         break;
2336                     }
2337                 }
2338 #if CONFIG_5GHz_SUPPORT
2339                 for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++)
2340                 {
2341                     if (cfp_table_A[i].code == pmadapter->otp_region->region_code)
2342                     {
2343                         max_tx_pwr_a = (cfp_table_A[i].cfp)->max_tx_power;
2344                         break;
2345                     }
2346                 }
2347 #endif
2348                 /* Update the region code and the country code in pmadapter */
2349                 pmadapter->region_code                = pmadapter->otp_region->region_code;
2350                 pmadapter->country_code[0]            = pmadapter->otp_region->country_code[0];
2351                 pmadapter->country_code[1]            = pmadapter->otp_region->country_code[1];
2352                 pmadapter->country_code[2]            = (t_u8)'\0';
2353                 pmadapter->domain_reg.country_code[0] = pmadapter->otp_region->country_code[0];
2354                 pmadapter->domain_reg.country_code[1] = pmadapter->otp_region->country_code[1];
2355                 pmadapter->domain_reg.country_code[2] = (t_u8)'\0';
2356                 pmadapter->cfp_code_bg                = pmadapter->otp_region->region_code;
2357 #if CONFIG_5GHz_SUPPORT
2358                 pmadapter->cfp_code_a = pmadapter->otp_region->region_code;
2359 #endif
2360                 break;
2361             case TLV_TYPE_CHAN_ATTR_CFG:
2362                 /* Skip adding fw cfp tables if they already exist or
2363                  * if this TLV has no set data
2364                  */
2365                 if (*data == 0U)
2366                 {
2367                     break;
2368                 }
2369 
2370 #if CONFIG_5GHz_SUPPORT
2371                 if ((pmadapter->cfp_otp_bg != MNULL) || (pmadapter->cfp_otp_a != MNULL))
2372 #else
2373                 if (pmadapter->cfp_otp_bg != MNULL)
2374 #endif
2375                 {
2376                     break;
2377                 }
2378 
2379                 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2380                                        pmadapter->tx_power_table_bg_rows * sizeof(chan_freq_power_t), MLAN_MEM_DEF,
2381                                        (t_u8 **)(void **)&pmadapter->cfp_otp_bg);
2382                 if ((ret != MLAN_STATUS_SUCCESS) || (pmadapter->cfp_otp_bg == MNULL))
2383                 {
2384                     PRINTM(MERROR,
2385                            "Memory allocation for storing otp bg"
2386                            " table data failed!\n");
2387                     break;
2388                 }
2389                 (void)__memset(pmadapter, pmadapter->cfp_otp_bg, 0, pmadapter->tx_power_table_bg_rows * sizeof(chan_freq_power_t));
2390                 /* Save channel usability flags from OTP data in the fw cfp bg
2391                  * table and set frequency and max_tx_power values
2392                  */
2393                 for (i = 0; i < pmadapter->tx_power_table_bg_rows; i++)
2394                 {
2395                     (pmadapter->cfp_otp_bg + i)->channel = *data;
2396                     if (*data == 14U)
2397                     {
2398                         (pmadapter->cfp_otp_bg + i)->freq = 2484;
2399                     }
2400                     else
2401                     {
2402                         (pmadapter->cfp_otp_bg + i)->freq = (t_u32)2412U + (t_u32)5U * ((t_u32)*data - (t_u32)1U);
2403                     }
2404                     (pmadapter->cfp_otp_bg + i)->max_tx_power = max_tx_pwr_bg;
2405                     data++;
2406                     (pmadapter->cfp_otp_bg + i)->dynamic.flags = *data;
2407                     if ((*data & NXP_CHANNEL_DFS) != 0U)
2408                     {
2409                         (pmadapter->cfp_otp_bg + i)->passive_scan_or_radar_detect = MTRUE;
2410                     }
2411                     data++;
2412                 }
2413 #if CONFIG_5GHz_SUPPORT
2414                 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
2415                                        pmadapter->tx_power_table_a_rows * sizeof(chan_freq_power_t), MLAN_MEM_DEF,
2416                                        (t_u8 **)(void *)&pmadapter->cfp_otp_a);
2417                 if ((ret != MLAN_STATUS_SUCCESS) || (pmadapter->cfp_otp_a == MNULL))
2418                 {
2419                     PRINTM(MERROR,
2420                            "Memory allocation for storing otp a"
2421                            " table data failed!\n");
2422                     break;
2423                 }
2424                 (void)__memset(pmadapter, pmadapter->cfp_otp_bg, 0, pmadapter->tx_power_table_bg_rows * sizeof(chan_freq_power_t));
2425                 /* Save channel usability flags from OTP data in the fw cfp a
2426                  * table and set frequency and max_tx_power values
2427                  */
2428                 for (i = 0; i < pmadapter->tx_power_table_a_rows; i++)
2429                 {
2430                     (pmadapter->cfp_otp_a + i)->channel = *data;
2431                     if (*data < 183U)
2432                     {
2433                         /* 5GHz channels */
2434                         (pmadapter->cfp_otp_a + i)->freq = (t_u32)5035U + (t_u32)5U * ((t_u32)*data - (t_u32)7U);
2435                     }
2436                     else
2437                     {
2438                         /* 4GHz channels */
2439                         (pmadapter->cfp_otp_a + i)->freq = (t_u32)4915U + (t_u32)5U * ((t_u32)*data - (t_u32)183U);
2440                     }
2441                     (pmadapter->cfp_otp_a + i)->max_tx_power = max_tx_pwr_a;
2442                     data++;
2443                     (pmadapter->cfp_otp_a + i)->dynamic.flags = *data;
2444                     if ((*data & NXP_CHANNEL_DFS) != 0U)
2445                     {
2446                         (pmadapter->cfp_otp_a + i)->passive_scan_or_radar_detect = MTRUE;
2447                     }
2448                     data++;
2449                 }
2450 #endif
2451                 break;
2452             case TLV_TYPE_POWER_TABLE:
2453                 /* Skip adding fw power tables if this TLV has no data or
2454                  * if they already exists but force reg rule is set in the otp
2455                  */
2456                 if (*data == 0U)
2457                 {
2458                     break;
2459                 }
2460                 if ((pmadapter->otp_region != MNULL) && (pmadapter->otp_region->force_reg != 0U) &&
2461                     (pmadapter->tx_power_table_bg != MNULL))
2462                 {
2463                     break;
2464                 }
2465 
2466                 /* Save the tlv data in power tables for band BG and A */
2467                 tmp = data;
2468                 i   = 0;
2469                 while ((i < (t_u16)pmadapter->tx_power_table_bg_rows * (t_u16)pmadapter->tx_power_table_bg_cols) &&
2470                        (i < tlv_buf_len) && (*tmp != 36U))
2471                 {
2472                     i++;
2473                     tmp++;
2474                 }
2475                 if (pmadapter->tx_power_table_bg == MNULL)
2476                 {
2477                     ret = pcb->moal_malloc(pmadapter->pmoal_handle, i, MLAN_MEM_DEF,
2478                                            (t_u8 **)&pmadapter->tx_power_table_bg);
2479                     if ((ret != MLAN_STATUS_SUCCESS) || (pmadapter->tx_power_table_bg == MNULL))
2480                     {
2481                         PRINTM(MERROR,
2482                                "Memory allocation for the BG-band"
2483                                " power table falied!\n");
2484                         break;
2485                     }
2486                 }
2487                 if (i > 0U)
2488                 {
2489                     (void)__memcpy(pmadapter, pmadapter->tx_power_table_bg, data, i);
2490                 }
2491                 pmadapter->tx_power_table_bg_size = i;
2492                 data += i;
2493 #if CONFIG_5GHz_SUPPORT
2494                 i = 0;
2495                 while ((i < (t_u16)pmadapter->tx_power_table_a_rows * (t_u16)pmadapter->tx_power_table_a_cols) &&
2496                        (i < (tlv_buf_len - pmadapter->tx_power_table_bg_size)))
2497                 {
2498                     i++;
2499                 }
2500                 if (pmadapter->tx_power_table_a == MNULL)
2501                 {
2502                     ret = pcb->moal_malloc(pmadapter->pmoal_handle, i, MLAN_MEM_DEF,
2503                                            (t_u8 **)&pmadapter->tx_power_table_a);
2504                     if ((ret != MLAN_STATUS_SUCCESS) || (pmadapter->tx_power_table_a == MNULL))
2505                     {
2506                         PRINTM(MERROR,
2507                                "Memory allocation for the A-band"
2508                                " power table failed!\n");
2509                         break;
2510                     }
2511                 }
2512                 if (i > 0U)
2513                 {
2514                     (void)__memcpy(pmadapter, pmadapter->tx_power_table_a, data, i);
2515                 }
2516                 pmadapter->tx_power_table_a_size = i;
2517 #endif
2518                 break;
2519             case TLV_TYPE_POWER_TABLE_ATTR:
2520                 pmadapter->tx_power_table_bg_rows = ((power_table_attr_t *)(void *)data)->rows_2g;
2521                 pmadapter->tx_power_table_bg_cols = ((power_table_attr_t *)(void *)data)->cols_2g;
2522 #if CONFIG_5GHz_SUPPORT
2523                 pmadapter->tx_power_table_a_rows = ((power_table_attr_t *)(void *)data)->rows_5g;
2524                 pmadapter->tx_power_table_a_cols = ((power_table_attr_t *)(void *)data)->cols_5g;
2525 #endif
2526                 break;
2527             default:
2528                 PRINTM(MINFO, "Unexpected TLV \n");
2529                 break;
2530         }
2531         tlv_buf += (sizeof(*head) + tlv_buf_len);
2532         tlv_buf_left -= ((t_u16)sizeof(*head) + tlv_buf_len);
2533     }
2534     if ((pmadapter->cfp_otp_bg == MNULL) || (pmadapter->tx_power_table_bg == MNULL))
2535     {
2536         goto out;
2537     }
2538     /* Set remaining flags for BG */
2539     rows = (int)pmadapter->tx_power_table_bg_rows;
2540     cols = (int)pmadapter->tx_power_table_bg_cols;
2541 
2542     for (i = 0; i < (t_u16)rows; i++)
2543     {
2544         k = ((int)i * (int)cols) + (int)1U;
2545         if (((pmadapter->cfp_otp_bg + i)->dynamic.flags & NXP_CHANNEL_DISABLED) != 0U)
2546         {
2547             continue;
2548         }
2549 
2550         if (pmadapter->tx_power_table_bg[k + (int)MOD_CCK] == 0U)
2551         {
2552             (pmadapter->cfp_otp_bg + i)->dynamic.flags |= NXP_CHANNEL_NO_CCK;
2553         }
2554 
2555         if (pmadapter->tx_power_table_bg[k + (int)MOD_OFDM_PSK] == 0U &&
2556             pmadapter->tx_power_table_bg[k + (int)MOD_OFDM_QAM16] == 0U &&
2557             pmadapter->tx_power_table_bg[k + (int)MOD_OFDM_QAM64] == 0U)
2558         {
2559             (pmadapter->cfp_otp_bg + i)->dynamic.flags |= NXP_CHANNEL_NO_OFDM;
2560         }
2561     }
2562 out:
2563     LEAVE();
2564 }
2565 
2566 /**
2567  *  @brief	This function deallocates otp cfp and power tables memory.
2568  *
2569  *  @param pmadapter	A pointer to mlan_adapter structure
2570  */
2571 void wlan_free_fw_cfp_tables(mlan_adapter *pmadapter)
2572 {
2573     pmlan_callbacks pcb;
2574 
2575     ENTER();
2576 
2577     pcb = &pmadapter->callbacks;
2578     if (pmadapter->otp_region != NULL)
2579     {
2580         (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->otp_region);
2581     }
2582     if (pmadapter->cfp_otp_bg != NULL)
2583     {
2584         (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->cfp_otp_bg);
2585     }
2586     if (pmadapter->tx_power_table_bg != NULL)
2587     {
2588         (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->tx_power_table_bg);
2589     }
2590     pmadapter->otp_region             = MNULL;
2591     pmadapter->cfp_otp_bg             = MNULL;
2592     pmadapter->tx_power_table_bg      = MNULL;
2593     pmadapter->tx_power_table_bg_size = 0;
2594 #if CONFIG_5GHz_SUPPORT
2595     if (pmadapter->cfp_otp_a != NULL)
2596     {
2597         (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->cfp_otp_a);
2598     }
2599     if (pmadapter->tx_power_table_a != NULL)
2600     {
2601         (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->tx_power_table_a);
2602     }
2603     pmadapter->cfp_otp_a             = MNULL;
2604     pmadapter->tx_power_table_a      = MNULL;
2605     pmadapter->tx_power_table_a_size = 0;
2606 #endif
2607     LEAVE();
2608 }
2609 #endif /* OTP_CHANINFO */
2610 
2611 t_bool wlan_is_etsi_country(pmlan_adapter pmadapter, t_u8 *country_code)
2612 {
2613     t_u8 i;
2614     t_u32 meas_country_code_len = 0;
2615 
2616     ENTER();
2617     /* Look for code in EU country code table */
2618     for (i = 0; i < NELEMENTS(eu_country_code_table); i++)
2619     {
2620         meas_country_code_len = COUNTRY_CODE_LEN - 1U;
2621         if (__memcmp(pmadapter, eu_country_code_table[i], country_code, meas_country_code_len) == 0)
2622         {
2623             LEAVE();
2624             return MTRUE;
2625         }
2626     }
2627 
2628     LEAVE();
2629     return MFALSE;
2630 }
2631 
2632 static oper_bw_chan *wlan_get_nonglobal_operclass_table(mlan_private *pmpriv, int *arraysize)
2633 {
2634     t_u8 country_code[][COUNTRY_CODE_LEN] = {"US", "JP", "CN"};
2635     int country_id                        = 0;
2636     oper_bw_chan *poper_bw_chan           = MNULL;
2637     t_u32 meas_country_code_len           = 0;
2638 
2639     ENTER();
2640     for (country_id = 0; country_id < 3; country_id++)
2641     {
2642         meas_country_code_len = COUNTRY_CODE_LEN - 1U;
2643         if (__memcmp(pmpriv->adapter, pmpriv->adapter->country_code, country_code[country_id], meas_country_code_len) ==
2644             0)
2645         {
2646             break;
2647         }
2648     }
2649     if (country_id >= 3)
2650     {
2651         country_id = COUNTRY_ID_US; /*Set default to US*/
2652     }
2653     if (wlan_is_etsi_country(pmpriv->adapter, pmpriv->adapter->country_code))
2654     {
2655         country_id = COUNTRY_ID_EU; /** Country in EU */
2656     }
2657 
2658     switch (country_id)
2659     {
2660         case COUNTRY_ID_US:
2661             poper_bw_chan = oper_bw_chan_us;
2662             *arraysize    = (int)sizeof(oper_bw_chan_us);
2663             break;
2664         case COUNTRY_ID_JP:
2665             poper_bw_chan = oper_bw_chan_jp;
2666             *arraysize    = (int)sizeof(oper_bw_chan_jp);
2667             break;
2668         case COUNTRY_ID_CN:
2669             poper_bw_chan = oper_bw_chan_cn;
2670             *arraysize    = (int)sizeof(oper_bw_chan_cn);
2671             break;
2672         case COUNTRY_ID_EU:
2673             poper_bw_chan = oper_bw_chan_eu;
2674             *arraysize    = (int)sizeof(oper_bw_chan_eu);
2675             break;
2676         default:
2677             PRINTM(MERROR, "Country not support!\n");
2678             break;
2679     }
2680 
2681     LEAVE();
2682     return poper_bw_chan;
2683 }
2684 
2685 mlan_status wlan_get_global_nonglobal_oper_class(
2686     mlan_private *pmpriv, t_u8 channel, t_u8 bw, t_u8 *oper_class, t_u8 *global_op_class)
2687 {
2688     oper_bw_chan *poper_bw_chan = MNULL;
2689 #if CONFIG_11AC
2690     t_u8 center_freq_idx = 0;
2691 #endif
2692     t_u8 center_freqs[] = {42, 50, 58, 106, 114, 122, 138, 155};
2693     int i = 0, arraysize = 0, channum = 0, table_size = 0;
2694 
2695     ENTER();
2696     poper_bw_chan = wlan_get_nonglobal_operclass_table(pmpriv, &arraysize);
2697     if (poper_bw_chan == MNULL)
2698     {
2699         PRINTM(MCMND, "Operating class table do not find!\n");
2700         LEAVE();
2701         return MLAN_STATUS_FAILURE;
2702     }
2703     for (i = 0; i < (int)sizeof(center_freqs); i++)
2704     {
2705         if (channel == center_freqs[i])
2706         {
2707             PRINTM(MERROR, "Invalid channel number %d!\n", channel);
2708             LEAVE();
2709             return MLAN_STATUS_FAILURE;
2710         }
2711     }
2712 #if CONFIG_11AC
2713     if (bw == (t_u8)BW_80MHZ)
2714     {
2715         center_freq_idx = wlan_get_center_freq_idx(pmpriv, BAND_AAC, channel, CHANNEL_BW_80MHZ);
2716         channel         = center_freq_idx;
2717     }
2718 #endif
2719     table_size = arraysize / (int)sizeof(oper_bw_chan);
2720     for (i = 0; i < table_size; i++)
2721     {
2722         if (poper_bw_chan[i].bandwidth == bw)
2723         {
2724             for (channum = 0; channum < (int)(sizeof(poper_bw_chan[i].channel_list)); channum++)
2725             {
2726                 if (poper_bw_chan[i].channel_list[channum] != (t_u8)0U &&
2727                     poper_bw_chan[i].channel_list[channum] == channel)
2728                 {
2729                     if (oper_class != MNULL)
2730                     {
2731                         *oper_class = poper_bw_chan[i].oper_class;
2732                     }
2733                     if (global_op_class != MNULL)
2734                     {
2735                         *global_op_class = poper_bw_chan[i].global_oper_class;
2736                     }
2737                     return MLAN_STATUS_SUCCESS;
2738                 }
2739             }
2740         }
2741     }
2742     PRINTM(MCMND, "Operating class not find!\n");
2743     LEAVE();
2744     return MLAN_STATUS_FAILURE;
2745 }
2746 
2747 int wlan_add_supported_oper_class_ie(mlan_private *pmpriv, t_u8 **pptlv_out, t_u8 curr_oper_class)
2748 {
2749     t_u8 oper_class_us[] = {115,
2750                             118,
2751                             124,
2752                             121,
2753                             125,
2754                             81,
2755                             116,
2756                             119,
2757                             122,
2758                             126,
2759                             126,
2760                             117,
2761                             120,
2762                             123,
2763                             127,
2764                             127,
2765                             83,
2766                             84
2767 #if CONFIG_11AC
2768                             ,
2769                             128,
2770                             129,
2771                             130
2772 #endif
2773     };
2774     t_u8 oper_class_eu[] = {115,
2775                             118,
2776                             121,
2777                             81,
2778                             116,
2779                             119,
2780                             122,
2781                             117,
2782                             120,
2783                             123,
2784                             83,
2785                             84,
2786                             125
2787 #if CONFIG_11AC
2788                             ,
2789                             128,
2790                             129,
2791                             130
2792 #endif
2793     };
2794     t_u8 oper_class_jp[] = {115,
2795                             81,
2796                             82,
2797                             118,
2798                             118,
2799                             121,
2800                             121,
2801                             116,
2802                             119,
2803                             119,
2804                             122,
2805                             122,
2806                             117,
2807                             120,
2808                             120,
2809                             123,
2810                             123,
2811                             83,
2812                             84,
2813                             121
2814 #if CONFIG_11AC
2815                             ,
2816                             128,
2817                             129,
2818                             130
2819 #endif
2820     };
2821     t_u8 oper_class_cn[] = {115,
2822                             118,
2823                             125,
2824                             116,
2825                             119,
2826                             126,
2827                             81,
2828                             83,
2829                             84
2830 #if CONFIG_11AC
2831                             ,
2832                             128,
2833                             129,
2834                             130
2835 #endif
2836     };
2837     t_u8 country_code[][COUNTRY_CODE_LEN] = {"US", "JP", "CN"};
2838     int country_id = 0, ret = 0;
2839     MrvlIETypes_SuppOperClass_t *poper_class = MNULL;
2840     t_u32 meas_country_code_len              = 0;
2841 
2842     ENTER();
2843 
2844     for (country_id = 0; country_id < 3; country_id++)
2845     {
2846         meas_country_code_len = COUNTRY_CODE_LEN - 1U;
2847         if (__memcmp(pmpriv->adapter, pmpriv->adapter->country_code, country_code[country_id], meas_country_code_len) ==
2848             0)
2849         {
2850             break;
2851         }
2852     }
2853     if (country_id >= 3)
2854     {
2855         country_id = COUNTRY_ID_US; /*Set default to US*/
2856     }
2857     if (wlan_is_etsi_country(pmpriv->adapter, pmpriv->adapter->country_code))
2858     {
2859         country_id = COUNTRY_ID_EU; /** Country in EU */
2860     }
2861     poper_class = (MrvlIETypes_SuppOperClass_t *)(void *)*pptlv_out;
2862     (void)__memset(pmpriv->adapter, poper_class, 0, sizeof(MrvlIETypes_SuppOperClass_t));
2863     poper_class->header.type = wlan_cpu_to_le16(REGULATORY_CLASS);
2864     if (country_id == COUNTRY_ID_US)
2865     {
2866         poper_class->header.len = (t_u16)sizeof(oper_class_us);
2867         (void)__memcpy(pmpriv->adapter, &poper_class->oper_class, oper_class_us, sizeof(oper_class_us));
2868     }
2869     else if (country_id == COUNTRY_ID_JP)
2870     {
2871         poper_class->header.len = (t_u16)sizeof(oper_class_jp);
2872         (void)__memcpy(pmpriv->adapter, &poper_class->oper_class, oper_class_jp, sizeof(oper_class_jp));
2873     }
2874     else if (country_id == COUNTRY_ID_CN)
2875     {
2876         poper_class->header.len = (t_u16)sizeof(oper_class_cn);
2877         (void)__memcpy(pmpriv->adapter, &poper_class->oper_class, oper_class_cn, sizeof(oper_class_cn));
2878     }
2879     else if (country_id == COUNTRY_ID_EU)
2880     {
2881         poper_class->header.len = (t_u16)sizeof(oper_class_eu);
2882         (void)__memcpy(pmpriv->adapter, &poper_class->oper_class, oper_class_eu, sizeof(oper_class_eu));
2883     }
2884     else
2885     {
2886         /* Do nothing */
2887     }
2888     poper_class->current_oper_class = curr_oper_class;
2889     poper_class->header.len += (t_u16)sizeof(poper_class->current_oper_class);
2890     DBG_HEXDUMP(MCMD_D, "Operating class", (t_u8 *)poper_class, sizeof(MrvlIEtypesHeader_t) + poper_class->header.len);
2891     ret = (int)sizeof(MrvlIEtypesHeader_t) + (int)poper_class->header.len;
2892     *pptlv_out += ret;
2893     poper_class->header.len = wlan_cpu_to_le16(poper_class->header.len);
2894 
2895     LEAVE();
2896     return ret;
2897 }
2898 
2899 #if CONFIG_ECSA
2900 /**
2901  *  @brief Check validation of given channel and oper class
2902  *
2903  *  @param pmpriv             A pointer to mlan_private structure
2904  *  @param channel            Channel number
2905  *  @param oper_class         operating class
2906  *
2907  *  @return                   MLAN_STATUS_PENDING --success, otherwise fail
2908  */
2909 mlan_status wlan_check_operclass_validation(mlan_private *pmpriv, t_u8 channel, t_u8 oper_class)
2910 {
2911     int arraysize = 0, i = 0, channum = 0;
2912     oper_bw_chan *poper_bw_chan = MNULL;
2913 #if CONFIG_11AC
2914     t_u8 center_freq_idx = 0;
2915 #endif
2916     t_u8 center_freqs[] = {42, 50, 58, 106, 114, 122, 138, 155};
2917 
2918     ENTER();
2919 
2920     for (i = 0; i < (int)sizeof(center_freqs); i++)
2921     {
2922         if (channel == center_freqs[i])
2923         {
2924             PRINTM(MERROR, "Invalid channel number %d!\n", channel);
2925             LEAVE();
2926             return MLAN_STATUS_FAILURE;
2927         }
2928     }
2929     if (oper_class <= 0 || oper_class > 130)
2930     {
2931         PRINTM(MERROR, "Invalid operating class!\n");
2932         LEAVE();
2933         return MLAN_STATUS_FAILURE;
2934     }
2935 #if CONFIG_11AC
2936     if (oper_class >= 128)
2937     {
2938         center_freq_idx = wlan_get_center_freq_idx(pmpriv, BAND_AAC, channel, CHANNEL_BW_80MHZ);
2939         channel         = center_freq_idx;
2940     }
2941 #endif
2942     poper_bw_chan = wlan_get_nonglobal_operclass_table(pmpriv, &arraysize);
2943 
2944     if (!poper_bw_chan)
2945     {
2946         PRINTM(MCMND, "Operating class table do not find!\n");
2947         LEAVE();
2948         return MLAN_STATUS_FAILURE;
2949     }
2950 
2951     for (i = 0; i < (int)(arraysize / sizeof(oper_bw_chan)); i++)
2952     {
2953         if (poper_bw_chan[i].oper_class == oper_class || poper_bw_chan[i].global_oper_class == oper_class)
2954         {
2955             for (channum = 0; channum < (int)sizeof(poper_bw_chan[i].channel_list); channum++)
2956             {
2957                 if (poper_bw_chan[i].channel_list[channum] && poper_bw_chan[i].channel_list[channum] == channel)
2958                 {
2959                     LEAVE();
2960                     return MLAN_STATUS_SUCCESS;
2961                 }
2962             }
2963         }
2964     }
2965 
2966     PRINTM(MCMND, "Operating class %d do not match channel %d!\n", oper_class, channel);
2967     LEAVE();
2968     return MLAN_STATUS_FAILURE;
2969 }
2970 #endif
2971