1*4882a593Smuzhiyun /**
2*4882a593Smuzhiyun * @file mlan_cfp.c
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * @brief This file contains WLAN client mode channel, frequency and power
5*4882a593Smuzhiyun * related code
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Copyright 2009-2022 NXP
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This software file (the File) is distributed by NXP
11*4882a593Smuzhiyun * under the terms of the GNU General Public License Version 2, June 1991
12*4882a593Smuzhiyun * (the License). You may use, redistribute and/or modify the File in
13*4882a593Smuzhiyun * accordance with the terms and conditions of the License, a copy of which
14*4882a593Smuzhiyun * is available by writing to the Free Software Foundation, Inc.,
15*4882a593Smuzhiyun * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
16*4882a593Smuzhiyun * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
19*4882a593Smuzhiyun * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
20*4882a593Smuzhiyun * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
21*4882a593Smuzhiyun * this warranty disclaimer.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun */
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun /*************************************************************
26*4882a593Smuzhiyun * Change Log:
27*4882a593Smuzhiyun * 04/16/2009: initial version
28*4882a593Smuzhiyun ************************************************************/
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include "mlan.h"
31*4882a593Smuzhiyun #include "mlan_util.h"
32*4882a593Smuzhiyun #include "mlan_fw.h"
33*4882a593Smuzhiyun #include "mlan_join.h"
34*4882a593Smuzhiyun #include "mlan_main.h"
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun /********************************************************
37*4882a593Smuzhiyun * Local Variables
38*4882a593Smuzhiyun ********************************************************/
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /** 100mW */
41*4882a593Smuzhiyun #define WLAN_TX_PWR_DEFAULT 20
42*4882a593Smuzhiyun /** 100mW */
43*4882a593Smuzhiyun #define WLAN_TX_PWR_00_DEFAULT 20
44*4882a593Smuzhiyun /** 100mW */
45*4882a593Smuzhiyun #define WLAN_TX_PWR_US_DEFAULT 20
46*4882a593Smuzhiyun /** 100mW */
47*4882a593Smuzhiyun #define WLAN_TX_PWR_JP_BG_DEFAULT 20
48*4882a593Smuzhiyun /** 200mW */
49*4882a593Smuzhiyun #define WLAN_TX_PWR_JP_A_DEFAULT 23
50*4882a593Smuzhiyun /** 100mW */
51*4882a593Smuzhiyun #define WLAN_TX_PWR_EMEA_DEFAULT 20
52*4882a593Smuzhiyun /** 2000mW */
53*4882a593Smuzhiyun #define WLAN_TX_PWR_CN_2000MW 33
54*4882a593Smuzhiyun /** 200mW */
55*4882a593Smuzhiyun #define WLAN_TX_PWR_200MW 23
56*4882a593Smuzhiyun /** 1000mW */
57*4882a593Smuzhiyun #define WLAN_TX_PWR_1000MW 30
58*4882a593Smuzhiyun /** 250mW */
59*4882a593Smuzhiyun #define WLAN_TX_PWR_250MW 24
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /** Region code mapping */
62*4882a593Smuzhiyun typedef struct _country_code_mapping {
63*4882a593Smuzhiyun /** Region */
64*4882a593Smuzhiyun t_u8 country_code[COUNTRY_CODE_LEN];
65*4882a593Smuzhiyun /** Code for B/G CFP table */
66*4882a593Smuzhiyun t_u8 cfp_code_bg;
67*4882a593Smuzhiyun /** Code for A CFP table */
68*4882a593Smuzhiyun t_u8 cfp_code_a;
69*4882a593Smuzhiyun } country_code_mapping_t;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun #define EU_CFP_CODE_BG 0x30
72*4882a593Smuzhiyun #define EU_CFP_CODE_A 0x30
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /** Region code mapping table */
75*4882a593Smuzhiyun static country_code_mapping_t country_code_mapping[] = {
76*4882a593Smuzhiyun {"WW", 0x00, 0x00}, /* World */
77*4882a593Smuzhiyun {"US", 0x10, 0x10}, /* US FCC */
78*4882a593Smuzhiyun {"CA", 0x10, 0x20}, /* IC Canada */
79*4882a593Smuzhiyun {"SG", 0x10, 0x10}, /* Singapore */
80*4882a593Smuzhiyun {"EU", 0x30, 0x30}, /* ETSI */
81*4882a593Smuzhiyun {"AU", 0x30, 0x30}, /* Australia */
82*4882a593Smuzhiyun {"KR", 0x30, 0x30}, /* Republic Of Korea */
83*4882a593Smuzhiyun {"JP", 0xFF, 0x40}, /* Japan */
84*4882a593Smuzhiyun {"CN", 0x30, 0x50}, /* China */
85*4882a593Smuzhiyun {"BR", 0x01, 0x09}, /* Brazil */
86*4882a593Smuzhiyun {"RU", 0x30, 0x0f}, /* Russia */
87*4882a593Smuzhiyun {"IN", 0x10, 0x06}, /* India */
88*4882a593Smuzhiyun {"MY", 0x30, 0x06}, /* Malaysia */
89*4882a593Smuzhiyun {"NZ", 0x30, 0x30}, /* New Zeland */
90*4882a593Smuzhiyun {"MX", 0x10, 0x07}, /* Mexico */
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /** Country code for ETSI */
94*4882a593Smuzhiyun static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = {
95*4882a593Smuzhiyun "AL", "AD", "AT", "AU", "BE", "BA", "BG", "HR", "CY", "CZ", "DK", "EE",
96*4882a593Smuzhiyun "FI", "FR", "MK", "DE", "GR", "HU", "IS", "IE", "IT", "LV", "LI", "LT",
97*4882a593Smuzhiyun "LU", "MT", "MD", "MC", "ME", "NL", "NO", "PL", "RO", "SM", "RS", "SI",
98*4882a593Smuzhiyun "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NZ", "DZ", "AO", "AM",
99*4882a593Smuzhiyun "AW", "BH", "BD", "BT", "BO", "BQ", "BW", "VG", "BF", "BI", "KH", "CL",
100*4882a593Smuzhiyun "KM", "CG", "CD", "CW", "EG", "FO", "GF", "PF", "GE", "GI", "GP", "HK",
101*4882a593Smuzhiyun "IN", "ID", "IM", "IL", "JE", "KE", "XK", "KW", "LA", "LR", "MW", "MV",
102*4882a593Smuzhiyun "MQ", "MR", "YT", "MA", "MZ", "MM", "NA", "NC", "NE", "NG", "OM", "PS",
103*4882a593Smuzhiyun "PT", "QA", "RW", "RE", "BL", "MF", "VC", "SA", "SC", "ZA", "SZ", "SY",
104*4882a593Smuzhiyun "TZ", "TG", "TN", "AE", "VA", "EH", "YE", "ZM", "ZW"};
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * The structure for Channel-Frequency-Power table
108*4882a593Smuzhiyun */
109*4882a593Smuzhiyun typedef struct _cfp_table {
110*4882a593Smuzhiyun /** Region or Code */
111*4882a593Smuzhiyun t_u8 code;
112*4882a593Smuzhiyun /** Frequency/Power */
113*4882a593Smuzhiyun chan_freq_power_t *cfp;
114*4882a593Smuzhiyun /** No of CFP flag */
115*4882a593Smuzhiyun int cfp_no;
116*4882a593Smuzhiyun } cfp_table_t;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /* Format { Channel, Frequency (MHz), MaxTxPower } */
119*4882a593Smuzhiyun /** Band : 'B/G', Region: World Wide Safe */
120*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_00_BG[] = {
121*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
122*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
123*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
124*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
125*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
126*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
127*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
128*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
129*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
130*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
131*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x1c, 0, 0}},
132*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x1d, 0, 0}},
133*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x1d, 0, 0}}};
134*4882a593Smuzhiyun /* Format { Channel, Frequency (MHz), MaxTxPower } */
135*4882a593Smuzhiyun /** Band: 'B/G', Region: USA FCC/Canada IC */
136*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_US_BG[] = {
137*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
138*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
139*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
140*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
141*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
142*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
143*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
144*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
145*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
146*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}},
147*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x1c, 0, 0}}};
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /** Band: 'B/G', Region: Europe ETSI/China */
150*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_EU_BG[] = {
151*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
152*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
153*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
154*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
155*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
156*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
157*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
158*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
159*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
160*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
161*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
162*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}},
163*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x1c, 0, 0}}};
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /** Band: 'B/G', Region: Japan */
166*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_JPN41_BG[] = {
167*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
168*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
169*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
170*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
171*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
172*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
173*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
174*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
175*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
176*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
177*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
178*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
179*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}}};
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /** Band: 'B/G', Region: Japan */
182*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_JPN40_BG[] = {
183*4882a593Smuzhiyun {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1d, 0, 0}}};
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /** Band: 'B/G', Region: Japan */
186*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_JPNFE_BG[] = {
187*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
188*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
189*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
190*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
191*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
192*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
193*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
194*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
195*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
196*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
197*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
198*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MTRUE, {0x1d, 0, 0}},
199*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MTRUE, {0x1d, 0, 0}}};
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /** Band : 'B/G', Region: Brazil */
202*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_BR_BG[] = {
203*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
204*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
205*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
206*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
207*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
208*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
209*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
210*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
211*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
212*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
213*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
214*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}},
215*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_1000MW, MFALSE, {0x1c, 0, 0}}};
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun /** Band : 'B/G', Region: Special */
218*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_SPECIAL_BG[] = {
219*4882a593Smuzhiyun {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
220*4882a593Smuzhiyun {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
221*4882a593Smuzhiyun {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
222*4882a593Smuzhiyun {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
223*4882a593Smuzhiyun {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
224*4882a593Smuzhiyun {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
225*4882a593Smuzhiyun {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
226*4882a593Smuzhiyun {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
227*4882a593Smuzhiyun {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
228*4882a593Smuzhiyun {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
229*4882a593Smuzhiyun {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
230*4882a593Smuzhiyun {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
231*4882a593Smuzhiyun {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}},
232*4882a593Smuzhiyun {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE, {0x1c, 0, 0}}};
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /**
235*4882a593Smuzhiyun * The 2.4GHz CFP tables
236*4882a593Smuzhiyun */
237*4882a593Smuzhiyun static cfp_table_t cfp_table_BG[] = {
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun 0x01, /* Brazil */
240*4882a593Smuzhiyun channel_freq_power_BR_BG,
241*4882a593Smuzhiyun NELEMENTS(channel_freq_power_BR_BG),
242*4882a593Smuzhiyun },
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 0x00, /* World FCC */
245*4882a593Smuzhiyun channel_freq_power_00_BG,
246*4882a593Smuzhiyun NELEMENTS(channel_freq_power_00_BG),
247*4882a593Smuzhiyun },
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 0x10, /* US FCC */
250*4882a593Smuzhiyun channel_freq_power_US_BG,
251*4882a593Smuzhiyun NELEMENTS(channel_freq_power_US_BG),
252*4882a593Smuzhiyun },
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 0x20, /* CANADA IC */
255*4882a593Smuzhiyun channel_freq_power_US_BG,
256*4882a593Smuzhiyun NELEMENTS(channel_freq_power_US_BG),
257*4882a593Smuzhiyun },
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun 0x30, /* EU */
260*4882a593Smuzhiyun channel_freq_power_EU_BG,
261*4882a593Smuzhiyun NELEMENTS(channel_freq_power_EU_BG),
262*4882a593Smuzhiyun },
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 0x40, /* JAPAN */
265*4882a593Smuzhiyun channel_freq_power_JPN40_BG,
266*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPN40_BG),
267*4882a593Smuzhiyun },
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 0x41, /* JAPAN */
270*4882a593Smuzhiyun channel_freq_power_JPN41_BG,
271*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPN41_BG),
272*4882a593Smuzhiyun },
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 0x50, /* China */
275*4882a593Smuzhiyun channel_freq_power_EU_BG,
276*4882a593Smuzhiyun NELEMENTS(channel_freq_power_EU_BG),
277*4882a593Smuzhiyun },
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 0xfe, /* JAPAN */
280*4882a593Smuzhiyun channel_freq_power_JPNFE_BG,
281*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPNFE_BG),
282*4882a593Smuzhiyun },
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 0xff, /* Special */
285*4882a593Smuzhiyun channel_freq_power_SPECIAL_BG,
286*4882a593Smuzhiyun NELEMENTS(channel_freq_power_SPECIAL_BG),
287*4882a593Smuzhiyun },
288*4882a593Smuzhiyun /* Add new region here */
289*4882a593Smuzhiyun };
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /** Number of the CFP tables for 2.4GHz */
292*4882a593Smuzhiyun #define MLAN_CFP_TABLE_SIZE_BG (NELEMENTS(cfp_table_BG))
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun /* Format { Channel, Frequency (MHz), MaxTxPower, DFS } */
295*4882a593Smuzhiyun /** Band: 'A', Region: World Wide Safe */
296*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_00_A[] = {
297*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
298*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
299*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
300*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
301*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
302*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
303*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
304*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
305*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
306*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
307*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
308*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
309*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
310*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
311*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
312*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
313*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
314*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
315*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
316*4882a593Smuzhiyun {144, 5720, WLAN_TX_PWR_00_DEFAULT, MTRUE, {0x13, 0, 0}},
317*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
318*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
319*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
320*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}},
321*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_00_DEFAULT, MFALSE, {0x10, 0, 0}}};
322*4882a593Smuzhiyun /* Format { Channel, Frequency (MHz), MaxTxPower, DFS } */
323*4882a593Smuzhiyun /** Band: 'A', Region: USA FCC */
324*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_A[] = {
325*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
326*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
327*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
328*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
329*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
330*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
331*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
332*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
333*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
334*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
335*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
336*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
337*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
338*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
339*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
340*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
341*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
342*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
343*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
344*4882a593Smuzhiyun {144, 5720, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
345*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
346*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
347*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
348*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
349*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
350*4882a593Smuzhiyun {169, 5845, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
351*4882a593Smuzhiyun {173, 5865, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
352*4882a593Smuzhiyun {177, 5885, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}};
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun /** Band: 'A', Region: Canada IC */
355*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_CAN_A[] = {
356*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
357*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
358*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
359*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
360*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
361*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
362*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
363*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
364*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
365*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
366*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
367*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
368*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
369*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
370*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
371*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
372*4882a593Smuzhiyun {144, 5720, WLAN_TX_PWR_US_DEFAULT, MTRUE, {0x13, 0, 0}},
373*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
374*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
375*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
376*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}},
377*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}};
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /** Band: 'A', Region: Europe ETSI */
380*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_EU_A[] = {
381*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
382*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
383*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
384*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
385*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
386*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
387*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
388*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
389*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
390*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
391*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
392*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
393*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
394*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
395*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
396*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
397*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
398*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
399*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
400*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
401*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
402*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
403*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
404*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}}};
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /** Band: 'A', Region: Japan */
407*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_JPN_A[] = {
408*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_JP_A_DEFAULT, MFALSE, {0x10, 0, 0}},
409*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_JP_A_DEFAULT, MFALSE, {0x10, 0, 0}},
410*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_JP_A_DEFAULT, MFALSE, {0x10, 0, 0}},
411*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_JP_A_DEFAULT, MFALSE, {0x10, 0, 0}},
412*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
413*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
414*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
415*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
416*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
417*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
418*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
419*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
420*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
421*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
422*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
423*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
424*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
425*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
426*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}},
427*4882a593Smuzhiyun {144, 5720, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE, {0x13, 0, 0}}};
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /** Band: 'A', Region: China */
430*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_CN_A[] = {
431*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
432*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
433*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
434*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
435*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
436*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
437*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
438*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
439*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_CN_2000MW, MFALSE, {0x10, 0, 0}},
440*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_CN_2000MW, MFALSE, {0x10, 0, 0}},
441*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_CN_2000MW, MFALSE, {0x10, 0, 0}},
442*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_CN_2000MW, MFALSE, {0x10, 0, 0}},
443*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_CN_2000MW, MFALSE, {0x10, 0, 0}}};
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun /** Band: 'A', NULL */
446*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_NULL_A[] = {};
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun /** Band: 'A', Region: Spain/Austria/Brazil */
449*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_SPN2_A[] = {
450*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
451*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
452*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
453*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_200MW, MFALSE, {0x10, 0, 0}},
454*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
455*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
456*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}},
457*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_200MW, MTRUE, {0x13, 0, 0}}};
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /** Band: 'A', Region: Brazil */
460*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_BR1_A[] = {
461*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
462*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
463*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
464*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
465*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
466*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
467*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
468*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
469*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
470*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}},
471*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_250MW, MTRUE, {0x13, 0, 0}}};
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun /** Band: 'A', Region: Brazil */
474*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_BR2_A[] = {
475*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_1000MW, MFALSE, {0x10, 0, 0}},
476*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_1000MW, MFALSE, {0x10, 0, 0}},
477*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_1000MW, MFALSE, {0x10, 0, 0}},
478*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_1000MW, MFALSE, {0x10, 0, 0}},
479*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_1000MW, MFALSE, {0x10, 0, 0}}};
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun /** Band: 'A', Region: Russia */
482*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_RU_A[] = {
483*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
484*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
485*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
486*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
487*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
488*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
489*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
490*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
491*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
492*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
493*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
494*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
495*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
496*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
497*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}};
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun /** Band: 'A', Region: Mexico */
500*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_MX_A[] = {
501*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
502*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
503*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
504*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
505*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
506*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
507*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
508*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
509*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
510*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
511*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
512*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
513*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
514*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
515*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
516*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE, {0x13, 0, 0}},
517*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
518*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
519*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
520*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}},
521*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE, {0x10, 0, 0}}};
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun /** Band: 'A', Code: 1, Low band (5150-5250 MHz) channels */
524*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_low_band[] = {
525*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
526*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
527*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
528*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}};
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /** Band: 'A', Code: 2, Lower middle band (5250-5350 MHz) channels */
531*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_lower_middle_band[] = {
532*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
533*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
534*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
535*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}}};
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /** Band: 'A', Code: 3, Upper middle band (5470-5725 MHz) channels */
538*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_upper_middle_band[] = {
539*4882a593Smuzhiyun {100, 5500, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
540*4882a593Smuzhiyun {104, 5520, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
541*4882a593Smuzhiyun {108, 5540, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
542*4882a593Smuzhiyun {112, 5560, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
543*4882a593Smuzhiyun {116, 5580, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
544*4882a593Smuzhiyun {120, 5600, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
545*4882a593Smuzhiyun {124, 5620, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
546*4882a593Smuzhiyun {128, 5640, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
547*4882a593Smuzhiyun {132, 5660, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
548*4882a593Smuzhiyun {136, 5680, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}},
549*4882a593Smuzhiyun {140, 5700, WLAN_TX_PWR_DEFAULT, MTRUE, {0x13, 0, 0}}};
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun /** Band: 'A', Code: 4, High band (5725-5850 MHz) channels */
552*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_high_band[] = {
553*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
554*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
555*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
556*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
557*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}};
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun /** Band: 'A', Code: 5, Low band (5150-5250 MHz) and
560*4882a593Smuzhiyun * High band (5725-5850 MHz) channels
561*4882a593Smuzhiyun */
562*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_low_high_band[] = {
563*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
564*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
565*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
566*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
567*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
568*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
569*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
570*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
571*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}};
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun /** Band: 'A', Code: 6, Low band (5150-5250 MHz) and
574*4882a593Smuzhiyun * mid low (5260-5320) and High band (5725-5850 MHz) channels
575*4882a593Smuzhiyun */
576*4882a593Smuzhiyun static chan_freq_power_t channel_freq_power_low_middle_high_band[] = {
577*4882a593Smuzhiyun {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
578*4882a593Smuzhiyun {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
579*4882a593Smuzhiyun {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
580*4882a593Smuzhiyun {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
581*4882a593Smuzhiyun {52, 5260, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
582*4882a593Smuzhiyun {56, 5280, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
583*4882a593Smuzhiyun {60, 5300, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
584*4882a593Smuzhiyun {64, 5320, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
585*4882a593Smuzhiyun {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
586*4882a593Smuzhiyun {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
587*4882a593Smuzhiyun {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
588*4882a593Smuzhiyun {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}},
589*4882a593Smuzhiyun {165, 5825, WLAN_TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}};
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun /**
592*4882a593Smuzhiyun * The 5GHz CFP tables
593*4882a593Smuzhiyun */
594*4882a593Smuzhiyun static cfp_table_t cfp_table_A[] = {
595*4882a593Smuzhiyun {0x1, /* Low band (5150-5250 MHz) channels */
596*4882a593Smuzhiyun channel_freq_power_low_band, NELEMENTS(channel_freq_power_low_band)},
597*4882a593Smuzhiyun {0x2, /* Lower middle band (5250-5350 MHz) channels */
598*4882a593Smuzhiyun channel_freq_power_lower_middle_band,
599*4882a593Smuzhiyun NELEMENTS(channel_freq_power_lower_middle_band)},
600*4882a593Smuzhiyun {0x3, /* Upper middle band (5470-5725 MHz) channels */
601*4882a593Smuzhiyun channel_freq_power_upper_middle_band,
602*4882a593Smuzhiyun NELEMENTS(channel_freq_power_upper_middle_band)},
603*4882a593Smuzhiyun {0x4, /* High band (5725-5850 MHz) channels */
604*4882a593Smuzhiyun channel_freq_power_high_band, NELEMENTS(channel_freq_power_high_band)},
605*4882a593Smuzhiyun {0x5, /* Low band (5150-5250 MHz) and
606*4882a593Smuzhiyun * High band (5725-5850 MHz) channels
607*4882a593Smuzhiyun */
608*4882a593Smuzhiyun channel_freq_power_low_high_band,
609*4882a593Smuzhiyun NELEMENTS(channel_freq_power_low_high_band)},
610*4882a593Smuzhiyun {0x6, /* Low band (5150-5250 MHz)
611*4882a593Smuzhiyun * Mid band (5260-5320) and
612*4882a593Smuzhiyun * High band (5725-5850 MHz) channels
613*4882a593Smuzhiyun */
614*4882a593Smuzhiyun channel_freq_power_low_middle_high_band,
615*4882a593Smuzhiyun NELEMENTS(channel_freq_power_low_middle_high_band)},
616*4882a593Smuzhiyun {
617*4882a593Smuzhiyun 0x07, /* Mexico */
618*4882a593Smuzhiyun channel_freq_power_MX_A,
619*4882a593Smuzhiyun NELEMENTS(channel_freq_power_MX_A),
620*4882a593Smuzhiyun },
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 0x09, /* SPAIN/Austria/Brazil */
624*4882a593Smuzhiyun channel_freq_power_SPN2_A,
625*4882a593Smuzhiyun NELEMENTS(channel_freq_power_SPN2_A),
626*4882a593Smuzhiyun },
627*4882a593Smuzhiyun {
628*4882a593Smuzhiyun 0x0c, /* Brazil */
629*4882a593Smuzhiyun channel_freq_power_BR1_A,
630*4882a593Smuzhiyun NELEMENTS(channel_freq_power_BR1_A),
631*4882a593Smuzhiyun },
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun 0x0e, /* Brazil */
634*4882a593Smuzhiyun channel_freq_power_BR2_A,
635*4882a593Smuzhiyun NELEMENTS(channel_freq_power_BR2_A),
636*4882a593Smuzhiyun },
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun 0x0f, /* Russia */
639*4882a593Smuzhiyun channel_freq_power_RU_A,
640*4882a593Smuzhiyun NELEMENTS(channel_freq_power_RU_A),
641*4882a593Smuzhiyun },
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun 0x00, /* World */
644*4882a593Smuzhiyun channel_freq_power_00_A,
645*4882a593Smuzhiyun NELEMENTS(channel_freq_power_00_A),
646*4882a593Smuzhiyun },
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 0x10, /* US FCC */
649*4882a593Smuzhiyun channel_freq_power_A,
650*4882a593Smuzhiyun NELEMENTS(channel_freq_power_A),
651*4882a593Smuzhiyun },
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 0x20, /* CANADA IC */
654*4882a593Smuzhiyun channel_freq_power_CAN_A,
655*4882a593Smuzhiyun NELEMENTS(channel_freq_power_CAN_A),
656*4882a593Smuzhiyun },
657*4882a593Smuzhiyun {
658*4882a593Smuzhiyun 0x30, /* EU */
659*4882a593Smuzhiyun channel_freq_power_EU_A,
660*4882a593Smuzhiyun NELEMENTS(channel_freq_power_EU_A),
661*4882a593Smuzhiyun },
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun 0x40, /* JAPAN */
664*4882a593Smuzhiyun channel_freq_power_JPN_A,
665*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPN_A),
666*4882a593Smuzhiyun },
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun 0x41, /* JAPAN */
669*4882a593Smuzhiyun channel_freq_power_JPN_A,
670*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPN_A),
671*4882a593Smuzhiyun },
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun 0x50, /* China */
674*4882a593Smuzhiyun channel_freq_power_CN_A,
675*4882a593Smuzhiyun NELEMENTS(channel_freq_power_CN_A),
676*4882a593Smuzhiyun },
677*4882a593Smuzhiyun {
678*4882a593Smuzhiyun 0xfe, /* JAPAN */
679*4882a593Smuzhiyun channel_freq_power_NULL_A,
680*4882a593Smuzhiyun NELEMENTS(channel_freq_power_NULL_A),
681*4882a593Smuzhiyun },
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun 0xff, /* Special */
684*4882a593Smuzhiyun channel_freq_power_JPN_A,
685*4882a593Smuzhiyun NELEMENTS(channel_freq_power_JPN_A),
686*4882a593Smuzhiyun },
687*4882a593Smuzhiyun /* Add new region here */
688*4882a593Smuzhiyun };
689*4882a593Smuzhiyun /** Number of the CFP tables for 5GHz */
690*4882a593Smuzhiyun #define MLAN_CFP_TABLE_SIZE_A (NELEMENTS(cfp_table_A))
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun enum { RATEID_DBPSK1Mbps, //(0)
693*4882a593Smuzhiyun RATEID_DQPSK2Mbps, //(1)
694*4882a593Smuzhiyun RATEID_CCK5_5Mbps, //(2)
695*4882a593Smuzhiyun RATEID_CCK11Mbps, //(3)
696*4882a593Smuzhiyun RATEID_CCK22Mbps, //(4)
697*4882a593Smuzhiyun RATEID_OFDM6Mbps, //(5)
698*4882a593Smuzhiyun RATEID_OFDM9Mbps, //(6)
699*4882a593Smuzhiyun RATEID_OFDM12Mbps, //(7)
700*4882a593Smuzhiyun RATEID_OFDM18Mbps, //(8)
701*4882a593Smuzhiyun RATEID_OFDM24Mbps, //(9)
702*4882a593Smuzhiyun RATEID_OFDM36Mbps, //(10)
703*4882a593Smuzhiyun RATEID_OFDM48Mbps, //(11)
704*4882a593Smuzhiyun RATEID_OFDM54Mbps, //(12)
705*4882a593Smuzhiyun RATEID_OFDM72Mbps, //(13)
706*4882a593Smuzhiyun };
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun static const t_u8 rateUnit_500Kbps[] = {
709*4882a593Smuzhiyun (10 / 5), /* 1Mbps */
710*4882a593Smuzhiyun (20 / 5), /* 2Mbps */
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun (55 / 5), /* 5.5Mbps */
713*4882a593Smuzhiyun (110 / 5), /* 11Mbps */
714*4882a593Smuzhiyun (10 / 5), /* 22Mbps, intentionally set to 1Mbps
715*4882a593Smuzhiyun * because it's not available
716*4882a593Smuzhiyun */
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun (60 / 5), /* 6Mbps */
719*4882a593Smuzhiyun (90 / 5), /* 9Mbps */
720*4882a593Smuzhiyun (120 / 5), /* 12Mbps */
721*4882a593Smuzhiyun (180 / 5), /* 18Mbps */
722*4882a593Smuzhiyun (240 / 5), /* 24Mbps */
723*4882a593Smuzhiyun (360 / 5), /* 36Mbps */
724*4882a593Smuzhiyun (480 / 5), /* 48Mbps */
725*4882a593Smuzhiyun (540 / 5), /* 54Mbps */
726*4882a593Smuzhiyun (60 / 5), /* 72Mbps, intentionally set to 6Mbps
727*4882a593Smuzhiyun * because it's not available
728*4882a593Smuzhiyun */
729*4882a593Smuzhiyun };
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun typedef struct _rate_map {
732*4882a593Smuzhiyun /** Rate, in 0.5Mbps */
733*4882a593Smuzhiyun t_u32 rate;
734*4882a593Smuzhiyun /** Mrvl rate id, refer to RATEID_XXX in FW */
735*4882a593Smuzhiyun t_u32 id;
736*4882a593Smuzhiyun /** nss: 0-nss1, 1-nss2 */
737*4882a593Smuzhiyun t_u8 nss;
738*4882a593Smuzhiyun } rate_map;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun /** If user configure to 1x1 or we found peer device only support 1x1,
741*4882a593Smuzhiyun * then we need skip the nss1 part when map to Mrvl rate.
742*4882a593Smuzhiyun */
743*4882a593Smuzhiyun static const rate_map rate_map_table_2x2[] = {
744*4882a593Smuzhiyun /* LG <--> Mrvl rate idx */
745*4882a593Smuzhiyun {2, 0, 0}, // RATEID_DBPSK1Mbps
746*4882a593Smuzhiyun {4, 1, 0}, // RATEID_DQPSK2Mbps
747*4882a593Smuzhiyun {11, 2, 0}, // RATEID_CCK5_5Mbps
748*4882a593Smuzhiyun {22, 3, 0}, // RATEID_CCK11Mbps
749*4882a593Smuzhiyun {44, 4, 0}, // RATEID_CCK22Mbps
750*4882a593Smuzhiyun {12, 5, 0}, // RATEID_OFDM6Mbps
751*4882a593Smuzhiyun {18, 6, 0}, // RATEID_OFDM9Mbps
752*4882a593Smuzhiyun {24, 7, 0}, // RATEID_OFDM12Mbps
753*4882a593Smuzhiyun {36, 8, 0}, // RATEID_OFDM18Mbps
754*4882a593Smuzhiyun {48, 9, 0}, // RATEID_OFDM24Mbps
755*4882a593Smuzhiyun {72, 10, 0}, // RATEID_OFDM36Mbps
756*4882a593Smuzhiyun {96, 11, 0}, // RATEID_OFDM48Mbps
757*4882a593Smuzhiyun {108, 12, 0}, // RATEID_OFDM54Mbps
758*4882a593Smuzhiyun {144, 13, 0}, // RATEID_OFDM72Mbps
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun /* HT bw20 <--> Mrvl rate idx - nss2 */
761*4882a593Smuzhiyun {26, 22, 1}, // RATEID_MCS8_13Mbps
762*4882a593Smuzhiyun {52, 23, 1}, // RATEID_MCS9_26Mbps
763*4882a593Smuzhiyun {78, 24, 1}, // RATEID_MCS10_39Mbps
764*4882a593Smuzhiyun {104, 25, 1}, // RATEID_MCS11_52Mbps
765*4882a593Smuzhiyun {156, 26, 1}, // RATEID_MCS12_78Mbps
766*4882a593Smuzhiyun {208, 27, 1}, // RATEID_MCS13_104Mbps
767*4882a593Smuzhiyun {234, 28, 1}, // RATEID_MCS14_117Mbps
768*4882a593Smuzhiyun {260, 29, 1}, // RATEID_MCS15_130Mbps
769*4882a593Smuzhiyun /* HT bw20 <--> Mrvl rate idx - nss1 */
770*4882a593Smuzhiyun {13, 14, 0}, // RATEID_MCS0_6d5Mbps
771*4882a593Smuzhiyun {26, 15, 0}, // RATEID_MCS1_13Mbps
772*4882a593Smuzhiyun {39, 16, 0}, // RATEID_MCS2_19d5Mbps
773*4882a593Smuzhiyun {52, 17, 0}, // RATEID_MCS3_26Mbps
774*4882a593Smuzhiyun {78, 18, 0}, // RATEID_MCS4_39Mbps
775*4882a593Smuzhiyun {104, 19, 0}, // RATEID_MCS5_52Mbps
776*4882a593Smuzhiyun {117, 20, 0}, // RATEID_MCS6_58d5Mbps
777*4882a593Smuzhiyun {130, 21, 0}, // RATEID_MCS7_65Mbps
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun /* HT bw40<--> Mrvl rate idx - nss2 */
780*4882a593Smuzhiyun {54, 39, 1}, // RATEID_MCS8BW40_27Mbps
781*4882a593Smuzhiyun {108, 40, 1}, // RATEID_MCS9BW40_54Mbps
782*4882a593Smuzhiyun {162, 41, 1}, // RATEID_MCS10BW40_81Mbps
783*4882a593Smuzhiyun {216, 42, 1}, // RATEID_MCS11BW40_108Mbps
784*4882a593Smuzhiyun {324, 43, 1}, // RATEID_MCS12BW40_162Mbps
785*4882a593Smuzhiyun {432, 44, 1}, // RATEID_MCS13BW40_216Mbps
786*4882a593Smuzhiyun {486, 45, 1}, // RATEID_MCS14BW40_243Mbps
787*4882a593Smuzhiyun {540, 46, 1}, // RATEID_MCS15BW40_270Mbps
788*4882a593Smuzhiyun /* HT bw40<--> Mrvl rate idx - nss1 */
789*4882a593Smuzhiyun {12, 30, 0}, // RATEID_MCS32BW40_6Mbps
790*4882a593Smuzhiyun {27, 31, 0}, // RATEID_MCS0BW40_13d5Mbps
791*4882a593Smuzhiyun {54, 32, 0}, // RATEID_MCS1BW40_27Mbps
792*4882a593Smuzhiyun {81, 33, 0}, // RATEID_MCS2BW40_40d5Mbps
793*4882a593Smuzhiyun {108, 34, 0}, // RATEID_MCS3BW40_54Mbps
794*4882a593Smuzhiyun {162, 35, 0}, // RATEID_MCS4BW40_81Mbps
795*4882a593Smuzhiyun {216, 36, 0}, // RATEID_MCS5BW40_108Mbps
796*4882a593Smuzhiyun {243, 37, 0}, // RATEID_MCS6BW40_121d5Mbps
797*4882a593Smuzhiyun {270, 38, 0}, // RATEID_MCS7BW40_135Mbps
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun /* VHT bw20<--> Mrvl rate idx - nss2 */
800*4882a593Smuzhiyun {26, 57, 1}, // RATEID_VHT_MCS0_2SS_BW20 13 Mbps
801*4882a593Smuzhiyun {52, 58, 1}, // RATEID_VHT_MCS1_2SS_BW20 26 Mbps
802*4882a593Smuzhiyun {78, 59, 1}, // RATEID_VHT_MCS2_2SS_BW20 39 Mbps
803*4882a593Smuzhiyun {104, 60, 1}, // RATEID_VHT_MCS3_2SS_BW20 52 Mbps
804*4882a593Smuzhiyun {156, 61, 1}, // RATEID_VHT_MCS4_2SS_BW20 78 Mbps
805*4882a593Smuzhiyun {208, 62, 1}, // RATEID_VHT_MCS5_2SS_BW20 104 Mbps
806*4882a593Smuzhiyun {234, 63, 1}, // RATEID_VHT_MCS6_2SS_BW20 117 Mbps
807*4882a593Smuzhiyun {260, 64, 1}, // RATEID_VHT_MCS7_2SS_BW20 130 Mbps
808*4882a593Smuzhiyun {312, 65, 1}, // RATEID_VHT_MCS8_2SS_BW20 156 Mbps
809*4882a593Smuzhiyun {0, 66, 1}, // RATEID_VHT_MCS9_2SS_BW20 173.3 Mbps(INVALID)
810*4882a593Smuzhiyun /* VHT bw20<--> Mrvl rate idx - nss1 */
811*4882a593Smuzhiyun {13, 47, 0}, // RATEID_VHT_MCS0_1SS_BW20 6.5 Mbps
812*4882a593Smuzhiyun {26, 48, 0}, // RATEID_VHT_MCS1_1SS_BW20 13 Mbps
813*4882a593Smuzhiyun {39, 49, 0}, // RATEID_VHT_MCS2_1SS_BW20 19.5 Mbps
814*4882a593Smuzhiyun {52, 50, 0}, // RATEID_VHT_MCS3_1SS_BW20 26 Mbps
815*4882a593Smuzhiyun {78, 51, 0}, // RATEID_VHT_MCS4_1SS_BW20 39 Mbps
816*4882a593Smuzhiyun {104, 52, 0}, // RATEID_VHT_MCS5_1SS_BW20 52 Mbps
817*4882a593Smuzhiyun {117, 53, 0}, // RATEID_VHT_MCS6_1SS_BW20 58.5 Mbps
818*4882a593Smuzhiyun {130, 54, 0}, // RATEID_VHT_MCS7_1SS_BW20 65 Mbps
819*4882a593Smuzhiyun {156, 55, 0}, // RATEID_VHT_MCS8_1SS_BW20 78 Mbps
820*4882a593Smuzhiyun {0, 56, 0}, // RATEID_VHT_MCS9_1SS_BW20 86.7 Mbps(INVALID)
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun /* VHT bw40<--> Mrvl rate idx - nss2 */
823*4882a593Smuzhiyun {54, 77, 1}, // RATEID_VHT_MCS0_2SS_BW40 27 Mbps
824*4882a593Smuzhiyun {108, 78, 1}, // RATEID_VHT_MCS1_2SS_BW40 54 Mbps
825*4882a593Smuzhiyun {162, 79, 1}, // RATEID_VHT_MCS2_2SS_BW40 81 Mbps
826*4882a593Smuzhiyun {216, 80, 1}, // RATEID_VHT_MCS3_2SS_BW40 108 Mbps
827*4882a593Smuzhiyun {324, 81, 1}, // RATEID_VHT_MCS4_2SS_BW40 162 Mbps
828*4882a593Smuzhiyun {432, 82, 1}, // RATEID_VHT_MCS5_2SS_BW40 216 Mbps
829*4882a593Smuzhiyun {486, 83, 1}, // RATEID_VHT_MCS6_2SS_BW40 243 Mbps
830*4882a593Smuzhiyun {540, 84, 1}, // RATEID_VHT_MCS7_2SS_BW40 270 Mbps
831*4882a593Smuzhiyun {648, 85, 1}, // RATEID_VHT_MCS8_2SS_BW40 324 Mbps
832*4882a593Smuzhiyun {720, 86, 1}, // RATEID_VHT_MCS9_2SS_BW40 360 Mbps
833*4882a593Smuzhiyun /* VHT bw40<--> Mrvl rate idx - nss1 */
834*4882a593Smuzhiyun {27, 67, 0}, // RATEID_VHT_MCS0_1SS_BW40 13.5 Mbps
835*4882a593Smuzhiyun {54, 68, 0}, // RATEID_VHT_MCS1_1SS_BW40 27 Mbps
836*4882a593Smuzhiyun {81, 69, 0}, // RATEID_VHT_MCS2_1SS_BW40 40.5 Mbps
837*4882a593Smuzhiyun {108, 70, 0}, // RATEID_VHT_MCS3_1SS_BW40 54 Mbps
838*4882a593Smuzhiyun {162, 71, 0}, // RATEID_VHT_MCS4_1SS_BW40 81 Mbps
839*4882a593Smuzhiyun {216, 72, 0}, // RATEID_VHT_MCS5_1SS_BW40 108 Mbps
840*4882a593Smuzhiyun {243, 73, 0}, // RATEID_VHT_MCS6_1SS_BW40 121.5 Mbps
841*4882a593Smuzhiyun {270, 74, 0}, // RATEID_VHT_MCS7_1SS_BW40 135 Mbps
842*4882a593Smuzhiyun {324, 75, 0}, // RATEID_VHT_MCS8_1SS_BW40 162 Mbps
843*4882a593Smuzhiyun {360, 76, 0}, // RATEID_VHT_MCS9_1SS_BW40 180 Mbps
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun /* VHT bw80<--> Mrvl rate idx - nss2 */
846*4882a593Smuzhiyun {117, 97, 1}, // RATEID_VHT_MCS0_2SS_BW80 58.5 Mbps
847*4882a593Smuzhiyun {234, 98, 1}, // RATEID_VHT_MCS1_2SS_BW80 117 Mbps
848*4882a593Smuzhiyun {350, 99, 1}, // RATEID_VHT_MCS2_2SS_BW80 175 Mbps
849*4882a593Smuzhiyun {468, 100, 1}, // RATEID_VHT_MCS3_2SS_BW80 234 Mbps
850*4882a593Smuzhiyun {702, 101, 1}, // RATEID_VHT_MCS4_2SS_BW80 351 Mbps
851*4882a593Smuzhiyun {936, 102, 1}, // RATEID_VHT_MCS5_2SS_BW80 468 Mbps
852*4882a593Smuzhiyun {1053, 103, 1}, // RATEID_VHT_MCS6_2SS_BW80 526.5 Mbps
853*4882a593Smuzhiyun {1170, 104, 1}, // RATEID_VHT_MCS7_2SS_BW80 585 Mbps
854*4882a593Smuzhiyun {1404, 105, 1}, // RATEID_VHT_MCS8_2SS_BW80 702 Mbps
855*4882a593Smuzhiyun {1560, 106, 1}, // RATEID_VHT_MCS9_2SS_BW80 780 Mbps
856*4882a593Smuzhiyun /* VHT bw80<--> Mrvl rate idx - nss1 */
857*4882a593Smuzhiyun {58, 87, 0}, // RATEID_VHT_MCS0_1SS_BW80 29.3 Mbps, 29.3x2 could
858*4882a593Smuzhiyun // correspond to 58
859*4882a593Smuzhiyun {59, 87, 0}, // RATEID_VHT_MCS0_1SS_BW80 29.3 Mbps, 29.3*2 could
860*4882a593Smuzhiyun // correspond to 59 too
861*4882a593Smuzhiyun {117, 88, 0}, // RATEID_VHT_MCS1_1SS_BW80 58.5 Mbps
862*4882a593Smuzhiyun {175, 89, 0}, // RATEID_VHT_MCS2_1SS_BW80 87.8 Mbps, 87.8x2 could
863*4882a593Smuzhiyun // correspond to 175
864*4882a593Smuzhiyun {176, 89, 0}, // RATEID_VHT_MCS2_1SS_BW80 87.8 Mbps, 87.8x2 could
865*4882a593Smuzhiyun // correspond to 176 too
866*4882a593Smuzhiyun {234, 90, 0}, // RATEID_VHT_MCS3_1SS_BW80 117 Mbps
867*4882a593Smuzhiyun {351, 91, 0}, // RATEID_VHT_MCS4_1SS_BW80 175.5 Mbps
868*4882a593Smuzhiyun {468, 92, 0}, // RATEID_VHT_MCS5_1SS_BW80 234 Mbps
869*4882a593Smuzhiyun {526, 93, 0}, // RATEID_VHT_MCS6_1SS_BW80 263.3 Mbps, 263.3x2 could
870*4882a593Smuzhiyun // correspond to 526
871*4882a593Smuzhiyun {527, 93, 0}, // RATEID_VHT_MCS6_1SS_BW80 263.3 Mbps, 263.3x2 could
872*4882a593Smuzhiyun // correspond to 527 too
873*4882a593Smuzhiyun {585, 94, 0}, // RATEID_VHT_MCS7_1SS_BW80 292.5 Mbps
874*4882a593Smuzhiyun {702, 95, 0}, // RATEID_VHT_MCS8_1SS_BW80 351 Mbps
875*4882a593Smuzhiyun {780, 96, 0}, // RATEID_VHT_MCS9_1SS_BW80 390 Mbps
876*4882a593Smuzhiyun };
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun /** rate_map_table_1x1 is based on rate_map_table_2x2 and remove nss2 part.
879*4882a593Smuzhiyun * For the chip who only support 1x1, Mrvl rate idx define is different with 2x2
880*4882a593Smuzhiyun * in FW We need redefine a bitrate to Mrvl rate idx table for 1x1 chip.
881*4882a593Smuzhiyun */
882*4882a593Smuzhiyun static const rate_map rate_map_table_1x1[] = {
883*4882a593Smuzhiyun /* LG <--> Mrvl rate idx */
884*4882a593Smuzhiyun {2, 0, 0}, // RATEID_DBPSK1Mbps
885*4882a593Smuzhiyun {4, 1, 0}, // RATEID_DQPSK2Mbps
886*4882a593Smuzhiyun {11, 2, 0}, // RATEID_CCK5_5Mbps
887*4882a593Smuzhiyun {22, 3, 0}, // RATEID_CCK11Mbps
888*4882a593Smuzhiyun {44, 4, 0}, // RATEID_CCK22Mbps
889*4882a593Smuzhiyun {12, 5, 0}, // RATEID_OFDM6Mbps
890*4882a593Smuzhiyun {18, 6, 0}, // RATEID_OFDM9Mbps
891*4882a593Smuzhiyun {24, 7, 0}, // RATEID_OFDM12Mbps
892*4882a593Smuzhiyun {36, 8, 0}, // RATEID_OFDM18Mbps
893*4882a593Smuzhiyun {48, 9, 0}, // RATEID_OFDM24Mbps
894*4882a593Smuzhiyun {72, 10, 0}, // RATEID_OFDM36Mbps
895*4882a593Smuzhiyun {96, 11, 0}, // RATEID_OFDM48Mbps
896*4882a593Smuzhiyun {108, 12, 0}, // RATEID_OFDM54Mbps
897*4882a593Smuzhiyun {144, 13, 0}, // RATEID_OFDM72Mbps
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun /* HT bw20 <--> Mrvl rate idx */
900*4882a593Smuzhiyun {13, 14, 0}, // RATEID_MCS0_6d5Mbps
901*4882a593Smuzhiyun {26, 15, 0}, // RATEID_MCS1_13Mbps
902*4882a593Smuzhiyun {39, 16, 0}, // RATEID_MCS2_19d5Mbps
903*4882a593Smuzhiyun {52, 17, 0}, // RATEID_MCS3_26Mbps
904*4882a593Smuzhiyun {78, 18, 0}, // RATEID_MCS4_39Mbps
905*4882a593Smuzhiyun {104, 19, 0}, // RATEID_MCS5_52Mbps
906*4882a593Smuzhiyun {117, 20, 0}, // RATEID_MCS6_58d5Mbps
907*4882a593Smuzhiyun {130, 21, 0}, // RATEID_MCS7_65Mbps
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun /* HT bw40<--> Mrvl rate idx */
910*4882a593Smuzhiyun {12, 22, 0}, // RATEID_MCS32BW40_6Mbps, for 1x1 start from 22
911*4882a593Smuzhiyun {27, 23, 0}, // RATEID_MCS0BW40_13d5Mbps
912*4882a593Smuzhiyun {54, 24, 0}, // RATEID_MCS1BW40_27Mbps
913*4882a593Smuzhiyun {81, 25, 0}, // RATEID_MCS2BW40_40d5Mbps
914*4882a593Smuzhiyun {108, 26, 0}, // RATEID_MCS3BW40_54Mbps
915*4882a593Smuzhiyun {162, 27, 0}, // RATEID_MCS4BW40_81Mbps
916*4882a593Smuzhiyun {216, 28, 0}, // RATEID_MCS5BW40_108Mbps
917*4882a593Smuzhiyun {243, 29, 0}, // RATEID_MCS6BW40_121d5Mbps
918*4882a593Smuzhiyun {270, 30, 0}, // RATEID_MCS7BW40_135Mbps
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun /* VHT bw20<--> Mrvl rate idx */
921*4882a593Smuzhiyun {13, 31, 0}, // RATEID_VHT_MCS0_1SS_BW20 6.5 Mbps
922*4882a593Smuzhiyun {26, 32, 0}, // RATEID_VHT_MCS1_1SS_BW20 13 Mbps
923*4882a593Smuzhiyun {39, 33, 0}, // RATEID_VHT_MCS2_1SS_BW20 19.5 Mbps
924*4882a593Smuzhiyun {52, 34, 0}, // RATEID_VHT_MCS3_1SS_BW20 26 Mbps
925*4882a593Smuzhiyun {78, 35, 0}, // RATEID_VHT_MCS4_1SS_BW20 39 Mbps
926*4882a593Smuzhiyun {104, 36, 0}, // RATEID_VHT_MCS5_1SS_BW20 52 Mbps
927*4882a593Smuzhiyun {117, 37, 0}, // RATEID_VHT_MCS6_1SS_BW20 58.5 Mbps
928*4882a593Smuzhiyun {130, 38, 0}, // RATEID_VHT_MCS7_1SS_BW20 65 Mbps
929*4882a593Smuzhiyun {156, 39, 0}, // RATEID_VHT_MCS8_1SS_BW20 78 Mbps
930*4882a593Smuzhiyun {0, 40, 0}, // RATEID_VHT_MCS9_1SS_BW20 86.7 Mbps(INVALID)
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun /* VHT bw40<--> Mrvl rate idx */
933*4882a593Smuzhiyun {27, 41, 0}, // RATEID_VHT_MCS0_1SS_BW40 13.5 Mbps
934*4882a593Smuzhiyun {54, 42, 0}, // RATEID_VHT_MCS1_1SS_BW40 27 Mbps
935*4882a593Smuzhiyun {81, 43, 0}, // RATEID_VHT_MCS2_1SS_BW40 40.5 Mbps
936*4882a593Smuzhiyun {108, 44, 0}, // RATEID_VHT_MCS3_1SS_BW40 54 Mbps
937*4882a593Smuzhiyun {162, 45, 0}, // RATEID_VHT_MCS4_1SS_BW40 81 Mbps
938*4882a593Smuzhiyun {216, 46, 0}, // RATEID_VHT_MCS5_1SS_BW40 108 Mbps
939*4882a593Smuzhiyun {243, 47, 0}, // RATEID_VHT_MCS6_1SS_BW40 121.5 Mbps
940*4882a593Smuzhiyun {270, 48, 0}, // RATEID_VHT_MCS7_1SS_BW40 135 Mbps
941*4882a593Smuzhiyun {324, 49, 0}, // RATEID_VHT_MCS8_1SS_BW40 162 Mbps
942*4882a593Smuzhiyun {360, 50, 0}, // RATEID_VHT_MCS9_1SS_BW40 180 Mbps
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun /* VHT bw80<--> Mrvl rate idx */
945*4882a593Smuzhiyun {58, 51, 0}, // RATEID_VHT_MCS0_1SS_BW80 29.3 Mbps, 29.3x2 could
946*4882a593Smuzhiyun // correspond to 58
947*4882a593Smuzhiyun {59, 51, 0}, // RATEID_VHT_MCS0_1SS_BW80 29.3 Mbps, 29.3x2 could
948*4882a593Smuzhiyun // correspond to 59 too
949*4882a593Smuzhiyun {117, 52, 0}, // RATEID_VHT_MCS1_1SS_BW80 58.5 Mbps
950*4882a593Smuzhiyun {175, 53, 0}, // RATEID_VHT_MCS2_1SS_BW80 87.8 Mbps, 87.8x2 could
951*4882a593Smuzhiyun // correspond to 175
952*4882a593Smuzhiyun {176, 53, 0}, // RATEID_VHT_MCS2_1SS_BW80 87.8 Mbps, 87.8x2 could
953*4882a593Smuzhiyun // correspond to 176 too
954*4882a593Smuzhiyun {234, 54, 0}, // RATEID_VHT_MCS3_1SS_BW80 117 Mbps
955*4882a593Smuzhiyun {351, 55, 0}, // RATEID_VHT_MCS4_1SS_BW80 175.5 Mbps
956*4882a593Smuzhiyun {468, 56, 0}, // RATEID_VHT_MCS5_1SS_BW80 234 Mbps
957*4882a593Smuzhiyun {526, 57, 0}, // RATEID_VHT_MCS6_1SS_BW80 263.3 Mbps, 263.3x2 could
958*4882a593Smuzhiyun // correspond to 526
959*4882a593Smuzhiyun {527, 57, 0}, // RATEID_VHT_MCS6_1SS_BW80 263.3 Mbps, 263.3x2 could
960*4882a593Smuzhiyun // correspond to 527 too
961*4882a593Smuzhiyun {585, 58, 0}, // RATEID_VHT_MCS7_1SS_BW80 292.5 Mbps
962*4882a593Smuzhiyun {702, 59, 0}, // RATEID_VHT_MCS8_1SS_BW80 351 Mbps
963*4882a593Smuzhiyun {780, 60, 0}, // RATEID_VHT_MCS9_1SS_BW80 390 Mbps
964*4882a593Smuzhiyun };
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun /********************************************************
967*4882a593Smuzhiyun * Global Variables
968*4882a593Smuzhiyun ********************************************************/
969*4882a593Smuzhiyun /**
970*4882a593Smuzhiyun * The table to keep region code
971*4882a593Smuzhiyun */
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun t_u16 region_code_index[MRVDRV_MAX_REGION_CODE] = {0x00, 0x10, 0x20, 0x30, 0x40,
974*4882a593Smuzhiyun 0x41, 0x50, 0xfe, 0xff};
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun /** The table to keep CFP code for A */
977*4882a593Smuzhiyun t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A] = {0x1, 0x2, 0x3, 0x4, 0x5};
978*4882a593Smuzhiyun
979*4882a593Smuzhiyun /**
980*4882a593Smuzhiyun * The rates supported for ad-hoc B mode
981*4882a593Smuzhiyun */
982*4882a593Smuzhiyun t_u8 AdhocRates_B[B_SUPPORTED_RATES] = {0x82, 0x84, 0x8b, 0x96, 0};
983*4882a593Smuzhiyun
984*4882a593Smuzhiyun /**
985*4882a593Smuzhiyun * The rates supported for ad-hoc G mode
986*4882a593Smuzhiyun */
987*4882a593Smuzhiyun t_u8 AdhocRates_G[G_SUPPORTED_RATES] = {0x8c, 0x12, 0x98, 0x24, 0xb0,
988*4882a593Smuzhiyun 0x48, 0x60, 0x6c, 0x00};
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun /**
991*4882a593Smuzhiyun * The rates supported for ad-hoc BG mode
992*4882a593Smuzhiyun */
993*4882a593Smuzhiyun t_u8 AdhocRates_BG[BG_SUPPORTED_RATES] = {0x82, 0x84, 0x8b, 0x96, 0x0c,
994*4882a593Smuzhiyun 0x12, 0x18, 0x24, 0x30, 0x48,
995*4882a593Smuzhiyun 0x60, 0x6c, 0x00};
996*4882a593Smuzhiyun
997*4882a593Smuzhiyun /**
998*4882a593Smuzhiyun * The rates supported in A mode for ad-hoc
999*4882a593Smuzhiyun */
1000*4882a593Smuzhiyun t_u8 AdhocRates_A[A_SUPPORTED_RATES] = {0x8c, 0x12, 0x98, 0x24, 0xb0,
1001*4882a593Smuzhiyun 0x48, 0x60, 0x6c, 0x00};
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun /**
1004*4882a593Smuzhiyun * The rates supported in A mode (used for BAND_A)
1005*4882a593Smuzhiyun */
1006*4882a593Smuzhiyun t_u8 SupportedRates_A[A_SUPPORTED_RATES] = {0x0c, 0x12, 0x18, 0x24, 0xb0,
1007*4882a593Smuzhiyun 0x48, 0x60, 0x6c, 0x00};
1008*4882a593Smuzhiyun
1009*4882a593Smuzhiyun /**
1010*4882a593Smuzhiyun * The rates supported by the card
1011*4882a593Smuzhiyun */
1012*4882a593Smuzhiyun static t_u16 WlanDataRates[WLAN_SUPPORTED_RATES_EXT] = {
1013*4882a593Smuzhiyun 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48,
1014*4882a593Smuzhiyun 0x60, 0x6C, 0x90, 0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82,
1015*4882a593Smuzhiyun 0x0C, 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00};
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun /**
1018*4882a593Smuzhiyun * The rates supported in B mode
1019*4882a593Smuzhiyun */
1020*4882a593Smuzhiyun t_u8 SupportedRates_B[B_SUPPORTED_RATES] = {0x02, 0x04, 0x0b, 0x16, 0x00};
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun /**
1023*4882a593Smuzhiyun * The rates supported in G mode (BAND_G, BAND_G|BAND_GN)
1024*4882a593Smuzhiyun */
1025*4882a593Smuzhiyun t_u8 SupportedRates_G[G_SUPPORTED_RATES] = {0x0c, 0x12, 0x18, 0x24, 0x30,
1026*4882a593Smuzhiyun 0x48, 0x60, 0x6c, 0x00};
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun /**
1029*4882a593Smuzhiyun * The rates supported in BG mode (BAND_B|BAND_G, BAND_B|BAND_G|BAND_GN)
1030*4882a593Smuzhiyun */
1031*4882a593Smuzhiyun t_u8 SupportedRates_BG[BG_SUPPORTED_RATES] = {0x02, 0x04, 0x0b, 0x0c, 0x12,
1032*4882a593Smuzhiyun 0x16, 0x18, 0x24, 0x30, 0x48,
1033*4882a593Smuzhiyun 0x60, 0x6c, 0x00};
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun /**
1036*4882a593Smuzhiyun * The rates supported in N mode
1037*4882a593Smuzhiyun */
1038*4882a593Smuzhiyun t_u8 SupportedRates_N[N_SUPPORTED_RATES] = {0x02, 0x04, 0};
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun #define MCS_NUM_AX 12
1041*4882a593Smuzhiyun // for MCS0/MCS1/MCS3/MCS4 have 4 additional DCM=1 value
1042*4882a593Smuzhiyun // note: the value in the table is 2 multiplier of the actual rate
1043*4882a593Smuzhiyun static t_u16 ax_mcs_rate_nss1[12][MCS_NUM_AX + 4] = {
1044*4882a593Smuzhiyun {0x90, 0x48, 0x120, 0x90, 0x1B0, 0x240, 0x120, 0x360, 0x1B0, 0x481,
1045*4882a593Smuzhiyun 0x511, 0x5A1, 0x6C1, 0x781, 0x871, 0x962}, /*SG 160M*/
1046*4882a593Smuzhiyun {0x88, 0x44, 0x110, 0x88, 0x198, 0x220, 0x110, 0x330, 0x198, 0x440,
1047*4882a593Smuzhiyun 0x4C9, 0x551, 0x661, 0x716, 0x7F9, 0x8DC}, /*MG 160M*/
1048*4882a593Smuzhiyun {0x7A, 0x3D, 0xF5, 0x7A, 0x16F, 0x1EA, 0xF5, 0x2DF, 0x16F, 0x3D4, 0x44E,
1049*4882a593Smuzhiyun 0x4C9, 0x5BE, 0x661, 0x72D, 0x7F9}, /*LG 160M*/
1050*4882a593Smuzhiyun {0x48, 0x24, 0x90, 0x48, 0xD8, 0x120, 0x90, 0x1B0, 0xD8, 0x240, 0x288,
1051*4882a593Smuzhiyun 0x2D0, 0x360, 0x3C0, 0x438, 0x4B0}, /*SG 80M*/
1052*4882a593Smuzhiyun {0x44, 0x22, 0x88, 0x44, 0xCC, 0x110, 0x88, 0x198, 0xCC, 0x220, 0x264,
1053*4882a593Smuzhiyun 0x2A8, 0x330, 0x38B, 0x3FC, 0x46E}, /*MG 80M*/
1054*4882a593Smuzhiyun {0x3D, 0x1E, 0x7A, 0x3D, 0xB7, 0xF5, 0x7A, 0x16F, 0xB7, 0x1EA, 0x227,
1055*4882a593Smuzhiyun 0x264, 0x2DF, 0x330, 0x396, 0x3FC}, /*LG 80M*/
1056*4882a593Smuzhiyun {0x22, 0x11, 0x44, 0x22, 0x67, 0x89, 0x44, 0xCE, 0x67, 0x113, 0x135,
1057*4882a593Smuzhiyun 0x158, 0x19D, 0x1CA, 0x204, 0x23D}, /*SG 40M*/
1058*4882a593Smuzhiyun {0x20, 0x10, 0x41, 0x20, 0x61, 0x82, 0x41, 0xC3, 0x61, 0x104, 0x124,
1059*4882a593Smuzhiyun 0x145, 0x186, 0x1B1, 0x1E7, 0x21D}, /*MG 40M*/
1060*4882a593Smuzhiyun {0x1D, 0xE, 0x3A, 0x1D, 0x57, 0x75, 0x3A, 0xAF, 0x57, 0xEA, 0x107,
1061*4882a593Smuzhiyun 0x124, 0x15F, 0x186, 0x1B6, 0x1E7}, /*LG 40M*/
1062*4882a593Smuzhiyun {0x11, 0x8, 0x22, 0x11, 0x33, 0x44, 0x22, 0x67, 0x33, 0x89, 0x9A, 0xAC,
1063*4882a593Smuzhiyun 0xCE, 0xE5, 0x102, 0x11E}, /*SG 20M*/
1064*4882a593Smuzhiyun {0x10, 0x8, 0x20, 0x10, 0x30, 0x41, 0x20, 0x61, 0x30, 0x82, 0x92, 0xA2,
1065*4882a593Smuzhiyun 0xC3, 0xD8, 0xF3, 0x10E}, /*MG 20M*/
1066*4882a593Smuzhiyun {0xE, 0x7, 0x1D, 0xE, 0x2B, 0x3A, 0x1D, 0x57, 0x2B, 0x75, 0x83, 0x92,
1067*4882a593Smuzhiyun 0xAF, 0xC3, 0xDB, 0xF3} /*LG 20M*/
1068*4882a593Smuzhiyun };
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun #if 0
1071*4882a593Smuzhiyun // note: the value in the table is 2 multiplier of the actual rate
1072*4882a593Smuzhiyun t_u16 ax_tone_ru_rate_nss1[9][MCS_NUM_AX + 4] = {
1073*4882a593Smuzhiyun {0x8, 0x4, 0xF, 0x8, 0x17, 0x1E, 0xF, 0x2D, 0x17, 0x3C, 0x44, 0x4B,
1074*4882a593Smuzhiyun 0x5A, 0x64, 0x71, 0x7D}, /*SG 106-tone*/
1075*4882a593Smuzhiyun {0x7, 0x4, 0xF, 0x7, 0x16, 0x1D, 0xF, 0x2B, 0x16, 0x39, 0x40, 0x47,
1076*4882a593Smuzhiyun 0x55, 0x5F, 0x6B, 0x76}, /*MG 106-tone*/
1077*4882a593Smuzhiyun {0x7, 0x3, 0xD, 0x6, 0x14, 0x1A, 0xD, 0x27, 0x14, 0x33, 0x3A, 0x40,
1078*4882a593Smuzhiyun 0x4D, 0x55, 0x60, 0x6B}, /*LG 106-tone*/
1079*4882a593Smuzhiyun {0x4, 0x2, 0x7, 0x4, 0xB, 0xF, 0x7, 0x16, 0xB, 0x1D, 0x20, 0x22, 0x2B,
1080*4882a593Smuzhiyun 0x2F, 0x35, 0x3B}, /*SG 52-tone*/
1081*4882a593Smuzhiyun {0x4, 0x2, 0x7, 0x4, 0xA, 0xE, 0x7, 0x14, 0xA, 0x1B, 0x1E, 0x22, 0x28,
1082*4882a593Smuzhiyun 0x2D, 0x32, 0x38}, /*MG 52-tone*/
1083*4882a593Smuzhiyun {0x3, 0x2, 0x6, 0x3, 0x9, 0xC, 0x6, 0x12, 0x9, 0x18, 0x1B, 0x1E, 0x24,
1084*4882a593Smuzhiyun 0x28, 0x2D, 0x32}, /*LG 52-tone*/
1085*4882a593Smuzhiyun {0x2, 0x1, 0x4, 0x2, 0x6, 0x7, 0x4, 0xB, 0x5, 0xE, 0x10, 0x12, 0x15,
1086*4882a593Smuzhiyun 0x18, 0x1A, 0x1D}, /*SG 26-tone*/
1087*4882a593Smuzhiyun {0x2, 0x1, 0x4, 0x2, 0x5, 0x6, 0x4, 0xA, 0x5, 0xD, 0xF, 0x11, 0x14,
1088*4882a593Smuzhiyun 0x16, 0x19, 0x1C}, /*MG 26-tone*/
1089*4882a593Smuzhiyun {0x2, 0x1, 0x3, 0x2, 0x5, 0x6, 0x3, 0x9, 0x4, 0xC, 0xE, 0xF, 0x12, 0x14,
1090*4882a593Smuzhiyun 0x17, 0x19} /*LG 26-tone*/
1091*4882a593Smuzhiyun };
1092*4882a593Smuzhiyun #endif
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun // note: the value in the table is 2 multiplier of the actual rate
1095*4882a593Smuzhiyun static t_u16 ax_mcs_rate_nss2[12][MCS_NUM_AX + 4] = {
1096*4882a593Smuzhiyun {0x120, 0x90, 0x240, 0x120, 0x360, 0x481, 0x240, 0x61C, 0x360, 0x901,
1097*4882a593Smuzhiyun 0xA22, 0xB42, 0xD82, 0xF03, 0x10E3, 0x12C3}, /*SG 160M*/
1098*4882a593Smuzhiyun {0x110, 0x88, 0x220, 0x110, 0x330, 0x440, 0x220, 0x661, 0x330, 0x881,
1099*4882a593Smuzhiyun 0x992, 0xAA2, 0xCAC, 0xE2D, 0xFF3, 0x11B9}, /*MG 160M*/
1100*4882a593Smuzhiyun {0xF5, 0x7A, 0x1EA, 0xF5, 0x2DF, 0x3D4, 0x1EA, 0x5BE, 0x2DF, 0x7A8,
1101*4882a593Smuzhiyun 0x1134, 0x992, 0xB7C, 0xCC2, 0xE5B, 0xFF3}, /*LG 160M*/
1102*4882a593Smuzhiyun {0x90, 0x48, 0x120, 0x90, 0x1B0, 0x240, 0x120, 0x360, 0x1B0, 0x481,
1103*4882a593Smuzhiyun 0x511, 0x5A1, 0x6C1, 0x781, 0x871, 0x962}, /*SG 80M*/
1104*4882a593Smuzhiyun {0x88, 0x44, 0x110, 0x88, 0x198, 0x220, 0x110, 0x330, 0x198, 0x440,
1105*4882a593Smuzhiyun 0x4C9, 0x551, 0x661, 0x716, 0x7F9, 0x8DC}, /*MG 80M*/
1106*4882a593Smuzhiyun {0x7A, 0x3D, 0xF5, 0x7A, 0x16F, 0x1EA, 0xF5, 0x2DF, 0x16F, 0x3D4, 0x44E,
1107*4882a593Smuzhiyun 0x4C9, 0x5BE, 0x661, 0x72D, 0x7F9}, /*LG 80M*/
1108*4882a593Smuzhiyun {0x44, 0x22, 0x89, 0x44, 0xCE, 0x113, 0x89, 0x19D, 0xCE, 0x226, 0x26B,
1109*4882a593Smuzhiyun 0x2B0, 0x339, 0x395, 0x408, 0x47B}, /*SG 40M*/
1110*4882a593Smuzhiyun {0x41, 0x20, 0x82, 0x41, 0xC3, 0x104, 0x82, 0x186, 0xC3, 0x208, 0x249,
1111*4882a593Smuzhiyun 0x28A, 0x30C, 0x362, 0x3CE, 0x43B}, /*MG 40M*/
1112*4882a593Smuzhiyun {0x3A, 0x1D, 0x75, 0x3A, 0xAF, 0xEA, 0x75, 0x15F, 0xAF, 0x1D4, 0x20E,
1113*4882a593Smuzhiyun 0x249, 0x2BE, 0x30C, 0x36D, 0x3CF}, /*LG 40M*/
1114*4882a593Smuzhiyun {0x22, 0x11, 0x44, 0x22, 0x67, 0x89, 0x44, 0xCE, 0x67, 0x113, 0x135,
1115*4882a593Smuzhiyun 0x158, 0x19D, 0x1CA, 0x204, 0x23D}, /*SG 20M*/
1116*4882a593Smuzhiyun {0x20, 0x10, 0x41, 0x20, 0x61, 0x82, 0x41, 0xC3, 0x61, 0x104, 0x124,
1117*4882a593Smuzhiyun 0x145, 0x186, 0x1B1, 0x1E7, 0x21D}, /*MG 20M*/
1118*4882a593Smuzhiyun {0x1D, 0xE, 0x3A, 0x1D, 0x57, 0x75, 0x3A, 0xAF, 0x57, 0xEA, 0x107,
1119*4882a593Smuzhiyun 0x124, 0x15F, 0x186, 0x1B6, 0x1E7} /*LG 20M*/
1120*4882a593Smuzhiyun };
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun #if 0
1123*4882a593Smuzhiyun // note: the value in the table is 2 multiplier of the actual rate
1124*4882a593Smuzhiyun t_u16 ax_tone_ru_rate_nss2[9][MCS_NUM_AX + 4] = {
1125*4882a593Smuzhiyun {0xF, 0x8, 0x1E, 0xF, 0x2D, 0x3C, 0x1E, 0x5A, 0x2D, 0x78, 0x87, 0x96,
1126*4882a593Smuzhiyun 0xB4, 0xC8, 0xE1, 0xFA}, /*SG 106-tone*/
1127*4882a593Smuzhiyun {0xE, 0x7, 0x1D, 0xE, 0x2B, 0x39, 0x1D, 0x55, 0x2B, 0x72, 0x80, 0x8E,
1128*4882a593Smuzhiyun 0xAA, 0xBD, 0xD5, 0xED}, /*MG 106-tone*/
1129*4882a593Smuzhiyun {0xD, 0x7, 0x1A, 0xD, 0x27, 0x33, 0x1A, 0x4D, 0x27, 0x66, 0x73, 0x80,
1130*4882a593Smuzhiyun 0x99, 0xAA, 0xC0, 0xD5}, /*LG 106-tone*/
1131*4882a593Smuzhiyun {0x7, 0x4, 0xF, 0x7, 0x16, 0x1D, 0xF, 0x2A, 0x16, 0x39, 0x40, 0x47,
1132*4882a593Smuzhiyun 0x55, 0x5F, 0x6A, 0x76}, /*SG 52-tone*/
1133*4882a593Smuzhiyun {0x7, 0x4, 0xE, 0x7, 0x14, 0x1B, 0xE, 0x28, 0x14, 0x36, 0x3C, 0x43,
1134*4882a593Smuzhiyun 0x50, 0x59, 0x64, 0x70}, /*MG 52-tone*/
1135*4882a593Smuzhiyun {0x6, 0x3, 0xC, 0x6, 0x12, 0x18, 0xC, 0x24, 0x12, 0x30, 0x36, 0x3C,
1136*4882a593Smuzhiyun 0x48, 0x50, 0x5A, 0x64}, /*LG 52-tone*/
1137*4882a593Smuzhiyun {0x4, 0x2, 0x7, 0x4, 0xB, 0xF, 0x7, 0x16, 0xB, 0x1D, 0x20, 0x22, 0x2B,
1138*4882a593Smuzhiyun 0x2F, 0x35, 0x3B}, /*SG 26-tone*/
1139*4882a593Smuzhiyun {0x4, 0x2, 0x7, 0x4, 0xA, 0xE, 0x7, 0x14, 0xA, 0x1B, 0x1E, 0x22, 0x28,
1140*4882a593Smuzhiyun 0x2D, 0x32, 0x38}, /*MG 26-tone*/
1141*4882a593Smuzhiyun {0x3, 0x2, 0x6, 0x3, 0x9, 0xC, 0x6, 0x12, 0x9, 0x18, 0x1B, 0x1E, 0x24,
1142*4882a593Smuzhiyun 0x28, 0x2D, 0x32} /*LG 26-tone*/
1143*4882a593Smuzhiyun };
1144*4882a593Smuzhiyun #endif
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun /********************************************************
1147*4882a593Smuzhiyun * Local Functions
1148*4882a593Smuzhiyun ********************************************************/
1149*4882a593Smuzhiyun /**
1150*4882a593Smuzhiyun * @brief Find a character in a string.
1151*4882a593Smuzhiyun *
1152*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1153*4882a593Smuzhiyun * @param s A pointer to string
1154*4882a593Smuzhiyun * @param c Character to be located
1155*4882a593Smuzhiyun * @param n The length of string
1156*4882a593Smuzhiyun *
1157*4882a593Smuzhiyun * @return A pointer to the first occurrence of c in string, or MNULL if
1158*4882a593Smuzhiyun * c is not found.
1159*4882a593Smuzhiyun */
wlan_memchr(pmlan_adapter pmadapter,void * s,int c,int n)1160*4882a593Smuzhiyun static void *wlan_memchr(pmlan_adapter pmadapter, void *s, int c, int n)
1161*4882a593Smuzhiyun {
1162*4882a593Smuzhiyun const t_u8 *p = (t_u8 *)s;
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun ENTER();
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun while (n--) {
1167*4882a593Smuzhiyun if ((t_u8)c == *p++) {
1168*4882a593Smuzhiyun LEAVE();
1169*4882a593Smuzhiyun return (void *)(p - 1);
1170*4882a593Smuzhiyun }
1171*4882a593Smuzhiyun }
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun LEAVE();
1174*4882a593Smuzhiyun return MNULL;
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun /**
1178*4882a593Smuzhiyun * @brief This function finds the CFP in
1179*4882a593Smuzhiyun * cfp_table_BG/A based on region/code and band parameter.
1180*4882a593Smuzhiyun *
1181*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1182*4882a593Smuzhiyun * @param region The region code
1183*4882a593Smuzhiyun * @param band The band
1184*4882a593Smuzhiyun * @param cfp_no A pointer to CFP number
1185*4882a593Smuzhiyun *
1186*4882a593Smuzhiyun * @return A pointer to CFP
1187*4882a593Smuzhiyun */
wlan_get_region_cfp_table(pmlan_adapter pmadapter,t_u8 region,t_u16 band,int * cfp_no)1188*4882a593Smuzhiyun static chan_freq_power_t *wlan_get_region_cfp_table(pmlan_adapter pmadapter,
1189*4882a593Smuzhiyun t_u8 region, t_u16 band,
1190*4882a593Smuzhiyun int *cfp_no)
1191*4882a593Smuzhiyun {
1192*4882a593Smuzhiyun t_u32 i;
1193*4882a593Smuzhiyun t_u8 cfp_bg, cfp_a;
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun ENTER();
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun cfp_bg = cfp_a = region;
1198*4882a593Smuzhiyun if (!region) {
1199*4882a593Smuzhiyun /* Invalid region code, use CFP code */
1200*4882a593Smuzhiyun cfp_bg = pmadapter->cfp_code_bg;
1201*4882a593Smuzhiyun cfp_a = pmadapter->cfp_code_a;
1202*4882a593Smuzhiyun }
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun if (band & (BAND_B | BAND_G | BAND_GN | BAND_GAC)) {
1205*4882a593Smuzhiyun /* Return the FW cfp table for requested region code, if
1206*4882a593Smuzhiyun * available. If region is not forced and the requested region
1207*4882a593Smuzhiyun * code is different, simply return the corresponding
1208*4882a593Smuzhiyun * pre-defined table.
1209*4882a593Smuzhiyun */
1210*4882a593Smuzhiyun if (pmadapter->otp_region && pmadapter->cfp_otp_bg) {
1211*4882a593Smuzhiyun if (pmadapter->otp_region->force_reg ||
1212*4882a593Smuzhiyun (cfp_bg ==
1213*4882a593Smuzhiyun (t_u8)pmadapter->otp_region->region_code)) {
1214*4882a593Smuzhiyun *cfp_no = pmadapter->tx_power_table_bg_rows;
1215*4882a593Smuzhiyun LEAVE();
1216*4882a593Smuzhiyun return pmadapter->cfp_otp_bg;
1217*4882a593Smuzhiyun }
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) {
1220*4882a593Smuzhiyun PRINTM(MINFO, "cfp_table_BG[%d].code=%d\n", i,
1221*4882a593Smuzhiyun cfp_table_BG[i].code);
1222*4882a593Smuzhiyun /* Check if region/code matches for BG bands */
1223*4882a593Smuzhiyun if (cfp_table_BG[i].code == cfp_bg) {
1224*4882a593Smuzhiyun /* Select by band */
1225*4882a593Smuzhiyun *cfp_no = cfp_table_BG[i].cfp_no;
1226*4882a593Smuzhiyun LEAVE();
1227*4882a593Smuzhiyun return cfp_table_BG[i].cfp;
1228*4882a593Smuzhiyun }
1229*4882a593Smuzhiyun }
1230*4882a593Smuzhiyun }
1231*4882a593Smuzhiyun if (band & (BAND_A | BAND_AN | BAND_AAC)) {
1232*4882a593Smuzhiyun /* Return the FW cfp table for requested region code */
1233*4882a593Smuzhiyun if (pmadapter->otp_region && pmadapter->cfp_otp_a) {
1234*4882a593Smuzhiyun if (pmadapter->otp_region->force_reg ||
1235*4882a593Smuzhiyun (cfp_a ==
1236*4882a593Smuzhiyun (t_u8)pmadapter->otp_region->region_code)) {
1237*4882a593Smuzhiyun *cfp_no = pmadapter->tx_power_table_a_rows;
1238*4882a593Smuzhiyun LEAVE();
1239*4882a593Smuzhiyun return pmadapter->cfp_otp_a;
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun }
1242*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) {
1243*4882a593Smuzhiyun PRINTM(MINFO, "cfp_table_A[%d].code=%d\n", i,
1244*4882a593Smuzhiyun cfp_table_A[i].code);
1245*4882a593Smuzhiyun /* Check if region/code matches for A bands */
1246*4882a593Smuzhiyun if (cfp_table_A[i].code == cfp_a) {
1247*4882a593Smuzhiyun /* Select by band */
1248*4882a593Smuzhiyun *cfp_no = cfp_table_A[i].cfp_no;
1249*4882a593Smuzhiyun LEAVE();
1250*4882a593Smuzhiyun return cfp_table_A[i].cfp;
1251*4882a593Smuzhiyun }
1252*4882a593Smuzhiyun }
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun if (!region)
1255*4882a593Smuzhiyun PRINTM(MERROR, "Error Band[0x%x] or code[BG:%#x, A:%#x]\n",
1256*4882a593Smuzhiyun band, cfp_bg, cfp_a);
1257*4882a593Smuzhiyun else
1258*4882a593Smuzhiyun PRINTM(MERROR, "Error Band[0x%x] or region[%#x]\n", band,
1259*4882a593Smuzhiyun region);
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun LEAVE();
1262*4882a593Smuzhiyun return MNULL;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun
1265*4882a593Smuzhiyun /**
1266*4882a593Smuzhiyun * @brief This function copies dynamic CFP elements from one table to another.
1267*4882a593Smuzhiyun * Only copy elements where channel numbers match.
1268*4882a593Smuzhiyun *
1269*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1270*4882a593Smuzhiyun * @param cfp Destination table
1271*4882a593Smuzhiyun * @param num_cfp Number of elements in dest table
1272*4882a593Smuzhiyun * @param cfp_src Source table
1273*4882a593Smuzhiyun * @param num_cfp_src Number of elements in source table
1274*4882a593Smuzhiyun */
wlan_cfp_copy_dynamic(pmlan_adapter pmadapter,chan_freq_power_t * cfp,t_u8 num_cfp,chan_freq_power_t * cfp_src,t_u8 num_cfp_src)1275*4882a593Smuzhiyun static t_void wlan_cfp_copy_dynamic(pmlan_adapter pmadapter,
1276*4882a593Smuzhiyun chan_freq_power_t *cfp, t_u8 num_cfp,
1277*4882a593Smuzhiyun chan_freq_power_t *cfp_src,
1278*4882a593Smuzhiyun t_u8 num_cfp_src)
1279*4882a593Smuzhiyun {
1280*4882a593Smuzhiyun int i, j;
1281*4882a593Smuzhiyun
1282*4882a593Smuzhiyun ENTER();
1283*4882a593Smuzhiyun
1284*4882a593Smuzhiyun if (cfp == cfp_src) {
1285*4882a593Smuzhiyun LEAVE();
1286*4882a593Smuzhiyun return;
1287*4882a593Smuzhiyun }
1288*4882a593Smuzhiyun
1289*4882a593Smuzhiyun /* first clear dest dynamic blacklisted entries */
1290*4882a593Smuzhiyun /* do not clear the flags */
1291*4882a593Smuzhiyun for (i = 0; i < num_cfp; i++) {
1292*4882a593Smuzhiyun cfp[i].dynamic.blacklist = MFALSE;
1293*4882a593Smuzhiyun cfp[i].dynamic.dfs_state = DFS_USABLE;
1294*4882a593Smuzhiyun }
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun /* copy dynamic blacklisted entries from source where channels match */
1297*4882a593Smuzhiyun if (cfp_src) {
1298*4882a593Smuzhiyun for (i = 0; i < num_cfp; i++)
1299*4882a593Smuzhiyun for (j = 0; j < num_cfp_src; j++)
1300*4882a593Smuzhiyun if (cfp[i].channel == cfp_src[j].channel) {
1301*4882a593Smuzhiyun cfp[i].dynamic.blacklist =
1302*4882a593Smuzhiyun cfp_src[j].dynamic.blacklist;
1303*4882a593Smuzhiyun cfp[i].dynamic.dfs_state =
1304*4882a593Smuzhiyun cfp_src[j].dynamic.dfs_state;
1305*4882a593Smuzhiyun break;
1306*4882a593Smuzhiyun }
1307*4882a593Smuzhiyun }
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun LEAVE();
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun /********************************************************
1313*4882a593Smuzhiyun * Global Functions
1314*4882a593Smuzhiyun ********************************************************/
1315*4882a593Smuzhiyun /**
1316*4882a593Smuzhiyun * @brief This function converts region string to integer code
1317*4882a593Smuzhiyun *
1318*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1319*4882a593Smuzhiyun * @param country_code Country string
1320*4882a593Smuzhiyun * @param cfp_bg Pointer to buffer
1321*4882a593Smuzhiyun * @param cfp_a Pointer to buffer
1322*4882a593Smuzhiyun *
1323*4882a593Smuzhiyun * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1324*4882a593Smuzhiyun */
wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter,t_u8 * country_code,t_u8 * cfp_bg,t_u8 * cfp_a)1325*4882a593Smuzhiyun mlan_status wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter,
1326*4882a593Smuzhiyun t_u8 *country_code, t_u8 *cfp_bg,
1327*4882a593Smuzhiyun t_u8 *cfp_a)
1328*4882a593Smuzhiyun {
1329*4882a593Smuzhiyun t_u8 i;
1330*4882a593Smuzhiyun
1331*4882a593Smuzhiyun ENTER();
1332*4882a593Smuzhiyun
1333*4882a593Smuzhiyun if (pmadapter->otp_region) {
1334*4882a593Smuzhiyun if (!memcmp(pmadapter, pmadapter->otp_region->country_code,
1335*4882a593Smuzhiyun country_code, COUNTRY_CODE_LEN - 1)) {
1336*4882a593Smuzhiyun if (pmadapter->cfp_otp_bg)
1337*4882a593Smuzhiyun *cfp_bg = pmadapter->otp_region->region_code;
1338*4882a593Smuzhiyun if (pmadapter->cfp_otp_a)
1339*4882a593Smuzhiyun *cfp_a = pmadapter->otp_region->region_code;
1340*4882a593Smuzhiyun LEAVE();
1341*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun }
1344*4882a593Smuzhiyun /* Look for code in mapping table */
1345*4882a593Smuzhiyun for (i = 0; i < NELEMENTS(country_code_mapping); i++) {
1346*4882a593Smuzhiyun if (!memcmp(pmadapter, country_code_mapping[i].country_code,
1347*4882a593Smuzhiyun country_code, COUNTRY_CODE_LEN - 1)) {
1348*4882a593Smuzhiyun *cfp_bg = country_code_mapping[i].cfp_code_bg;
1349*4882a593Smuzhiyun *cfp_a = country_code_mapping[i].cfp_code_a;
1350*4882a593Smuzhiyun LEAVE();
1351*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun }
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun /* If still not found, look for code in EU country code table */
1356*4882a593Smuzhiyun for (i = 0; i < NELEMENTS(eu_country_code_table); i++) {
1357*4882a593Smuzhiyun if (!memcmp(pmadapter, eu_country_code_table[i], country_code,
1358*4882a593Smuzhiyun COUNTRY_CODE_LEN - 1)) {
1359*4882a593Smuzhiyun *cfp_bg = EU_CFP_CODE_BG;
1360*4882a593Smuzhiyun *cfp_a = EU_CFP_CODE_A;
1361*4882a593Smuzhiyun LEAVE();
1362*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
1363*4882a593Smuzhiyun }
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun
1366*4882a593Smuzhiyun LEAVE();
1367*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
1368*4882a593Smuzhiyun }
1369*4882a593Smuzhiyun
1370*4882a593Smuzhiyun /**
1371*4882a593Smuzhiyun * @brief This function finds if given country code is in EU table
1372*4882a593Smuzhiyun *
1373*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1374*4882a593Smuzhiyun * @param country_code Country string
1375*4882a593Smuzhiyun *
1376*4882a593Smuzhiyun * @return MTRUE or MFALSE
1377*4882a593Smuzhiyun */
wlan_is_etsi_country(pmlan_adapter pmadapter,t_u8 * country_code)1378*4882a593Smuzhiyun t_bool wlan_is_etsi_country(pmlan_adapter pmadapter, t_u8 *country_code)
1379*4882a593Smuzhiyun {
1380*4882a593Smuzhiyun t_u8 i;
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun ENTER();
1383*4882a593Smuzhiyun
1384*4882a593Smuzhiyun /* Look for code in EU country code table */
1385*4882a593Smuzhiyun for (i = 0; i < NELEMENTS(eu_country_code_table); i++) {
1386*4882a593Smuzhiyun if (!memcmp(pmadapter, eu_country_code_table[i], country_code,
1387*4882a593Smuzhiyun COUNTRY_CODE_LEN - 1)) {
1388*4882a593Smuzhiyun LEAVE();
1389*4882a593Smuzhiyun return MTRUE;
1390*4882a593Smuzhiyun }
1391*4882a593Smuzhiyun }
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun LEAVE();
1394*4882a593Smuzhiyun return MFALSE;
1395*4882a593Smuzhiyun }
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun /**
1398*4882a593Smuzhiyun * @brief This function adjust the antenna index
1399*4882a593Smuzhiyun *
1400*4882a593Smuzhiyun * V16_FW_API: Bit0: ant A, Bit 1:ant B, Bit0 & Bit 1: A+B
1401*4882a593Smuzhiyun * 8887: case1: 0 - 2.4G ant A, 1- 2.4G antB, 2-- 5G ant C
1402*4882a593Smuzhiyun * case2: 0 - 2.4G ant A, 1- 2.4G antB, 0x80- 5G antA, 0x81-5G ant B
1403*4882a593Smuzhiyun * @param priv A pointer to mlan_private structure
1404*4882a593Smuzhiyun * @param prx_pd A pointer to the RxPD structure
1405*4882a593Smuzhiyun *
1406*4882a593Smuzhiyun * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1407*4882a593Smuzhiyun */
wlan_adjust_antenna(pmlan_private priv,RxPD * prx_pd)1408*4882a593Smuzhiyun t_u8 wlan_adjust_antenna(pmlan_private priv, RxPD *prx_pd)
1409*4882a593Smuzhiyun {
1410*4882a593Smuzhiyun t_u8 antenna = prx_pd->antenna;
1411*4882a593Smuzhiyun #if defined(SD8887) || defined(SD8987)
1412*4882a593Smuzhiyun t_u32 rx_channel = (prx_pd->rx_info & RXPD_CHAN_MASK) >> 5;
1413*4882a593Smuzhiyun #endif
1414*4882a593Smuzhiyun if (prx_pd->antenna == 0xff)
1415*4882a593Smuzhiyun return 0;
1416*4882a593Smuzhiyun if (priv->adapter->pcard_info->v16_fw_api) {
1417*4882a593Smuzhiyun if ((antenna & MBIT(0)) && (antenna & MBIT(1)))
1418*4882a593Smuzhiyun antenna = 2;
1419*4882a593Smuzhiyun else if (antenna & MBIT(1))
1420*4882a593Smuzhiyun antenna = 1;
1421*4882a593Smuzhiyun else if (antenna & MBIT(0))
1422*4882a593Smuzhiyun antenna = 0;
1423*4882a593Smuzhiyun }
1424*4882a593Smuzhiyun
1425*4882a593Smuzhiyun #if defined(SD8887) || defined(SD8987)
1426*4882a593Smuzhiyun #define ANTENNA_OFFSET 2
1427*4882a593Smuzhiyun if (MFALSE
1428*4882a593Smuzhiyun #ifdef SD8887
1429*4882a593Smuzhiyun || IS_SD8887(priv->adapter->card_type)
1430*4882a593Smuzhiyun #endif
1431*4882a593Smuzhiyun #ifdef SD8987
1432*4882a593Smuzhiyun || IS_SD8987(priv->adapter->card_type)
1433*4882a593Smuzhiyun #endif
1434*4882a593Smuzhiyun ) {
1435*4882a593Smuzhiyun if ((priv->adapter->antinfo & ANT_DIVERSITY_2G) &&
1436*4882a593Smuzhiyun (priv->adapter->antinfo & ANT_DIVERSITY_5G)) {
1437*4882a593Smuzhiyun #define MAX_2G_CHAN 14
1438*4882a593Smuzhiyun if (rx_channel > MAX_2G_CHAN)
1439*4882a593Smuzhiyun antenna += ANTENNA_OFFSET;
1440*4882a593Smuzhiyun }
1441*4882a593Smuzhiyun }
1442*4882a593Smuzhiyun #endif
1443*4882a593Smuzhiyun
1444*4882a593Smuzhiyun return antenna;
1445*4882a593Smuzhiyun }
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun /**
1448*4882a593Smuzhiyun * @brief This function adjust the rate index
1449*4882a593Smuzhiyun *
1450*4882a593Smuzhiyun * @param priv A pointer to mlan_private structure
1451*4882a593Smuzhiyun * @param rx_rate rx rate
1452*4882a593Smuzhiyun * @param rate_info rate info
1453*4882a593Smuzhiyun * @return rate index
1454*4882a593Smuzhiyun */
wlan_adjust_data_rate(mlan_private * priv,t_u8 rx_rate,t_u8 rate_info)1455*4882a593Smuzhiyun t_u16 wlan_adjust_data_rate(mlan_private *priv, t_u8 rx_rate, t_u8 rate_info)
1456*4882a593Smuzhiyun {
1457*4882a593Smuzhiyun t_u16 rate_index = 0;
1458*4882a593Smuzhiyun t_u8 bw = 0;
1459*4882a593Smuzhiyun t_u8 nss = 0;
1460*4882a593Smuzhiyun t_bool sgi_enable = 0;
1461*4882a593Smuzhiyun t_u8 gi = 0;
1462*4882a593Smuzhiyun #define MAX_MCS_NUM_AX 12
1463*4882a593Smuzhiyun
1464*4882a593Smuzhiyun #define MAX_MCS_NUM_SUPP 16
1465*4882a593Smuzhiyun #define MAX_MCS_NUM_AC 10
1466*4882a593Smuzhiyun #define RATE_INDEX_MCS0 12
1467*4882a593Smuzhiyun bw = (rate_info & 0xC) >> 2;
1468*4882a593Smuzhiyun sgi_enable = (rate_info & 0x10) >> 4;
1469*4882a593Smuzhiyun if ((rate_info & 0x3) == 0) {
1470*4882a593Smuzhiyun rate_index = (rx_rate > MLAN_RATE_INDEX_OFDM0) ? rx_rate - 1 :
1471*4882a593Smuzhiyun rx_rate;
1472*4882a593Smuzhiyun } else if ((rate_info & 0x03) == 1) {
1473*4882a593Smuzhiyun rate_index = RATE_INDEX_MCS0 +
1474*4882a593Smuzhiyun MAX_MCS_NUM_SUPP * 2 * sgi_enable +
1475*4882a593Smuzhiyun MAX_MCS_NUM_SUPP * bw + rx_rate;
1476*4882a593Smuzhiyun } else if ((rate_info & 0x3) == 2) {
1477*4882a593Smuzhiyun if (IS_STREAM_2X2(priv->adapter->feature_control))
1478*4882a593Smuzhiyun nss = rx_rate >> 4; // 0:NSS1, 1:NSS2
1479*4882a593Smuzhiyun rate_index = RATE_INDEX_MCS0 + MAX_MCS_NUM_SUPP * 4 +
1480*4882a593Smuzhiyun MAX_MCS_NUM_AC * 6 * sgi_enable +
1481*4882a593Smuzhiyun MAX_MCS_NUM_AC * 2 * bw + MAX_MCS_NUM_AC * nss +
1482*4882a593Smuzhiyun (rx_rate & 0x0f);
1483*4882a593Smuzhiyun } else if ((rate_info & 0x3) == 3) {
1484*4882a593Smuzhiyun gi = (rate_info & 0x10) >> 4 | (rate_info & 0x80) >> 6;
1485*4882a593Smuzhiyun if (IS_STREAM_2X2(priv->adapter->feature_control))
1486*4882a593Smuzhiyun nss = rx_rate >> 4; // 0:NSS1, 1:NSS2
1487*4882a593Smuzhiyun rate_index = RATE_INDEX_MCS0 + MAX_MCS_NUM_SUPP * 4 +
1488*4882a593Smuzhiyun MAX_MCS_NUM_AC * 12 + MAX_MCS_NUM_AX * 6 * gi +
1489*4882a593Smuzhiyun MAX_MCS_NUM_AX * 2 * bw + MAX_MCS_NUM_AX * nss +
1490*4882a593Smuzhiyun (rx_rate & 0x0f);
1491*4882a593Smuzhiyun }
1492*4882a593Smuzhiyun return rate_index;
1493*4882a593Smuzhiyun }
1494*4882a593Smuzhiyun
1495*4882a593Smuzhiyun #ifdef STA_SUPPORT
1496*4882a593Smuzhiyun #endif /* STA_SUPPORT */
1497*4882a593Smuzhiyun
1498*4882a593Smuzhiyun /**
1499*4882a593Smuzhiyun * @brief convert TX rate_info from v14 to v15+ FW rate_info
1500*4882a593Smuzhiyun *
1501*4882a593Smuzhiyun * @param v14_rate_info v14 rate info
1502*4882a593Smuzhiyun *
1503*4882a593Smuzhiyun * @return v15+ rate info
1504*4882a593Smuzhiyun */
wlan_convert_v14_tx_rate_info(pmlan_private pmpriv,t_u8 v14_rate_info)1505*4882a593Smuzhiyun t_u8 wlan_convert_v14_tx_rate_info(pmlan_private pmpriv, t_u8 v14_rate_info)
1506*4882a593Smuzhiyun {
1507*4882a593Smuzhiyun t_u8 rate_info = 0;
1508*4882a593Smuzhiyun
1509*4882a593Smuzhiyun if (!pmpriv->adapter->pcard_info->v14_fw_api) {
1510*4882a593Smuzhiyun PRINTM(MERROR, "%s: Not convert for this is not V14 FW\n",
1511*4882a593Smuzhiyun __func__);
1512*4882a593Smuzhiyun return v14_rate_info;
1513*4882a593Smuzhiyun }
1514*4882a593Smuzhiyun
1515*4882a593Smuzhiyun rate_info = v14_rate_info & 0x01;
1516*4882a593Smuzhiyun /* band */
1517*4882a593Smuzhiyun rate_info |= (v14_rate_info & MBIT(1)) << 1;
1518*4882a593Smuzhiyun /* short GI */
1519*4882a593Smuzhiyun rate_info |= (v14_rate_info & MBIT(2)) << 2;
1520*4882a593Smuzhiyun return rate_info;
1521*4882a593Smuzhiyun }
1522*4882a593Smuzhiyun
1523*4882a593Smuzhiyun /**
1524*4882a593Smuzhiyun * @brief convert RX rate_info from v14 to v15+ FW rate_info
1525*4882a593Smuzhiyun *
1526*4882a593Smuzhiyun * @param v14_rate_info v14 rate info
1527*4882a593Smuzhiyun *
1528*4882a593Smuzhiyun * @return v15+ rate info
1529*4882a593Smuzhiyun */
wlan_convert_v14_rx_rate_info(pmlan_private pmpriv,t_u8 v14_rate_info)1530*4882a593Smuzhiyun t_u8 wlan_convert_v14_rx_rate_info(pmlan_private pmpriv, t_u8 v14_rate_info)
1531*4882a593Smuzhiyun {
1532*4882a593Smuzhiyun t_u8 rate_info = 0;
1533*4882a593Smuzhiyun t_u8 mode = 0;
1534*4882a593Smuzhiyun t_u8 bw = 0;
1535*4882a593Smuzhiyun t_u8 sgi = 0;
1536*4882a593Smuzhiyun
1537*4882a593Smuzhiyun if (!pmpriv->adapter->pcard_info->v14_fw_api) {
1538*4882a593Smuzhiyun PRINTM(MERROR, "%s: Not convert for this is not V14 FW\n",
1539*4882a593Smuzhiyun __func__);
1540*4882a593Smuzhiyun return v14_rate_info;
1541*4882a593Smuzhiyun }
1542*4882a593Smuzhiyun
1543*4882a593Smuzhiyun mode = v14_rate_info & MBIT(0);
1544*4882a593Smuzhiyun bw = v14_rate_info & MBIT(1);
1545*4882a593Smuzhiyun sgi = (v14_rate_info & 0x04) >> 2;
1546*4882a593Smuzhiyun
1547*4882a593Smuzhiyun rate_info = (mode & 0x01) | ((bw & 0x01) << 2) | ((sgi & 0x01) << 4);
1548*4882a593Smuzhiyun
1549*4882a593Smuzhiyun return rate_info;
1550*4882a593Smuzhiyun }
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun /**
1553*4882a593Smuzhiyun * @brief Use index to get the data rate
1554*4882a593Smuzhiyun *
1555*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1556*4882a593Smuzhiyun * @param index The index of data rate
1557*4882a593Smuzhiyun * @param tx_rate_info Tx rate info
1558*4882a593Smuzhiyun * @param ext_rate_info Extend tx rate info
1559*4882a593Smuzhiyun *
1560*4882a593Smuzhiyun * @return Data rate or 0
1561*4882a593Smuzhiyun */
wlan_index_to_data_rate(pmlan_adapter pmadapter,t_u8 index,t_u8 tx_rate_info,t_u8 ext_rate_info)1562*4882a593Smuzhiyun t_u32 wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index,
1563*4882a593Smuzhiyun t_u8 tx_rate_info, t_u8 ext_rate_info)
1564*4882a593Smuzhiyun {
1565*4882a593Smuzhiyun #define MCS_NUM_SUPP 16
1566*4882a593Smuzhiyun t_u16 mcs_rate[4][MCS_NUM_SUPP] = {
1567*4882a593Smuzhiyun {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e, 0x36, 0x6c,
1568*4882a593Smuzhiyun 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c}, /*LG 40M*/
1569*4882a593Smuzhiyun {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c, 0x3c, 0x78,
1570*4882a593Smuzhiyun 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258}, /*SG 40M */
1571*4882a593Smuzhiyun {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82, 0x1a, 0x34,
1572*4882a593Smuzhiyun 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104}, /*LG 20M */
1573*4882a593Smuzhiyun {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 0x1c, 0x39,
1574*4882a593Smuzhiyun 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120}}; /*SG 20M */
1575*4882a593Smuzhiyun
1576*4882a593Smuzhiyun #define MCS_NUM_AC 10
1577*4882a593Smuzhiyun /* NSS 1. note: the value in the table is 2 multiplier of the actual
1578*4882a593Smuzhiyun * rate in other words, it is in the unit of 500 Kbs
1579*4882a593Smuzhiyun */
1580*4882a593Smuzhiyun t_u16 ac_mcs_rate_nss1[8][MCS_NUM_AC] = {
1581*4882a593Smuzhiyun {0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D, 0x492, 0x57C,
1582*4882a593Smuzhiyun 0x618}, /* LG 160M*/
1583*4882a593Smuzhiyun {0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492, 0x514, 0x618,
1584*4882a593Smuzhiyun 0x6C6}, /* SG 160M*/
1585*4882a593Smuzhiyun {0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F, 0x249, 0x2BE,
1586*4882a593Smuzhiyun 0x30C}, /* LG 80M */
1587*4882a593Smuzhiyun {0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249, 0x28A, 0x30C,
1588*4882a593Smuzhiyun 0x363}, /* SG 80M */
1589*4882a593Smuzhiyun {0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x144,
1590*4882a593Smuzhiyun 0x168}, /* LG 40M */
1591*4882a593Smuzhiyun {0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E, 0x12C, 0x168,
1592*4882a593Smuzhiyun 0x190}, /* SG 40M */
1593*4882a593Smuzhiyun {0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C,
1594*4882a593Smuzhiyun 0x00}, /* LG 20M */
1595*4882a593Smuzhiyun {0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE,
1596*4882a593Smuzhiyun 0x00}, /* SG 20M */
1597*4882a593Smuzhiyun };
1598*4882a593Smuzhiyun /* NSS 2. note: the value in the table is 2 multiplier of the actual
1599*4882a593Smuzhiyun * rate
1600*4882a593Smuzhiyun */
1601*4882a593Smuzhiyun t_u16 ac_mcs_rate_nss2[8][MCS_NUM_AC] = {
1602*4882a593Smuzhiyun {0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A, 0x924, 0xAF8,
1603*4882a593Smuzhiyun 0xC30}, /*LG 160M*/
1604*4882a593Smuzhiyun {0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924, 0xA28, 0xC30,
1605*4882a593Smuzhiyun 0xD8B}, /*SG 160M*/
1606*4882a593Smuzhiyun
1607*4882a593Smuzhiyun {0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D, 0x492, 0x57C,
1608*4882a593Smuzhiyun 0x618}, /*LG 80M*/
1609*4882a593Smuzhiyun {0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492, 0x514, 0x618,
1610*4882a593Smuzhiyun 0x6C6}, /*SG 80M*/
1611*4882a593Smuzhiyun {0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6, 0x21C, 0x288,
1612*4882a593Smuzhiyun 0x2D0}, /*LG 40M*/
1613*4882a593Smuzhiyun {0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C, 0x258, 0x2D0,
1614*4882a593Smuzhiyun 0x320}, /*SG 40M*/
1615*4882a593Smuzhiyun {0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104, 0x138,
1616*4882a593Smuzhiyun 0x00}, /*LG 20M*/
1617*4882a593Smuzhiyun {0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121, 0x15B,
1618*4882a593Smuzhiyun 0x00}, /*SG 20M*/
1619*4882a593Smuzhiyun };
1620*4882a593Smuzhiyun
1621*4882a593Smuzhiyun t_u32 rate = 0;
1622*4882a593Smuzhiyun t_u8 mcs_index = 0;
1623*4882a593Smuzhiyun t_u8 he_dcm = 0;
1624*4882a593Smuzhiyun // t_u8 he_tone = 0;
1625*4882a593Smuzhiyun t_u8 stbc = 0;
1626*4882a593Smuzhiyun
1627*4882a593Smuzhiyun t_u8 bw = 0;
1628*4882a593Smuzhiyun t_u8 gi = 0;
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun ENTER();
1631*4882a593Smuzhiyun
1632*4882a593Smuzhiyun PRINTM(MINFO, "%s:index=%d, tx_rate_info=%d, ext_rate_info=%d\n",
1633*4882a593Smuzhiyun __func__, index, tx_rate_info, ext_rate_info);
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun if ((tx_rate_info & 0x3) == MLAN_RATE_FORMAT_VHT) {
1636*4882a593Smuzhiyun /* VHT rate */
1637*4882a593Smuzhiyun mcs_index = index & 0xF;
1638*4882a593Smuzhiyun
1639*4882a593Smuzhiyun if (mcs_index > 9)
1640*4882a593Smuzhiyun mcs_index = 9;
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
1643*4882a593Smuzhiyun bw = (tx_rate_info & 0xC) >> 2;
1644*4882a593Smuzhiyun /* LGI: gi =0, SGI: gi = 1 */
1645*4882a593Smuzhiyun gi = (tx_rate_info & 0x10) >> 4;
1646*4882a593Smuzhiyun if ((index >> 4) == 1) {
1647*4882a593Smuzhiyun /* NSS = 2 */
1648*4882a593Smuzhiyun rate = ac_mcs_rate_nss2[2 * (3 - bw) + gi][mcs_index];
1649*4882a593Smuzhiyun } else
1650*4882a593Smuzhiyun /* NSS = 1 */
1651*4882a593Smuzhiyun rate = ac_mcs_rate_nss1[2 * (3 - bw) + gi][mcs_index];
1652*4882a593Smuzhiyun } else
1653*4882a593Smuzhiyun
1654*4882a593Smuzhiyun if ((tx_rate_info & 0x3) == MLAN_RATE_FORMAT_HE) {
1655*4882a593Smuzhiyun /* VHT rate */
1656*4882a593Smuzhiyun mcs_index = index & 0xF;
1657*4882a593Smuzhiyun he_dcm = ext_rate_info & MBIT(0);
1658*4882a593Smuzhiyun
1659*4882a593Smuzhiyun if (mcs_index > MCS_NUM_AX - 1)
1660*4882a593Smuzhiyun mcs_index = MCS_NUM_AX - 1;
1661*4882a593Smuzhiyun
1662*4882a593Smuzhiyun /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
1663*4882a593Smuzhiyun bw = (tx_rate_info & (MBIT(3) | MBIT(2))) >> 2;
1664*4882a593Smuzhiyun /* BIT7:BIT4 0:0= 0.8us,0:1= 0.8us, 1:0=1.6us, 1:1=3.2us or
1665*4882a593Smuzhiyun * 0.8us
1666*4882a593Smuzhiyun */
1667*4882a593Smuzhiyun gi = (tx_rate_info & MBIT(4)) >> 4 |
1668*4882a593Smuzhiyun (tx_rate_info & MBIT(7)) >> 6;
1669*4882a593Smuzhiyun /* STBC: BIT5 in tx rate info */
1670*4882a593Smuzhiyun stbc = (tx_rate_info & MBIT(5)) >> 5;
1671*4882a593Smuzhiyun
1672*4882a593Smuzhiyun if (gi > 3) {
1673*4882a593Smuzhiyun PRINTM(MERROR, "Invalid gi value");
1674*4882a593Smuzhiyun return 0;
1675*4882a593Smuzhiyun }
1676*4882a593Smuzhiyun
1677*4882a593Smuzhiyun if ((gi == 3) && stbc && he_dcm) {
1678*4882a593Smuzhiyun gi = 0;
1679*4882a593Smuzhiyun stbc = 0;
1680*4882a593Smuzhiyun he_dcm = 0;
1681*4882a593Smuzhiyun }
1682*4882a593Smuzhiyun /* map to gi 0:0.8us,1:1.6us 2:3.2us*/
1683*4882a593Smuzhiyun if (gi > 0)
1684*4882a593Smuzhiyun gi = gi - 1;
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun //#ifdef ENABLE_802_11AX
1687*4882a593Smuzhiyun // TODO: hardcode he_tone here, wait for FW value ready.
1688*4882a593Smuzhiyun // he_tone = 4;
1689*4882a593Smuzhiyun
1690*4882a593Smuzhiyun // he_tone = (ext_rate_info & 0xE) >> 1;
1691*4882a593Smuzhiyun //#endif
1692*4882a593Smuzhiyun
1693*4882a593Smuzhiyun if ((index >> 4) == 1) {
1694*4882a593Smuzhiyun switch (mcs_index) {
1695*4882a593Smuzhiyun case 0:
1696*4882a593Smuzhiyun case 1:
1697*4882a593Smuzhiyun // #if 0
1698*4882a593Smuzhiyun // if (he_tone < 3) {
1699*4882a593Smuzhiyun // rate =
1700*4882a593Smuzhiyun //ax_tone_ru_rate_nss2[3*(2-he_tone)+gi][mcs_index*2
1701*4882a593Smuzhiyun //+ he_dcm];
1702*4882a593Smuzhiyun // } else {
1703*4882a593Smuzhiyun // #endif
1704*4882a593Smuzhiyun rate = ax_mcs_rate_nss2[3 * (3 - bw) + gi]
1705*4882a593Smuzhiyun [mcs_index * 2 + he_dcm];
1706*4882a593Smuzhiyun break;
1707*4882a593Smuzhiyun case 2:
1708*4882a593Smuzhiyun // #if 0
1709*4882a593Smuzhiyun // if (he_tone < 3) {
1710*4882a593Smuzhiyun // rate =
1711*4882a593Smuzhiyun //ax_tone_ru_rate_nss2[3*(2-he_tone)+gi][mcs_index*2];
1712*4882a593Smuzhiyun // } else {
1713*4882a593Smuzhiyun // #endif
1714*4882a593Smuzhiyun rate = ax_mcs_rate_nss2[3 * (3 - bw) + gi]
1715*4882a593Smuzhiyun [mcs_index * 2];
1716*4882a593Smuzhiyun break;
1717*4882a593Smuzhiyun case 3:
1718*4882a593Smuzhiyun case 4:
1719*4882a593Smuzhiyun // #if 0
1720*4882a593Smuzhiyun // if (he_tone < 3) {
1721*4882a593Smuzhiyun // rate =
1722*4882a593Smuzhiyun //ax_tone_ru_rate_nss2[3*(2-he_tone)+gi][mcs_index*2
1723*4882a593Smuzhiyun //- 1 + he_dcm];
1724*4882a593Smuzhiyun // } else {
1725*4882a593Smuzhiyun // #endif
1726*4882a593Smuzhiyun rate = ax_mcs_rate_nss2[3 * (3 - bw) + gi]
1727*4882a593Smuzhiyun [mcs_index * 2 - 1 +
1728*4882a593Smuzhiyun he_dcm];
1729*4882a593Smuzhiyun break;
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun default:
1732*4882a593Smuzhiyun // #if 0
1733*4882a593Smuzhiyun // if (he_tone < 3) {
1734*4882a593Smuzhiyun // rate =
1735*4882a593Smuzhiyun //ax_tone_ru_rate_nss2[3*(2-he_tone)+gi][mcs_index
1736*4882a593Smuzhiyun //+ 4];
1737*4882a593Smuzhiyun // } else {
1738*4882a593Smuzhiyun // #endif
1739*4882a593Smuzhiyun rate = ax_mcs_rate_nss2[3 * (3 - bw) + gi]
1740*4882a593Smuzhiyun [mcs_index + 4];
1741*4882a593Smuzhiyun break;
1742*4882a593Smuzhiyun }
1743*4882a593Smuzhiyun } else {
1744*4882a593Smuzhiyun switch (mcs_index) {
1745*4882a593Smuzhiyun case 0:
1746*4882a593Smuzhiyun case 1:
1747*4882a593Smuzhiyun // #if 0
1748*4882a593Smuzhiyun // if (he_tone < 3) {
1749*4882a593Smuzhiyun // rate =
1750*4882a593Smuzhiyun //ax_tone_ru_rate_nss1[3*(2-he_tone)+gi][mcs_index*2
1751*4882a593Smuzhiyun //+ he_dcm];
1752*4882a593Smuzhiyun // } else {
1753*4882a593Smuzhiyun // #endif
1754*4882a593Smuzhiyun rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi]
1755*4882a593Smuzhiyun [mcs_index * 2 + he_dcm];
1756*4882a593Smuzhiyun break;
1757*4882a593Smuzhiyun case 2:
1758*4882a593Smuzhiyun // #if 0
1759*4882a593Smuzhiyun // if (he_tone < 3) {
1760*4882a593Smuzhiyun // rate =
1761*4882a593Smuzhiyun //ax_tone_ru_rate_nss1[3*(2-he_tone)+gi][mcs_index*2];
1762*4882a593Smuzhiyun // } else {
1763*4882a593Smuzhiyun // #endif
1764*4882a593Smuzhiyun rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi]
1765*4882a593Smuzhiyun [mcs_index * 2];
1766*4882a593Smuzhiyun break;
1767*4882a593Smuzhiyun case 3:
1768*4882a593Smuzhiyun case 4:
1769*4882a593Smuzhiyun // #if 0
1770*4882a593Smuzhiyun // if (he_tone < 3) {
1771*4882a593Smuzhiyun // rate =
1772*4882a593Smuzhiyun //ax_tone_ru_rate_nss1[3*(2-he_tone)+gi][mcs_index*2
1773*4882a593Smuzhiyun //- 1 + he_dcm];
1774*4882a593Smuzhiyun // } else {
1775*4882a593Smuzhiyun // #endif
1776*4882a593Smuzhiyun rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi]
1777*4882a593Smuzhiyun [mcs_index * 2 - 1 +
1778*4882a593Smuzhiyun he_dcm];
1779*4882a593Smuzhiyun break;
1780*4882a593Smuzhiyun
1781*4882a593Smuzhiyun default:
1782*4882a593Smuzhiyun // #if 0
1783*4882a593Smuzhiyun // if (he_tone < 3) {
1784*4882a593Smuzhiyun // rate =
1785*4882a593Smuzhiyun //ax_tone_ru_rate_nss1[3*(2-he_tone)+gi][mcs_index
1786*4882a593Smuzhiyun //+ 4];
1787*4882a593Smuzhiyun // } else {
1788*4882a593Smuzhiyun // #endif
1789*4882a593Smuzhiyun rate = ax_mcs_rate_nss1[3 * (3 - bw) + gi]
1790*4882a593Smuzhiyun [mcs_index + 4];
1791*4882a593Smuzhiyun break;
1792*4882a593Smuzhiyun }
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun } else if ((tx_rate_info & 0x3) == MLAN_RATE_FORMAT_HT) {
1795*4882a593Smuzhiyun /* HT rate */
1796*4882a593Smuzhiyun /* 20M: bw=0, 40M: bw=1 */
1797*4882a593Smuzhiyun bw = (tx_rate_info & 0xC) >> 2;
1798*4882a593Smuzhiyun /* LGI: gi =0, SGI: gi = 1 */
1799*4882a593Smuzhiyun gi = (tx_rate_info & 0x10) >> 4;
1800*4882a593Smuzhiyun if (index == MLAN_RATE_BITMAP_MCS0) {
1801*4882a593Smuzhiyun if (gi == 1)
1802*4882a593Smuzhiyun rate = 0x0D; /* MCS 32 SGI rate */
1803*4882a593Smuzhiyun else
1804*4882a593Smuzhiyun rate = 0x0C; /* MCS 32 LGI rate */
1805*4882a593Smuzhiyun } else if (index < MCS_NUM_SUPP) {
1806*4882a593Smuzhiyun if (bw <= 1)
1807*4882a593Smuzhiyun rate = mcs_rate[2 * (1 - bw) + gi][index];
1808*4882a593Smuzhiyun else
1809*4882a593Smuzhiyun rate = WlanDataRates[0];
1810*4882a593Smuzhiyun } else
1811*4882a593Smuzhiyun rate = WlanDataRates[0];
1812*4882a593Smuzhiyun } else {
1813*4882a593Smuzhiyun /* 11n non HT rates */
1814*4882a593Smuzhiyun if (index >= WLAN_SUPPORTED_RATES_EXT)
1815*4882a593Smuzhiyun index = 0;
1816*4882a593Smuzhiyun rate = WlanDataRates[index];
1817*4882a593Smuzhiyun }
1818*4882a593Smuzhiyun LEAVE();
1819*4882a593Smuzhiyun return rate;
1820*4882a593Smuzhiyun }
1821*4882a593Smuzhiyun
1822*4882a593Smuzhiyun /**
1823*4882a593Smuzhiyun * @brief Use rate to get the index
1824*4882a593Smuzhiyun *
1825*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1826*4882a593Smuzhiyun * @param rate Data rate
1827*4882a593Smuzhiyun *
1828*4882a593Smuzhiyun * @return Index or 0
1829*4882a593Smuzhiyun */
wlan_data_rate_to_index(pmlan_adapter pmadapter,t_u32 rate)1830*4882a593Smuzhiyun t_u8 wlan_data_rate_to_index(pmlan_adapter pmadapter, t_u32 rate)
1831*4882a593Smuzhiyun {
1832*4882a593Smuzhiyun t_u16 *ptr;
1833*4882a593Smuzhiyun
1834*4882a593Smuzhiyun ENTER();
1835*4882a593Smuzhiyun if (rate) {
1836*4882a593Smuzhiyun ptr = wlan_memchr(pmadapter, WlanDataRates, (t_u8)rate,
1837*4882a593Smuzhiyun sizeof(WlanDataRates));
1838*4882a593Smuzhiyun if (ptr) {
1839*4882a593Smuzhiyun LEAVE();
1840*4882a593Smuzhiyun return (t_u8)(ptr - WlanDataRates);
1841*4882a593Smuzhiyun }
1842*4882a593Smuzhiyun }
1843*4882a593Smuzhiyun LEAVE();
1844*4882a593Smuzhiyun return 0;
1845*4882a593Smuzhiyun }
1846*4882a593Smuzhiyun
1847*4882a593Smuzhiyun /**
1848*4882a593Smuzhiyun * @brief Get active data rates
1849*4882a593Smuzhiyun *
1850*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
1851*4882a593Smuzhiyun * @param bss_mode The specified BSS mode (Infra/IBSS)
1852*4882a593Smuzhiyun * @param config_bands The specified band configuration
1853*4882a593Smuzhiyun * @param rates The buf to return the active rates
1854*4882a593Smuzhiyun *
1855*4882a593Smuzhiyun * @return The number of Rates
1856*4882a593Smuzhiyun */
wlan_get_active_data_rates(mlan_private * pmpriv,t_u32 bss_mode,t_u16 config_bands,WLAN_802_11_RATES rates)1857*4882a593Smuzhiyun t_u32 wlan_get_active_data_rates(mlan_private *pmpriv, t_u32 bss_mode,
1858*4882a593Smuzhiyun t_u16 config_bands, WLAN_802_11_RATES rates)
1859*4882a593Smuzhiyun {
1860*4882a593Smuzhiyun t_u32 k;
1861*4882a593Smuzhiyun
1862*4882a593Smuzhiyun ENTER();
1863*4882a593Smuzhiyun
1864*4882a593Smuzhiyun if (pmpriv->media_connected != MTRUE) {
1865*4882a593Smuzhiyun k = wlan_get_supported_rates(pmpriv, bss_mode, config_bands,
1866*4882a593Smuzhiyun rates);
1867*4882a593Smuzhiyun } else {
1868*4882a593Smuzhiyun k = wlan_copy_rates(rates, 0,
1869*4882a593Smuzhiyun pmpriv->curr_bss_params.data_rates,
1870*4882a593Smuzhiyun pmpriv->curr_bss_params.num_of_rates);
1871*4882a593Smuzhiyun }
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun LEAVE();
1874*4882a593Smuzhiyun return k;
1875*4882a593Smuzhiyun }
1876*4882a593Smuzhiyun
1877*4882a593Smuzhiyun #ifdef STA_SUPPORT
1878*4882a593Smuzhiyun /**
1879*4882a593Smuzhiyun * @brief This function search through all the regions cfp table to find the
1880*4882a593Smuzhiyun * channel, if the channel is found then gets the MIN txpower of the channel
1881*4882a593Smuzhiyun * present in all the regions.
1882*4882a593Smuzhiyun *
1883*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
1884*4882a593Smuzhiyun * @param band band.
1885*4882a593Smuzhiyun * @param channel Channel number.
1886*4882a593Smuzhiyun *
1887*4882a593Smuzhiyun * @return The Tx power
1888*4882a593Smuzhiyun */
wlan_get_txpwr_of_chan_from_cfp(mlan_private * pmpriv,t_u16 band,t_u8 channel)1889*4882a593Smuzhiyun t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private *pmpriv, t_u16 band,
1890*4882a593Smuzhiyun t_u8 channel)
1891*4882a593Smuzhiyun {
1892*4882a593Smuzhiyun t_u8 i = 0;
1893*4882a593Smuzhiyun t_u8 j = 0;
1894*4882a593Smuzhiyun t_u8 tx_power = 0;
1895*4882a593Smuzhiyun t_u32 cfp_no;
1896*4882a593Smuzhiyun chan_freq_power_t *cfp = MNULL;
1897*4882a593Smuzhiyun chan_freq_power_t *cfp_a = MNULL;
1898*4882a593Smuzhiyun t_u32 cfp_no_a;
1899*4882a593Smuzhiyun
1900*4882a593Smuzhiyun ENTER();
1901*4882a593Smuzhiyun
1902*4882a593Smuzhiyun if (band & (BAND_B | BAND_G)) {
1903*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) {
1904*4882a593Smuzhiyun /* Get CFP */
1905*4882a593Smuzhiyun cfp = cfp_table_BG[i].cfp;
1906*4882a593Smuzhiyun cfp_no = cfp_table_BG[i].cfp_no;
1907*4882a593Smuzhiyun /* Find matching channel and get Tx power */
1908*4882a593Smuzhiyun for (j = 0; j < cfp_no; j++) {
1909*4882a593Smuzhiyun if ((cfp + j)->channel == channel) {
1910*4882a593Smuzhiyun if (tx_power != 0)
1911*4882a593Smuzhiyun tx_power = MIN(
1912*4882a593Smuzhiyun tx_power,
1913*4882a593Smuzhiyun (cfp + j)->max_tx_power);
1914*4882a593Smuzhiyun else
1915*4882a593Smuzhiyun tx_power =
1916*4882a593Smuzhiyun (t_u8)(cfp + j)
1917*4882a593Smuzhiyun ->max_tx_power;
1918*4882a593Smuzhiyun break;
1919*4882a593Smuzhiyun }
1920*4882a593Smuzhiyun }
1921*4882a593Smuzhiyun }
1922*4882a593Smuzhiyun }
1923*4882a593Smuzhiyun
1924*4882a593Smuzhiyun if (band & BAND_A) {
1925*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) {
1926*4882a593Smuzhiyun /* Get CFP */
1927*4882a593Smuzhiyun cfp_a = cfp_table_A[i].cfp;
1928*4882a593Smuzhiyun cfp_no_a = cfp_table_A[i].cfp_no;
1929*4882a593Smuzhiyun for (j = 0; j < cfp_no_a; j++) {
1930*4882a593Smuzhiyun if ((cfp_a + j)->channel == channel) {
1931*4882a593Smuzhiyun if (tx_power != 0)
1932*4882a593Smuzhiyun tx_power = MIN(
1933*4882a593Smuzhiyun tx_power,
1934*4882a593Smuzhiyun (cfp_a + j)
1935*4882a593Smuzhiyun ->max_tx_power);
1936*4882a593Smuzhiyun else
1937*4882a593Smuzhiyun tx_power = (t_u8)(
1938*4882a593Smuzhiyun (cfp_a + j)
1939*4882a593Smuzhiyun ->max_tx_power);
1940*4882a593Smuzhiyun break;
1941*4882a593Smuzhiyun }
1942*4882a593Smuzhiyun }
1943*4882a593Smuzhiyun }
1944*4882a593Smuzhiyun }
1945*4882a593Smuzhiyun
1946*4882a593Smuzhiyun LEAVE();
1947*4882a593Smuzhiyun return tx_power;
1948*4882a593Smuzhiyun }
1949*4882a593Smuzhiyun
1950*4882a593Smuzhiyun /**
1951*4882a593Smuzhiyun * @brief Get the channel frequency power info for a specific channel
1952*4882a593Smuzhiyun *
1953*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
1954*4882a593Smuzhiyun * @param band It can be BAND_A, BAND_G or BAND_B
1955*4882a593Smuzhiyun * @param channel The channel to search for
1956*4882a593Smuzhiyun * @param region_channel A pointer to region_chan_t structure
1957*4882a593Smuzhiyun *
1958*4882a593Smuzhiyun * @return A pointer to chan_freq_power_t structure or
1959*4882a593Smuzhiyun * MNULL if not found.
1960*4882a593Smuzhiyun */
1961*4882a593Smuzhiyun
1962*4882a593Smuzhiyun chan_freq_power_t *
wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter,t_u16 band,t_u16 channel,region_chan_t * region_channel)1963*4882a593Smuzhiyun wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, t_u16 band,
1964*4882a593Smuzhiyun t_u16 channel, region_chan_t *region_channel)
1965*4882a593Smuzhiyun {
1966*4882a593Smuzhiyun region_chan_t *rc;
1967*4882a593Smuzhiyun chan_freq_power_t *cfp = MNULL;
1968*4882a593Smuzhiyun int i, j;
1969*4882a593Smuzhiyun
1970*4882a593Smuzhiyun ENTER();
1971*4882a593Smuzhiyun
1972*4882a593Smuzhiyun for (j = 0; !cfp && (j < MAX_REGION_CHANNEL_NUM); j++) {
1973*4882a593Smuzhiyun rc = ®ion_channel[j];
1974*4882a593Smuzhiyun
1975*4882a593Smuzhiyun if (!rc->valid || !rc->pcfp)
1976*4882a593Smuzhiyun continue;
1977*4882a593Smuzhiyun switch (rc->band) {
1978*4882a593Smuzhiyun case BAND_A:
1979*4882a593Smuzhiyun switch (band) {
1980*4882a593Smuzhiyun case BAND_AN:
1981*4882a593Smuzhiyun case BAND_A | BAND_AN:
1982*4882a593Smuzhiyun case BAND_A | BAND_AN | BAND_AAC:
1983*4882a593Smuzhiyun /* Fall Through */
1984*4882a593Smuzhiyun case BAND_A: /* Matching BAND_A */
1985*4882a593Smuzhiyun break;
1986*4882a593Smuzhiyun
1987*4882a593Smuzhiyun default:
1988*4882a593Smuzhiyun continue;
1989*4882a593Smuzhiyun }
1990*4882a593Smuzhiyun break;
1991*4882a593Smuzhiyun case BAND_B:
1992*4882a593Smuzhiyun case BAND_G:
1993*4882a593Smuzhiyun switch (band) {
1994*4882a593Smuzhiyun case BAND_GN:
1995*4882a593Smuzhiyun case BAND_B | BAND_G | BAND_GN:
1996*4882a593Smuzhiyun case BAND_G | BAND_GN:
1997*4882a593Smuzhiyun case BAND_GN | BAND_GAC:
1998*4882a593Smuzhiyun case BAND_B | BAND_G | BAND_GN | BAND_GAC:
1999*4882a593Smuzhiyun case BAND_G | BAND_GN | BAND_GAC:
2000*4882a593Smuzhiyun case BAND_B | BAND_G:
2001*4882a593Smuzhiyun /* Fall Through */
2002*4882a593Smuzhiyun case BAND_B: /* Matching BAND_B/G */
2003*4882a593Smuzhiyun /* Fall Through */
2004*4882a593Smuzhiyun case BAND_G:
2005*4882a593Smuzhiyun /* Fall Through */
2006*4882a593Smuzhiyun case 0:
2007*4882a593Smuzhiyun break;
2008*4882a593Smuzhiyun default:
2009*4882a593Smuzhiyun continue;
2010*4882a593Smuzhiyun }
2011*4882a593Smuzhiyun break;
2012*4882a593Smuzhiyun default:
2013*4882a593Smuzhiyun continue;
2014*4882a593Smuzhiyun }
2015*4882a593Smuzhiyun if (channel == FIRST_VALID_CHANNEL)
2016*4882a593Smuzhiyun cfp = &rc->pcfp[0];
2017*4882a593Smuzhiyun else {
2018*4882a593Smuzhiyun for (i = 0; i < rc->num_cfp; i++) {
2019*4882a593Smuzhiyun if (rc->pcfp[i].channel == channel) {
2020*4882a593Smuzhiyun cfp = &rc->pcfp[i];
2021*4882a593Smuzhiyun break;
2022*4882a593Smuzhiyun }
2023*4882a593Smuzhiyun }
2024*4882a593Smuzhiyun }
2025*4882a593Smuzhiyun }
2026*4882a593Smuzhiyun
2027*4882a593Smuzhiyun if (!cfp && channel)
2028*4882a593Smuzhiyun PRINTM(MCMND, "%s: can not find cfp by band %d & channel %d\n",
2029*4882a593Smuzhiyun __func__, band, channel);
2030*4882a593Smuzhiyun
2031*4882a593Smuzhiyun LEAVE();
2032*4882a593Smuzhiyun return cfp;
2033*4882a593Smuzhiyun }
2034*4882a593Smuzhiyun
2035*4882a593Smuzhiyun /**
2036*4882a593Smuzhiyun * @brief Find the channel frequency power info for a specific channel
2037*4882a593Smuzhiyun *
2038*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
2039*4882a593Smuzhiyun * @param band It can be BAND_A, BAND_G or BAND_B
2040*4882a593Smuzhiyun * @param channel The channel to search for
2041*4882a593Smuzhiyun *
2042*4882a593Smuzhiyun * @return A pointer to chan_freq_power_t structure or MNULL if not
2043*4882a593Smuzhiyun * found.
2044*4882a593Smuzhiyun */
wlan_find_cfp_by_band_and_channel(mlan_adapter * pmadapter,t_u16 band,t_u16 channel)2045*4882a593Smuzhiyun chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter *pmadapter,
2046*4882a593Smuzhiyun t_u16 band, t_u16 channel)
2047*4882a593Smuzhiyun {
2048*4882a593Smuzhiyun chan_freq_power_t *cfp = MNULL;
2049*4882a593Smuzhiyun
2050*4882a593Smuzhiyun ENTER();
2051*4882a593Smuzhiyun
2052*4882a593Smuzhiyun /* Any station(s) with 11D enabled */
2053*4882a593Smuzhiyun if (wlan_count_priv_cond(pmadapter, wlan_11d_is_enabled,
2054*4882a593Smuzhiyun wlan_is_station) > 0)
2055*4882a593Smuzhiyun cfp = wlan_get_cfp_by_band_and_channel(
2056*4882a593Smuzhiyun pmadapter, band, channel, pmadapter->universal_channel);
2057*4882a593Smuzhiyun else
2058*4882a593Smuzhiyun cfp = wlan_get_cfp_by_band_and_channel(
2059*4882a593Smuzhiyun pmadapter, band, channel, pmadapter->region_channel);
2060*4882a593Smuzhiyun
2061*4882a593Smuzhiyun LEAVE();
2062*4882a593Smuzhiyun return cfp;
2063*4882a593Smuzhiyun }
2064*4882a593Smuzhiyun
2065*4882a593Smuzhiyun /**
2066*4882a593Smuzhiyun * @brief Find the channel frequency power info for a specific frequency
2067*4882a593Smuzhiyun *
2068*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
2069*4882a593Smuzhiyun * @param band It can be BAND_A, BAND_G or BAND_B
2070*4882a593Smuzhiyun * @param freq The frequency to search for
2071*4882a593Smuzhiyun *
2072*4882a593Smuzhiyun * @return Pointer to chan_freq_power_t structure; MNULL if not found
2073*4882a593Smuzhiyun */
wlan_find_cfp_by_band_and_freq(mlan_adapter * pmadapter,t_u16 band,t_u32 freq)2074*4882a593Smuzhiyun chan_freq_power_t *wlan_find_cfp_by_band_and_freq(mlan_adapter *pmadapter,
2075*4882a593Smuzhiyun t_u16 band, t_u32 freq)
2076*4882a593Smuzhiyun {
2077*4882a593Smuzhiyun chan_freq_power_t *cfp = MNULL;
2078*4882a593Smuzhiyun region_chan_t *rc;
2079*4882a593Smuzhiyun int i, j;
2080*4882a593Smuzhiyun
2081*4882a593Smuzhiyun ENTER();
2082*4882a593Smuzhiyun
2083*4882a593Smuzhiyun for (j = 0; !cfp && (j < MAX_REGION_CHANNEL_NUM); j++) {
2084*4882a593Smuzhiyun rc = &pmadapter->region_channel[j];
2085*4882a593Smuzhiyun
2086*4882a593Smuzhiyun /* Any station(s) with 11D enabled */
2087*4882a593Smuzhiyun if (wlan_count_priv_cond(pmadapter, wlan_11d_is_enabled,
2088*4882a593Smuzhiyun wlan_is_station) > 0)
2089*4882a593Smuzhiyun rc = &pmadapter->universal_channel[j];
2090*4882a593Smuzhiyun
2091*4882a593Smuzhiyun if (!rc->valid || !rc->pcfp)
2092*4882a593Smuzhiyun continue;
2093*4882a593Smuzhiyun switch (rc->band) {
2094*4882a593Smuzhiyun case BAND_A:
2095*4882a593Smuzhiyun switch (band) {
2096*4882a593Smuzhiyun case BAND_AN:
2097*4882a593Smuzhiyun case BAND_A | BAND_AN:
2098*4882a593Smuzhiyun case BAND_A | BAND_AN | BAND_AAC:
2099*4882a593Smuzhiyun /* Fall Through */
2100*4882a593Smuzhiyun case BAND_A: /* Matching BAND_A */
2101*4882a593Smuzhiyun break;
2102*4882a593Smuzhiyun default:
2103*4882a593Smuzhiyun continue;
2104*4882a593Smuzhiyun }
2105*4882a593Smuzhiyun break;
2106*4882a593Smuzhiyun case BAND_B:
2107*4882a593Smuzhiyun case BAND_G:
2108*4882a593Smuzhiyun switch (band) {
2109*4882a593Smuzhiyun case BAND_GN:
2110*4882a593Smuzhiyun case BAND_B | BAND_G | BAND_GN:
2111*4882a593Smuzhiyun case BAND_G | BAND_GN:
2112*4882a593Smuzhiyun case BAND_GN | BAND_GAC:
2113*4882a593Smuzhiyun case BAND_B | BAND_G | BAND_GN | BAND_GAC:
2114*4882a593Smuzhiyun case BAND_G | BAND_GN | BAND_GAC:
2115*4882a593Smuzhiyun case BAND_B | BAND_G:
2116*4882a593Smuzhiyun /* Fall Through */
2117*4882a593Smuzhiyun case BAND_B:
2118*4882a593Smuzhiyun /* Fall Through */
2119*4882a593Smuzhiyun case BAND_G:
2120*4882a593Smuzhiyun /* Fall Through */
2121*4882a593Smuzhiyun case 0:
2122*4882a593Smuzhiyun break;
2123*4882a593Smuzhiyun default:
2124*4882a593Smuzhiyun continue;
2125*4882a593Smuzhiyun }
2126*4882a593Smuzhiyun break;
2127*4882a593Smuzhiyun default:
2128*4882a593Smuzhiyun continue;
2129*4882a593Smuzhiyun }
2130*4882a593Smuzhiyun for (i = 0; i < rc->num_cfp; i++) {
2131*4882a593Smuzhiyun if (rc->pcfp[i].freq == freq) {
2132*4882a593Smuzhiyun cfp = &rc->pcfp[i];
2133*4882a593Smuzhiyun break;
2134*4882a593Smuzhiyun }
2135*4882a593Smuzhiyun }
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun
2138*4882a593Smuzhiyun if (!cfp && freq)
2139*4882a593Smuzhiyun PRINTM(MERROR, "%s: cannot find cfp by band %d & freq %d\n",
2140*4882a593Smuzhiyun __func__, band, freq);
2141*4882a593Smuzhiyun
2142*4882a593Smuzhiyun LEAVE();
2143*4882a593Smuzhiyun return cfp;
2144*4882a593Smuzhiyun }
2145*4882a593Smuzhiyun #endif /* STA_SUPPORT */
2146*4882a593Smuzhiyun
2147*4882a593Smuzhiyun /**
2148*4882a593Smuzhiyun * @brief Check if Rate Auto
2149*4882a593Smuzhiyun *
2150*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2151*4882a593Smuzhiyun *
2152*4882a593Smuzhiyun * @return MTRUE or MFALSE
2153*4882a593Smuzhiyun */
wlan_is_rate_auto(mlan_private * pmpriv)2154*4882a593Smuzhiyun t_u8 wlan_is_rate_auto(mlan_private *pmpriv)
2155*4882a593Smuzhiyun {
2156*4882a593Smuzhiyun t_u32 i;
2157*4882a593Smuzhiyun int rate_num = 0;
2158*4882a593Smuzhiyun
2159*4882a593Smuzhiyun ENTER();
2160*4882a593Smuzhiyun
2161*4882a593Smuzhiyun for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates); i++)
2162*4882a593Smuzhiyun if (pmpriv->bitmap_rates[i])
2163*4882a593Smuzhiyun rate_num++;
2164*4882a593Smuzhiyun
2165*4882a593Smuzhiyun LEAVE();
2166*4882a593Smuzhiyun if (rate_num > 1)
2167*4882a593Smuzhiyun return MTRUE;
2168*4882a593Smuzhiyun else
2169*4882a593Smuzhiyun return MFALSE;
2170*4882a593Smuzhiyun }
2171*4882a593Smuzhiyun
2172*4882a593Smuzhiyun /**
2173*4882a593Smuzhiyun * @brief Covert Rate Bitmap to Rate index
2174*4882a593Smuzhiyun *
2175*4882a593Smuzhiyun * @param pmadapter Pointer to mlan_adapter structure
2176*4882a593Smuzhiyun * @param rate_bitmap Pointer to rate bitmap
2177*4882a593Smuzhiyun * @param size Size of the bitmap array
2178*4882a593Smuzhiyun *
2179*4882a593Smuzhiyun * @return Rate index
2180*4882a593Smuzhiyun */
wlan_get_rate_index(pmlan_adapter pmadapter,t_u16 * rate_bitmap,int size)2181*4882a593Smuzhiyun int wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 *rate_bitmap, int size)
2182*4882a593Smuzhiyun {
2183*4882a593Smuzhiyun int i;
2184*4882a593Smuzhiyun
2185*4882a593Smuzhiyun ENTER();
2186*4882a593Smuzhiyun
2187*4882a593Smuzhiyun for (i = 0; i < size * 8; i++) {
2188*4882a593Smuzhiyun if (rate_bitmap[i / 16] & (1 << (i % 16))) {
2189*4882a593Smuzhiyun LEAVE();
2190*4882a593Smuzhiyun return i;
2191*4882a593Smuzhiyun }
2192*4882a593Smuzhiyun }
2193*4882a593Smuzhiyun
2194*4882a593Smuzhiyun LEAVE();
2195*4882a593Smuzhiyun return -1;
2196*4882a593Smuzhiyun }
2197*4882a593Smuzhiyun
2198*4882a593Smuzhiyun /**
2199*4882a593Smuzhiyun * @brief Convert config_bands to B/G/A band
2200*4882a593Smuzhiyun *
2201*4882a593Smuzhiyun * @param config_bands The specified band configuration
2202*4882a593Smuzhiyun *
2203*4882a593Smuzhiyun * @return BAND_B|BAND_G|BAND_A
2204*4882a593Smuzhiyun */
wlan_convert_config_bands(t_u16 config_bands)2205*4882a593Smuzhiyun t_u16 wlan_convert_config_bands(t_u16 config_bands)
2206*4882a593Smuzhiyun {
2207*4882a593Smuzhiyun t_u16 bands = 0;
2208*4882a593Smuzhiyun if (config_bands & BAND_B)
2209*4882a593Smuzhiyun bands |= BAND_B;
2210*4882a593Smuzhiyun if (config_bands & BAND_G || config_bands & BAND_GN ||
2211*4882a593Smuzhiyun config_bands & BAND_GAC || config_bands & BAND_GAX)
2212*4882a593Smuzhiyun bands |= BAND_G;
2213*4882a593Smuzhiyun if (config_bands & BAND_A || config_bands & BAND_AN ||
2214*4882a593Smuzhiyun config_bands & BAND_AAC || config_bands & BAND_AAX)
2215*4882a593Smuzhiyun bands |= BAND_A;
2216*4882a593Smuzhiyun return bands;
2217*4882a593Smuzhiyun }
2218*4882a593Smuzhiyun
2219*4882a593Smuzhiyun /**
2220*4882a593Smuzhiyun * @brief Get supported data rates
2221*4882a593Smuzhiyun *
2222*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2223*4882a593Smuzhiyun * @param bss_mode The specified BSS mode (Infra/IBSS)
2224*4882a593Smuzhiyun * @param config_bands The specified band configuration
2225*4882a593Smuzhiyun * @param rates The buf to return the supported rates
2226*4882a593Smuzhiyun *
2227*4882a593Smuzhiyun * @return The number of Rates
2228*4882a593Smuzhiyun */
wlan_get_supported_rates(mlan_private * pmpriv,t_u32 bss_mode,t_u16 config_bands,WLAN_802_11_RATES rates)2229*4882a593Smuzhiyun t_u32 wlan_get_supported_rates(mlan_private *pmpriv, t_u32 bss_mode,
2230*4882a593Smuzhiyun t_u16 config_bands, WLAN_802_11_RATES rates)
2231*4882a593Smuzhiyun {
2232*4882a593Smuzhiyun t_u32 k = 0;
2233*4882a593Smuzhiyun t_u16 bands = 0;
2234*4882a593Smuzhiyun
2235*4882a593Smuzhiyun ENTER();
2236*4882a593Smuzhiyun bands = wlan_convert_config_bands(config_bands);
2237*4882a593Smuzhiyun
2238*4882a593Smuzhiyun if (bss_mode == MLAN_BSS_MODE_INFRA) {
2239*4882a593Smuzhiyun /* Infra. mode */
2240*4882a593Smuzhiyun if (bands == BAND_B) {
2241*4882a593Smuzhiyun /* B only */
2242*4882a593Smuzhiyun PRINTM(MINFO, "Band: Infra B\n");
2243*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, SupportedRates_B,
2244*4882a593Smuzhiyun sizeof(SupportedRates_B));
2245*4882a593Smuzhiyun } else if (bands == BAND_G) {
2246*4882a593Smuzhiyun /* G only */
2247*4882a593Smuzhiyun PRINTM(MINFO, "Band: Infra G\n");
2248*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, SupportedRates_G,
2249*4882a593Smuzhiyun sizeof(SupportedRates_G));
2250*4882a593Smuzhiyun
2251*4882a593Smuzhiyun } else if (bands & (BAND_B | BAND_G)) {
2252*4882a593Smuzhiyun /* BG only */
2253*4882a593Smuzhiyun PRINTM(MINFO, "Band: Infra BG\n");
2254*4882a593Smuzhiyun #ifdef WIFI_DIRECT_SUPPORT
2255*4882a593Smuzhiyun if (pmpriv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
2256*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, SupportedRates_G,
2257*4882a593Smuzhiyun sizeof(SupportedRates_G));
2258*4882a593Smuzhiyun else
2259*4882a593Smuzhiyun #endif
2260*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, SupportedRates_BG,
2261*4882a593Smuzhiyun sizeof(SupportedRates_BG));
2262*4882a593Smuzhiyun } else if (bands & BAND_A) {
2263*4882a593Smuzhiyun /* support A */
2264*4882a593Smuzhiyun PRINTM(MINFO, "Band: Infra A\n");
2265*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, SupportedRates_A,
2266*4882a593Smuzhiyun sizeof(SupportedRates_A));
2267*4882a593Smuzhiyun }
2268*4882a593Smuzhiyun } else {
2269*4882a593Smuzhiyun /* Adhoc. mode */
2270*4882a593Smuzhiyun if (bands == BAND_B) {
2271*4882a593Smuzhiyun /* B only */
2272*4882a593Smuzhiyun PRINTM(MINFO, "Band: Adhoc B\n");
2273*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, AdhocRates_B,
2274*4882a593Smuzhiyun sizeof(AdhocRates_B));
2275*4882a593Smuzhiyun } else if (bands == BAND_G) {
2276*4882a593Smuzhiyun /* G only */
2277*4882a593Smuzhiyun PRINTM(MINFO, "Band: Adhoc G\n");
2278*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, AdhocRates_G,
2279*4882a593Smuzhiyun sizeof(AdhocRates_G));
2280*4882a593Smuzhiyun
2281*4882a593Smuzhiyun } else if (bands & BAND_A) {
2282*4882a593Smuzhiyun /* support A */
2283*4882a593Smuzhiyun PRINTM(MINFO, "Band: Adhoc A\n");
2284*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, AdhocRates_A,
2285*4882a593Smuzhiyun sizeof(AdhocRates_A));
2286*4882a593Smuzhiyun
2287*4882a593Smuzhiyun } else {
2288*4882a593Smuzhiyun PRINTM(MINFO, "Band: Adhoc BG\n");
2289*4882a593Smuzhiyun k = wlan_copy_rates(rates, k, AdhocRates_BG,
2290*4882a593Smuzhiyun sizeof(AdhocRates_BG));
2291*4882a593Smuzhiyun }
2292*4882a593Smuzhiyun }
2293*4882a593Smuzhiyun
2294*4882a593Smuzhiyun LEAVE();
2295*4882a593Smuzhiyun return k;
2296*4882a593Smuzhiyun }
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun #define COUNTRY_ID_US 0
2299*4882a593Smuzhiyun #define COUNTRY_ID_JP 1
2300*4882a593Smuzhiyun #define COUNTRY_ID_CN 2
2301*4882a593Smuzhiyun #define COUNTRY_ID_EU 3
2302*4882a593Smuzhiyun typedef struct _oper_bw_chan {
2303*4882a593Smuzhiyun /*non-global operating class*/
2304*4882a593Smuzhiyun t_u8 oper_class;
2305*4882a593Smuzhiyun /*global operating class*/
2306*4882a593Smuzhiyun t_u8 global_oper_class;
2307*4882a593Smuzhiyun /*bandwidth 0-20M 1-40M 2-80M 3-160M*/
2308*4882a593Smuzhiyun t_u8 bandwidth;
2309*4882a593Smuzhiyun /*channel list*/
2310*4882a593Smuzhiyun t_u8 channel_list[13];
2311*4882a593Smuzhiyun } oper_bw_chan;
2312*4882a593Smuzhiyun
2313*4882a593Smuzhiyun /** oper class table for US*/
2314*4882a593Smuzhiyun static oper_bw_chan oper_bw_chan_us[] = {
2315*4882a593Smuzhiyun /** non-Global oper class, global oper class, bandwidth, channel list*/
2316*4882a593Smuzhiyun {1, 115, 0, {36, 40, 44, 48}},
2317*4882a593Smuzhiyun {2, 118, 0, {52, 56, 60, 64}},
2318*4882a593Smuzhiyun {3, 124, 0, {149, 153, 157, 161}},
2319*4882a593Smuzhiyun {4,
2320*4882a593Smuzhiyun 121,
2321*4882a593Smuzhiyun 0,
2322*4882a593Smuzhiyun {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144}},
2323*4882a593Smuzhiyun {5, 125, 0, {149, 153, 157, 161, 165}},
2324*4882a593Smuzhiyun {12, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}},
2325*4882a593Smuzhiyun {22, 116, 1, {36, 44}},
2326*4882a593Smuzhiyun {23, 119, 1, {52, 60}},
2327*4882a593Smuzhiyun {24, 122, 1, {100, 108, 116, 124, 132, 140}},
2328*4882a593Smuzhiyun {25, 126, 1, {149, 157}},
2329*4882a593Smuzhiyun {26, 126, 1, {149, 157}},
2330*4882a593Smuzhiyun {27, 117, 1, {40, 48}},
2331*4882a593Smuzhiyun {28, 120, 1, {56, 64}},
2332*4882a593Smuzhiyun {29, 123, 1, {104, 112, 120, 128, 136, 144}},
2333*4882a593Smuzhiyun {30, 127, 1, {153, 161}},
2334*4882a593Smuzhiyun {31, 127, 1, {153, 161}},
2335*4882a593Smuzhiyun {32, 83, 1, {1, 2, 3, 4, 5, 6, 7}},
2336*4882a593Smuzhiyun {33, 84, 1, {5, 6, 7, 8, 9, 10, 11}},
2337*4882a593Smuzhiyun {128, 128, 2, {42, 58, 106, 122, 138, 155}},
2338*4882a593Smuzhiyun {129, 129, 3, {50, 114}},
2339*4882a593Smuzhiyun {130, 130, 2, {42, 58, 106, 122, 138, 155}},
2340*4882a593Smuzhiyun };
2341*4882a593Smuzhiyun /** oper class table for EU*/
2342*4882a593Smuzhiyun static oper_bw_chan oper_bw_chan_eu[] = {
2343*4882a593Smuzhiyun /** non-global oper class,global oper class, bandwidth, channel list*/
2344*4882a593Smuzhiyun {1, 115, 0, {36, 40, 44, 48}},
2345*4882a593Smuzhiyun {2, 118, 0, {52, 56, 60, 64}},
2346*4882a593Smuzhiyun {3, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
2347*4882a593Smuzhiyun {4, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
2348*4882a593Smuzhiyun {5, 116, 1, {36, 44}},
2349*4882a593Smuzhiyun {6, 119, 1, {52, 60}},
2350*4882a593Smuzhiyun {7, 122, 1, {100, 108, 116, 124, 132}},
2351*4882a593Smuzhiyun {8, 117, 1, {40, 48}},
2352*4882a593Smuzhiyun {9, 120, 1, {56, 64}},
2353*4882a593Smuzhiyun {10, 123, 1, {104, 112, 120, 128, 136}},
2354*4882a593Smuzhiyun {11, 83, 1, {1, 2, 3, 4, 5, 6, 7, 8, 9}},
2355*4882a593Smuzhiyun {12, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
2356*4882a593Smuzhiyun {17, 125, 0, {149, 153, 157, 161, 165, 169}},
2357*4882a593Smuzhiyun {128, 128, 2, {42, 58, 106, 122, 138, 155}},
2358*4882a593Smuzhiyun {129, 129, 3, {50, 114}},
2359*4882a593Smuzhiyun {130, 130, 2, {42, 58, 106, 122, 138, 155}},
2360*4882a593Smuzhiyun };
2361*4882a593Smuzhiyun /** oper class table for Japan*/
2362*4882a593Smuzhiyun static oper_bw_chan oper_bw_chan_jp[] = {
2363*4882a593Smuzhiyun /** non-Global oper class,global oper class, bandwidth, channel list*/
2364*4882a593Smuzhiyun {1, 115, 0, {34, 38, 42, 46, 36, 40, 44, 48}},
2365*4882a593Smuzhiyun {30, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
2366*4882a593Smuzhiyun {31, 82, 0, {14}},
2367*4882a593Smuzhiyun {32, 118, 0, {52, 56, 60, 64}},
2368*4882a593Smuzhiyun {33, 118, 0, {52, 56, 60, 64}},
2369*4882a593Smuzhiyun {34, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
2370*4882a593Smuzhiyun {35, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
2371*4882a593Smuzhiyun {36, 116, 1, {36, 44}},
2372*4882a593Smuzhiyun {37, 119, 1, {52, 60}},
2373*4882a593Smuzhiyun {38, 119, 1, {52, 60}},
2374*4882a593Smuzhiyun {39, 122, 1, {100, 108, 116, 124, 132}},
2375*4882a593Smuzhiyun {40, 122, 1, {100, 108, 116, 124, 132}},
2376*4882a593Smuzhiyun {41, 117, 1, {40, 48}},
2377*4882a593Smuzhiyun {42, 120, 1, {56, 64}},
2378*4882a593Smuzhiyun {43, 120, 1, {56, 64}},
2379*4882a593Smuzhiyun {44, 123, 1, {104, 112, 120, 128, 136}},
2380*4882a593Smuzhiyun {45, 123, 1, {104, 112, 120, 128, 136}},
2381*4882a593Smuzhiyun {56, 83, 1, {1, 2, 3, 4, 5, 6, 7, 8, 9}},
2382*4882a593Smuzhiyun {57, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
2383*4882a593Smuzhiyun {58, 121, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
2384*4882a593Smuzhiyun {128, 128, 2, {42, 58, 106, 122, 138, 155}},
2385*4882a593Smuzhiyun {129, 129, 3, {50, 114}},
2386*4882a593Smuzhiyun {130, 130, 2, {42, 58, 106, 122, 138, 155}},
2387*4882a593Smuzhiyun };
2388*4882a593Smuzhiyun /** oper class table for China*/
2389*4882a593Smuzhiyun static oper_bw_chan oper_bw_chan_cn[] = {
2390*4882a593Smuzhiyun /** non-Global oper class,global oper class, bandwidth, channel list*/
2391*4882a593Smuzhiyun {1, 115, 0, {36, 40, 44, 48}},
2392*4882a593Smuzhiyun {2, 118, 0, {52, 56, 60, 64}},
2393*4882a593Smuzhiyun {3, 125, 0, {149, 153, 157, 161, 165}},
2394*4882a593Smuzhiyun {4, 116, 1, {36, 44}},
2395*4882a593Smuzhiyun {5, 119, 1, {52, 60}},
2396*4882a593Smuzhiyun {6, 126, 1, {149, 157}},
2397*4882a593Smuzhiyun {7, 81, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
2398*4882a593Smuzhiyun {8, 83, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9}},
2399*4882a593Smuzhiyun {9, 84, 1, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
2400*4882a593Smuzhiyun {128, 128, 2, {42, 58, 106, 122, 138, 155}},
2401*4882a593Smuzhiyun {129, 129, 3, {50, 114}},
2402*4882a593Smuzhiyun {130, 130, 2, {42, 58, 106, 122, 138, 155}},
2403*4882a593Smuzhiyun };
2404*4882a593Smuzhiyun
2405*4882a593Smuzhiyun /**
2406*4882a593Smuzhiyun * @brief Get non-global operaing class table according to country
2407*4882a593Smuzhiyun *
2408*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2409*4882a593Smuzhiyun * @param arraysize A pointer to table size
2410*4882a593Smuzhiyun *
2411*4882a593Smuzhiyun * @return A pointer to oper_bw_chan
2412*4882a593Smuzhiyun */
wlan_get_nonglobal_operclass_table(mlan_private * pmpriv,int * arraysize)2413*4882a593Smuzhiyun static oper_bw_chan *wlan_get_nonglobal_operclass_table(mlan_private *pmpriv,
2414*4882a593Smuzhiyun int *arraysize)
2415*4882a593Smuzhiyun {
2416*4882a593Smuzhiyun t_u8 country_code[][COUNTRY_CODE_LEN] = {"US", "JP", "CN"};
2417*4882a593Smuzhiyun int country_id = 0;
2418*4882a593Smuzhiyun oper_bw_chan *poper_bw_chan = MNULL;
2419*4882a593Smuzhiyun
2420*4882a593Smuzhiyun ENTER();
2421*4882a593Smuzhiyun
2422*4882a593Smuzhiyun for (country_id = 0; country_id < 3; country_id++)
2423*4882a593Smuzhiyun if (!memcmp(pmpriv->adapter, pmpriv->adapter->country_code,
2424*4882a593Smuzhiyun country_code[country_id], COUNTRY_CODE_LEN - 1))
2425*4882a593Smuzhiyun break;
2426*4882a593Smuzhiyun if (country_id >= 3)
2427*4882a593Smuzhiyun country_id = COUNTRY_ID_US; /*Set default to US*/
2428*4882a593Smuzhiyun if (wlan_is_etsi_country(pmpriv->adapter,
2429*4882a593Smuzhiyun pmpriv->adapter->country_code))
2430*4882a593Smuzhiyun country_id = COUNTRY_ID_EU; /** Country in EU */
2431*4882a593Smuzhiyun
2432*4882a593Smuzhiyun switch (country_id) {
2433*4882a593Smuzhiyun case COUNTRY_ID_US:
2434*4882a593Smuzhiyun poper_bw_chan = oper_bw_chan_us;
2435*4882a593Smuzhiyun *arraysize = sizeof(oper_bw_chan_us);
2436*4882a593Smuzhiyun break;
2437*4882a593Smuzhiyun case COUNTRY_ID_JP:
2438*4882a593Smuzhiyun poper_bw_chan = oper_bw_chan_jp;
2439*4882a593Smuzhiyun *arraysize = sizeof(oper_bw_chan_jp);
2440*4882a593Smuzhiyun break;
2441*4882a593Smuzhiyun case COUNTRY_ID_CN:
2442*4882a593Smuzhiyun poper_bw_chan = oper_bw_chan_cn;
2443*4882a593Smuzhiyun *arraysize = sizeof(oper_bw_chan_cn);
2444*4882a593Smuzhiyun break;
2445*4882a593Smuzhiyun case COUNTRY_ID_EU:
2446*4882a593Smuzhiyun poper_bw_chan = oper_bw_chan_eu;
2447*4882a593Smuzhiyun *arraysize = sizeof(oper_bw_chan_eu);
2448*4882a593Smuzhiyun break;
2449*4882a593Smuzhiyun default:
2450*4882a593Smuzhiyun PRINTM(MERROR, "Country not support!\n");
2451*4882a593Smuzhiyun break;
2452*4882a593Smuzhiyun }
2453*4882a593Smuzhiyun
2454*4882a593Smuzhiyun LEAVE();
2455*4882a593Smuzhiyun return poper_bw_chan;
2456*4882a593Smuzhiyun }
2457*4882a593Smuzhiyun
2458*4882a593Smuzhiyun /**
2459*4882a593Smuzhiyun * @brief Check validation of given channel and oper class
2460*4882a593Smuzhiyun *
2461*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2462*4882a593Smuzhiyun * @param channel Channel number
2463*4882a593Smuzhiyun * @param oper_class operating class
2464*4882a593Smuzhiyun *
2465*4882a593Smuzhiyun * @return MLAN_STATUS_PENDING --success, otherwise fail
2466*4882a593Smuzhiyun */
wlan_check_operclass_validation(mlan_private * pmpriv,t_u8 channel,t_u8 oper_class)2467*4882a593Smuzhiyun mlan_status wlan_check_operclass_validation(mlan_private *pmpriv, t_u8 channel,
2468*4882a593Smuzhiyun t_u8 oper_class)
2469*4882a593Smuzhiyun {
2470*4882a593Smuzhiyun int arraysize = 0, i = 0, channum = 0;
2471*4882a593Smuzhiyun oper_bw_chan *poper_bw_chan = MNULL;
2472*4882a593Smuzhiyun t_u8 center_freq_idx = 0;
2473*4882a593Smuzhiyun t_u8 center_freqs[] = {42, 50, 58, 106, 114, 122, 138, 155};
2474*4882a593Smuzhiyun
2475*4882a593Smuzhiyun ENTER();
2476*4882a593Smuzhiyun
2477*4882a593Smuzhiyun for (i = 0; i < (int)sizeof(center_freqs); i++) {
2478*4882a593Smuzhiyun if (channel == center_freqs[i]) {
2479*4882a593Smuzhiyun PRINTM(MERROR, "Invalid channel number %d!\n", channel);
2480*4882a593Smuzhiyun LEAVE();
2481*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2482*4882a593Smuzhiyun }
2483*4882a593Smuzhiyun }
2484*4882a593Smuzhiyun if (oper_class <= 0 || oper_class > 130) {
2485*4882a593Smuzhiyun PRINTM(MERROR, "Invalid operating class!\n");
2486*4882a593Smuzhiyun LEAVE();
2487*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2488*4882a593Smuzhiyun }
2489*4882a593Smuzhiyun if (oper_class >= 128) {
2490*4882a593Smuzhiyun center_freq_idx = wlan_get_center_freq_idx(
2491*4882a593Smuzhiyun pmpriv, BAND_AAC, channel, CHANNEL_BW_80MHZ);
2492*4882a593Smuzhiyun channel = center_freq_idx;
2493*4882a593Smuzhiyun }
2494*4882a593Smuzhiyun poper_bw_chan = wlan_get_nonglobal_operclass_table(pmpriv, &arraysize);
2495*4882a593Smuzhiyun
2496*4882a593Smuzhiyun if (!poper_bw_chan) {
2497*4882a593Smuzhiyun PRINTM(MCMND, "Operating class table do not find!\n");
2498*4882a593Smuzhiyun LEAVE();
2499*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2500*4882a593Smuzhiyun }
2501*4882a593Smuzhiyun
2502*4882a593Smuzhiyun for (i = 0; i < (int)(arraysize / sizeof(oper_bw_chan)); i++) {
2503*4882a593Smuzhiyun if (poper_bw_chan[i].oper_class == oper_class ||
2504*4882a593Smuzhiyun poper_bw_chan[i].global_oper_class == oper_class) {
2505*4882a593Smuzhiyun for (channum = 0;
2506*4882a593Smuzhiyun channum <
2507*4882a593Smuzhiyun (int)sizeof(poper_bw_chan[i].channel_list);
2508*4882a593Smuzhiyun channum++) {
2509*4882a593Smuzhiyun if (poper_bw_chan[i].channel_list[channum] &&
2510*4882a593Smuzhiyun poper_bw_chan[i].channel_list[channum] ==
2511*4882a593Smuzhiyun channel) {
2512*4882a593Smuzhiyun LEAVE();
2513*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
2514*4882a593Smuzhiyun }
2515*4882a593Smuzhiyun }
2516*4882a593Smuzhiyun }
2517*4882a593Smuzhiyun }
2518*4882a593Smuzhiyun
2519*4882a593Smuzhiyun PRINTM(MCMND, "Operating class %d do not match channel %d!\n",
2520*4882a593Smuzhiyun oper_class, channel);
2521*4882a593Smuzhiyun LEAVE();
2522*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2523*4882a593Smuzhiyun }
2524*4882a593Smuzhiyun
2525*4882a593Smuzhiyun /**
2526*4882a593Smuzhiyun * @brief Get current operating class from channel and bandwidth
2527*4882a593Smuzhiyun *
2528*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2529*4882a593Smuzhiyun * @param channel Channel number
2530*4882a593Smuzhiyun * @param bw Bandwidth
2531*4882a593Smuzhiyun * @param oper_class A pointer to current operating class
2532*4882a593Smuzhiyun *
2533*4882a593Smuzhiyun * @return MLAN_STATUS_PENDING --success, otherwise fail
2534*4882a593Smuzhiyun */
wlan_get_curr_oper_class(mlan_private * pmpriv,t_u8 channel,t_u8 bw,t_u8 * oper_class)2535*4882a593Smuzhiyun mlan_status wlan_get_curr_oper_class(mlan_private *pmpriv, t_u8 channel,
2536*4882a593Smuzhiyun t_u8 bw, t_u8 *oper_class)
2537*4882a593Smuzhiyun {
2538*4882a593Smuzhiyun oper_bw_chan *poper_bw_chan = MNULL;
2539*4882a593Smuzhiyun t_u8 center_freq_idx = 0;
2540*4882a593Smuzhiyun t_u8 center_freqs[] = {42, 50, 58, 106, 114, 122, 138, 155};
2541*4882a593Smuzhiyun int i = 0, arraysize = 0, channum = 0;
2542*4882a593Smuzhiyun
2543*4882a593Smuzhiyun ENTER();
2544*4882a593Smuzhiyun
2545*4882a593Smuzhiyun poper_bw_chan = wlan_get_nonglobal_operclass_table(pmpriv, &arraysize);
2546*4882a593Smuzhiyun
2547*4882a593Smuzhiyun if (!poper_bw_chan) {
2548*4882a593Smuzhiyun PRINTM(MCMND, "Operating class table do not find!\n");
2549*4882a593Smuzhiyun LEAVE();
2550*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2551*4882a593Smuzhiyun }
2552*4882a593Smuzhiyun for (i = 0; i < (int)sizeof(center_freqs); i++) {
2553*4882a593Smuzhiyun if (channel == center_freqs[i]) {
2554*4882a593Smuzhiyun PRINTM(MERROR, "Invalid channel number %d!\n", channel);
2555*4882a593Smuzhiyun LEAVE();
2556*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2557*4882a593Smuzhiyun }
2558*4882a593Smuzhiyun }
2559*4882a593Smuzhiyun if (bw == BW_80MHZ) {
2560*4882a593Smuzhiyun center_freq_idx = wlan_get_center_freq_idx(
2561*4882a593Smuzhiyun pmpriv, BAND_AAC, channel, CHANNEL_BW_80MHZ);
2562*4882a593Smuzhiyun channel = center_freq_idx;
2563*4882a593Smuzhiyun }
2564*4882a593Smuzhiyun
2565*4882a593Smuzhiyun for (i = 0; i < (int)(arraysize / sizeof(oper_bw_chan)); i++) {
2566*4882a593Smuzhiyun if (poper_bw_chan[i].bandwidth == bw) {
2567*4882a593Smuzhiyun for (channum = 0;
2568*4882a593Smuzhiyun channum <
2569*4882a593Smuzhiyun (int)(sizeof(poper_bw_chan[i].channel_list));
2570*4882a593Smuzhiyun channum++) {
2571*4882a593Smuzhiyun if (poper_bw_chan[i].channel_list[channum] &&
2572*4882a593Smuzhiyun poper_bw_chan[i].channel_list[channum] ==
2573*4882a593Smuzhiyun channel) {
2574*4882a593Smuzhiyun *oper_class =
2575*4882a593Smuzhiyun poper_bw_chan[i].oper_class;
2576*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
2577*4882a593Smuzhiyun }
2578*4882a593Smuzhiyun }
2579*4882a593Smuzhiyun }
2580*4882a593Smuzhiyun }
2581*4882a593Smuzhiyun
2582*4882a593Smuzhiyun PRINTM(MCMND, "Operating class not found!\n");
2583*4882a593Smuzhiyun LEAVE();
2584*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2585*4882a593Smuzhiyun }
2586*4882a593Smuzhiyun
2587*4882a593Smuzhiyun /**
2588*4882a593Smuzhiyun * @brief Add Supported operating classes IE
2589*4882a593Smuzhiyun *
2590*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2591*4882a593Smuzhiyun * @param pptlv_out A pointer to TLV to fill in
2592*4882a593Smuzhiyun * @param curr_oper_class Current operating class
2593*4882a593Smuzhiyun *
2594*4882a593Smuzhiyun * @return Length
2595*4882a593Smuzhiyun */
wlan_add_supported_oper_class_ie(mlan_private * pmpriv,t_u8 ** pptlv_out,t_u8 curr_oper_class)2596*4882a593Smuzhiyun int wlan_add_supported_oper_class_ie(mlan_private *pmpriv, t_u8 **pptlv_out,
2597*4882a593Smuzhiyun t_u8 curr_oper_class)
2598*4882a593Smuzhiyun {
2599*4882a593Smuzhiyun t_u8 oper_class_us[] = {1, 2, 3, 4, 5, 12, 22, 23, 24, 25, 26,
2600*4882a593Smuzhiyun 27, 28, 29, 30, 31, 32, 33, 128, 129, 130};
2601*4882a593Smuzhiyun t_u8 oper_class_eu[] = {1, 2, 3, 4, 5, 6, 7, 8,
2602*4882a593Smuzhiyun 9, 10, 11, 12, 17, 128, 129, 130};
2603*4882a593Smuzhiyun t_u8 oper_class_jp[] = {1, 30, 31, 32, 33, 34, 35, 36,
2604*4882a593Smuzhiyun 37, 38, 39, 40, 41, 42, 43, 44,
2605*4882a593Smuzhiyun 45, 56, 57, 58, 128, 129, 130};
2606*4882a593Smuzhiyun t_u8 oper_class_cn[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 129, 130};
2607*4882a593Smuzhiyun t_u8 country_code[][COUNTRY_CODE_LEN] = {"US", "JP", "CN"};
2608*4882a593Smuzhiyun int country_id = 0, ret = 0;
2609*4882a593Smuzhiyun MrvlIETypes_SuppOperClass_t *poper_class = MNULL;
2610*4882a593Smuzhiyun
2611*4882a593Smuzhiyun ENTER();
2612*4882a593Smuzhiyun
2613*4882a593Smuzhiyun for (country_id = 0; country_id < 3; country_id++)
2614*4882a593Smuzhiyun if (!memcmp(pmpriv->adapter, pmpriv->adapter->country_code,
2615*4882a593Smuzhiyun country_code[country_id], COUNTRY_CODE_LEN - 1))
2616*4882a593Smuzhiyun break;
2617*4882a593Smuzhiyun if (country_id >= 3)
2618*4882a593Smuzhiyun country_id = COUNTRY_ID_US; /*Set default to US*/
2619*4882a593Smuzhiyun if (wlan_is_etsi_country(pmpriv->adapter,
2620*4882a593Smuzhiyun pmpriv->adapter->country_code))
2621*4882a593Smuzhiyun country_id = COUNTRY_ID_EU; /** Country in EU */
2622*4882a593Smuzhiyun poper_class = (MrvlIETypes_SuppOperClass_t *)*pptlv_out;
2623*4882a593Smuzhiyun memset(pmpriv->adapter, poper_class, 0,
2624*4882a593Smuzhiyun sizeof(MrvlIETypes_SuppOperClass_t));
2625*4882a593Smuzhiyun poper_class->header.type = wlan_cpu_to_le16(REGULATORY_CLASS);
2626*4882a593Smuzhiyun if (country_id == COUNTRY_ID_US) {
2627*4882a593Smuzhiyun poper_class->header.len = sizeof(oper_class_us);
2628*4882a593Smuzhiyun memcpy_ext(pmpriv->adapter, &poper_class->oper_class,
2629*4882a593Smuzhiyun oper_class_us, sizeof(oper_class_us),
2630*4882a593Smuzhiyun poper_class->header.len);
2631*4882a593Smuzhiyun } else if (country_id == COUNTRY_ID_JP) {
2632*4882a593Smuzhiyun poper_class->header.len = sizeof(oper_class_jp);
2633*4882a593Smuzhiyun memcpy_ext(pmpriv->adapter, &poper_class->oper_class,
2634*4882a593Smuzhiyun oper_class_jp, sizeof(oper_class_jp),
2635*4882a593Smuzhiyun poper_class->header.len);
2636*4882a593Smuzhiyun } else if (country_id == COUNTRY_ID_CN) {
2637*4882a593Smuzhiyun poper_class->header.len = sizeof(oper_class_cn);
2638*4882a593Smuzhiyun memcpy_ext(pmpriv->adapter, &poper_class->oper_class,
2639*4882a593Smuzhiyun oper_class_cn, sizeof(oper_class_cn),
2640*4882a593Smuzhiyun poper_class->header.len);
2641*4882a593Smuzhiyun } else if (country_id == COUNTRY_ID_EU) {
2642*4882a593Smuzhiyun poper_class->header.len = sizeof(oper_class_eu);
2643*4882a593Smuzhiyun memcpy_ext(pmpriv->adapter, &poper_class->oper_class,
2644*4882a593Smuzhiyun oper_class_eu, sizeof(oper_class_eu),
2645*4882a593Smuzhiyun poper_class->header.len);
2646*4882a593Smuzhiyun }
2647*4882a593Smuzhiyun poper_class->current_oper_class = curr_oper_class;
2648*4882a593Smuzhiyun poper_class->header.len += sizeof(poper_class->current_oper_class);
2649*4882a593Smuzhiyun DBG_HEXDUMP(MCMD_D, "Operating class", (t_u8 *)poper_class,
2650*4882a593Smuzhiyun sizeof(MrvlIEtypesHeader_t) + poper_class->header.len);
2651*4882a593Smuzhiyun ret = sizeof(MrvlIEtypesHeader_t) + poper_class->header.len;
2652*4882a593Smuzhiyun *pptlv_out += ret;
2653*4882a593Smuzhiyun poper_class->header.len = wlan_cpu_to_le16(poper_class->header.len);
2654*4882a593Smuzhiyun
2655*4882a593Smuzhiyun LEAVE();
2656*4882a593Smuzhiyun return ret;
2657*4882a593Smuzhiyun }
2658*4882a593Smuzhiyun
2659*4882a593Smuzhiyun /**
2660*4882a593Smuzhiyun * @brief This function sets region table.
2661*4882a593Smuzhiyun *
2662*4882a593Smuzhiyun * @param pmpriv A pointer to mlan_private structure
2663*4882a593Smuzhiyun * @param region The region code
2664*4882a593Smuzhiyun * @param band The band
2665*4882a593Smuzhiyun *
2666*4882a593Smuzhiyun * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2667*4882a593Smuzhiyun */
wlan_set_regiontable(mlan_private * pmpriv,t_u8 region,t_u16 band)2668*4882a593Smuzhiyun mlan_status wlan_set_regiontable(mlan_private *pmpriv, t_u8 region, t_u16 band)
2669*4882a593Smuzhiyun {
2670*4882a593Smuzhiyun mlan_adapter *pmadapter = pmpriv->adapter;
2671*4882a593Smuzhiyun int i = 0, j;
2672*4882a593Smuzhiyun chan_freq_power_t *cfp;
2673*4882a593Smuzhiyun int cfp_no;
2674*4882a593Smuzhiyun region_chan_t region_chan_old[MAX_REGION_CHANNEL_NUM];
2675*4882a593Smuzhiyun t_u8 cfp_code_bg = region;
2676*4882a593Smuzhiyun t_u8 cfp_code_a = region;
2677*4882a593Smuzhiyun
2678*4882a593Smuzhiyun ENTER();
2679*4882a593Smuzhiyun
2680*4882a593Smuzhiyun memcpy_ext(pmadapter, region_chan_old, pmadapter->region_channel,
2681*4882a593Smuzhiyun sizeof(pmadapter->region_channel), sizeof(region_chan_old));
2682*4882a593Smuzhiyun memset(pmadapter, pmadapter->region_channel, 0,
2683*4882a593Smuzhiyun sizeof(pmadapter->region_channel));
2684*4882a593Smuzhiyun
2685*4882a593Smuzhiyun if (band & (BAND_B | BAND_G | BAND_GN)) {
2686*4882a593Smuzhiyun if (pmadapter->cfp_code_bg)
2687*4882a593Smuzhiyun cfp_code_bg = pmadapter->cfp_code_bg;
2688*4882a593Smuzhiyun PRINTM(MCMND, "%s: 2.4G 0x%x\n", __func__, cfp_code_bg);
2689*4882a593Smuzhiyun cfp = wlan_get_region_cfp_table(pmadapter, cfp_code_bg,
2690*4882a593Smuzhiyun BAND_G | BAND_B | BAND_GN,
2691*4882a593Smuzhiyun &cfp_no);
2692*4882a593Smuzhiyun if (cfp) {
2693*4882a593Smuzhiyun pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no;
2694*4882a593Smuzhiyun pmadapter->region_channel[i].pcfp = cfp;
2695*4882a593Smuzhiyun } else {
2696*4882a593Smuzhiyun PRINTM(MERROR, "wrong region code %#x in Band B-G\n",
2697*4882a593Smuzhiyun region);
2698*4882a593Smuzhiyun LEAVE();
2699*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2700*4882a593Smuzhiyun }
2701*4882a593Smuzhiyun pmadapter->region_channel[i].valid = MTRUE;
2702*4882a593Smuzhiyun pmadapter->region_channel[i].region = region;
2703*4882a593Smuzhiyun if (band & BAND_GN)
2704*4882a593Smuzhiyun pmadapter->region_channel[i].band = BAND_G;
2705*4882a593Smuzhiyun else
2706*4882a593Smuzhiyun pmadapter->region_channel[i].band =
2707*4882a593Smuzhiyun (band & BAND_G) ? BAND_G : BAND_B;
2708*4882a593Smuzhiyun
2709*4882a593Smuzhiyun for (j = 0; j < MAX_REGION_CHANNEL_NUM; j++) {
2710*4882a593Smuzhiyun if (region_chan_old[j].band & (BAND_B | BAND_G))
2711*4882a593Smuzhiyun break;
2712*4882a593Smuzhiyun }
2713*4882a593Smuzhiyun
2714*4882a593Smuzhiyun if ((j < MAX_REGION_CHANNEL_NUM) &&
2715*4882a593Smuzhiyun (region_chan_old[j].valid == MTRUE)) {
2716*4882a593Smuzhiyun wlan_cfp_copy_dynamic(pmadapter, cfp, cfp_no,
2717*4882a593Smuzhiyun region_chan_old[j].pcfp,
2718*4882a593Smuzhiyun region_chan_old[j].num_cfp);
2719*4882a593Smuzhiyun } else if (cfp) {
2720*4882a593Smuzhiyun wlan_cfp_copy_dynamic(pmadapter, cfp, cfp_no, MNULL, 0);
2721*4882a593Smuzhiyun }
2722*4882a593Smuzhiyun i++;
2723*4882a593Smuzhiyun }
2724*4882a593Smuzhiyun if (band & (BAND_A | BAND_AN | BAND_AAC)) {
2725*4882a593Smuzhiyun if (pmadapter->cfp_code_a)
2726*4882a593Smuzhiyun cfp_code_a = pmadapter->cfp_code_a;
2727*4882a593Smuzhiyun PRINTM(MCMND, "%s: 5G 0x%x\n", __func__, cfp_code_a);
2728*4882a593Smuzhiyun cfp = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A,
2729*4882a593Smuzhiyun &cfp_no);
2730*4882a593Smuzhiyun if (cfp) {
2731*4882a593Smuzhiyun pmadapter->region_channel[i].num_cfp = (t_u8)cfp_no;
2732*4882a593Smuzhiyun pmadapter->region_channel[i].pcfp = cfp;
2733*4882a593Smuzhiyun } else {
2734*4882a593Smuzhiyun PRINTM(MERROR, "wrong region code %#x in Band A\n",
2735*4882a593Smuzhiyun region);
2736*4882a593Smuzhiyun LEAVE();
2737*4882a593Smuzhiyun return MLAN_STATUS_FAILURE;
2738*4882a593Smuzhiyun }
2739*4882a593Smuzhiyun pmadapter->region_channel[i].valid = MTRUE;
2740*4882a593Smuzhiyun pmadapter->region_channel[i].region = region;
2741*4882a593Smuzhiyun pmadapter->region_channel[i].band = BAND_A;
2742*4882a593Smuzhiyun
2743*4882a593Smuzhiyun for (j = 0; j < MAX_REGION_CHANNEL_NUM; j++) {
2744*4882a593Smuzhiyun if (region_chan_old[j].band & BAND_A)
2745*4882a593Smuzhiyun break;
2746*4882a593Smuzhiyun }
2747*4882a593Smuzhiyun if ((j < MAX_REGION_CHANNEL_NUM) && region_chan_old[j].valid) {
2748*4882a593Smuzhiyun wlan_cfp_copy_dynamic(pmadapter, cfp, cfp_no,
2749*4882a593Smuzhiyun region_chan_old[j].pcfp,
2750*4882a593Smuzhiyun region_chan_old[j].num_cfp);
2751*4882a593Smuzhiyun } else if (cfp) {
2752*4882a593Smuzhiyun wlan_cfp_copy_dynamic(pmadapter, cfp, cfp_no, MNULL, 0);
2753*4882a593Smuzhiyun }
2754*4882a593Smuzhiyun i++;
2755*4882a593Smuzhiyun }
2756*4882a593Smuzhiyun LEAVE();
2757*4882a593Smuzhiyun return MLAN_STATUS_SUCCESS;
2758*4882a593Smuzhiyun }
2759*4882a593Smuzhiyun
2760*4882a593Smuzhiyun /**
2761*4882a593Smuzhiyun * @brief Get if radar detection is enabled or not on a certain channel
2762*4882a593Smuzhiyun *
2763*4882a593Smuzhiyun * @param priv Private driver information structure
2764*4882a593Smuzhiyun * @param chnl Channel to determine radar detection requirements
2765*4882a593Smuzhiyun *
2766*4882a593Smuzhiyun * @return
2767*4882a593Smuzhiyun * - MTRUE if radar detection is required
2768*4882a593Smuzhiyun * - MFALSE otherwise
2769*4882a593Smuzhiyun */
wlan_get_cfp_radar_detect(mlan_private * priv,t_u8 chnl)2770*4882a593Smuzhiyun t_bool wlan_get_cfp_radar_detect(mlan_private *priv, t_u8 chnl)
2771*4882a593Smuzhiyun {
2772*4882a593Smuzhiyun int i, j;
2773*4882a593Smuzhiyun t_bool required = MFALSE;
2774*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
2775*4882a593Smuzhiyun
2776*4882a593Smuzhiyun ENTER();
2777*4882a593Smuzhiyun
2778*4882a593Smuzhiyun /*get the cfp table first*/
2779*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
2780*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band == BAND_A) {
2781*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
2782*4882a593Smuzhiyun break;
2783*4882a593Smuzhiyun }
2784*4882a593Smuzhiyun }
2785*4882a593Smuzhiyun
2786*4882a593Smuzhiyun if (!pcfp) {
2787*4882a593Smuzhiyun /* This means operation in BAND-A is not support, we can
2788*4882a593Smuzhiyun * just return false here, it's harmless
2789*4882a593Smuzhiyun */
2790*4882a593Smuzhiyun goto done;
2791*4882a593Smuzhiyun }
2792*4882a593Smuzhiyun
2793*4882a593Smuzhiyun /*get the radar detection requirements according to chan num*/
2794*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
2795*4882a593Smuzhiyun if (pcfp[j].channel == chnl) {
2796*4882a593Smuzhiyun required = pcfp[j].passive_scan_or_radar_detect;
2797*4882a593Smuzhiyun break;
2798*4882a593Smuzhiyun }
2799*4882a593Smuzhiyun }
2800*4882a593Smuzhiyun
2801*4882a593Smuzhiyun done:
2802*4882a593Smuzhiyun LEAVE();
2803*4882a593Smuzhiyun return required;
2804*4882a593Smuzhiyun }
2805*4882a593Smuzhiyun
2806*4882a593Smuzhiyun /**
2807*4882a593Smuzhiyun * @brief Get if scan type is passive or not on a certain channel for b/g band
2808*4882a593Smuzhiyun *
2809*4882a593Smuzhiyun * @param priv Private driver information structure
2810*4882a593Smuzhiyun * @param chnl Channel to determine scan type
2811*4882a593Smuzhiyun *
2812*4882a593Smuzhiyun * @return
2813*4882a593Smuzhiyun * - MTRUE if scan type is passive
2814*4882a593Smuzhiyun * - MFALSE otherwise
2815*4882a593Smuzhiyun */
wlan_bg_scan_type_is_passive(mlan_private * priv,t_u8 chnl)2816*4882a593Smuzhiyun t_bool wlan_bg_scan_type_is_passive(mlan_private *priv, t_u8 chnl)
2817*4882a593Smuzhiyun {
2818*4882a593Smuzhiyun int i, j;
2819*4882a593Smuzhiyun t_bool passive = MFALSE;
2820*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
2821*4882a593Smuzhiyun
2822*4882a593Smuzhiyun ENTER();
2823*4882a593Smuzhiyun
2824*4882a593Smuzhiyun /*get the cfp table first*/
2825*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
2826*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & (BAND_B | BAND_G)) {
2827*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
2828*4882a593Smuzhiyun break;
2829*4882a593Smuzhiyun }
2830*4882a593Smuzhiyun }
2831*4882a593Smuzhiyun
2832*4882a593Smuzhiyun if (!pcfp) {
2833*4882a593Smuzhiyun /*This means operation in BAND-B or BAND_G is not support, we
2834*4882a593Smuzhiyun * can just return false here
2835*4882a593Smuzhiyun */
2836*4882a593Smuzhiyun goto done;
2837*4882a593Smuzhiyun }
2838*4882a593Smuzhiyun
2839*4882a593Smuzhiyun /*get the bg scan type according to chan num*/
2840*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
2841*4882a593Smuzhiyun if (pcfp[j].channel == chnl) {
2842*4882a593Smuzhiyun passive = pcfp[j].passive_scan_or_radar_detect;
2843*4882a593Smuzhiyun break;
2844*4882a593Smuzhiyun }
2845*4882a593Smuzhiyun }
2846*4882a593Smuzhiyun
2847*4882a593Smuzhiyun done:
2848*4882a593Smuzhiyun LEAVE();
2849*4882a593Smuzhiyun return passive;
2850*4882a593Smuzhiyun }
2851*4882a593Smuzhiyun
2852*4882a593Smuzhiyun /**
2853*4882a593Smuzhiyun * @brief Get if a channel is NO_IR (passive) or not
2854*4882a593Smuzhiyun *
2855*4882a593Smuzhiyun * @param priv Private driver information structure
2856*4882a593Smuzhiyun * @param band Band to check
2857*4882a593Smuzhiyun * @param chan Channel to check
2858*4882a593Smuzhiyun *
2859*4882a593Smuzhiyun * @return
2860*4882a593Smuzhiyun * - MTRUE if channel is passive
2861*4882a593Smuzhiyun * - MFALSE otherwise
2862*4882a593Smuzhiyun */
2863*4882a593Smuzhiyun
wlan_is_chan_passive(mlan_private * priv,t_u16 band,t_u8 chan)2864*4882a593Smuzhiyun t_bool wlan_is_chan_passive(mlan_private *priv, t_u16 band, t_u8 chan)
2865*4882a593Smuzhiyun {
2866*4882a593Smuzhiyun int i, j;
2867*4882a593Smuzhiyun t_bool passive = MFALSE;
2868*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
2869*4882a593Smuzhiyun
2870*4882a593Smuzhiyun ENTER();
2871*4882a593Smuzhiyun
2872*4882a593Smuzhiyun /* get the cfp table first */
2873*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
2874*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
2875*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
2876*4882a593Smuzhiyun break;
2877*4882a593Smuzhiyun }
2878*4882a593Smuzhiyun }
2879*4882a593Smuzhiyun
2880*4882a593Smuzhiyun if (pcfp) {
2881*4882a593Smuzhiyun /* check table according to chan num */
2882*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
2883*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
2884*4882a593Smuzhiyun if (pcfp[j].dynamic.flags & NXP_CHANNEL_PASSIVE)
2885*4882a593Smuzhiyun passive = MTRUE;
2886*4882a593Smuzhiyun break;
2887*4882a593Smuzhiyun }
2888*4882a593Smuzhiyun }
2889*4882a593Smuzhiyun }
2890*4882a593Smuzhiyun
2891*4882a593Smuzhiyun LEAVE();
2892*4882a593Smuzhiyun return passive;
2893*4882a593Smuzhiyun }
2894*4882a593Smuzhiyun
2895*4882a593Smuzhiyun /**
2896*4882a593Smuzhiyun * @brief Get if a channel is disabled or not
2897*4882a593Smuzhiyun *
2898*4882a593Smuzhiyun * @param priv Private driver information structure
2899*4882a593Smuzhiyun * @param band Band to check
2900*4882a593Smuzhiyun * @param chan Channel to check
2901*4882a593Smuzhiyun *
2902*4882a593Smuzhiyun * @return
2903*4882a593Smuzhiyun * - MTRUE if channel is disabled
2904*4882a593Smuzhiyun * - MFALSE otherwise
2905*4882a593Smuzhiyun */
2906*4882a593Smuzhiyun
wlan_is_chan_disabled(mlan_private * priv,t_u16 band,t_u8 chan)2907*4882a593Smuzhiyun t_bool wlan_is_chan_disabled(mlan_private *priv, t_u16 band, t_u8 chan)
2908*4882a593Smuzhiyun {
2909*4882a593Smuzhiyun int i, j;
2910*4882a593Smuzhiyun t_bool disabled = MFALSE;
2911*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
2912*4882a593Smuzhiyun
2913*4882a593Smuzhiyun ENTER();
2914*4882a593Smuzhiyun
2915*4882a593Smuzhiyun /* get the cfp table first */
2916*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
2917*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
2918*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
2919*4882a593Smuzhiyun break;
2920*4882a593Smuzhiyun }
2921*4882a593Smuzhiyun }
2922*4882a593Smuzhiyun
2923*4882a593Smuzhiyun if (pcfp) {
2924*4882a593Smuzhiyun /* check table according to chan num */
2925*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
2926*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
2927*4882a593Smuzhiyun if (pcfp[j].dynamic.flags &
2928*4882a593Smuzhiyun NXP_CHANNEL_DISABLED)
2929*4882a593Smuzhiyun disabled = MTRUE;
2930*4882a593Smuzhiyun break;
2931*4882a593Smuzhiyun }
2932*4882a593Smuzhiyun }
2933*4882a593Smuzhiyun }
2934*4882a593Smuzhiyun
2935*4882a593Smuzhiyun LEAVE();
2936*4882a593Smuzhiyun return disabled;
2937*4882a593Smuzhiyun }
2938*4882a593Smuzhiyun
2939*4882a593Smuzhiyun /**
2940*4882a593Smuzhiyun * @brief Get if a channel is blacklisted or not
2941*4882a593Smuzhiyun *
2942*4882a593Smuzhiyun * @param priv Private driver information structure
2943*4882a593Smuzhiyun * @param band Band to check
2944*4882a593Smuzhiyun * @param chan Channel to check
2945*4882a593Smuzhiyun *
2946*4882a593Smuzhiyun * @return
2947*4882a593Smuzhiyun * - MTRUE if channel is blacklisted
2948*4882a593Smuzhiyun * - MFALSE otherwise
2949*4882a593Smuzhiyun */
2950*4882a593Smuzhiyun
wlan_is_chan_blacklisted(mlan_private * priv,t_u16 band,t_u8 chan)2951*4882a593Smuzhiyun t_bool wlan_is_chan_blacklisted(mlan_private *priv, t_u16 band, t_u8 chan)
2952*4882a593Smuzhiyun {
2953*4882a593Smuzhiyun int i, j;
2954*4882a593Smuzhiyun t_bool blacklist = MFALSE;
2955*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
2956*4882a593Smuzhiyun
2957*4882a593Smuzhiyun ENTER();
2958*4882a593Smuzhiyun
2959*4882a593Smuzhiyun /*get the cfp table first*/
2960*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
2961*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
2962*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
2963*4882a593Smuzhiyun break;
2964*4882a593Smuzhiyun }
2965*4882a593Smuzhiyun }
2966*4882a593Smuzhiyun
2967*4882a593Smuzhiyun if (pcfp) {
2968*4882a593Smuzhiyun /*check table according to chan num*/
2969*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
2970*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
2971*4882a593Smuzhiyun blacklist = pcfp[j].dynamic.blacklist;
2972*4882a593Smuzhiyun break;
2973*4882a593Smuzhiyun }
2974*4882a593Smuzhiyun }
2975*4882a593Smuzhiyun }
2976*4882a593Smuzhiyun
2977*4882a593Smuzhiyun LEAVE();
2978*4882a593Smuzhiyun return blacklist;
2979*4882a593Smuzhiyun }
2980*4882a593Smuzhiyun
2981*4882a593Smuzhiyun /**
2982*4882a593Smuzhiyun * @brief Set a channel as blacklisted or not
2983*4882a593Smuzhiyun *
2984*4882a593Smuzhiyun * @param priv Private driver information structure
2985*4882a593Smuzhiyun * @param band Band to check
2986*4882a593Smuzhiyun * @param chan Channel to check
2987*4882a593Smuzhiyun * @param bl Blacklist if MTRUE
2988*4882a593Smuzhiyun *
2989*4882a593Smuzhiyun * @return
2990*4882a593Smuzhiyun * - MTRUE if channel setting is updated
2991*4882a593Smuzhiyun * - MFALSE otherwise
2992*4882a593Smuzhiyun */
2993*4882a593Smuzhiyun
wlan_set_chan_blacklist(mlan_private * priv,t_u16 band,t_u8 chan,t_bool bl)2994*4882a593Smuzhiyun t_bool wlan_set_chan_blacklist(mlan_private *priv, t_u16 band, t_u8 chan,
2995*4882a593Smuzhiyun t_bool bl)
2996*4882a593Smuzhiyun {
2997*4882a593Smuzhiyun int i, j;
2998*4882a593Smuzhiyun t_bool set_bl = MFALSE;
2999*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
3000*4882a593Smuzhiyun
3001*4882a593Smuzhiyun ENTER();
3002*4882a593Smuzhiyun
3003*4882a593Smuzhiyun /*get the cfp table first*/
3004*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
3005*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
3006*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
3007*4882a593Smuzhiyun break;
3008*4882a593Smuzhiyun }
3009*4882a593Smuzhiyun }
3010*4882a593Smuzhiyun
3011*4882a593Smuzhiyun if (pcfp) {
3012*4882a593Smuzhiyun /*check table according to chan num*/
3013*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
3014*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
3015*4882a593Smuzhiyun pcfp[j].dynamic.blacklist = bl;
3016*4882a593Smuzhiyun set_bl = MTRUE;
3017*4882a593Smuzhiyun break;
3018*4882a593Smuzhiyun }
3019*4882a593Smuzhiyun }
3020*4882a593Smuzhiyun }
3021*4882a593Smuzhiyun
3022*4882a593Smuzhiyun LEAVE();
3023*4882a593Smuzhiyun return set_bl;
3024*4882a593Smuzhiyun }
3025*4882a593Smuzhiyun
3026*4882a593Smuzhiyun /**
3027*4882a593Smuzhiyun * @brief Set channel's dfs state
3028*4882a593Smuzhiyun *
3029*4882a593Smuzhiyun * @param priv Private driver information structure
3030*4882a593Smuzhiyun * @param band Band to check
3031*4882a593Smuzhiyun * @param chan Channel to check
3032*4882a593Smuzhiyun * @param dfs_state dfs state
3033*4882a593Smuzhiyun *
3034*4882a593Smuzhiyun * @return N/A
3035*4882a593Smuzhiyun */
wlan_set_chan_dfs_state(mlan_private * priv,t_u16 band,t_u8 chan,dfs_state_t dfs_state)3036*4882a593Smuzhiyun t_void wlan_set_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan,
3037*4882a593Smuzhiyun dfs_state_t dfs_state)
3038*4882a593Smuzhiyun {
3039*4882a593Smuzhiyun int i, j;
3040*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
3041*4882a593Smuzhiyun
3042*4882a593Smuzhiyun ENTER();
3043*4882a593Smuzhiyun
3044*4882a593Smuzhiyun /*get the cfp table first*/
3045*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
3046*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
3047*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
3048*4882a593Smuzhiyun break;
3049*4882a593Smuzhiyun }
3050*4882a593Smuzhiyun }
3051*4882a593Smuzhiyun
3052*4882a593Smuzhiyun if (pcfp) {
3053*4882a593Smuzhiyun /*check table according to chan num*/
3054*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
3055*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
3056*4882a593Smuzhiyun pcfp[j].dynamic.dfs_state = dfs_state;
3057*4882a593Smuzhiyun break;
3058*4882a593Smuzhiyun }
3059*4882a593Smuzhiyun }
3060*4882a593Smuzhiyun }
3061*4882a593Smuzhiyun
3062*4882a593Smuzhiyun LEAVE();
3063*4882a593Smuzhiyun }
3064*4882a593Smuzhiyun
3065*4882a593Smuzhiyun /**
3066*4882a593Smuzhiyun * @brief get channel's dfs state
3067*4882a593Smuzhiyun *
3068*4882a593Smuzhiyun * @param priv Private driver information structure
3069*4882a593Smuzhiyun * @param band Band to check
3070*4882a593Smuzhiyun * @param chan Channel to check
3071*4882a593Smuzhiyun *
3072*4882a593Smuzhiyun * @return channel's dfs state
3073*4882a593Smuzhiyun */
wlan_get_chan_dfs_state(mlan_private * priv,t_u16 band,t_u8 chan)3074*4882a593Smuzhiyun dfs_state_t wlan_get_chan_dfs_state(mlan_private *priv, t_u16 band, t_u8 chan)
3075*4882a593Smuzhiyun {
3076*4882a593Smuzhiyun int i, j;
3077*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
3078*4882a593Smuzhiyun dfs_state_t dfs_state = DFS_USABLE;
3079*4882a593Smuzhiyun
3080*4882a593Smuzhiyun ENTER();
3081*4882a593Smuzhiyun
3082*4882a593Smuzhiyun /*get the cfp table first*/
3083*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
3084*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
3085*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
3086*4882a593Smuzhiyun break;
3087*4882a593Smuzhiyun }
3088*4882a593Smuzhiyun }
3089*4882a593Smuzhiyun
3090*4882a593Smuzhiyun if (pcfp) {
3091*4882a593Smuzhiyun /*check table according to chan num*/
3092*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
3093*4882a593Smuzhiyun if (pcfp[j].channel == chan) {
3094*4882a593Smuzhiyun dfs_state = pcfp[j].dynamic.dfs_state;
3095*4882a593Smuzhiyun break;
3096*4882a593Smuzhiyun }
3097*4882a593Smuzhiyun }
3098*4882a593Smuzhiyun }
3099*4882a593Smuzhiyun
3100*4882a593Smuzhiyun LEAVE();
3101*4882a593Smuzhiyun return dfs_state;
3102*4882a593Smuzhiyun }
3103*4882a593Smuzhiyun
3104*4882a593Smuzhiyun /**
3105*4882a593Smuzhiyun * @brief reset all channel's dfs state
3106*4882a593Smuzhiyun *
3107*4882a593Smuzhiyun * @param priv Private driver information structure
3108*4882a593Smuzhiyun * @param band Band to check
3109*4882a593Smuzhiyun * @param dfs_state dfs state
3110*4882a593Smuzhiyun *
3111*4882a593Smuzhiyun * @return N/A
3112*4882a593Smuzhiyun */
wlan_reset_all_chan_dfs_state(mlan_private * priv,t_u16 band,dfs_state_t dfs_state)3113*4882a593Smuzhiyun t_void wlan_reset_all_chan_dfs_state(mlan_private *priv, t_u16 band,
3114*4882a593Smuzhiyun dfs_state_t dfs_state)
3115*4882a593Smuzhiyun {
3116*4882a593Smuzhiyun int i, j;
3117*4882a593Smuzhiyun chan_freq_power_t *pcfp = MNULL;
3118*4882a593Smuzhiyun
3119*4882a593Smuzhiyun ENTER();
3120*4882a593Smuzhiyun
3121*4882a593Smuzhiyun /*get the cfp table first*/
3122*4882a593Smuzhiyun for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) {
3123*4882a593Smuzhiyun if (priv->adapter->region_channel[i].band & band) {
3124*4882a593Smuzhiyun pcfp = priv->adapter->region_channel[i].pcfp;
3125*4882a593Smuzhiyun break;
3126*4882a593Smuzhiyun }
3127*4882a593Smuzhiyun }
3128*4882a593Smuzhiyun
3129*4882a593Smuzhiyun if (pcfp) {
3130*4882a593Smuzhiyun /*check table according to chan num*/
3131*4882a593Smuzhiyun for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) {
3132*4882a593Smuzhiyun pcfp[j].dynamic.dfs_state = dfs_state;
3133*4882a593Smuzhiyun }
3134*4882a593Smuzhiyun }
3135*4882a593Smuzhiyun
3136*4882a593Smuzhiyun LEAVE();
3137*4882a593Smuzhiyun }
3138*4882a593Smuzhiyun
3139*4882a593Smuzhiyun /**
3140*4882a593Smuzhiyun * @brief Convert rateid in IEEE format to MRVL format
3141*4882a593Smuzhiyun *
3142*4882a593Smuzhiyun * @param priv Private driver information structure
3143*4882a593Smuzhiyun * @param IeeeMacRate Rate in terms of IEEE format
3144*4882a593Smuzhiyun * @param pmbuf A pointer to packet buffer
3145*4882a593Smuzhiyun *
3146*4882a593Smuzhiyun * @return
3147*4882a593Smuzhiyun * Rate ID in terms of MRVL format
3148*4882a593Smuzhiyun */
wlan_ieee_rateid_to_mrvl_rateid(mlan_private * priv,t_u16 IeeeMacRate,t_u8 * dst_mac)3149*4882a593Smuzhiyun t_u8 wlan_ieee_rateid_to_mrvl_rateid(mlan_private *priv, t_u16 IeeeMacRate,
3150*4882a593Smuzhiyun t_u8 *dst_mac)
3151*4882a593Smuzhiyun {
3152*4882a593Smuzhiyun /* Set default rate ID to RATEID_DBPSK1Mbps */
3153*4882a593Smuzhiyun t_u8 mrvlRATEID = 0;
3154*4882a593Smuzhiyun const rate_map *rate_tbl = rate_map_table_1x1;
3155*4882a593Smuzhiyun t_u32 cnt = sizeof(rate_map_table_1x1) / sizeof(rate_map);
3156*4882a593Smuzhiyun t_u8 skip_nss2 = MTRUE;
3157*4882a593Smuzhiyun t_u32 i = 0;
3158*4882a593Smuzhiyun IEEEtypes_HTCap_t *htcap = MNULL;
3159*4882a593Smuzhiyun t_u8 tx_mcs_supp = GET_TXMCSSUPP(priv->usr_dev_mcs_support);
3160*4882a593Smuzhiyun #ifdef UAP_SUPPORT
3161*4882a593Smuzhiyun psta_node sta_ptr = MNULL;
3162*4882a593Smuzhiyun #endif
3163*4882a593Smuzhiyun
3164*4882a593Smuzhiyun ENTER();
3165*4882a593Smuzhiyun
3166*4882a593Smuzhiyun if (priv->adapter->hw_dev_mcs_support == HT_STREAM_MODE_2X2) {
3167*4882a593Smuzhiyun rate_tbl = rate_map_table_2x2;
3168*4882a593Smuzhiyun cnt = sizeof(rate_map_table_2x2) / sizeof(rate_map);
3169*4882a593Smuzhiyun }
3170*4882a593Smuzhiyun
3171*4882a593Smuzhiyun #ifdef UAP_SUPPORT
3172*4882a593Smuzhiyun if (priv->bss_role == MLAN_BSS_ROLE_UAP) {
3173*4882a593Smuzhiyun if (!dst_mac) {
3174*4882a593Smuzhiyun LEAVE();
3175*4882a593Smuzhiyun return mrvlRATEID;
3176*4882a593Smuzhiyun }
3177*4882a593Smuzhiyun sta_ptr = (sta_node *)util_peek_list(
3178*4882a593Smuzhiyun priv->adapter->pmoal_handle, &priv->sta_list,
3179*4882a593Smuzhiyun priv->adapter->callbacks.moal_spin_lock,
3180*4882a593Smuzhiyun priv->adapter->callbacks.moal_spin_unlock);
3181*4882a593Smuzhiyun if (!sta_ptr) {
3182*4882a593Smuzhiyun LEAVE();
3183*4882a593Smuzhiyun return mrvlRATEID;
3184*4882a593Smuzhiyun }
3185*4882a593Smuzhiyun while (sta_ptr != (sta_node *)&priv->sta_list) {
3186*4882a593Smuzhiyun if (memcmp(priv->adapter, dst_mac, sta_ptr->mac_addr,
3187*4882a593Smuzhiyun MLAN_MAC_ADDR_LENGTH)) {
3188*4882a593Smuzhiyun htcap = &(sta_ptr->HTcap);
3189*4882a593Smuzhiyun break;
3190*4882a593Smuzhiyun }
3191*4882a593Smuzhiyun sta_ptr = sta_ptr->pnext;
3192*4882a593Smuzhiyun }
3193*4882a593Smuzhiyun }
3194*4882a593Smuzhiyun #endif
3195*4882a593Smuzhiyun #ifdef STA_SUPPORT
3196*4882a593Smuzhiyun if (priv->bss_role == MLAN_BSS_ROLE_STA)
3197*4882a593Smuzhiyun htcap = priv->curr_bss_params.bss_descriptor.pht_cap;
3198*4882a593Smuzhiyun #endif
3199*4882a593Smuzhiyun if (htcap) {
3200*4882a593Smuzhiyun /* If user configure tx to 2x2 and peer device rx is 2x2 */
3201*4882a593Smuzhiyun if (tx_mcs_supp >= 2 && htcap->ht_cap.supported_mcs_set[1])
3202*4882a593Smuzhiyun skip_nss2 = MFALSE;
3203*4882a593Smuzhiyun }
3204*4882a593Smuzhiyun
3205*4882a593Smuzhiyun for (i = 0; i < cnt; i++) {
3206*4882a593Smuzhiyun if (rate_tbl[i].nss && skip_nss2)
3207*4882a593Smuzhiyun continue;
3208*4882a593Smuzhiyun if (rate_tbl[i].rate == IeeeMacRate) {
3209*4882a593Smuzhiyun mrvlRATEID = rate_tbl[i].id;
3210*4882a593Smuzhiyun break;
3211*4882a593Smuzhiyun }
3212*4882a593Smuzhiyun }
3213*4882a593Smuzhiyun
3214*4882a593Smuzhiyun return mrvlRATEID;
3215*4882a593Smuzhiyun }
3216*4882a593Smuzhiyun
3217*4882a593Smuzhiyun /**
3218*4882a593Smuzhiyun * @brief Convert rateid in MRVL format to IEEE format
3219*4882a593Smuzhiyun *
3220*4882a593Smuzhiyun * @param IeeeMacRate Rate in terms of MRVL format
3221*4882a593Smuzhiyun *
3222*4882a593Smuzhiyun * @return
3223*4882a593Smuzhiyun * Rate ID in terms of IEEE format
3224*4882a593Smuzhiyun */
wlan_mrvl_rateid_to_ieee_rateid(t_u8 rate)3225*4882a593Smuzhiyun t_u8 wlan_mrvl_rateid_to_ieee_rateid(t_u8 rate)
3226*4882a593Smuzhiyun {
3227*4882a593Smuzhiyun return rateUnit_500Kbps[rate];
3228*4882a593Smuzhiyun }
3229*4882a593Smuzhiyun
3230*4882a593Smuzhiyun /**
3231*4882a593Smuzhiyun * @brief sort cfp otp table
3232*4882a593Smuzhiyun *
3233*4882a593Smuzhiyun * @param pmapdater a pointer to mlan_adapter structure
3234*4882a593Smuzhiyun *
3235*4882a593Smuzhiyun * @return
3236*4882a593Smuzhiyun * None
3237*4882a593Smuzhiyun */
wlan_sort_cfp_otp_table(mlan_adapter * pmadapter)3238*4882a593Smuzhiyun static void wlan_sort_cfp_otp_table(mlan_adapter *pmadapter)
3239*4882a593Smuzhiyun {
3240*4882a593Smuzhiyun t_u8 c, d;
3241*4882a593Smuzhiyun chan_freq_power_t *ch1;
3242*4882a593Smuzhiyun chan_freq_power_t *ch2;
3243*4882a593Smuzhiyun chan_freq_power_t swap;
3244*4882a593Smuzhiyun
3245*4882a593Smuzhiyun if (pmadapter->tx_power_table_a_rows <= 1)
3246*4882a593Smuzhiyun return;
3247*4882a593Smuzhiyun for (c = 0; c < pmadapter->tx_power_table_a_rows - 1; c++) {
3248*4882a593Smuzhiyun for (d = 0; d < pmadapter->tx_power_table_a_rows - c - 1; d++) {
3249*4882a593Smuzhiyun ch1 = (chan_freq_power_t *)(pmadapter->cfp_otp_a + d);
3250*4882a593Smuzhiyun ch2 = (chan_freq_power_t *)(pmadapter->cfp_otp_a + d +
3251*4882a593Smuzhiyun 1);
3252*4882a593Smuzhiyun if (ch1->channel > ch2->channel) {
3253*4882a593Smuzhiyun memcpy_ext(pmadapter, &swap, ch1,
3254*4882a593Smuzhiyun sizeof(chan_freq_power_t),
3255*4882a593Smuzhiyun sizeof(chan_freq_power_t));
3256*4882a593Smuzhiyun memcpy_ext(pmadapter, ch1, ch2,
3257*4882a593Smuzhiyun sizeof(chan_freq_power_t),
3258*4882a593Smuzhiyun sizeof(chan_freq_power_t));
3259*4882a593Smuzhiyun memcpy_ext(pmadapter, ch2, &swap,
3260*4882a593Smuzhiyun sizeof(chan_freq_power_t),
3261*4882a593Smuzhiyun sizeof(chan_freq_power_t));
3262*4882a593Smuzhiyun }
3263*4882a593Smuzhiyun }
3264*4882a593Smuzhiyun }
3265*4882a593Smuzhiyun }
3266*4882a593Smuzhiyun
3267*4882a593Smuzhiyun /**
3268*4882a593Smuzhiyun * @brief Update CFP tables and power tables from FW
3269*4882a593Smuzhiyun *
3270*4882a593Smuzhiyun * @param priv Private driver information structure
3271*4882a593Smuzhiyun * @param buf Pointer to the buffer holding TLV data
3272*4882a593Smuzhiyun * from 0x242 command response.
3273*4882a593Smuzhiyun * @param buf_left bufsize
3274*4882a593Smuzhiyun *
3275*4882a593Smuzhiyun * @return
3276*4882a593Smuzhiyun * None
3277*4882a593Smuzhiyun */
wlan_add_fw_cfp_tables(pmlan_private pmpriv,t_u8 * buf,t_u16 buf_left)3278*4882a593Smuzhiyun void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
3279*4882a593Smuzhiyun {
3280*4882a593Smuzhiyun mlan_adapter *pmadapter = pmpriv->adapter;
3281*4882a593Smuzhiyun mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
3282*4882a593Smuzhiyun MrvlIEtypesHeader_t *head;
3283*4882a593Smuzhiyun t_u16 tlv;
3284*4882a593Smuzhiyun t_u16 tlv_buf_len;
3285*4882a593Smuzhiyun t_u16 tlv_buf_left;
3286*4882a593Smuzhiyun t_u16 i;
3287*4882a593Smuzhiyun int k = 0, rows, cols;
3288*4882a593Smuzhiyun t_u16 max_tx_pwr_bg = WLAN_TX_PWR_DEFAULT;
3289*4882a593Smuzhiyun t_u16 max_tx_pwr_a = WLAN_TX_PWR_DEFAULT;
3290*4882a593Smuzhiyun t_u8 *tlv_buf;
3291*4882a593Smuzhiyun t_u8 *data;
3292*4882a593Smuzhiyun t_u8 *tmp;
3293*4882a593Smuzhiyun mlan_status ret;
3294*4882a593Smuzhiyun
3295*4882a593Smuzhiyun ENTER();
3296*4882a593Smuzhiyun
3297*4882a593Smuzhiyun if (!buf) {
3298*4882a593Smuzhiyun PRINTM(MERROR, "CFP table update failed!\n");
3299*4882a593Smuzhiyun goto out;
3300*4882a593Smuzhiyun }
3301*4882a593Smuzhiyun if (pmadapter->otp_region) {
3302*4882a593Smuzhiyun memset(pmadapter, pmadapter->region_channel, 0,
3303*4882a593Smuzhiyun sizeof(pmadapter->region_channel));
3304*4882a593Smuzhiyun wlan_free_fw_cfp_tables(pmadapter);
3305*4882a593Smuzhiyun }
3306*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows = FW_CFP_TABLE_MAX_ROWS_BG;
3307*4882a593Smuzhiyun pmadapter->tx_power_table_bg_cols = FW_CFP_TABLE_MAX_COLS_BG;
3308*4882a593Smuzhiyun pmadapter->tx_power_table_a_rows = FW_CFP_TABLE_MAX_ROWS_A;
3309*4882a593Smuzhiyun pmadapter->tx_power_table_a_cols = FW_CFP_TABLE_MAX_COLS_A;
3310*4882a593Smuzhiyun tlv_buf = (t_u8 *)buf;
3311*4882a593Smuzhiyun tlv_buf_left = buf_left;
3312*4882a593Smuzhiyun
3313*4882a593Smuzhiyun while (tlv_buf_left >= sizeof(*head)) {
3314*4882a593Smuzhiyun head = (MrvlIEtypesHeader_t *)tlv_buf;
3315*4882a593Smuzhiyun tlv = wlan_le16_to_cpu(head->type);
3316*4882a593Smuzhiyun tlv_buf_len = wlan_le16_to_cpu(head->len);
3317*4882a593Smuzhiyun
3318*4882a593Smuzhiyun if (tlv_buf_left < (sizeof(*head) + tlv_buf_len))
3319*4882a593Smuzhiyun break;
3320*4882a593Smuzhiyun data = (t_u8 *)head + sizeof(*head);
3321*4882a593Smuzhiyun
3322*4882a593Smuzhiyun switch (tlv) {
3323*4882a593Smuzhiyun case TLV_TYPE_REGION_INFO:
3324*4882a593Smuzhiyun /* Skip adding fw region info if it already exists or
3325*4882a593Smuzhiyun * if this TLV has no set data
3326*4882a593Smuzhiyun */
3327*4882a593Smuzhiyun if (*data == 0)
3328*4882a593Smuzhiyun break;
3329*4882a593Smuzhiyun if (pmadapter->otp_region)
3330*4882a593Smuzhiyun break;
3331*4882a593Smuzhiyun
3332*4882a593Smuzhiyun ret = pcb->moal_malloc(pmadapter->pmoal_handle,
3333*4882a593Smuzhiyun sizeof(otp_region_info_t),
3334*4882a593Smuzhiyun MLAN_MEM_DEF,
3335*4882a593Smuzhiyun (t_u8 **)&pmadapter->otp_region);
3336*4882a593Smuzhiyun if (ret != MLAN_STATUS_SUCCESS ||
3337*4882a593Smuzhiyun !pmadapter->otp_region) {
3338*4882a593Smuzhiyun PRINTM(MERROR,
3339*4882a593Smuzhiyun "Memory allocation for the otp region info struct failed!\n");
3340*4882a593Smuzhiyun break;
3341*4882a593Smuzhiyun }
3342*4882a593Smuzhiyun /* Save region info values from OTP in the otp_region
3343*4882a593Smuzhiyun * structure
3344*4882a593Smuzhiyun */
3345*4882a593Smuzhiyun memcpy_ext(pmadapter, pmadapter->otp_region, data,
3346*4882a593Smuzhiyun sizeof(otp_region_info_t),
3347*4882a593Smuzhiyun sizeof(otp_region_info_t));
3348*4882a593Smuzhiyun data += sizeof(otp_region_info_t);
3349*4882a593Smuzhiyun /* Get pre-defined cfp tables corresponding to the
3350*4882a593Smuzhiyun * region code in OTP
3351*4882a593Smuzhiyun */
3352*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) {
3353*4882a593Smuzhiyun if (cfp_table_BG[i].code ==
3354*4882a593Smuzhiyun pmadapter->otp_region->region_code) {
3355*4882a593Smuzhiyun max_tx_pwr_bg = (cfp_table_BG[i].cfp)
3356*4882a593Smuzhiyun ->max_tx_power;
3357*4882a593Smuzhiyun break;
3358*4882a593Smuzhiyun }
3359*4882a593Smuzhiyun }
3360*4882a593Smuzhiyun for (i = 0; i < MLAN_CFP_TABLE_SIZE_A; i++) {
3361*4882a593Smuzhiyun if (cfp_table_A[i].code ==
3362*4882a593Smuzhiyun pmadapter->otp_region->region_code) {
3363*4882a593Smuzhiyun max_tx_pwr_a = (cfp_table_A[i].cfp)
3364*4882a593Smuzhiyun ->max_tx_power;
3365*4882a593Smuzhiyun break;
3366*4882a593Smuzhiyun }
3367*4882a593Smuzhiyun }
3368*4882a593Smuzhiyun /* Update the region code and the country code in
3369*4882a593Smuzhiyun * pmadapter
3370*4882a593Smuzhiyun */
3371*4882a593Smuzhiyun pmadapter->region_code =
3372*4882a593Smuzhiyun pmadapter->otp_region->region_code;
3373*4882a593Smuzhiyun pmadapter->country_code[0] =
3374*4882a593Smuzhiyun pmadapter->otp_region->country_code[0];
3375*4882a593Smuzhiyun pmadapter->country_code[1] =
3376*4882a593Smuzhiyun pmadapter->otp_region->country_code[1];
3377*4882a593Smuzhiyun pmadapter->country_code[2] = '\0';
3378*4882a593Smuzhiyun pmadapter->domain_reg.country_code[0] =
3379*4882a593Smuzhiyun pmadapter->otp_region->country_code[0];
3380*4882a593Smuzhiyun pmadapter->domain_reg.country_code[1] =
3381*4882a593Smuzhiyun pmadapter->otp_region->country_code[1];
3382*4882a593Smuzhiyun pmadapter->domain_reg.country_code[2] = '\0';
3383*4882a593Smuzhiyun PRINTM(MCMND,
3384*4882a593Smuzhiyun "OTP region: region_code=%d %c%c dfs_region=%d\n",
3385*4882a593Smuzhiyun pmadapter->otp_region->region_code,
3386*4882a593Smuzhiyun pmadapter->country_code[0],
3387*4882a593Smuzhiyun pmadapter->country_code[1],
3388*4882a593Smuzhiyun pmadapter->otp_region->dfs_region);
3389*4882a593Smuzhiyun pmadapter->cfp_code_bg =
3390*4882a593Smuzhiyun pmadapter->otp_region->region_code;
3391*4882a593Smuzhiyun pmadapter->cfp_code_a =
3392*4882a593Smuzhiyun pmadapter->otp_region->region_code;
3393*4882a593Smuzhiyun break;
3394*4882a593Smuzhiyun case TLV_TYPE_CHAN_ATTR_CFG:
3395*4882a593Smuzhiyun /* Skip adding fw cfp tables if they already exist or
3396*4882a593Smuzhiyun * if this TLV has no set data
3397*4882a593Smuzhiyun */
3398*4882a593Smuzhiyun if (*data == 0)
3399*4882a593Smuzhiyun break;
3400*4882a593Smuzhiyun if (pmadapter->cfp_otp_bg || pmadapter->cfp_otp_a) {
3401*4882a593Smuzhiyun break;
3402*4882a593Smuzhiyun }
3403*4882a593Smuzhiyun
3404*4882a593Smuzhiyun ret = pcb->moal_malloc(
3405*4882a593Smuzhiyun pmadapter->pmoal_handle,
3406*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows *
3407*4882a593Smuzhiyun sizeof(chan_freq_power_t),
3408*4882a593Smuzhiyun MLAN_MEM_DEF, (t_u8 **)&pmadapter->cfp_otp_bg);
3409*4882a593Smuzhiyun if (ret != MLAN_STATUS_SUCCESS ||
3410*4882a593Smuzhiyun !pmadapter->cfp_otp_bg) {
3411*4882a593Smuzhiyun PRINTM(MERROR,
3412*4882a593Smuzhiyun "Memory allocation for storing otp bg table data failed!\n");
3413*4882a593Smuzhiyun break;
3414*4882a593Smuzhiyun }
3415*4882a593Smuzhiyun /* Save channel usability flags from OTP data in the fw
3416*4882a593Smuzhiyun * cfp bg table and set frequency and max_tx_power
3417*4882a593Smuzhiyun * values
3418*4882a593Smuzhiyun */
3419*4882a593Smuzhiyun for (i = 0; i < pmadapter->tx_power_table_bg_rows;
3420*4882a593Smuzhiyun i++) {
3421*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->channel = *data;
3422*4882a593Smuzhiyun if (*data == 14)
3423*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->freq =
3424*4882a593Smuzhiyun 2484;
3425*4882a593Smuzhiyun else
3426*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->freq =
3427*4882a593Smuzhiyun 2412 + 5 * (*data - 1);
3428*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->max_tx_power =
3429*4882a593Smuzhiyun max_tx_pwr_bg;
3430*4882a593Smuzhiyun data++;
3431*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->dynamic.flags =
3432*4882a593Smuzhiyun *data;
3433*4882a593Smuzhiyun if (*data & NXP_CHANNEL_DFS)
3434*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)
3435*4882a593Smuzhiyun ->passive_scan_or_radar_detect =
3436*4882a593Smuzhiyun MTRUE;
3437*4882a593Smuzhiyun PRINTM(MCMD_D,
3438*4882a593Smuzhiyun "OTP Region (BG): chan=%d flags=0x%x\n",
3439*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->channel,
3440*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)
3441*4882a593Smuzhiyun ->dynamic.flags);
3442*4882a593Smuzhiyun data++;
3443*4882a593Smuzhiyun }
3444*4882a593Smuzhiyun ret = pcb->moal_malloc(
3445*4882a593Smuzhiyun pmadapter->pmoal_handle,
3446*4882a593Smuzhiyun pmadapter->tx_power_table_a_rows *
3447*4882a593Smuzhiyun sizeof(chan_freq_power_t),
3448*4882a593Smuzhiyun MLAN_MEM_DEF, (t_u8 **)&pmadapter->cfp_otp_a);
3449*4882a593Smuzhiyun if (ret != MLAN_STATUS_SUCCESS ||
3450*4882a593Smuzhiyun !pmadapter->cfp_otp_a) {
3451*4882a593Smuzhiyun PRINTM(MERROR,
3452*4882a593Smuzhiyun "Memory allocation for storing otp a table data failed!\n");
3453*4882a593Smuzhiyun break;
3454*4882a593Smuzhiyun }
3455*4882a593Smuzhiyun /* Save channel usability flags from OTP data in the fw
3456*4882a593Smuzhiyun * cfp a table and set frequency and max_tx_power values
3457*4882a593Smuzhiyun */
3458*4882a593Smuzhiyun for (i = 0; i < pmadapter->tx_power_table_a_rows; i++) {
3459*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->channel = *data;
3460*4882a593Smuzhiyun if (*data < 183)
3461*4882a593Smuzhiyun /* 5GHz channels */
3462*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->freq =
3463*4882a593Smuzhiyun 5035 + 5 * (*data - 7);
3464*4882a593Smuzhiyun else
3465*4882a593Smuzhiyun /* 4GHz channels */
3466*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->freq =
3467*4882a593Smuzhiyun 4915 + 5 * (*data - 183);
3468*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->max_tx_power =
3469*4882a593Smuzhiyun max_tx_pwr_a;
3470*4882a593Smuzhiyun data++;
3471*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->dynamic.flags =
3472*4882a593Smuzhiyun *data;
3473*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->dynamic.dfs_state =
3474*4882a593Smuzhiyun DFS_USABLE;
3475*4882a593Smuzhiyun if (*data & NXP_CHANNEL_DFS)
3476*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)
3477*4882a593Smuzhiyun ->passive_scan_or_radar_detect =
3478*4882a593Smuzhiyun MTRUE;
3479*4882a593Smuzhiyun PRINTM(MCMD_D,
3480*4882a593Smuzhiyun "OTP Region (A): chan=%d flags=0x%x\n",
3481*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)->channel,
3482*4882a593Smuzhiyun (pmadapter->cfp_otp_a + i)
3483*4882a593Smuzhiyun ->dynamic.flags);
3484*4882a593Smuzhiyun
3485*4882a593Smuzhiyun data++;
3486*4882a593Smuzhiyun }
3487*4882a593Smuzhiyun break;
3488*4882a593Smuzhiyun case TLV_TYPE_POWER_TABLE:
3489*4882a593Smuzhiyun /* Skip adding fw power tables if this TLV has no data
3490*4882a593Smuzhiyun * or if they already exists but force reg rule is set
3491*4882a593Smuzhiyun * in the otp
3492*4882a593Smuzhiyun */
3493*4882a593Smuzhiyun if (*data == 0)
3494*4882a593Smuzhiyun break;
3495*4882a593Smuzhiyun if (pmadapter->otp_region &&
3496*4882a593Smuzhiyun pmadapter->otp_region->force_reg &&
3497*4882a593Smuzhiyun pmadapter->tx_power_table_bg)
3498*4882a593Smuzhiyun break;
3499*4882a593Smuzhiyun
3500*4882a593Smuzhiyun /* Save the tlv data in power tables for band BG and A
3501*4882a593Smuzhiyun */
3502*4882a593Smuzhiyun tmp = data;
3503*4882a593Smuzhiyun i = 0;
3504*4882a593Smuzhiyun while ((i <
3505*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows *
3506*4882a593Smuzhiyun pmadapter->tx_power_table_bg_cols) &&
3507*4882a593Smuzhiyun (i < tlv_buf_len)) {
3508*4882a593Smuzhiyun i++;
3509*4882a593Smuzhiyun tmp++;
3510*4882a593Smuzhiyun }
3511*4882a593Smuzhiyun if (!pmadapter->tx_power_table_bg) {
3512*4882a593Smuzhiyun ret = pcb->moal_malloc(
3513*4882a593Smuzhiyun pmadapter->pmoal_handle, i,
3514*4882a593Smuzhiyun MLAN_MEM_DEF,
3515*4882a593Smuzhiyun (t_u8 **)&pmadapter->tx_power_table_bg);
3516*4882a593Smuzhiyun if (ret != MLAN_STATUS_SUCCESS ||
3517*4882a593Smuzhiyun !pmadapter->tx_power_table_bg) {
3518*4882a593Smuzhiyun PRINTM(MERROR,
3519*4882a593Smuzhiyun "Memory allocation for the BG-band power table failed!\n");
3520*4882a593Smuzhiyun break;
3521*4882a593Smuzhiyun }
3522*4882a593Smuzhiyun }
3523*4882a593Smuzhiyun memcpy_ext(pmadapter, pmadapter->tx_power_table_bg,
3524*4882a593Smuzhiyun data, i, i);
3525*4882a593Smuzhiyun pmadapter->tx_power_table_bg_size = i;
3526*4882a593Smuzhiyun data += i;
3527*4882a593Smuzhiyun i = 0;
3528*4882a593Smuzhiyun while ((i < pmadapter->tx_power_table_a_rows *
3529*4882a593Smuzhiyun pmadapter->tx_power_table_a_cols) &&
3530*4882a593Smuzhiyun (i < (tlv_buf_len -
3531*4882a593Smuzhiyun pmadapter->tx_power_table_bg_size))) {
3532*4882a593Smuzhiyun i++;
3533*4882a593Smuzhiyun }
3534*4882a593Smuzhiyun if (!pmadapter->tx_power_table_a) {
3535*4882a593Smuzhiyun ret = pcb->moal_malloc(
3536*4882a593Smuzhiyun pmadapter->pmoal_handle, i,
3537*4882a593Smuzhiyun MLAN_MEM_DEF,
3538*4882a593Smuzhiyun (t_u8 **)&pmadapter->tx_power_table_a);
3539*4882a593Smuzhiyun if (ret != MLAN_STATUS_SUCCESS ||
3540*4882a593Smuzhiyun !pmadapter->tx_power_table_a) {
3541*4882a593Smuzhiyun PRINTM(MERROR,
3542*4882a593Smuzhiyun "Memory allocation for the A-band power table failed!\n");
3543*4882a593Smuzhiyun break;
3544*4882a593Smuzhiyun }
3545*4882a593Smuzhiyun }
3546*4882a593Smuzhiyun memcpy_ext(pmadapter, pmadapter->tx_power_table_a, data,
3547*4882a593Smuzhiyun i, i);
3548*4882a593Smuzhiyun pmadapter->tx_power_table_a_size = i;
3549*4882a593Smuzhiyun break;
3550*4882a593Smuzhiyun case TLV_TYPE_POWER_TABLE_ATTR:
3551*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows =
3552*4882a593Smuzhiyun ((power_table_attr_t *)data)->rows_2g;
3553*4882a593Smuzhiyun pmadapter->tx_power_table_bg_cols =
3554*4882a593Smuzhiyun ((power_table_attr_t *)data)->cols_2g;
3555*4882a593Smuzhiyun pmadapter->tx_power_table_a_rows =
3556*4882a593Smuzhiyun ((power_table_attr_t *)data)->rows_5g;
3557*4882a593Smuzhiyun pmadapter->tx_power_table_a_cols =
3558*4882a593Smuzhiyun ((power_table_attr_t *)data)->cols_5g;
3559*4882a593Smuzhiyun PRINTM(MCMD_D,
3560*4882a593Smuzhiyun "OTP region: bg_row=%d,bg_cols=%d a_row=%d, a_cols=%d\n",
3561*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows,
3562*4882a593Smuzhiyun pmadapter->tx_power_table_bg_cols,
3563*4882a593Smuzhiyun pmadapter->tx_power_table_a_rows,
3564*4882a593Smuzhiyun pmadapter->tx_power_table_a_cols);
3565*4882a593Smuzhiyun break;
3566*4882a593Smuzhiyun default:
3567*4882a593Smuzhiyun break;
3568*4882a593Smuzhiyun }
3569*4882a593Smuzhiyun tlv_buf += (sizeof(*head) + tlv_buf_len);
3570*4882a593Smuzhiyun tlv_buf_left -= (sizeof(*head) + tlv_buf_len);
3571*4882a593Smuzhiyun }
3572*4882a593Smuzhiyun if (!pmadapter->cfp_otp_bg || !pmadapter->tx_power_table_bg)
3573*4882a593Smuzhiyun goto out;
3574*4882a593Smuzhiyun /* Set remaining flags for BG */
3575*4882a593Smuzhiyun rows = pmadapter->tx_power_table_bg_rows;
3576*4882a593Smuzhiyun cols = pmadapter->tx_power_table_bg_cols;
3577*4882a593Smuzhiyun
3578*4882a593Smuzhiyun for (i = 0; i < rows; i++) {
3579*4882a593Smuzhiyun k = (i * cols) + 1;
3580*4882a593Smuzhiyun if ((pmadapter->cfp_otp_bg + i)->dynamic.flags &
3581*4882a593Smuzhiyun NXP_CHANNEL_DISABLED)
3582*4882a593Smuzhiyun continue;
3583*4882a593Smuzhiyun
3584*4882a593Smuzhiyun if (pmadapter->tx_power_table_bg[k + MOD_CCK] == 0)
3585*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->dynamic.flags |=
3586*4882a593Smuzhiyun NXP_CHANNEL_NO_CCK;
3587*4882a593Smuzhiyun
3588*4882a593Smuzhiyun if (pmadapter->tx_power_table_bg[k + MOD_OFDM_PSK] == 0 &&
3589*4882a593Smuzhiyun pmadapter->tx_power_table_bg[k + MOD_OFDM_QAM16] == 0 &&
3590*4882a593Smuzhiyun pmadapter->tx_power_table_bg[k + MOD_OFDM_QAM64] == 0) {
3591*4882a593Smuzhiyun (pmadapter->cfp_otp_bg + i)->dynamic.flags |=
3592*4882a593Smuzhiyun NXP_CHANNEL_NO_OFDM;
3593*4882a593Smuzhiyun }
3594*4882a593Smuzhiyun }
3595*4882a593Smuzhiyun if (pmadapter->cfp_otp_a)
3596*4882a593Smuzhiyun wlan_sort_cfp_otp_table(pmadapter);
3597*4882a593Smuzhiyun out:
3598*4882a593Smuzhiyun LEAVE();
3599*4882a593Smuzhiyun }
3600*4882a593Smuzhiyun
3601*4882a593Smuzhiyun /**
3602*4882a593Smuzhiyun * @brief This function deallocates otp cfp and power tables memory.
3603*4882a593Smuzhiyun *
3604*4882a593Smuzhiyun * @param pmadapter A pointer to mlan_adapter structure
3605*4882a593Smuzhiyun */
wlan_free_fw_cfp_tables(mlan_adapter * pmadapter)3606*4882a593Smuzhiyun void wlan_free_fw_cfp_tables(mlan_adapter *pmadapter)
3607*4882a593Smuzhiyun {
3608*4882a593Smuzhiyun pmlan_callbacks pcb;
3609*4882a593Smuzhiyun
3610*4882a593Smuzhiyun ENTER();
3611*4882a593Smuzhiyun
3612*4882a593Smuzhiyun pcb = &pmadapter->callbacks;
3613*4882a593Smuzhiyun if (pmadapter->otp_region)
3614*4882a593Smuzhiyun pcb->moal_mfree(pmadapter->pmoal_handle,
3615*4882a593Smuzhiyun (t_u8 *)pmadapter->otp_region);
3616*4882a593Smuzhiyun if (pmadapter->cfp_otp_bg)
3617*4882a593Smuzhiyun pcb->moal_mfree(pmadapter->pmoal_handle,
3618*4882a593Smuzhiyun (t_u8 *)pmadapter->cfp_otp_bg);
3619*4882a593Smuzhiyun if (pmadapter->tx_power_table_bg)
3620*4882a593Smuzhiyun pcb->moal_mfree(pmadapter->pmoal_handle,
3621*4882a593Smuzhiyun (t_u8 *)pmadapter->tx_power_table_bg);
3622*4882a593Smuzhiyun pmadapter->otp_region = MNULL;
3623*4882a593Smuzhiyun pmadapter->cfp_otp_bg = MNULL;
3624*4882a593Smuzhiyun pmadapter->tx_power_table_bg = MNULL;
3625*4882a593Smuzhiyun pmadapter->tx_power_table_bg_size = 0;
3626*4882a593Smuzhiyun if (pmadapter->cfp_otp_a)
3627*4882a593Smuzhiyun pcb->moal_mfree(pmadapter->pmoal_handle,
3628*4882a593Smuzhiyun (t_u8 *)pmadapter->cfp_otp_a);
3629*4882a593Smuzhiyun if (pmadapter->tx_power_table_a)
3630*4882a593Smuzhiyun pcb->moal_mfree(pmadapter->pmoal_handle,
3631*4882a593Smuzhiyun (t_u8 *)pmadapter->tx_power_table_a);
3632*4882a593Smuzhiyun pmadapter->cfp_otp_a = MNULL;
3633*4882a593Smuzhiyun pmadapter->tx_power_table_a = MNULL;
3634*4882a593Smuzhiyun pmadapter->tx_power_table_a_size = 0;
3635*4882a593Smuzhiyun LEAVE();
3636*4882a593Smuzhiyun }
3637*4882a593Smuzhiyun
3638*4882a593Smuzhiyun /**
3639*4882a593Smuzhiyun * @brief Get DFS chan list
3640*4882a593Smuzhiyun *
3641*4882a593Smuzhiyun * @param pmadapter Pointer to mlan_adapter
3642*4882a593Smuzhiyun * @param pioctl_req Pointer to mlan_ioctl_req
3643*4882a593Smuzhiyun *
3644*4882a593Smuzhiyun * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
3645*4882a593Smuzhiyun */
wlan_get_cfp_table(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3646*4882a593Smuzhiyun mlan_status wlan_get_cfp_table(pmlan_adapter pmadapter,
3647*4882a593Smuzhiyun pmlan_ioctl_req pioctl_req)
3648*4882a593Smuzhiyun {
3649*4882a593Smuzhiyun mlan_ds_misc_cfg *ds_misc_cfg = MNULL;
3650*4882a593Smuzhiyun mlan_status ret = MLAN_STATUS_FAILURE;
3651*4882a593Smuzhiyun chan_freq_power_t *cfp = MNULL;
3652*4882a593Smuzhiyun t_u32 cfp_no = 0;
3653*4882a593Smuzhiyun
3654*4882a593Smuzhiyun ENTER();
3655*4882a593Smuzhiyun if (pioctl_req) {
3656*4882a593Smuzhiyun ds_misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
3657*4882a593Smuzhiyun if (pioctl_req->action == MLAN_ACT_GET) {
3658*4882a593Smuzhiyun cfp = wlan_get_region_cfp_table(
3659*4882a593Smuzhiyun pmadapter, pmadapter->region_code,
3660*4882a593Smuzhiyun ds_misc_cfg->param.cfp.band, &cfp_no);
3661*4882a593Smuzhiyun if (cfp) {
3662*4882a593Smuzhiyun ds_misc_cfg->param.cfp.num_chan = cfp_no;
3663*4882a593Smuzhiyun memcpy_ext(pmadapter,
3664*4882a593Smuzhiyun ds_misc_cfg->param.cfp.cfp_tbl, cfp,
3665*4882a593Smuzhiyun cfp_no * sizeof(chan_freq_power_t),
3666*4882a593Smuzhiyun cfp_no * sizeof(chan_freq_power_t));
3667*4882a593Smuzhiyun }
3668*4882a593Smuzhiyun ret = MLAN_STATUS_SUCCESS;
3669*4882a593Smuzhiyun }
3670*4882a593Smuzhiyun }
3671*4882a593Smuzhiyun LEAVE();
3672*4882a593Smuzhiyun return ret;
3673*4882a593Smuzhiyun }
3674*4882a593Smuzhiyun
3675*4882a593Smuzhiyun /**
3676*4882a593Smuzhiyun * @brief Get power tables and cfp tables for set region code
3677*4882a593Smuzhiyun * into the IOCTL request buffer
3678*4882a593Smuzhiyun *
3679*4882a593Smuzhiyun * @param pmadapter Private mlan adapter structure
3680*4882a593Smuzhiyun * @param pioctl_req Pointer to the IOCTL request structure
3681*4882a593Smuzhiyun *
3682*4882a593Smuzhiyun * @return success, otherwise fail
3683*4882a593Smuzhiyun *
3684*4882a593Smuzhiyun */
wlan_get_cfpinfo(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)3685*4882a593Smuzhiyun mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter,
3686*4882a593Smuzhiyun pmlan_ioctl_req pioctl_req)
3687*4882a593Smuzhiyun {
3688*4882a593Smuzhiyun chan_freq_power_t *cfp_bg = MNULL;
3689*4882a593Smuzhiyun t_u32 cfp_no_bg = 0;
3690*4882a593Smuzhiyun chan_freq_power_t *cfp_a = MNULL;
3691*4882a593Smuzhiyun t_u32 cfp_no_a = 0;
3692*4882a593Smuzhiyun t_u8 cfp_code_a = pmadapter->region_code;
3693*4882a593Smuzhiyun t_u8 cfp_code_bg = pmadapter->region_code;
3694*4882a593Smuzhiyun t_u32 len = 0, size = 0;
3695*4882a593Smuzhiyun t_u8 *req_buf, *tmp;
3696*4882a593Smuzhiyun mlan_status ret = MLAN_STATUS_SUCCESS;
3697*4882a593Smuzhiyun
3698*4882a593Smuzhiyun ENTER();
3699*4882a593Smuzhiyun
3700*4882a593Smuzhiyun if (!pioctl_req || !pioctl_req->pbuf) {
3701*4882a593Smuzhiyun PRINTM(MERROR, "MLAN IOCTL information is not present!\n");
3702*4882a593Smuzhiyun ret = MLAN_STATUS_FAILURE;
3703*4882a593Smuzhiyun goto out;
3704*4882a593Smuzhiyun }
3705*4882a593Smuzhiyun /* Calculate the total response size required to return region,
3706*4882a593Smuzhiyun * country codes, cfp tables and power tables
3707*4882a593Smuzhiyun */
3708*4882a593Smuzhiyun size = sizeof(pmadapter->country_code) + sizeof(pmadapter->region_code);
3709*4882a593Smuzhiyun /* Add size to store region, country and environment codes */
3710*4882a593Smuzhiyun size += sizeof(t_u32);
3711*4882a593Smuzhiyun if (pmadapter->cfp_code_bg)
3712*4882a593Smuzhiyun cfp_code_bg = pmadapter->cfp_code_bg;
3713*4882a593Smuzhiyun
3714*4882a593Smuzhiyun /* Get cfp table and its size corresponding to the region code */
3715*4882a593Smuzhiyun cfp_bg = wlan_get_region_cfp_table(pmadapter, cfp_code_bg,
3716*4882a593Smuzhiyun BAND_G | BAND_B, &cfp_no_bg);
3717*4882a593Smuzhiyun size += cfp_no_bg * sizeof(chan_freq_power_t);
3718*4882a593Smuzhiyun if (pmadapter->cfp_code_a)
3719*4882a593Smuzhiyun cfp_code_a = pmadapter->cfp_code_a;
3720*4882a593Smuzhiyun cfp_a = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A,
3721*4882a593Smuzhiyun &cfp_no_a);
3722*4882a593Smuzhiyun size += cfp_no_a * sizeof(chan_freq_power_t);
3723*4882a593Smuzhiyun if (pmadapter->otp_region)
3724*4882a593Smuzhiyun size += sizeof(pmadapter->otp_region->environment);
3725*4882a593Smuzhiyun
3726*4882a593Smuzhiyun /* Get power table size */
3727*4882a593Smuzhiyun if (pmadapter->tx_power_table_bg) {
3728*4882a593Smuzhiyun size += pmadapter->tx_power_table_bg_size;
3729*4882a593Smuzhiyun /* Add size to store table size, rows and cols */
3730*4882a593Smuzhiyun size += 3 * sizeof(t_u32);
3731*4882a593Smuzhiyun }
3732*4882a593Smuzhiyun if (pmadapter->tx_power_table_a) {
3733*4882a593Smuzhiyun size += pmadapter->tx_power_table_a_size;
3734*4882a593Smuzhiyun size += 3 * sizeof(t_u32);
3735*4882a593Smuzhiyun }
3736*4882a593Smuzhiyun /* Check information buffer length of MLAN IOCTL */
3737*4882a593Smuzhiyun if (pioctl_req->buf_len < size) {
3738*4882a593Smuzhiyun PRINTM(MWARN,
3739*4882a593Smuzhiyun "MLAN IOCTL information buffer length is too short.\n");
3740*4882a593Smuzhiyun pioctl_req->buf_len_needed = size;
3741*4882a593Smuzhiyun pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
3742*4882a593Smuzhiyun ret = MLAN_STATUS_RESOURCE;
3743*4882a593Smuzhiyun goto out;
3744*4882a593Smuzhiyun }
3745*4882a593Smuzhiyun /* Copy the total size of region code, country code and environment
3746*4882a593Smuzhiyun * in first four bytes of the IOCTL request buffer and then copy
3747*4882a593Smuzhiyun * codes respectively in following bytes
3748*4882a593Smuzhiyun */
3749*4882a593Smuzhiyun req_buf = (t_u8 *)pioctl_req->pbuf;
3750*4882a593Smuzhiyun size = sizeof(pmadapter->country_code) + sizeof(pmadapter->region_code);
3751*4882a593Smuzhiyun if (pmadapter->otp_region)
3752*4882a593Smuzhiyun size += sizeof(pmadapter->otp_region->environment);
3753*4882a593Smuzhiyun tmp = (t_u8 *)&size;
3754*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf, tmp, sizeof(size), sizeof(size));
3755*4882a593Smuzhiyun len += sizeof(size);
3756*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, &pmadapter->region_code,
3757*4882a593Smuzhiyun sizeof(pmadapter->region_code),
3758*4882a593Smuzhiyun sizeof(pmadapter->region_code));
3759*4882a593Smuzhiyun len += sizeof(pmadapter->region_code);
3760*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, &pmadapter->country_code,
3761*4882a593Smuzhiyun sizeof(pmadapter->country_code),
3762*4882a593Smuzhiyun sizeof(pmadapter->country_code));
3763*4882a593Smuzhiyun len += sizeof(pmadapter->country_code);
3764*4882a593Smuzhiyun if (pmadapter->otp_region) {
3765*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len,
3766*4882a593Smuzhiyun &pmadapter->otp_region->environment,
3767*4882a593Smuzhiyun sizeof(pmadapter->otp_region->environment),
3768*4882a593Smuzhiyun sizeof(pmadapter->otp_region->environment));
3769*4882a593Smuzhiyun len += sizeof(pmadapter->otp_region->environment);
3770*4882a593Smuzhiyun }
3771*4882a593Smuzhiyun /* copy the cfp table size followed by the entire table */
3772*4882a593Smuzhiyun if (!cfp_bg)
3773*4882a593Smuzhiyun goto out;
3774*4882a593Smuzhiyun size = cfp_no_bg * sizeof(chan_freq_power_t);
3775*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3776*4882a593Smuzhiyun len += sizeof(size);
3777*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, cfp_bg, size, size);
3778*4882a593Smuzhiyun len += size;
3779*4882a593Smuzhiyun if (!cfp_a)
3780*4882a593Smuzhiyun goto out;
3781*4882a593Smuzhiyun size = cfp_no_a * sizeof(chan_freq_power_t);
3782*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3783*4882a593Smuzhiyun len += sizeof(size);
3784*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, cfp_a, size, size);
3785*4882a593Smuzhiyun len += size;
3786*4882a593Smuzhiyun /* Copy the size of the power table, number of rows, number of cols
3787*4882a593Smuzhiyun * and the entire power table
3788*4882a593Smuzhiyun */
3789*4882a593Smuzhiyun if (!pmadapter->tx_power_table_bg)
3790*4882a593Smuzhiyun goto out;
3791*4882a593Smuzhiyun size = pmadapter->tx_power_table_bg_size;
3792*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3793*4882a593Smuzhiyun len += sizeof(size);
3794*4882a593Smuzhiyun
3795*4882a593Smuzhiyun /* No. of rows */
3796*4882a593Smuzhiyun size = pmadapter->tx_power_table_bg_rows;
3797*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3798*4882a593Smuzhiyun len += sizeof(size);
3799*4882a593Smuzhiyun
3800*4882a593Smuzhiyun /* No. of cols */
3801*4882a593Smuzhiyun size = pmadapter->tx_power_table_bg_size /
3802*4882a593Smuzhiyun pmadapter->tx_power_table_bg_rows;
3803*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3804*4882a593Smuzhiyun len += sizeof(size);
3805*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, pmadapter->tx_power_table_bg,
3806*4882a593Smuzhiyun pmadapter->tx_power_table_bg_size,
3807*4882a593Smuzhiyun pmadapter->tx_power_table_bg_size);
3808*4882a593Smuzhiyun len += pmadapter->tx_power_table_bg_size;
3809*4882a593Smuzhiyun if (!pmadapter->tx_power_table_a)
3810*4882a593Smuzhiyun goto out;
3811*4882a593Smuzhiyun size = pmadapter->tx_power_table_a_size;
3812*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3813*4882a593Smuzhiyun len += sizeof(size);
3814*4882a593Smuzhiyun
3815*4882a593Smuzhiyun /* No. of rows */
3816*4882a593Smuzhiyun size = pmadapter->tx_power_table_a_rows;
3817*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3818*4882a593Smuzhiyun len += sizeof(size);
3819*4882a593Smuzhiyun
3820*4882a593Smuzhiyun /* No. of cols */
3821*4882a593Smuzhiyun size = pmadapter->tx_power_table_a_size /
3822*4882a593Smuzhiyun pmadapter->tx_power_table_a_rows;
3823*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, tmp, sizeof(size), sizeof(size));
3824*4882a593Smuzhiyun len += sizeof(size);
3825*4882a593Smuzhiyun memcpy_ext(pmadapter, req_buf + len, pmadapter->tx_power_table_a,
3826*4882a593Smuzhiyun pmadapter->tx_power_table_a_size,
3827*4882a593Smuzhiyun pmadapter->tx_power_table_a_size);
3828*4882a593Smuzhiyun len += pmadapter->tx_power_table_a_size;
3829*4882a593Smuzhiyun out:
3830*4882a593Smuzhiyun if (pioctl_req)
3831*4882a593Smuzhiyun pioctl_req->data_read_written = len;
3832*4882a593Smuzhiyun
3833*4882a593Smuzhiyun LEAVE();
3834*4882a593Smuzhiyun return ret;
3835*4882a593Smuzhiyun }
3836