blob: 70811025f2bc9b7f1e39eaaf522c3b4a92c055e0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*============================================================================
43 FILE: vos_nvitem.c
44 OVERVIEW: This source file contains definitions for vOS NV Item APIs
45 DEPENDENCIES: NV, remote API client, WinCE REX
46 Copyright (c) 2008 QUALCOMM Incorporated.
47 All Rights Reserved.
48 Qualcomm Confidential and Proprietary
49============================================================================*/
50/*============================================================================
51 EDIT HISTORY FOR MODULE
52============================================================================*/
53// the following is used to disable warning for having too many labels in
54// the 'nv_items_enum_type'
55
56/*----------------------------------------------------------------------------
57 * Include Files
58 * -------------------------------------------------------------------------*/
59#include "vos_types.h"
60#include "aniGlobal.h"
61#include "vos_nvitem.h"
62#include "vos_trace.h"
63#include "vos_api.h"
64#include "wlan_hdd_misc.h"
65#include "vos_sched.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070066#include "wlan_hdd_main.h"
67#include <net/cfg80211.h>
68static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
69static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
70static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
71static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070072
Jeff Johnson295189b2012-06-20 16:38:30 -070073/*----------------------------------------------------------------------------
74 * Preprocessor Definitions and Constants
75 * -------------------------------------------------------------------------*/
76#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
77#define VALIDITY_BITMAP_SIZE 32
78#define MAX_COUNTRY_COUNT 300
79//To be removed when NV support is fully functional
80#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070081
82#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
83
Jeff Johnson295189b2012-06-20 16:38:30 -070084/*----------------------------------------------------------------------------
85 * Type Declarations
86 * -------------------------------------------------------------------------*/
87// this wrapper structure is identical to nv_cmd_type except the
88// data_ptr type is changed void* to avoid exceeding the debug information
89// module size as there are too many elements within nv_items_type union
90
91// structure for code and regulatory domain of a single country
92typedef struct
93{
94 v_U8_t regDomain;
95 v_COUNTRYCODE_t countryCode;
96} CountryInfo_t;
97// structure of table to map country code and regulatory domain
98typedef struct
99{
100 v_U16_t countryCount;
101 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
102} CountryInfoTable_t;
103/*----------------------------------------------------------------------------
104 * Global Data Definitions
105 * -------------------------------------------------------------------------*/
106/*----------------------------------------------------------------------------
107 * Static Variable Definitions
108 * -------------------------------------------------------------------------*/
109// cache of country info table;
110// this is re-initialized from data on binary file
111// loaded on driver initialization if available
112static CountryInfoTable_t countryInfoTable =
113{
114 254,
115 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700116 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
117 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
118 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
119 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
120 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
121 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700122 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700123 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
124 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
125 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
126 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
127 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
128 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
129 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
130 { REGDOMAIN_APAC, {'A', 'U'}}, //AUSTRALIA
131 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
132 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
133 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
134 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
135 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
136 { REGDOMAIN_NO_5GHZ, {'B', 'D'}}, //BANGLADESH
137 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
138 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
139 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
140 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
141 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
142 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
143 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
144 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
145 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
146 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
147 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
148 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
149 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
150 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
151 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
152 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
153 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
154 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
155 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
156 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
157 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
158 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
159 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
160 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
161 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
162 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530163 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700164 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
165 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
166 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
167 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
168 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
169 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
170 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
171 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
172 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
173 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
174 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
175 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700176 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700177 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
178 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
179 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
180 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
181 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
182 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
183 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
184 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
185 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
186 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
187 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
188 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
189 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
190 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
191 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
192 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
193 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
194 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
195 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
196 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
197 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
198 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
199 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
200 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
201 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
202 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
203 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
204 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
205 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
206 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700207 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700208 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
209 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
210 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
211 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
212 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
213 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
214 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
215 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
216 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
217 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700218 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700219 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
220 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
221 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
222 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
223 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
224 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
225 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
226 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
227 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
228 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
229 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
230 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
231 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
232 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700233 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700234 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
235 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
236 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
237 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
238 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
239 { REGDOMAIN_HI_5GHZ, {'K', 'E'}}, //KENYA
240 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
241 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
242 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
243 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
244 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
245 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
246 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
247 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
248 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700249 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700250 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
251 { REGDOMAIN_HI_5GHZ, {'L', 'B'}}, //LEBANON
252 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
253 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
254 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
255 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
256 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
257 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
258 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
259 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
260 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700261 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700262 { REGDOMAIN_N_AMER_EXC_FCC, {'M', 'C'}}, //MONACO
263 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
264 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
265 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
266 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
267 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
268 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
269 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
270 { REGDOMAIN_NO_5GHZ, {'M', 'N'}}, //MONGOLIA
271 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
272 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
273 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
274 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
275 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
276 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
277 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
278 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
279 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
280 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
281 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
282 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
283 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
284 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
285 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
286 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
287 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
288 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
289 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
290 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700291 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700292 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
293 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
294 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
295 { REGDOMAIN_WORLD, {'O', 'M'}}, //OMAN
296 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700297 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700298 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
299 { REGDOMAIN_APAC, {'P', 'G'}}, //PAPUA NEW GUINEA
300 { REGDOMAIN_HI_5GHZ, {'P', 'H'}}, //PHILIPPINES
301 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
302 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
303 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
304 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
305 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
306 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
307 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
308 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
309 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
310 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
311 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
312 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
313 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700314 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
315 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
316 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700317 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
318 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
319 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
320 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
321 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
322 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
323 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
324 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
325 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
326 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
327 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
328 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
329 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
330 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
331 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
332 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
333 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
334 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
335 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
336 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
337 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
338 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
339 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
340 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
341 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
342 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
343 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
344 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
345 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
346 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'R'}}, //TURKEY
347 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
348 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700349 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700350 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700351 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
352 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700353 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
354 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700355 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700356 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
357 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
358 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
359 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
360 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
361 { REGDOMAIN_N_AMER_EXC_FCC, {'V', 'N'}}, //VIET NAM
362 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
363 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
364 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
365 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
366 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
367 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
368 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700369 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 }
371};
372typedef struct nvEFSTable_s
373{
374 v_U32_t nvValidityBitmap;
375 sHalNv halnv;
376} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377nvEFSTable_t *gnvEFSTable;
Jeff Johnson295189b2012-06-20 16:38:30 -0700378/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700379static nvEFSTable_t *pnvEFSTable;
Jeff Johnson295189b2012-06-20 16:38:30 -0700380
381const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
382{
383 //RF_SUBBAND_2_4_GHZ
384 //freq, chan#, band
385 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
386 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
387 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
388 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
389 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
390 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
391 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
392 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
393 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
394 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
395 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
396 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
397 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
398 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700399 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
400 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
401 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
402 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
403 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
404 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
405 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
407 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
408 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
409 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
410 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
411 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
412 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
413 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
414 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
415 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
416 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
417 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
418 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
419 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
420 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
421 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
422 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
423 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
424 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
425 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
426 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
427 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
428 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
429 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700430 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
431 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
432 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
433 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
434 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
435 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
436 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
437 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
438 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
439 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
440 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
441 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
442 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
443 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
444 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
445 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
446 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
447 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
448 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
449 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
450 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
451 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
452 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
453 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
454 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
455 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
456 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
457 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
458 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
459 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
460 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
461 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
462 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
463 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
464 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467extern const sHalNv nvDefaults;
468
469const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
470
471/*----------------------------------------------------------------------------
472 Function Definitions and Documentation
473 * -------------------------------------------------------------------------*/
474VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
475/**------------------------------------------------------------------------
476 \brief vos_nv_init() - initialize the NV module
477 The \a vos_nv_init() initializes the NV module. This read the binary
478 file for country code and regulatory domain information.
479 \return VOS_STATUS_SUCCESS - module is initialized successfully
480 otherwise - module is not initialized
481 \sa
482 -------------------------------------------------------------------------*/
483VOS_STATUS vos_nv_init(void)
484{
485 return VOS_STATUS_SUCCESS;
486}
487
488VOS_STATUS vos_nv_open(void)
489{
490 VOS_STATUS status = VOS_STATUS_SUCCESS;
491 v_CONTEXT_t pVosContext= NULL;
492 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700493 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700494 v_BOOL_t itemIsValid = VOS_FALSE;
495
496 /*Get the global context */
497 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800498
499 if(pVosContext == NULL)
500 {
501 return (eHAL_STATUS_FAILURE);
502 }
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504 bufSize = sizeof(nvEFSTable_t);
505 status = hdd_request_firmware(WLAN_NV_FILE,
506 ((VosContextType*)(pVosContext))->pHDDContext,
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700507 (v_VOID_t**)&gnvEFSTable, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700508
509 if ( (!VOS_IS_STATUS_SUCCESS( status )) || !gnvEFSTable)
510 {
511 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
512 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700513 __func__, WLAN_NV_FILE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 return VOS_STATUS_E_RESOURCES;
515 }
516
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800517 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
518 "INFO: NV binary file version=%d Driver default NV version=%d, continue...\n",
519 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
520
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 /* Copying the read nv data to the globa NV EFS table */
522 {
523 /* Allocate memory to global NV table */
524 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
525 if (NULL == pnvEFSTable)
526 {
527 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700528 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 return VOS_STATUS_E_NOMEM;
530 }
531
532 /*Copying the NV defaults */
533 vos_mem_copy(&(pnvEFSTable->halnv),&nvDefaults,sizeof(sHalNv));
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800534
535 /* Size mismatch */
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700536 if ( nvReadBufSize != bufSize)
537 {
538 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
539 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
540 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
541 nvReadBufSize, bufSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800542 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700543 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800545 /* Version mismatch */
546 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
547 {
548 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
549 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
550 {
551 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
552 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
553 "Make sure that this is intented or may impact performance!!!\n");
554 }
555 else
556 {
557 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
558 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
559 "Driver NV defaults will be used, may impact performance!!!\n");
560
561 return VOS_STATUS_SUCCESS;
562 }
563 }
564
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700565 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Jeff Johnson295189b2012-06-20 16:38:30 -0700566 /* Copy the valid fields to the NV Global structure */
567 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
568 VOS_STATUS_SUCCESS)
569 {
570 if (itemIsValid == VOS_TRUE) {
571
572 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
573 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800574 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700575 }
576 }
577
578 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
579 VOS_STATUS_SUCCESS)
580 {
581 if (itemIsValid == VOS_TRUE)
582 {
583 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
584 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
585 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800586 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700587 }
588 }
589
590 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
591 VOS_STATUS_SUCCESS)
592 {
593
594 if (itemIsValid == VOS_TRUE)
595 {
596 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
597 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
598 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800599 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 }
601 }
602
603 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
604 VOS_STATUS_SUCCESS)
605 {
606 if (itemIsValid == VOS_TRUE)
607 {
608 if(vos_nv_read( VNV_DEFAULT_LOCATION,
609 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
610 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800611 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 }
613 }
614
615 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
616 VOS_STATUS_SUCCESS)
617 {
618 if (itemIsValid == VOS_TRUE)
619 {
620 if(vos_nv_read( VNV_TPC_POWER_TABLE,
621 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
622 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800623 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 }
625 }
626
627 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
628 VOS_STATUS_SUCCESS)
629 {
630 if (itemIsValid == VOS_TRUE)
631 {
632 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
633 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
634 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800635 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 }
637 }
638 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
639 VOS_STATUS_SUCCESS)
640 {
641 if (itemIsValid == VOS_TRUE)
642 {
643 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
644 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
645 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800646 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700647 }
648 }
649
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800650 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700651 VOS_STATUS_SUCCESS)
652 {
653 if (itemIsValid == VOS_TRUE)
654 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800655 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
656 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
657 goto error;
658 }
659 }
660
661 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
662 VOS_STATUS_SUCCESS)
663 {
664 if (itemIsValid == VOS_TRUE)
665 {
666 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
667 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800668 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700669 }
670 }
671
672 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
673 VOS_STATUS_SUCCESS)
674 {
675 if (itemIsValid == VOS_TRUE)
676 {
677 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
678 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
679 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800680 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700681 }
682 }
683 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
684 VOS_STATUS_SUCCESS)
685 {
686 if (itemIsValid == VOS_TRUE)
687 {
688 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
689 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
690 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800691 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 }
694
695 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
696 VOS_STATUS_SUCCESS)
697 {
698 if (itemIsValid == VOS_TRUE)
699 {
700 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
701 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
702 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800703 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 }
705 }
706
707 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
708 VOS_STATUS_SUCCESS)
709 {
710 if (itemIsValid == VOS_TRUE)
711 {
712 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
713 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
714 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800715 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 }
717 }
718 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
719 VOS_STATUS_SUCCESS)
720 {
721 if (itemIsValid == VOS_TRUE)
722 {
723 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
724 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
725 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800726 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700727 }
728 }
729 }
730
731 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800732error:
733 vos_mem_free(pnvEFSTable);
734 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700735}
736
737VOS_STATUS vos_nv_close(void)
738{
739 VOS_STATUS status = VOS_STATUS_SUCCESS;
740 v_CONTEXT_t pVosContext= NULL;
741 /*Get the global context */
742 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
743 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
744 if ( !VOS_IS_STATUS_SUCCESS( status ))
745 {
746 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
747 "%s : vos_open failed\n",__func__);
748 return VOS_STATUS_E_FAILURE;
749 }
750 vos_mem_free(pnvEFSTable);
751 gnvEFSTable=NULL;
752 return VOS_STATUS_SUCCESS;
753}
754/**------------------------------------------------------------------------
755 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
756 a country given its country code
757 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
758 a country given its country code. This is done from reading a cached
759 copy of the binary file.
760 \param pRegDomain - pointer to regulatory domain
761 \param countryCode - country code
762 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
763 VOS_STATUS_E_FAULT - invalid pointer error
764 VOS_STATUS_E_EMPTY - country code table is empty
765 VOS_STATUS_E_EXISTS - given country code does not exist in table
766 \sa
767 -------------------------------------------------------------------------*/
768VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
769 const v_COUNTRYCODE_t countryCode )
770{
771 int i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700772 v_CONTEXT_t pVosContext = NULL;
773 hdd_context_t *pHddCtx = NULL;
774 struct wiphy *wiphy = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700775 // sanity checks
776 if (NULL == pRegDomain)
777 {
778 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
779 ("Invalid reg domain pointer\r\n") );
780 return VOS_STATUS_E_FAULT;
781 }
782 *pRegDomain = REGDOMAIN_COUNT;
783
784 if (NULL == countryCode)
785 {
786 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
787 ("Country code array is NULL\r\n") );
788 return VOS_STATUS_E_FAULT;
789 }
790 if (0 == countryInfoTable.countryCount)
791 {
792 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
793 ("Reg domain table is empty\r\n") );
794 return VOS_STATUS_E_EMPTY;
795 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700796 /* If CRDA regulatory settings is valid, i.e. crda is enabled
797 and reg_notifier is called back.
798 Intercept here and redirect to the Reg domain table's CRDA
799 entry if country code is crda's country.
800 last one NUM_REG_DOMAINS-1 is reserved for crda */
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800801 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700802 "vos_nv_getRegDomainFromCountryCode %c%c\n",
803 countryCode[0], countryCode[1]);
804
805 if (crda_regulatory_entry_valid == VOS_TRUE)
806 {
807 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
808 {
809 *pRegDomain = NUM_REG_DOMAINS-1;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800810 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700811 "vos_nv_getRegDomainFromCountryCode return crda init entry\n");
812 return VOS_STATUS_SUCCESS;
813 }
814 if (run_time_alpha2[0]==countryCode[0] &&
815 run_time_alpha2[1]==countryCode[1] &&
816 crda_regulatory_run_time_entry_valid == VOS_TRUE)
817 {
818 *pRegDomain = NUM_REG_DOMAINS-2;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800819 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700820 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry\n");
821 return VOS_STATUS_SUCCESS;
822 }
823 else
824 {
825 crda_regulatory_run_time_entry_valid = VOS_FALSE;
826 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
827 if (NULL != pVosContext)
828 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
829 else
830 return VOS_STATUS_E_EXISTS;
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700831 if (NULL == pHddCtx)
832 {
833 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
834 ("Invalid pHddCtx pointer\r\n") );
835 return VOS_STATUS_E_FAULT;
836 }
837
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700838 wiphy = pHddCtx->wiphy;
839 init_completion(&pHddCtx->driver_crda_req);
840 regulatory_hint(wiphy, countryCode);
841 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
842 CRDA_WAIT_TIME);
843 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
844 {
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800845 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700846 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry\n");
847 return VOS_STATUS_SUCCESS;
848 }
849 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
850 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry\n");
851 return VOS_STATUS_E_EXISTS;
852 }
853 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700854
Jeff Johnson295189b2012-06-20 16:38:30 -0700855 // iterate the country info table until end of table or the country code
856 // is found
857 for (i = 0; i < countryInfoTable.countryCount &&
858 REGDOMAIN_COUNT == *pRegDomain; i++)
859 {
860 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
861 VOS_COUNTRY_CODE_LEN) == 0)
862 {
863 // country code is found
864 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
865 }
866 }
867 if (REGDOMAIN_COUNT != *pRegDomain)
868 {
869 return VOS_STATUS_SUCCESS;
870 }
871 else
872 {
873 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
874 ("country code is not found\r\n"));
875 return VOS_STATUS_E_EXISTS;
876 }
877}
878/**------------------------------------------------------------------------
879 \brief vos_nv_getSupportedCountryCode() - get the list of supported
880 country codes
881 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
882 country codes with paddings in the provided buffer
883 \param pBuffer - pointer to buffer where supported country codes
884 and paddings are encoded; this may be set to NULL
885 if user wishes to query the required buffer size to
886 get the country code list
887 \param pBufferSize - this is the provided buffer size on input;
888 this is the required or consumed buffer size on output
889 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
890 VOS_STATUS_E_NOMEM - country codes are not encoded because either
891 the buffer is NULL or buffer size is
892 sufficient
893 \sa
894 -------------------------------------------------------------------------*/
895VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
896 v_SIZE_t paddingSize )
897{
898 v_SIZE_t providedBufferSize = *pBufferSize;
899 int i;
900 // pBufferSize now points to the required buffer size
901 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
902 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
903 {
904 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
905 ("Insufficient memory for country code list\r\n"));
906 return VOS_STATUS_E_NOMEM;
907 }
908 for (i = 0; i < countryInfoTable.countryCount; i++)
909 {
910 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
911 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
912 }
913 return VOS_STATUS_SUCCESS;
914}
915/**------------------------------------------------------------------------
916 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
917 \param pTxAntennaCount - antenna count
918 \return status of the NV read operation
919 \sa
920 -------------------------------------------------------------------------*/
921VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
922{
923 sNvFields fieldImage;
924 VOS_STATUS status;
925 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
926 sizeof(fieldImage) );
927 if (VOS_STATUS_SUCCESS == status)
928 {
929 *pTxAntennaCount = fieldImage.numOfTxChains;
930 }
931 return status;
932}
933/**------------------------------------------------------------------------
934 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
935 \param pRxAntennaCount - antenna count
936 \return status of the NV read operation
937 \sa
938 -------------------------------------------------------------------------*/
939VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
940{
941 sNvFields fieldImage;
942 VOS_STATUS status;
943 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
944 sizeof(fieldImage) );
945 if (VOS_STATUS_SUCCESS == status)
946 {
947 *pRxAntennaCount = fieldImage.numOfRxChains;
948 }
949 return status;
950}
951
952/**------------------------------------------------------------------------
953 \brief vos_nv_readMacAddress() - return the MAC address
954 \param pMacAddress - MAC address
955 \return status of the NV read operation
956 \sa
957 -------------------------------------------------------------------------*/
958VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
959{
960 sNvFields fieldImage;
961 VOS_STATUS status;
962 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
963 sizeof(fieldImage) );
964 if (VOS_STATUS_SUCCESS == status)
965 {
966 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
967 }
968 else
969 {
970 //This part of the code can be removed when NV is programmed
971 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
972 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
973 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
974 " fail to get MAC address from NV, hardcoded to %02X-%02X-%02X-%02X-%02X%02X",
975 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
976 status = VOS_STATUS_SUCCESS;
977 }
978 return status;
979}
980
981/**------------------------------------------------------------------------
982
983 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
984
985 \param pMacAddress - MAC address
986 \param macCount - Count of valid MAC addresses to get from NV field
987
988 \return status of the NV read operation
989
990 \sa
991
992 -------------------------------------------------------------------------*/
993VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
994 v_U8_t macCount )
995{
996 sNvFields fieldImage;
997 VOS_STATUS status;
998 v_U8_t countLoop;
999 v_U8_t *pNVMacAddress;
1000
1001 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1002 (NULL == pMacAddress))
1003 {
1004 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301005 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 macCount, pMacAddress);
1007 }
1008
1009 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1010 sizeof(fieldImage) );
1011 if (VOS_STATUS_SUCCESS == status)
1012 {
1013 pNVMacAddress = fieldImage.macAddr;
1014 for(countLoop = 0; countLoop < macCount; countLoop++)
1015 {
1016 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1017 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1018 VOS_MAC_ADDRESS_LEN);
1019 }
1020 }
1021 else
1022 {
1023 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1024 "vos_nv_readMultiMacAddress Get NV Field Fail");
1025 }
1026
1027 return status;
1028}
1029
1030/**------------------------------------------------------------------------
1031 \brief vos_nv_setValidity() - set the validity of an NV item.
1032 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1033 validity information is stored in NV memory.
1034 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1035 An item becomes valid when one has written to it successfully.
1036 \param type - NV item type
1037 \param itemIsValid - boolean value indicating the item's validity
1038 \return VOS_STATUS_SUCCESS - validity is set successfully
1039 VOS_STATUS_E_INVAL - one of the parameters is invalid
1040 VOS_STATUS_E_FAILURE - unknown error
1041 \sa
1042 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
1044VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1045{
1046 v_U32_t lastNvValidityBitmap;
1047 v_U32_t newNvValidityBitmap;
1048 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001049
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001051 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 {
1053 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001054 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 return VOS_STATUS_E_INVAL;
1056 }
1057 // read the validity bitmap
1058 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1059 // modify the validity bitmap
1060 if (itemIsValid)
1061 {
1062 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1063 // commit to NV store if bitmap has been modified
1064 if (newNvValidityBitmap != lastNvValidityBitmap)
1065 {
1066 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1067 }
1068 }
1069 else
1070 {
1071 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1072 if (newNvValidityBitmap != lastNvValidityBitmap)
1073 {
1074 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1075 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1076 if (! VOS_IS_STATUS_SUCCESS(status)) {
1077 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1078 status = VOS_STATUS_E_FAULT;
1079 }
1080 }
1081 }
1082
1083 return status;
1084}
Jeff Johnson295189b2012-06-20 16:38:30 -07001085/**------------------------------------------------------------------------
1086 \brief vos_nv_getValidity() - get the validity of an NV item.
1087 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1088 validity information is stored in NV memory.
1089 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1090 An item becomes valid when one has written to it successfully.
1091 \param type - NV item type
1092 \param pItemIsValid- pointer to the boolean value indicating the item's
1093 validity
1094 \return VOS_STATUS_SUCCESS - validity is determined successfully
1095 VOS_STATUS_E_INVAL - one of the parameters is invalid
1096 VOS_STATUS_E_FAILURE - unknown error
1097 \sa
1098 -------------------------------------------------------------------------*/
1099VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1100{
1101 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1102 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001103 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 {
1105 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001106 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 return VOS_STATUS_E_INVAL;
1108 }
1109 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1110 return VOS_STATUS_SUCCESS;
1111}
1112/**------------------------------------------------------------------------
1113 \brief vos_nv_read() - read a NV item to an output buffer
1114 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1115 an array, this function would read the entire array. One would get a
1116 VOS_STATUS_E_EXISTS error when reading an invalid item.
1117 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1118 if a default buffer is provided (with a non-NULL value),
1119 the default buffer content is copied to the output buffer.
1120 \param type - NV item type
1121 \param outputBuffer - output buffer
1122 \param defaultBuffer - default buffer
1123 \param bufferSize - output buffer size
1124 \return VOS_STATUS_SUCCESS - NV item is read successfully
1125 VOS_STATUS_E_INVAL - one of the parameters is invalid
1126 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1127 VOS_STATUS_E_EXISTS - NV type is unsupported
1128 VOS_STATUS_E_FAILURE - unknown error
1129 \sa
1130 -------------------------------------------------------------------------*/
1131VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1132 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1133{
1134 VOS_STATUS status = VOS_STATUS_SUCCESS;
1135 v_SIZE_t itemSize;
1136 v_BOOL_t itemIsValid = VOS_TRUE;
1137
1138 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001139 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 {
1141 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001142 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001143 return VOS_STATUS_E_INVAL;
1144 }
1145 if (NULL == outputVoidBuffer)
1146 {
1147 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1148 ("Buffer provided is NULL\r\n") );
1149 return VOS_STATUS_E_FAULT;
1150 }
1151 if (0 == bufferSize)
1152 {
1153 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1154 ("NV type=%d is invalid\r\n"), type );
1155 return VOS_STATUS_E_INVAL;
1156 }
1157 // check if the NV item has valid data
1158 status = vos_nv_getValidity( type, &itemIsValid );
1159 if (!itemIsValid)
1160 {
1161 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1162 "NV type=%d does not have valid data\r\n", type );
1163 return VOS_STATUS_E_EMPTY;
1164 }
1165 switch(type)
1166 {
1167 case VNV_FIELD_IMAGE:
1168 itemSize = sizeof(gnvEFSTable->halnv.fields);
1169 if(bufferSize != itemSize) {
1170 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1171 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1172 itemSize);
1173 status = VOS_STATUS_E_INVAL;
1174 }
1175 else {
1176 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1177 }
1178 break;
1179 case VNV_RATE_TO_POWER_TABLE:
1180 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1181 if(bufferSize != itemSize) {
1182 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1183 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1184 itemSize);
1185 status = VOS_STATUS_E_INVAL;
1186 }
1187 else {
1188 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1189 }
1190 break;
1191 case VNV_REGULARTORY_DOMAIN_TABLE:
1192 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1193 if(bufferSize != itemSize) {
1194 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1195 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1196 itemSize);
1197 status = VOS_STATUS_E_INVAL;
1198 }
1199 else {
1200 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1201 }
1202 break;
1203 case VNV_DEFAULT_LOCATION:
1204 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1205 if(bufferSize != itemSize) {
1206 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1207 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1208 itemSize);
1209 status = VOS_STATUS_E_INVAL;
1210 }
1211 else {
1212 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1213 }
1214 break;
1215 case VNV_TPC_POWER_TABLE:
1216 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1217 if(bufferSize != itemSize) {
1218 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1219 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1220 itemSize);
1221 status = VOS_STATUS_E_INVAL;
1222 }
1223 else {
1224 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1225 }
1226 break;
1227 case VNV_TPC_PDADC_OFFSETS:
1228 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1229 if(bufferSize != itemSize) {
1230 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1231 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1232 itemSize);
1233 status = VOS_STATUS_E_INVAL;
1234 }
1235 else {
1236 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1237 }
1238 break;
1239 case VNV_RSSI_CHANNEL_OFFSETS:
1240
1241 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1242
1243 if(bufferSize != itemSize) {
1244
1245 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1246 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1247 itemSize);
1248 status = VOS_STATUS_E_INVAL;
1249 }
1250 else {
1251 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1252 }
1253 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001254 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001255
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001256 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001257
1258 if(bufferSize != itemSize) {
1259
1260 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1261 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1262 itemSize);
1263 status = VOS_STATUS_E_INVAL;
1264 }
1265 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001266 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1267 }
1268 break;
1269 case VNV_FW_CONFIG:
1270
1271 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
1272
1273 if(bufferSize != itemSize) {
1274
1275 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1276 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1277 itemSize);
1278 status = VOS_STATUS_E_INVAL;
1279 }
1280 else {
1281 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 }
1283 break;
1284 case VNV_ANTENNA_PATH_LOSS:
1285 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1286 if(bufferSize != itemSize) {
1287 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1288 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1289 itemSize);
1290 status = VOS_STATUS_E_INVAL;
1291 }
1292 else {
1293 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1294 }
1295 break;
1296 case VNV_PACKET_TYPE_POWER_LIMITS:
1297 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1298 if(bufferSize != itemSize) {
1299 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1300 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1301 itemSize);
1302 status = VOS_STATUS_E_INVAL;
1303 }
1304 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001305 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 }
1307 break;
1308 case VNV_OFDM_CMD_PWR_OFFSET:
1309 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1310 if(bufferSize != itemSize) {
1311 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1312 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1313 itemSize);
1314 status = VOS_STATUS_E_INVAL;
1315 }
1316 else {
1317 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1318 }
1319 break;
1320 case VNV_TX_BB_FILTER_MODE:
1321 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1322 if(bufferSize != itemSize) {
1323 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1324 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1325 itemSize);
1326 status = VOS_STATUS_E_INVAL;
1327 }
1328 else {
1329 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1330 }
1331 break;
1332
Jeff Johnson295189b2012-06-20 16:38:30 -07001333
1334 case VNV_TABLE_VIRTUAL_RATE:
1335 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1336 if(bufferSize != itemSize) {
1337 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1338 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1339 itemSize);
1340 status = VOS_STATUS_E_INVAL;
1341 }
1342 else {
1343 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1344 }
1345 break;
1346
1347 default:
1348 break;
1349 }
1350 return status;
1351}
Jeff Johnson295189b2012-06-20 16:38:30 -07001352
1353/**------------------------------------------------------------------------
1354 \brief vos_nv_write() - write to a NV item from an input buffer
1355 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1356 validate the NV item if the write operation is successful.
1357 \param type - NV item type
1358 \param inputBuffer - input buffer
1359 \param inputBufferSize - input buffer size
1360 \return VOS_STATUS_SUCCESS - NV item is read successfully
1361 VOS_STATUS_E_INVAL - one of the parameters is invalid
1362 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1363 VOS_STATUS_E_EXISTS - NV type is unsupported
1364 VOS_STATUS_E_FAILURE - unknown error
1365 \sa
1366 -------------------------------------------------------------------------*/
1367VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1368 v_SIZE_t bufferSize )
1369{
1370 VOS_STATUS status = VOS_STATUS_SUCCESS;
1371 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001372
1373 // sanity check
1374 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001375 {
1376 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001377 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 return VOS_STATUS_E_INVAL;
1379 }
1380 if (NULL == inputVoidBuffer)
1381 {
1382 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1383 ("Buffer provided is NULL\r\n") );
1384 return VOS_STATUS_E_FAULT;
1385 }
1386 if (0 == bufferSize)
1387 {
1388 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1389 ("NV type=%d is invalid\r\n"), type );
1390 return VOS_STATUS_E_INVAL;
1391 }
1392 switch(type)
1393 {
1394 case VNV_FIELD_IMAGE:
1395 itemSize = sizeof(gnvEFSTable->halnv.fields);
1396 if(bufferSize != itemSize) {
1397 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1398 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1399 itemSize);
1400 status = VOS_STATUS_E_INVAL;
1401 }
1402 else {
1403 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1404 }
1405 break;
1406 case VNV_RATE_TO_POWER_TABLE:
1407 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1408 if(bufferSize != itemSize) {
1409 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1410 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1411 itemSize);
1412 status = VOS_STATUS_E_INVAL;
1413 }
1414 else {
1415 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1416 }
1417 break;
1418 case VNV_REGULARTORY_DOMAIN_TABLE:
1419 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1420 if(bufferSize != itemSize) {
1421 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1422 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1423 itemSize);
1424 status = VOS_STATUS_E_INVAL;
1425 }
1426 else {
1427 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1428 }
1429 break;
1430 case VNV_DEFAULT_LOCATION:
1431 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1432 if(bufferSize != itemSize) {
1433 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1434 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1435 itemSize);
1436 status = VOS_STATUS_E_INVAL;
1437 }
1438 else {
1439 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1440 }
1441 break;
1442 case VNV_TPC_POWER_TABLE:
1443 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1444 if(bufferSize != itemSize) {
1445 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1446 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1447 itemSize);
1448 status = VOS_STATUS_E_INVAL;
1449 }
1450 else {
1451 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1452 }
1453 break;
1454 case VNV_TPC_PDADC_OFFSETS:
1455 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1456 if(bufferSize != itemSize) {
1457 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1458 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1459 itemSize);
1460 status = VOS_STATUS_E_INVAL;
1461 }
1462 else {
1463 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1464 }
1465 break;
1466 case VNV_RSSI_CHANNEL_OFFSETS:
1467
1468 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1469
1470 if(bufferSize != itemSize) {
1471
1472 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1473 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1474 itemSize);
1475 status = VOS_STATUS_E_INVAL;
1476 }
1477 else {
1478 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1479 }
1480 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001481 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001482
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001483 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001484
1485 if(bufferSize != itemSize) {
1486
1487 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1488 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1489 itemSize);
1490 status = VOS_STATUS_E_INVAL;
1491 }
1492 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001493 memcpy(&gnvEFSTable->halnv.tables.hwCalValues,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001494 }
1495 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001496 case VNV_FW_CONFIG:
1497
1498 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
1499
1500 if(bufferSize != itemSize) {
1501
1502 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1503 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1504 itemSize);
1505 status = VOS_STATUS_E_INVAL;
1506 }
1507 else {
1508 memcpy(&gnvEFSTable->halnv.tables.fwConfig,inputVoidBuffer,bufferSize);
1509 }
1510 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 case VNV_ANTENNA_PATH_LOSS:
1512 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1513 if(bufferSize != itemSize) {
1514 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1515 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1516 itemSize);
1517 status = VOS_STATUS_E_INVAL;
1518 }
1519 else {
1520 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1521 }
1522 break;
1523
1524 case VNV_PACKET_TYPE_POWER_LIMITS:
1525 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1526 if(bufferSize != itemSize) {
1527 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1528 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1529 itemSize);
1530 status = VOS_STATUS_E_INVAL;
1531 }
1532 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001533 memcpy(gnvEFSTable->halnv.tables.pktTypePwrLimits,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001534 }
1535 break;
1536
1537 case VNV_OFDM_CMD_PWR_OFFSET:
1538 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1539 if(bufferSize != itemSize) {
1540 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1541 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1542 itemSize);
1543 status = VOS_STATUS_E_INVAL;
1544 }
1545 else {
1546 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1547 }
1548 break;
1549
1550 case VNV_TX_BB_FILTER_MODE:
1551 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1552 if(bufferSize != itemSize) {
1553 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1554 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1555 itemSize);
1556 status = VOS_STATUS_E_INVAL;
1557 }
1558 else {
1559 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1560 }
1561 break;
1562
Jeff Johnson295189b2012-06-20 16:38:30 -07001563
1564 case VNV_TABLE_VIRTUAL_RATE:
1565 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1566 if(bufferSize != itemSize) {
1567 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1568 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1569 itemSize);
1570 status = VOS_STATUS_E_INVAL;
1571 }
1572 else {
1573 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1574 }
1575 break;
1576
1577 default:
1578 break;
1579 }
1580 if (VOS_STATUS_SUCCESS == status)
1581 {
1582 // set NV item to have valid data
1583 status = vos_nv_setValidity( type, VOS_TRUE );
1584 if (! VOS_IS_STATUS_SUCCESS(status)) {
1585 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!\r\n"));
1586 status = VOS_STATUS_E_FAULT;
1587 }
1588 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1589
1590 if (! VOS_IS_STATUS_SUCCESS(status)) {
1591 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1592 status = VOS_STATUS_E_FAULT;
1593 }
1594 }
1595 return status;
1596}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08001597
Jeff Johnson295189b2012-06-20 16:38:30 -07001598/**------------------------------------------------------------------------
1599 \brief vos_nv_getChannelListWithPower() - function to return the list of
1600 supported channels with the power limit info too.
1601 \param pChannels20MHz - list of 20 Mhz channels
1602 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1603 \param pChannels40MHz - list of 20 Mhz channels
1604 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1605 \return status of the NV read operation
1606 \Note: 40Mhz not currently supported
1607 \sa
1608 -------------------------------------------------------------------------*/
1609VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1610 tANI_U8 *num20MHzChannelsFound,
1611 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1612 tANI_U8 *num40MHzChannelsFound
1613 )
1614{
1615 VOS_STATUS status = VOS_STATUS_SUCCESS;
1616 int i, count;
1617
1618 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1619 // or pass it as a parameter to NV from SME?
1620
1621 if( channels20MHz && num20MHzChannelsFound )
1622 {
1623 count = 0;
1624 for( i = 0; i <= RF_CHAN_14; i++ )
1625 {
1626 if( regChannels[i].enabled )
1627 {
1628 channels20MHz[count].chanId = rfChannels[i].channelNum;
1629 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1630 }
1631 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1633 {
1634 if( regChannels[i].enabled )
1635 {
1636 channels20MHz[count].chanId = rfChannels[i].channelNum;
1637 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1638 }
1639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 *num20MHzChannelsFound = (tANI_U8)count;
1641 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001642
1643 if( channels40MHz && num40MHzChannelsFound )
1644 {
1645 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07001646 //center channels for 2.4 Ghz 40 MHz channels
1647 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1648 {
1649
1650 if( regChannels[i].enabled )
1651 {
1652 channels40MHz[count].chanId = rfChannels[i].channelNum;
1653 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1654 }
1655 }
1656 //center channels for 5 Ghz 40 MHz channels
1657 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1658 {
1659
1660 if( regChannels[i].enabled )
1661 {
1662 channels40MHz[count].chanId = rfChannels[i].channelNum;
1663 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1664 }
1665 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001666 *num40MHzChannelsFound = (tANI_U8)count;
1667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 return (status);
1669}
1670
1671/**------------------------------------------------------------------------
1672 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1673 \return default regulatory domain
1674 \sa
1675 -------------------------------------------------------------------------*/
1676
1677v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1678{
1679 return countryInfoTable.countryInfo[0].regDomain;
1680}
1681
1682/**------------------------------------------------------------------------
1683 \brief vos_nv_getSupportedChannels() - function to return the list of
1684 supported channels
1685 \param p20MhzChannels - list of 20 Mhz channels
1686 \param pNum20MhzChannels - number of 20 Mhz channels
1687 \param p40MhzChannels - list of 40 Mhz channels
1688 \param pNum40MhzChannels - number of 40 Mhz channels
1689 \return status of the NV read operation
1690 \Note: 40Mhz not currently supported
1691 \sa
1692 -------------------------------------------------------------------------*/
1693VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1694 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1695{
1696 VOS_STATUS status = VOS_STATUS_E_INVAL;
1697 int i, count = 0;
1698
1699 if( p20MhzChannels && pNum20MhzChannels )
1700 {
1701 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1702 {
1703 for( i = 0; i <= RF_CHAN_14; i++ )
1704 {
1705 p20MhzChannels[count++] = rfChannels[i].channelNum;
1706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001707 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1708 {
1709 p20MhzChannels[count++] = rfChannels[i].channelNum;
1710 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001711 status = VOS_STATUS_SUCCESS;
1712 }
1713 *pNum20MhzChannels = count;
1714 }
1715
1716 return (status);
1717}
1718
1719/**------------------------------------------------------------------------
1720 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1721 \param table data - a union to return the default country table data in.
1722 \return status of the NV read operation
1723 \sa
1724 -------------------------------------------------------------------------*/
1725VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1726{
1727
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001728 VOS_STATUS status = VOS_STATUS_SUCCESS;
1729 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1730 pr_info("DefaultCountry is %c%c\n",
1731 tableData->defaultCountryTable.countryCode[0],
1732 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001733 return status;
1734}
1735
1736/**------------------------------------------------------------------------
1737 \brief vos_nv_getBuffer -
1738 \param pBuffer - to return the buffer address
1739 pSize - buffer size.
1740 \return status of the NV read operation
1741 \sa
1742 -------------------------------------------------------------------------*/
1743VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1744{
1745
1746 /* Send the NV structure and size */
1747 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1748 *pSize = sizeof(sHalNv);
1749
1750 return VOS_STATUS_SUCCESS;
1751}
1752
Jeff Johnson295189b2012-06-20 16:38:30 -07001753/**------------------------------------------------------------------------
1754 \brief vos_nv_setRegDomain -
1755 \param clientCtxt - Client Context, Not used for PRIMA
1756 regId - Regulatory Domain ID
1757 \return status set REG domain operation
1758 \sa
1759 -------------------------------------------------------------------------*/
1760VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
1761{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05301762 v_CONTEXT_t pVosContext = NULL;
1763 hdd_context_t *pHddCtx = NULL;
1764 struct wiphy *wiphy = NULL;
1765 v_U8_t nBandCapability;
1766 int i, j, k, m;
1767
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 /* Client Context Argumant not used for PRIMA */
1769 if(regId >= REGDOMAIN_COUNT)
1770 {
1771 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1772 "VOS set reg domain, invalid REG domain ID %d", regId);
1773 return VOS_STATUS_E_INVAL;
1774 }
1775
1776 /* Set correct channel information based on REG Domain */
1777 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
1778
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05301779 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1780 if (NULL != pVosContext)
1781 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1782 else
1783 return VOS_STATUS_E_EXISTS;
1784
1785 if (NULL == pHddCtx)
1786 return VOS_STATUS_E_EXISTS;
1787
1788 wiphy = pHddCtx->wiphy;
1789 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
1790
1791 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
1792 {
1793
1794 if (NULL == wiphy->bands[i])
1795 {
1796 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1797 "error: wiphy->bands[i] is NULL, i = %d", i);
1798 continue;
1799 }
1800
1801 // internal channels[] is one continous array for both 2G and 5G bands
1802 // m is internal starting channel index for each band
1803 if (0 == i)
1804 m = 0;
1805 else
1806 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
1807
1808 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
1809 {
1810 struct ieee80211_supported_band *band = wiphy->bands[i];
1811
1812 // k = (m + j) is internal current channel index for 20MHz channel
1813 // n is internal channel index for corresponding 40MHz channel
1814 k = m + j;
1815 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
1816 {
1817 // Enable social channels for P2P
1818 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
1819 NV_CHANNEL_ENABLE == regChannels[k].enabled)
1820 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
1821 else
1822 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
1823 continue;
1824 }
1825 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
1826 {
1827 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
1828 continue;
1829 }
1830
1831 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
1832 NV_CHANNEL_INVALID == regChannels[k].enabled)
1833 {
1834 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
1835 }
1836 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
1837 {
1838 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
1839 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
1840 }
1841 else
1842 {
1843 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
1844 |IEEE80211_CHAN_RADAR);
1845 }
1846 }
1847 }
1848
Jeff Johnson295189b2012-06-20 16:38:30 -07001849 return VOS_STATUS_SUCCESS;
1850}
1851
1852/**------------------------------------------------------------------------
1853 \brief vos_nv_getChannelEnabledState -
1854 \param rfChannel - input channel enum to know evabled state
1855 \return eNVChannelEnabledType enabled state for channel
1856 * enabled
1857 * disabled
1858 * DFS
1859 \sa
1860 -------------------------------------------------------------------------*/
1861eNVChannelEnabledType vos_nv_getChannelEnabledState
1862(
1863 v_U32_t rfChannel
1864)
1865{
1866 v_U32_t channelLoop;
1867 eRfChannels channelEnum = INVALID_RF_CHANNEL;
1868
1869 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
1870 {
1871 if(rfChannels[channelLoop].channelNum == rfChannel)
1872 {
1873 channelEnum = (eRfChannels)channelLoop;
1874 break;
1875 }
1876 }
1877
1878 if(INVALID_RF_CHANNEL == channelEnum)
1879 {
1880 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08001881 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 return NV_CHANNEL_INVALID;
1883 }
1884
1885 return regChannels[channelEnum].enabled;
1886}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001887
1888/******************************************************************
1889 Add CRDA regulatory support
1890*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001891
1892static int bw20_ch_index_to_bw40_ch_index(int k)
1893{
1894 int m = -1;
1895 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
1896 {
1897 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
1898 if (m > RF_CHAN_BOND_11)
1899 m = RF_CHAN_BOND_11;
1900 }
1901 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
1902 {
1903 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
1904 if (m > RF_CHAN_BOND_214)
1905 m = RF_CHAN_BOND_214;
1906 }
1907 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
1908 {
1909 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
1910 if (m > RF_CHAN_BOND_62)
1911 m = RF_CHAN_BOND_62;
1912 }
1913 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
1914 {
1915 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
1916 if (m > RF_CHAN_BOND_138)
1917 m = RF_CHAN_BOND_138;
1918 }
1919 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
1920 {
1921 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
1922 if (m > RF_CHAN_BOND_163)
1923 m = RF_CHAN_BOND_163;
1924 }
1925return m;
1926}
1927
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07001928void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
1929{
1930 int k;
1931 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
1932 countryCode[0], countryCode[1], domain_id);
1933 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
1934 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
1935 NV_CHANNEL_ENABLE;
1936 /* Max Tx Power 20dBm */
1937 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
1938 }
1939 /* enable ch 12 to ch 14 passive scan */
1940 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
1941 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
1942 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
1943 NV_CHANNEL_DFS;
1944 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
1945 }
1946 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
1947 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
1948 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
1949 NV_CHANNEL_DFS;
1950 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
1951 }
1952#ifdef PASSIVE_SCAN_4_9GHZ
1953 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
1954 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
1955 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
1956 NV_CHANNEL_DFS;
1957 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
1958 }
1959#endif
1960 if (domain_id == NUM_REG_DOMAINS-1)
1961 { /* init time */
1962 crda_alpha2[0] = countryCode[0];
1963 crda_alpha2[1] = countryCode[1];
1964 crda_regulatory_entry_valid = VOS_TRUE;
1965 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
1966 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
1967 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
1968 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
1969 }
1970 if (domain_id == NUM_REG_DOMAINS-2)
1971 { /* none-default country */
1972 run_time_alpha2[0] = countryCode[0];
1973 run_time_alpha2[1] = countryCode[1];
1974 crda_regulatory_run_time_entry_valid = VOS_TRUE;
1975 }
1976}
1977
1978static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
1979 struct regulatory_request *request,
1980 v_U8_t nBandCapability,
1981 int domain_id)
1982{
1983 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
1984 pr_info("Country 00 special handling to enable passive scan.\n");
1985 crda_regulatory_entry_default(request->alpha2, domain_id);
1986 }
1987 return 0;
1988}
1989
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001990/* create_crda_regulatory_entry should be called from user command or 11d country IE */
1991static int create_crda_regulatory_entry(struct wiphy *wiphy,
1992 struct regulatory_request *request,
1993 v_U8_t nBandCapability)
1994{
1995 int i, j, m;
1996 int k = 0, n = 0;
1997
1998 if (run_time_alpha2[0]==request->alpha2[0] &&
1999 run_time_alpha2[1]==request->alpha2[1] &&
2000 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2001 return 0; /* already created */
2002
2003 /* 20MHz channels */
2004 if (nBandCapability == eCSR_BAND_24)
2005 pr_info("BandCapability is set to 2G only.\n");
2006 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
2007 {
2008 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2009 continue;
2010 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2011 continue;
2012 if (wiphy->bands[i] == NULL)
2013 {
2014 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2015 return -1;
2016 }
2017 // internal channels[] is one continous array for both 2G and 5G bands
2018 // m is internal starting channel index for each band
2019 if (i == 0)
2020 m = 0;
2021 else
2022 m = wiphy->bands[i-1]->n_channels + m;
2023 for (j=0;j<wiphy->bands[i]->n_channels;j++)
2024 {
2025 // k = (m + j) is internal current channel index for 20MHz channel
2026 // n is internal channel index for corresponding 40MHz channel
2027 k = m + j;
2028 n = bw20_ch_index_to_bw40_ch_index(k);
2029 if (n == -1)
2030 return -1;
2031 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2032 {
2033 if (pnvEFSTable == NULL)
2034 {
2035 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2036 return -1;
2037 }
2038 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2039 NV_CHANNEL_DISABLE;
2040 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2041 NV_CHANNEL_DISABLE;
2042 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2043 // rfChannels[n].channelNum);
2044 }
2045 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2046 {
2047 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2048 NV_CHANNEL_DFS;
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002049 // max_power is in mBm = 100 * dBm
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002050 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002051 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002052 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2053 {
2054 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2055 NV_CHANNEL_DFS;
2056 // 40MHz channel power is half of 20MHz (-3dB) ??
2057 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002058 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002059 }
2060 }
2061 else // Enable is only last flag we support
2062 {
2063 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2064 NV_CHANNEL_ENABLE;
2065 // max_power is in dBm
2066 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002067 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002068 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2069 {
2070 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2071 NV_CHANNEL_ENABLE;
2072 // 40MHz channel power is half of 20MHz (-3dB) ??
2073 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002074 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002075 }
2076 }
2077 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2078 real gain which should be provided by the real design */
2079 }
2080 }
2081 if (k == 0)
2082 return -1;
2083 run_time_alpha2[0] = request->alpha2[0];
2084 run_time_alpha2[1] = request->alpha2[1];
2085 crda_regulatory_run_time_entry_valid = VOS_TRUE;
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002086 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002087return 0;
2088}
2089v_BOOL_t is_crda_regulatory_entry_valid(void)
2090{
2091return crda_regulatory_entry_valid;
2092}
2093
2094/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2095start freq + 10000 = center freq of the 20MHz start channel
2096end freq - 10000 = center freq of the 20MHz end channel
2097start freq + 20000 = center freq of the 40MHz start channel
2098end freq - 20000 = center freq of the 40MHz end channel
2099*/
2100static int bw20_start_freq_to_channel_index(u32 freq_khz)
2101{
2102int i;
2103u32 center_freq = freq_khz + 10000;
2104 //Has to compare from low freq to high freq
2105 //RF_SUBBAND_2_4_GHZ
2106 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2107 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2108 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002109 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2110 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2111 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2112 return i;
2113 //RF_SUBBAND_5_LOW_GHZ
2114 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2115 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2116 return i;
2117 //RF_SUBBAND_5_MID_GHZ
2118 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
2119 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2120 return i;
2121 //RF_SUBBAND_5_HIGH_GHZ
2122 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2123 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2124 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002125return -1;
2126}
2127
2128static int bw20_end_freq_to_channel_index(u32 freq_khz)
2129{
2130int i;
2131u32 center_freq = freq_khz - 10000;
2132 //Has to compare from high freq to low freq
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002133 //RF_SUBBAND_5_HIGH_GHZ
2134 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2135 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2136 return i;
2137 //RF_SUBBAND_5_MID_GHZ
2138 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
2139 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2140 return i;
2141 //RF_SUBBAND_5_LOW_GHZ
2142 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2143 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2144 return i;
2145 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2146 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2147 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2148 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002149 //RF_SUBBAND_2_4_GHZ
2150 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2151 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2152 return i;
2153return -1;
2154}
2155
2156static int bw40_start_freq_to_channel_index(u32 freq_khz)
2157{
2158int i;
2159u32 center_freq = freq_khz + 20000;
2160 //Has to compare from low freq to high freq
2161 //RF_SUBBAND_2_4_GHZ
2162 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2163 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2164 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002165 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2166 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2167 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2168 return i;
2169 //RF_SUBBAND_5_LOW_GHZ
2170 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2171 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2172 return i;
2173 //RF_SUBBAND_5_MID_GHZ
2174 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
2175 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2176 return i;
2177 //RF_SUBBAND_5_HIGH_GHZ
2178 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2179 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2180 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002181return -1;
2182}
2183
2184static int bw40_end_freq_to_channel_index(u32 freq_khz)
2185{
2186int i;
2187u32 center_freq = freq_khz - 20000;
2188 //Has to compare from high freq to low freq
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002189 //RF_SUBBAND_5_HIGH_GHZ
2190 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2191 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2192 return i;
2193 //RF_SUBBAND_5_MID_GHZ
2194 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
2195 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2196 return i;
2197 //RF_SUBBAND_5_LOW_GHZ
2198 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2199 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2200 return i;
2201 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2202 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2203 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2204 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002205 //RF_SUBBAND_2_4_GHZ
2206 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2207 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2208 return i;
2209return -1;
2210}
2211
2212static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2213{
2214 switch (nBandCapability)
2215 {
2216 case eCSR_BAND_ALL:
2217 return VOS_TRUE;
2218 case eCSR_BAND_24:
2219 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2220 return VOS_TRUE;
2221 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2222 return VOS_TRUE; // 2.4G 40MHz channel
2223 break;
2224 case eCSR_BAND_5G:
2225 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2226 return VOS_TRUE;
2227 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2228 return VOS_TRUE; // 2.4G 40MHz channel
2229 break;
2230 default:
2231 break;
2232 }
2233 return VOS_FALSE;
2234}
2235
2236/* create_crda_regulatory_entry_from_regd should be called during init time */
2237static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2238 struct regulatory_request *request,
2239 v_U8_t nBandCapability)
2240{
2241 int i, j, n, domain_id;
2242 int bw20_start_channel_index, bw20_end_channel_index;
2243 int bw40_start_channel_index, bw40_end_channel_index;
2244
2245 if (wiphy == NULL || wiphy->regd == NULL)
2246 {
2247 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2248 return -1;
2249 }
2250 if (crda_regulatory_entry_valid == VOS_FALSE)
2251 domain_id = NUM_REG_DOMAINS-1; /* init time */
2252 else
2253 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2254 for (n = 0; n < NUM_RF_CHANNELS; n++)
2255 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2256
2257 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2258 {
2259 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2260 bw20_start_channel_index =
2261 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2262 bw20_end_channel_index =
2263 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2264 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2265 {
2266 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2267 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2268 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2269 continue; // skip this rull, but continue to next rule
2270 }
2271 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2272 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2273 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2274 bw20_start_channel_index, bw20_end_channel_index);
2275 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2276 {
2277 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2278 {
2279 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2280 rfChannels[j].channelNum);
2281 continue; // skip this channel, continue to next
2282 }
2283 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2284 {
2285 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2286 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2287 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2288 }
2289 else
2290 {
2291 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2292 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2293 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2294 }
2295 /* max_eirp is in mBm (= 100 * dBm) unit */
2296 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2297 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2298 }
2299 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2300 real gain which should be provided by the real design */
2301 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2302 {
2303 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2304 bw40_start_channel_index =
2305 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2306 bw40_end_channel_index =
2307 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2308 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2309 {
2310 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2311 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2312 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2313 continue; // skip this rull, but continue to next rule
2314 }
2315 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2316 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2317 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2318 bw40_start_channel_index, bw40_end_channel_index);
2319 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2320 {
2321 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2322 continue; // skip this channel, continue to next
2323 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2324 {
2325 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2326 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2327 }
2328 else
2329 {
2330 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2331 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2332 }
2333 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2334 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2335 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2336 }
2337 }
2338 }
2339 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
2340 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
2341 these flags and has no implementation yet. */
2342 if (crda_regulatory_entry_valid == VOS_FALSE)
2343 { /* init time */
2344 crda_alpha2[0] = request->alpha2[0];
2345 crda_alpha2[1] = request->alpha2[1];
2346 crda_regulatory_entry_valid = VOS_TRUE;
2347 }
2348 else
2349 { /* none-default country */
2350 run_time_alpha2[0] = request->alpha2[0];
2351 run_time_alpha2[1] = request->alpha2[1];
2352 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2353 }
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002354 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002355 return 0;
2356}
2357
2358/*
2359 * Function: wlan_hdd_crda_reg_notifier
2360 * This function is called from cfg80211 core to provide regulatory settings
2361 * after new country is requested or intersected (init, user input or 11d)
2362 * This function is used to create a CRDA regulatory settings entry into internal
2363 * regulatory setting table.
2364 */
2365int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
2366 struct regulatory_request *request)
2367{
2368 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2369 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
2370 " %c%c\n", request->alpha2[0], request->alpha2[1]);
2371 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
2372 {
2373 wiphy_dbg(wiphy, "info: set by user\n");
2374 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
2375 return 0;
2376 // ToDo
2377 /* Don't change default country code to CRDA country code by user req */
2378 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
2379 regd for new country settings */
2380 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2381 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2382 }
2383 else if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
2384 {
2385 wiphy_dbg(wiphy, "info: set by country IE\n");
2386 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
2387 return 0;
2388 // ToDo
2389 /* Intersect of 11d and crda settings */
2390
2391 /* Don't change default country code to CRDA country code by 11d req */
2392 /* for every adapter call sme_ChangeCountryCode to trigger read regd
2393 for intersected new country settings */
2394 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2395 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2396 }
2397 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
2398 {
2399 wiphy_dbg(wiphy, "info: set by driver\n");
2400 /* if set by driver itself, it means driver can accept the crda
2401 regulatory settings and wiphy->regd should be populated with crda
2402 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
2403 correctly, this may be fixed by later kernel */
2404 if (create_crda_regulatory_entry_from_regd(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
2405 {
2406 pr_info("crda entry created.\n");
2407 if (crda_alpha2[0] == request->alpha2[0] && crda_alpha2[1] == request->alpha2[1])
2408 { /* first CRDA request should be from init time */
2409 /* Change default country code to CRDA country code, assume indoor */
2410 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = request->alpha2[0];
2411 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = request->alpha2[1];
2412 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2413 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2414 wiphy_dbg(wiphy, "info: init time default country code is %c%c%c\n",
2415 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
2416 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
2417 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2]);
2418 }
2419 else /* second or later CRDA request after init time */
2420 {
2421 wiphy_dbg(wiphy, "info: crda none-default country code is %c%c\n",
2422 request->alpha2[0], request->alpha2[1]);
2423 }
2424 // hdd will read regd for this country after complete
2425 }
2426 complete(&pHddCtx->driver_crda_req);
2427
2428 /* Haven't seen any condition that will set by driver after init.
2429 If we do, then we should also call sme_ChangeCountryCode */
2430 }
2431return 0;
2432}