blob: 48e8c0ecab435ab30afd4fc645040e435856a5b3 [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"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070066#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070067#include "wlan_hdd_main.h"
68#include <net/cfg80211.h>
Amar Singhalfddc28c2013-09-05 13:03:40 -070069
Amar Singhala49cbc52013-10-08 18:37:44 -070070
Amar Singhalfddc28c2013-09-05 13:03:40 -070071#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhala49cbc52013-10-08 18:37:44 -070072
73static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -070074static char linux_reg_cc[2] = {0, 0};
75static v_BOOL_t linux_regulatory_init = VOS_FALSE;
76static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
Amar Singhala49cbc52013-10-08 18:37:44 -070077
Amar Singhalfddc28c2013-09-05 13:03:40 -070078#endif
79
Amar Singhala49cbc52013-10-08 18:37:44 -070080static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
81static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
82static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
83static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
84
85
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070086
Jeff Johnson295189b2012-06-20 16:38:30 -070087/*----------------------------------------------------------------------------
88 * Preprocessor Definitions and Constants
89 * -------------------------------------------------------------------------*/
90#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
91#define VALIDITY_BITMAP_SIZE 32
92#define MAX_COUNTRY_COUNT 300
93//To be removed when NV support is fully functional
94#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070095
96#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070097#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070098
Jeff Johnson295189b2012-06-20 16:38:30 -070099/*----------------------------------------------------------------------------
100 * Type Declarations
101 * -------------------------------------------------------------------------*/
102// this wrapper structure is identical to nv_cmd_type except the
103// data_ptr type is changed void* to avoid exceeding the debug information
104// module size as there are too many elements within nv_items_type union
105
106// structure for code and regulatory domain of a single country
107typedef struct
108{
109 v_U8_t regDomain;
110 v_COUNTRYCODE_t countryCode;
111} CountryInfo_t;
112// structure of table to map country code and regulatory domain
113typedef struct
114{
115 v_U16_t countryCount;
116 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
117} CountryInfoTable_t;
118/*----------------------------------------------------------------------------
119 * Global Data Definitions
120 * -------------------------------------------------------------------------*/
121/*----------------------------------------------------------------------------
122 * Static Variable Definitions
123 * -------------------------------------------------------------------------*/
Amar Singhala49cbc52013-10-08 18:37:44 -0700124// cache of country info table;
125// this is re-initialized from data on binary file
126// loaded on driver initialization if available
Amar Singhalfddc28c2013-09-05 13:03:40 -0700127
128#ifdef CONFIG_ENABLE_LINUX_REG
129
130static CountryInfoTable_t countryInfoTable =
131{
132 /* the first entry in the table is always the world domain */
133 138,
134 {
135 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
136 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
137 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
138 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
139 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
140 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
141 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
142 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
143 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
144 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
145 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
146 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
147 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
148 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
149 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
150 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
151 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
152 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
153 {REGDOMAIN_ETSI, {'B', 'L'}}, //
154 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
155 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
156 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
157 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
158 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
159 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
160 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
161 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
162 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
163 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
164 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
165 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
166 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
167 {REGDOMAIN_ETSI, {'C', 'S'}},
168 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
169 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
170 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
171 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
172 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
173 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
174 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
175 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
176 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
177 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
178 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
179 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
180 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
181 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
182 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
183 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
184 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
185 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
186 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
187 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
188 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
189 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
190 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
191 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
192 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
193 {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
194 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
195 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
196 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
197 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
198 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
199 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
200 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
201 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
202 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
203 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
204 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
205 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
206 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
207 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
208 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
209 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
210 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
211 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
212 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
213 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
214 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
215 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
216 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
217 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
218 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
219 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
220 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
221 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
222 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
223 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
224 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
225 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
226 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
227 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
228 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
229 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
230 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
231 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
232 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
233 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
234 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
235 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
236 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
237 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
238 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
239 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
240 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
241 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
242 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
243 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
244 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
245 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
246 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
247 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
248 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
249 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
250 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
251 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
252 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
253 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
254 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
255 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
256 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
257 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
258 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
259 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
260 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
261 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
262 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
263 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
264 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
265 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
266 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
267 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
268 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
269 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
270 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
271 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
272 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
273 }
274};
275
276#else
277
Jeff Johnson295189b2012-06-20 16:38:30 -0700278// cache of country info table;
279// this is re-initialized from data on binary file
280// loaded on driver initialization if available
281static CountryInfoTable_t countryInfoTable =
282{
283 254,
284 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700285 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
286 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
287 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
288 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
289 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
290 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700291 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700292 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
293 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
294 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
295 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
296 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
297 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
298 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530299 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700300 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
301 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
302 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
303 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
304 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700305 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700306 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
307 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
308 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
309 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
310 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
311 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
312 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
313 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
314 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
315 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
316 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
317 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
318 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
319 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
320 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
321 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
322 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
323 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
324 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
325 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
326 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
327 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
328 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
329 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
330 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
331 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530332 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700333 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
334 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
335 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
336 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
337 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
338 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
339 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
340 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
341 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
342 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
343 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
344 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700345 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700346 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
347 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
348 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
349 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
350 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
351 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
352 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
353 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
354 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
355 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
356 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
357 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
358 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
359 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
360 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
361 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
362 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
363 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
364 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
365 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
366 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
367 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
368 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
369 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
370 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
371 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
372 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
373 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
374 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
375 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700376 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700377 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
378 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
379 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
380 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
381 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
382 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
383 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
384 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
385 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
386 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700387 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700388 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
389 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
390 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
391 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
392 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
393 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
394 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
395 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
396 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
397 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
398 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
399 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
400 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
401 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700402 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700403 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
404 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
405 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
406 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
407 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700408 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700409 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
410 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
411 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
412 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
413 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
414 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
415 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
416 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
417 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700418 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700419 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700420 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700421 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
422 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
423 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
424 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
425 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
426 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
427 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
428 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
429 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700430 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700431 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700432 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
433 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
434 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
435 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
436 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
437 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
438 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700439 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700440 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
441 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
442 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
443 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
444 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
445 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
446 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
447 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
448 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
449 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
450 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
451 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
452 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
453 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
454 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
455 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
456 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
457 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
458 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
459 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700460 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700461 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
462 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
463 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700464 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700465 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700466 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700467 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700468 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
469 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700470 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
471 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
472 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
473 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
474 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
475 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
476 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
477 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
478 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
479 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
480 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
481 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
482 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700483 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
484 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
485 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700486 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
487 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
488 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
489 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
490 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
491 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
492 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
493 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
494 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
495 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
496 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
497 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
498 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
499 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
500 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
501 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
502 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
503 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
504 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
505 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
506 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
507 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
508 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
509 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
510 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
511 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
512 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
513 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
514 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700515 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700516 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
517 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700518 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700519 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700520 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
521 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700522 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
523 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700524 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700525 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
526 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
527 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
528 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
529 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700530 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700531 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
532 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
533 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
534 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
535 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
536 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
537 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700538 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700539 }
540};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700541
542#endif
543
Amar Singhala49cbc52013-10-08 18:37:44 -0700544
Jeff Johnson295189b2012-06-20 16:38:30 -0700545typedef struct nvEFSTable_s
546{
547 v_U32_t nvValidityBitmap;
548 sHalNv halnv;
549} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700550nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700551/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700552static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700553static v_U8_t *pnvEncodedBuf;
554static v_U8_t *pDictFile;
555static v_U8_t *pEncodedBuf;
556static v_SIZE_t nvReadEncodeBufSize;
557static v_SIZE_t nDictionarySize;
558static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700559
560const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
561{
562 //RF_SUBBAND_2_4_GHZ
563 //freq, chan#, band
564 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
565 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
566 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
567 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
568 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
569 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
570 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
571 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
572 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
573 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
574 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
575 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
576 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
577 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700578 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
579 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
580 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
581 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
582 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
583 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
584 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700585 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
586 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
587 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
588 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
589 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
590 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
591 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
592 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
593 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
594 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
595 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
596 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
597 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
598 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
599 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
600 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
601 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
602 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
603 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
604 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
605 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
606 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
607 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
608 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700609 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
610 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
611 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
612 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
613 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
614 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
615 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
616 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
617 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
618 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
619 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
620 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
621 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
622 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
623 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
624 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
625 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
626 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
627 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
628 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
629 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
630 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
631 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
632 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
633 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
634 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
635 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
636 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
637 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
638 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
639 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
640 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
641 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
642 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
643 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700644};
645
646extern const sHalNv nvDefaults;
647
648const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
649
650/*----------------------------------------------------------------------------
651 Function Definitions and Documentation
652 * -------------------------------------------------------------------------*/
653VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
654/**------------------------------------------------------------------------
655 \brief vos_nv_init() - initialize the NV module
656 The \a vos_nv_init() initializes the NV module. This read the binary
657 file for country code and regulatory domain information.
658 \return VOS_STATUS_SUCCESS - module is initialized successfully
659 otherwise - module is not initialized
660 \sa
661 -------------------------------------------------------------------------*/
662VOS_STATUS vos_nv_init(void)
663{
664 return VOS_STATUS_SUCCESS;
665}
666
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700667/**------------------------------------------------------------------------
668 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
669 \ tools
670 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
671 otherwise - not successful
672 \sa
673-------------------------------------------------------------------------*/
674VOS_STATUS vos_nv_get_dictionary_data(void)
675{
676 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
677
678 if (MAGIC_NUMBER != magicNumber)
679 {
680 return VOS_STATUS_SUCCESS;
681 }
682
683 nDictionarySize = 0;
684
685 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
686 &nDictionarySize );
687 if (VOS_STATUS_E_NOMEM != vosStatus)
688 {
689 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
690 "Error obtaining binary size" );
691/// NOTE:
692/// We can still work without a dictionary file..
693 return VOS_STATUS_SUCCESS;
694 }
695
696 // malloc a buffer to read in the Configuration binary file.
697 pDictFile = vos_mem_malloc( nDictionarySize );
698 if (NULL == pDictFile)
699 {
700 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
701 "Unable to allocate memory for the CFG binary [size= %d bytes]",
702 nDictionarySize );
703 vosStatus = VOS_STATUS_E_NOMEM;
704 goto fail;
705 }
706
707 /* Get the entire CFG file image... */
708 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
709 &nDictionarySize );
710 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
711 {
712 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
713 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
714 nDictionarySize );
715 return VOS_STATUS_SUCCESS;
716 }
717
718 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
719 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
720
721fail:
722 return vosStatus;
723}
724
Jeff Johnson295189b2012-06-20 16:38:30 -0700725VOS_STATUS vos_nv_open(void)
726{
727 VOS_STATUS status = VOS_STATUS_SUCCESS;
728 v_CONTEXT_t pVosContext= NULL;
729 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700730 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700732 v_U32_t dataOffset;
733 sHalNv *pnvData = NULL;
734
Jeff Johnson295189b2012-06-20 16:38:30 -0700735 /*Get the global context */
736 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700737
738 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800739 {
740 return (eHAL_STATUS_FAILURE);
741 }
742
Jeff Johnson295189b2012-06-20 16:38:30 -0700743 bufSize = sizeof(nvEFSTable_t);
744 status = hdd_request_firmware(WLAN_NV_FILE,
745 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700746 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700747
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700748 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700750 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700751 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700752 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700753 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -0700754 }
755
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700756 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
757
758 /// Allocate buffer with maximum length..
759 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
760
761 if (NULL == pEncodedBuf)
762 {
763 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
764 "%s : failed to allocate memory for NV", __func__);
765 return VOS_STATUS_E_NOMEM;
766 }
767
768 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
769
770 if (MAGIC_NUMBER == magicNumber)
771 {
772 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
773
774 if (NULL == pnvData)
775 {
776 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
777 "%s : failed to allocate memory for NV", __func__);
778 return VOS_STATUS_E_NOMEM;
779 }
780
781 memset(pnvData, 0, sizeof(sHalNv));
782
783 /// Data starts from offset of validity bit map + magic number..
784 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
785
786 status = nvParser(&pnvEncodedBuf[dataOffset],
787 (nvReadBufSize-dataOffset), pnvData);
788
789 ///ignore validity bit map
790 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
791
792 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
793 nvReadEncodeBufSize);
794
795 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
796 "readEncodeBufSize %d",nvReadEncodeBufSize);
797
798 if (VOS_STATUS_SUCCESS == status) {
799 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
800 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
801 pnvData->fields.productId,
802 pnvData->fields.couplerType,
803 pnvData->fields.wlanNvRevId);
804
805 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
806
807 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
808 }
809 else
810 {
811 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
812 "nvParser failed %d",status);
813
814 nvReadBufSize = 0;
815
816 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
817
818 nvReadEncodeBufSize = sizeof(sHalNv);
819 }
820 }
821 else
822 {
823 dataOffset = sizeof(v_U32_t);
824 nvReadEncodeBufSize = sizeof(sHalNv);
825 memcpy(pEncodedBuf, &pnvEncodedBuf[dataOffset], nvReadEncodeBufSize);
826 }
827
828 if (NULL != pnvData)
829 {
830 vos_mem_free(pnvData);
831 }
832
833 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800834 "INFO: NV binary file version=%d Driver default NV version=%d, continue...\n",
835 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
836
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 /* Copying the read nv data to the globa NV EFS table */
838 {
839 /* Allocate memory to global NV table */
840 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700841 if ( NULL == pnvEFSTable )
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 {
843 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700844 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700845 return VOS_STATUS_E_NOMEM;
846 }
847
848 /*Copying the NV defaults */
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700849 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800850
851 /* Size mismatch */
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700852 if ( nvReadBufSize != bufSize)
853 {
854 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
855 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
856 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
857 nvReadBufSize, bufSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800858 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700859 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700860
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800861 /* Version mismatch */
862 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
863 {
864 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
865 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
866 {
867 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
868 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
869 "Make sure that this is intented or may impact performance!!!\n");
870 }
871 else
872 {
873 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
874 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
875 "Driver NV defaults will be used, may impact performance!!!\n");
876
877 return VOS_STATUS_SUCCESS;
878 }
879 }
880
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700881 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700882 /* Copy the valid fields to the NV Global structure */
883 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 VOS_STATUS_SUCCESS)
885 {
886 if (itemIsValid == VOS_TRUE) {
887
888 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
889 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800890 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 }
892 }
893
Amar Singhalfddc28c2013-09-05 13:03:40 -0700894 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 VOS_STATUS_SUCCESS)
896 {
897 if (itemIsValid == VOS_TRUE)
898 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700899 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700900 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
901 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800902 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 }
904 }
905
Amar Singhalfddc28c2013-09-05 13:03:40 -0700906 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 VOS_STATUS_SUCCESS)
908 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700909
Jeff Johnson295189b2012-06-20 16:38:30 -0700910 if (itemIsValid == VOS_TRUE)
911 {
912 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
913 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
914 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800915 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 }
917 }
918
Amar Singhalfddc28c2013-09-05 13:03:40 -0700919 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 VOS_STATUS_SUCCESS)
921 {
922 if (itemIsValid == VOS_TRUE)
923 {
924 if(vos_nv_read( VNV_DEFAULT_LOCATION,
925 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
926 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800927 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 }
929 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700930
931 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 VOS_STATUS_SUCCESS)
933 {
934 if (itemIsValid == VOS_TRUE)
935 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700936 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
938 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800939 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 }
941 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700942
943 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 VOS_STATUS_SUCCESS)
945 {
946 if (itemIsValid == VOS_TRUE)
947 {
948 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
949 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
950 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800951 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 }
953 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700954 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 VOS_STATUS_SUCCESS)
956 {
957 if (itemIsValid == VOS_TRUE)
958 {
959 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
960 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
961 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800962 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 }
964 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700965
966 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700967 VOS_STATUS_SUCCESS)
968 {
969 if (itemIsValid == VOS_TRUE)
970 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800971 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
972 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
973 goto error;
974 }
975 }
976
Amar Singhalfddc28c2013-09-05 13:03:40 -0700977 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800978 VOS_STATUS_SUCCESS)
979 {
980 if (itemIsValid == VOS_TRUE)
981 {
982 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
983 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800984 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 }
986 }
987
Amar Singhalfddc28c2013-09-05 13:03:40 -0700988 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 VOS_STATUS_SUCCESS)
990 {
991 if (itemIsValid == VOS_TRUE)
992 {
993 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -0700994 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800996 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 }
998 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700999 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 VOS_STATUS_SUCCESS)
1001 {
1002 if (itemIsValid == VOS_TRUE)
1003 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001004 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1005 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001007 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 }
1009 }
1010
Amar Singhalfddc28c2013-09-05 13:03:40 -07001011 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 VOS_STATUS_SUCCESS)
1013 {
1014 if (itemIsValid == VOS_TRUE)
1015 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001016 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1017 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001019 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 }
1021 }
1022
Amar Singhalfddc28c2013-09-05 13:03:40 -07001023 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 VOS_STATUS_SUCCESS)
1025 {
1026 if (itemIsValid == VOS_TRUE)
1027 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001028 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1029 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001031 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 }
1033 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001034 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 VOS_STATUS_SUCCESS)
1036 {
1037 if (itemIsValid == VOS_TRUE)
1038 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001039 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1040 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001042 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 }
1044 }
1045 }
1046
1047 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001048error:
1049 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001050 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001051 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001052}
1053
1054VOS_STATUS vos_nv_close(void)
1055{
1056 VOS_STATUS status = VOS_STATUS_SUCCESS;
1057 v_CONTEXT_t pVosContext= NULL;
1058 /*Get the global context */
1059 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1060 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1061 if ( !VOS_IS_STATUS_SUCCESS( status ))
1062 {
1063 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1064 "%s : vos_open failed\n",__func__);
1065 return VOS_STATUS_E_FAILURE;
1066 }
1067 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001068 vos_mem_free(pEncodedBuf);
1069 vos_mem_free(pDictFile);
1070
Jeff Johnson295189b2012-06-20 16:38:30 -07001071 gnvEFSTable=NULL;
1072 return VOS_STATUS_SUCCESS;
1073}
Jeff Johnson295189b2012-06-20 16:38:30 -07001074
Jeff Johnson295189b2012-06-20 16:38:30 -07001075/**------------------------------------------------------------------------
1076 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1077 country codes
1078 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1079 country codes with paddings in the provided buffer
1080 \param pBuffer - pointer to buffer where supported country codes
1081 and paddings are encoded; this may be set to NULL
1082 if user wishes to query the required buffer size to
1083 get the country code list
1084 \param pBufferSize - this is the provided buffer size on input;
1085 this is the required or consumed buffer size on output
1086 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1087 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1088 the buffer is NULL or buffer size is
1089 sufficient
1090 \sa
1091 -------------------------------------------------------------------------*/
1092VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1093 v_SIZE_t paddingSize )
1094{
1095 v_SIZE_t providedBufferSize = *pBufferSize;
1096 int i;
1097 // pBufferSize now points to the required buffer size
1098 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1099 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1100 {
1101 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07001102 ("Insufficient memory for country code list\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 return VOS_STATUS_E_NOMEM;
1104 }
1105 for (i = 0; i < countryInfoTable.countryCount; i++)
1106 {
1107 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1108 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1109 }
1110 return VOS_STATUS_SUCCESS;
1111}
1112/**------------------------------------------------------------------------
1113 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1114 \param pTxAntennaCount - antenna count
1115 \return status of the NV read operation
1116 \sa
1117 -------------------------------------------------------------------------*/
1118VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1119{
1120 sNvFields fieldImage;
1121 VOS_STATUS status;
1122 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1123 sizeof(fieldImage) );
1124 if (VOS_STATUS_SUCCESS == status)
1125 {
1126 *pTxAntennaCount = fieldImage.numOfTxChains;
1127 }
1128 return status;
1129}
1130/**------------------------------------------------------------------------
1131 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1132 \param pRxAntennaCount - antenna count
1133 \return status of the NV read operation
1134 \sa
1135 -------------------------------------------------------------------------*/
1136VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1137{
1138 sNvFields fieldImage;
1139 VOS_STATUS status;
1140 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1141 sizeof(fieldImage) );
1142 if (VOS_STATUS_SUCCESS == status)
1143 {
1144 *pRxAntennaCount = fieldImage.numOfRxChains;
1145 }
1146 return status;
1147}
1148
1149/**------------------------------------------------------------------------
1150 \brief vos_nv_readMacAddress() - return the MAC address
1151 \param pMacAddress - MAC address
1152 \return status of the NV read operation
1153 \sa
1154 -------------------------------------------------------------------------*/
1155VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1156{
1157 sNvFields fieldImage;
1158 VOS_STATUS status;
1159 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1160 sizeof(fieldImage) );
1161 if (VOS_STATUS_SUCCESS == status)
1162 {
1163 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1164 }
1165 else
1166 {
1167 //This part of the code can be removed when NV is programmed
1168 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1169 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
1170 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1171 " fail to get MAC address from NV, hardcoded to %02X-%02X-%02X-%02X-%02X%02X",
1172 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
1173 status = VOS_STATUS_SUCCESS;
1174 }
1175 return status;
1176}
1177
1178/**------------------------------------------------------------------------
1179
1180 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1181
1182 \param pMacAddress - MAC address
1183 \param macCount - Count of valid MAC addresses to get from NV field
1184
1185 \return status of the NV read operation
1186
1187 \sa
1188
1189 -------------------------------------------------------------------------*/
1190VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1191 v_U8_t macCount )
1192{
1193 sNvFields fieldImage;
1194 VOS_STATUS status;
1195 v_U8_t countLoop;
1196 v_U8_t *pNVMacAddress;
1197
1198 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1199 (NULL == pMacAddress))
1200 {
1201 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301202 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 macCount, pMacAddress);
1204 }
1205
1206 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1207 sizeof(fieldImage) );
1208 if (VOS_STATUS_SUCCESS == status)
1209 {
1210 pNVMacAddress = fieldImage.macAddr;
1211 for(countLoop = 0; countLoop < macCount; countLoop++)
1212 {
1213 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1214 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1215 VOS_MAC_ADDRESS_LEN);
1216 }
1217 }
1218 else
1219 {
1220 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1221 "vos_nv_readMultiMacAddress Get NV Field Fail");
1222 }
1223
1224 return status;
1225}
1226
1227/**------------------------------------------------------------------------
1228 \brief vos_nv_setValidity() - set the validity of an NV item.
1229 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1230 validity information is stored in NV memory.
1231 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1232 An item becomes valid when one has written to it successfully.
1233 \param type - NV item type
1234 \param itemIsValid - boolean value indicating the item's validity
1235 \return VOS_STATUS_SUCCESS - validity is set successfully
1236 VOS_STATUS_E_INVAL - one of the parameters is invalid
1237 VOS_STATUS_E_FAILURE - unknown error
1238 \sa
1239 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001240
1241VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1242{
1243 v_U32_t lastNvValidityBitmap;
1244 v_U32_t newNvValidityBitmap;
1245 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001246
Jeff Johnson295189b2012-06-20 16:38:30 -07001247 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001248 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 {
1250 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001251 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 return VOS_STATUS_E_INVAL;
1253 }
1254 // read the validity bitmap
1255 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1256 // modify the validity bitmap
1257 if (itemIsValid)
1258 {
1259 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1260 // commit to NV store if bitmap has been modified
1261 if (newNvValidityBitmap != lastNvValidityBitmap)
1262 {
1263 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1264 }
1265 }
1266 else
1267 {
1268 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1269 if (newNvValidityBitmap != lastNvValidityBitmap)
1270 {
1271 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1272 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1273 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhala49cbc52013-10-08 18:37:44 -07001274 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 status = VOS_STATUS_E_FAULT;
1276 }
1277 }
1278 }
1279
1280 return status;
1281}
Jeff Johnson295189b2012-06-20 16:38:30 -07001282/**------------------------------------------------------------------------
1283 \brief vos_nv_getValidity() - get the validity of an NV item.
1284 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1285 validity information is stored in NV memory.
1286 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1287 An item becomes valid when one has written to it successfully.
1288 \param type - NV item type
1289 \param pItemIsValid- pointer to the boolean value indicating the item's
1290 validity
1291 \return VOS_STATUS_SUCCESS - validity is determined successfully
1292 VOS_STATUS_E_INVAL - one of the parameters is invalid
1293 VOS_STATUS_E_FAILURE - unknown error
1294 \sa
1295 -------------------------------------------------------------------------*/
1296VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1297{
1298 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1299 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001300 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 {
1302 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001303 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 return VOS_STATUS_E_INVAL;
1305 }
1306 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1307 return VOS_STATUS_SUCCESS;
1308}
1309/**------------------------------------------------------------------------
1310 \brief vos_nv_read() - read a NV item to an output buffer
1311 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1312 an array, this function would read the entire array. One would get a
1313 VOS_STATUS_E_EXISTS error when reading an invalid item.
1314 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1315 if a default buffer is provided (with a non-NULL value),
1316 the default buffer content is copied to the output buffer.
1317 \param type - NV item type
1318 \param outputBuffer - output buffer
1319 \param defaultBuffer - default buffer
1320 \param bufferSize - output buffer size
1321 \return VOS_STATUS_SUCCESS - NV item is read successfully
1322 VOS_STATUS_E_INVAL - one of the parameters is invalid
1323 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1324 VOS_STATUS_E_EXISTS - NV type is unsupported
1325 VOS_STATUS_E_FAILURE - unknown error
1326 \sa
1327 -------------------------------------------------------------------------*/
1328VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1329 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1330{
1331 VOS_STATUS status = VOS_STATUS_SUCCESS;
1332 v_SIZE_t itemSize;
1333 v_BOOL_t itemIsValid = VOS_TRUE;
1334
Amar Singhala49cbc52013-10-08 18:37:44 -07001335 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001336 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 {
1338 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001339 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001340 return VOS_STATUS_E_INVAL;
1341 }
1342 if (NULL == outputVoidBuffer)
1343 {
1344 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001345 ("Buffer provided is NULL\r\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001346 return VOS_STATUS_E_FAULT;
1347 }
1348 if (0 == bufferSize)
1349 {
1350 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001351 ("NV type=%d is invalid\r\n"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 return VOS_STATUS_E_INVAL;
1353 }
1354 // check if the NV item has valid data
1355 status = vos_nv_getValidity( type, &itemIsValid );
1356 if (!itemIsValid)
1357 {
1358 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Amar Singhala49cbc52013-10-08 18:37:44 -07001359 "NV type=%d does not have valid data\r\n", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 return VOS_STATUS_E_EMPTY;
1361 }
1362 switch(type)
1363 {
1364 case VNV_FIELD_IMAGE:
1365 itemSize = sizeof(gnvEFSTable->halnv.fields);
1366 if(bufferSize != itemSize) {
1367 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001368 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 itemSize);
1370 status = VOS_STATUS_E_INVAL;
1371 }
1372 else {
1373 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1374 }
1375 break;
1376 case VNV_RATE_TO_POWER_TABLE:
1377 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1378 if(bufferSize != itemSize) {
1379 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001380 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001381 itemSize);
1382 status = VOS_STATUS_E_INVAL;
1383 }
1384 else {
1385 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1386 }
1387 break;
1388 case VNV_REGULARTORY_DOMAIN_TABLE:
1389 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1390 if(bufferSize != itemSize) {
1391 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001392 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001393 itemSize);
1394 status = VOS_STATUS_E_INVAL;
1395 }
1396 else {
1397 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1398 }
1399 break;
1400 case VNV_DEFAULT_LOCATION:
1401 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1402 if(bufferSize != itemSize) {
1403 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001404 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 itemSize);
1406 status = VOS_STATUS_E_INVAL;
1407 }
1408 else {
1409 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1410 }
1411 break;
1412 case VNV_TPC_POWER_TABLE:
1413 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1414 if(bufferSize != itemSize) {
1415 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001416 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 itemSize);
1418 status = VOS_STATUS_E_INVAL;
1419 }
1420 else {
1421 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1422 }
1423 break;
1424 case VNV_TPC_PDADC_OFFSETS:
1425 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1426 if(bufferSize != itemSize) {
1427 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001428 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 itemSize);
1430 status = VOS_STATUS_E_INVAL;
1431 }
1432 else {
1433 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1434 }
1435 break;
1436 case VNV_RSSI_CHANNEL_OFFSETS:
1437
1438 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1439
1440 if(bufferSize != itemSize) {
1441
1442 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001443 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 itemSize);
1445 status = VOS_STATUS_E_INVAL;
1446 }
1447 else {
1448 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1449 }
1450 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001451 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001452
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001453 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001454
1455 if(bufferSize != itemSize) {
1456
1457 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001458 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001459 itemSize);
1460 status = VOS_STATUS_E_INVAL;
1461 }
1462 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001463 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1464 }
1465 break;
1466 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001467
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001468 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001469
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001470 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001471
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001472 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001473 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001474 itemSize);
1475 status = VOS_STATUS_E_INVAL;
1476 }
1477 else {
1478 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 }
1480 break;
1481 case VNV_ANTENNA_PATH_LOSS:
1482 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1483 if(bufferSize != itemSize) {
1484 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001485 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 itemSize);
1487 status = VOS_STATUS_E_INVAL;
1488 }
1489 else {
1490 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1491 }
1492 break;
1493 case VNV_PACKET_TYPE_POWER_LIMITS:
1494 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1495 if(bufferSize != itemSize) {
1496 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001497 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001498 itemSize);
1499 status = VOS_STATUS_E_INVAL;
1500 }
1501 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001502 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001503 }
1504 break;
1505 case VNV_OFDM_CMD_PWR_OFFSET:
1506 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1507 if(bufferSize != itemSize) {
1508 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001509 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001510 itemSize);
1511 status = VOS_STATUS_E_INVAL;
1512 }
1513 else {
1514 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1515 }
1516 break;
1517 case VNV_TX_BB_FILTER_MODE:
1518 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1519 if(bufferSize != itemSize) {
1520 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001521 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 itemSize);
1523 status = VOS_STATUS_E_INVAL;
1524 }
1525 else {
1526 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1527 }
1528 break;
1529
Jeff Johnson295189b2012-06-20 16:38:30 -07001530
1531 case VNV_TABLE_VIRTUAL_RATE:
1532 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1533 if(bufferSize != itemSize) {
1534 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001535 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001536 itemSize);
1537 status = VOS_STATUS_E_INVAL;
1538 }
1539 else {
1540 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1541 }
1542 break;
1543
1544 default:
1545 break;
1546 }
1547 return status;
1548}
Jeff Johnson295189b2012-06-20 16:38:30 -07001549
1550/**------------------------------------------------------------------------
1551 \brief vos_nv_write() - write to a NV item from an input buffer
1552 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1553 validate the NV item if the write operation is successful.
1554 \param type - NV item type
1555 \param inputBuffer - input buffer
1556 \param inputBufferSize - input buffer size
1557 \return VOS_STATUS_SUCCESS - NV item is read successfully
1558 VOS_STATUS_E_INVAL - one of the parameters is invalid
1559 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1560 VOS_STATUS_E_EXISTS - NV type is unsupported
1561 VOS_STATUS_E_FAILURE - unknown error
1562 \sa
1563 -------------------------------------------------------------------------*/
1564VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1565 v_SIZE_t bufferSize )
1566{
1567 VOS_STATUS status = VOS_STATUS_SUCCESS;
1568 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001569
Amar Singhala49cbc52013-10-08 18:37:44 -07001570 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001571 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 {
1573 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001574 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 return VOS_STATUS_E_INVAL;
1576 }
1577 if (NULL == inputVoidBuffer)
1578 {
1579 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001580 ("Buffer provided is NULL\r\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 return VOS_STATUS_E_FAULT;
1582 }
1583 if (0 == bufferSize)
1584 {
1585 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001586 ("NV type=%d is invalid\r\n"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001587 return VOS_STATUS_E_INVAL;
1588 }
1589 switch(type)
1590 {
1591 case VNV_FIELD_IMAGE:
1592 itemSize = sizeof(gnvEFSTable->halnv.fields);
1593 if(bufferSize != itemSize) {
1594 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001595 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 itemSize);
1597 status = VOS_STATUS_E_INVAL;
1598 }
1599 else {
1600 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1601 }
1602 break;
1603 case VNV_RATE_TO_POWER_TABLE:
1604 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1605 if(bufferSize != itemSize) {
1606 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001607 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 itemSize);
1609 status = VOS_STATUS_E_INVAL;
1610 }
1611 else {
1612 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1613 }
1614 break;
1615 case VNV_REGULARTORY_DOMAIN_TABLE:
1616 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1617 if(bufferSize != itemSize) {
1618 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001619 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001620 itemSize);
1621 status = VOS_STATUS_E_INVAL;
1622 }
1623 else {
1624 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1625 }
1626 break;
1627 case VNV_DEFAULT_LOCATION:
1628 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1629 if(bufferSize != itemSize) {
1630 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001631 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 itemSize);
1633 status = VOS_STATUS_E_INVAL;
1634 }
1635 else {
1636 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1637 }
1638 break;
1639 case VNV_TPC_POWER_TABLE:
1640 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1641 if(bufferSize != itemSize) {
1642 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001643 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 itemSize);
1645 status = VOS_STATUS_E_INVAL;
1646 }
1647 else {
1648 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1649 }
1650 break;
1651 case VNV_TPC_PDADC_OFFSETS:
1652 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1653 if(bufferSize != itemSize) {
1654 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001655 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 itemSize);
1657 status = VOS_STATUS_E_INVAL;
1658 }
1659 else {
1660 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1661 }
1662 break;
1663 case VNV_RSSI_CHANNEL_OFFSETS:
1664
1665 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1666
1667 if(bufferSize != itemSize) {
1668
1669 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001670 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 itemSize);
1672 status = VOS_STATUS_E_INVAL;
1673 }
1674 else {
1675 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1676 }
1677 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001678 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001679
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001680 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001681
1682 if(bufferSize != itemSize) {
1683
1684 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001685 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001686 itemSize);
1687 status = VOS_STATUS_E_INVAL;
1688 }
1689 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001690 memcpy(&gnvEFSTable->halnv.tables.hwCalValues,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001691 }
1692 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001693 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001694
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001695 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001696
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001697 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001698
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001699 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001700 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001701 itemSize);
1702 status = VOS_STATUS_E_INVAL;
1703 }
1704 else {
1705 memcpy(&gnvEFSTable->halnv.tables.fwConfig,inputVoidBuffer,bufferSize);
1706 }
1707 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001708 case VNV_ANTENNA_PATH_LOSS:
1709 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1710 if(bufferSize != itemSize) {
1711 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001712 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001713 itemSize);
1714 status = VOS_STATUS_E_INVAL;
1715 }
1716 else {
1717 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1718 }
1719 break;
1720
1721 case VNV_PACKET_TYPE_POWER_LIMITS:
1722 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1723 if(bufferSize != itemSize) {
1724 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001725 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001726 itemSize);
1727 status = VOS_STATUS_E_INVAL;
1728 }
1729 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001730 memcpy(gnvEFSTable->halnv.tables.pktTypePwrLimits,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 }
1732 break;
1733
1734 case VNV_OFDM_CMD_PWR_OFFSET:
1735 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1736 if(bufferSize != itemSize) {
1737 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001738 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 itemSize);
1740 status = VOS_STATUS_E_INVAL;
1741 }
1742 else {
1743 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1744 }
1745 break;
1746
1747 case VNV_TX_BB_FILTER_MODE:
1748 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1749 if(bufferSize != itemSize) {
1750 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001751 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001752 itemSize);
1753 status = VOS_STATUS_E_INVAL;
1754 }
1755 else {
1756 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1757 }
1758 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001759
Jeff Johnson295189b2012-06-20 16:38:30 -07001760
1761 case VNV_TABLE_VIRTUAL_RATE:
1762 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1763 if(bufferSize != itemSize) {
1764 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhala49cbc52013-10-08 18:37:44 -07001765 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 itemSize);
1767 status = VOS_STATUS_E_INVAL;
1768 }
1769 else {
1770 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1771 }
1772 break;
1773
1774 default:
1775 break;
1776 }
1777 if (VOS_STATUS_SUCCESS == status)
1778 {
1779 // set NV item to have valid data
1780 status = vos_nv_setValidity( type, VOS_TRUE );
1781 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhala49cbc52013-10-08 18:37:44 -07001782 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!\r\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 status = VOS_STATUS_E_FAULT;
1784 }
1785 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1786
1787 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhala49cbc52013-10-08 18:37:44 -07001788 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 status = VOS_STATUS_E_FAULT;
1790 }
1791 }
1792 return status;
1793}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08001794
Jeff Johnson295189b2012-06-20 16:38:30 -07001795/**------------------------------------------------------------------------
1796 \brief vos_nv_getChannelListWithPower() - function to return the list of
1797 supported channels with the power limit info too.
1798 \param pChannels20MHz - list of 20 Mhz channels
1799 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1800 \param pChannels40MHz - list of 20 Mhz channels
1801 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1802 \return status of the NV read operation
1803 \Note: 40Mhz not currently supported
1804 \sa
1805 -------------------------------------------------------------------------*/
1806VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1807 tANI_U8 *num20MHzChannelsFound,
1808 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1809 tANI_U8 *num40MHzChannelsFound
1810 )
1811{
1812 VOS_STATUS status = VOS_STATUS_SUCCESS;
1813 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001814
Jeff Johnson295189b2012-06-20 16:38:30 -07001815 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1816 // or pass it as a parameter to NV from SME?
1817
1818 if( channels20MHz && num20MHzChannelsFound )
1819 {
1820 count = 0;
1821 for( i = 0; i <= RF_CHAN_14; i++ )
1822 {
1823 if( regChannels[i].enabled )
1824 {
1825 channels20MHz[count].chanId = rfChannels[i].channelNum;
1826 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1827 }
1828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001829 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1830 {
1831 if( regChannels[i].enabled )
1832 {
1833 channels20MHz[count].chanId = rfChannels[i].channelNum;
1834 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1835 }
1836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 *num20MHzChannelsFound = (tANI_U8)count;
1838 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001839
1840 if( channels40MHz && num40MHzChannelsFound )
1841 {
1842 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07001843 //center channels for 2.4 Ghz 40 MHz channels
1844 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1845 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001846
Jeff Johnsone7245742012-09-05 17:12:55 -07001847 if( regChannels[i].enabled )
1848 {
1849 channels40MHz[count].chanId = rfChannels[i].channelNum;
1850 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1851 }
1852 }
1853 //center channels for 5 Ghz 40 MHz channels
1854 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1855 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001856
Jeff Johnsone7245742012-09-05 17:12:55 -07001857 if( regChannels[i].enabled )
1858 {
1859 channels40MHz[count].chanId = rfChannels[i].channelNum;
1860 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1861 }
1862 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001863 *num40MHzChannelsFound = (tANI_U8)count;
1864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001865 return (status);
1866}
1867
1868/**------------------------------------------------------------------------
1869 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1870 \return default regulatory domain
1871 \sa
1872 -------------------------------------------------------------------------*/
1873
1874v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1875{
1876 return countryInfoTable.countryInfo[0].regDomain;
1877}
1878
1879/**------------------------------------------------------------------------
1880 \brief vos_nv_getSupportedChannels() - function to return the list of
1881 supported channels
1882 \param p20MhzChannels - list of 20 Mhz channels
1883 \param pNum20MhzChannels - number of 20 Mhz channels
1884 \param p40MhzChannels - list of 40 Mhz channels
1885 \param pNum40MhzChannels - number of 40 Mhz channels
1886 \return status of the NV read operation
1887 \Note: 40Mhz not currently supported
1888 \sa
1889 -------------------------------------------------------------------------*/
1890VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1891 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1892{
1893 VOS_STATUS status = VOS_STATUS_E_INVAL;
1894 int i, count = 0;
1895
1896 if( p20MhzChannels && pNum20MhzChannels )
1897 {
1898 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1899 {
1900 for( i = 0; i <= RF_CHAN_14; i++ )
1901 {
1902 p20MhzChannels[count++] = rfChannels[i].channelNum;
1903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1905 {
1906 p20MhzChannels[count++] = rfChannels[i].channelNum;
1907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 status = VOS_STATUS_SUCCESS;
1909 }
1910 *pNum20MhzChannels = count;
1911 }
1912
1913 return (status);
1914}
1915
1916/**------------------------------------------------------------------------
1917 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1918 \param table data - a union to return the default country table data in.
1919 \return status of the NV read operation
1920 \sa
1921 -------------------------------------------------------------------------*/
1922VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1923{
Amar Singhalfddc28c2013-09-05 13:03:40 -07001924
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001925 VOS_STATUS status = VOS_STATUS_SUCCESS;
1926 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1927 pr_info("DefaultCountry is %c%c\n",
1928 tableData->defaultCountryTable.countryCode[0],
1929 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001930 return status;
1931}
1932
1933/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07001934 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 \param pBuffer - to return the buffer address
1936 pSize - buffer size.
1937 \return status of the NV read operation
1938 \sa
1939 -------------------------------------------------------------------------*/
1940VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1941{
Jeff Johnson295189b2012-06-20 16:38:30 -07001942 /* Send the NV structure and size */
1943 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1944 *pSize = sizeof(sHalNv);
1945
1946 return VOS_STATUS_SUCCESS;
1947}
1948
Jeff Johnson295189b2012-06-20 16:38:30 -07001949/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001950 \brief vos_nv_getBuffer -
1951 \param pBuffer - to return the buffer address
1952 pSize - buffer size.
1953 \return status of the NV read operation
1954 \sa
1955 -------------------------------------------------------------------------*/
1956VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1957{
1958 /* Send the NV structure and size */
1959 VOS_STATUS status;
1960
1961 status = vos_nv_isEmbeddedNV();
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
1965 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
1966 *pSize = nvReadEncodeBufSize;
1967 }
1968 else
1969 {
1970 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1971 *pSize = sizeof(sHalNv);
1972 }
1973
1974 return VOS_STATUS_SUCCESS;
1975}
1976
1977
1978VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1979{
1980 /* Send the NV structure and size */
1981 *pNvBuffer = (v_VOID_t *)(pDictFile);
1982 *pSize = nDictionarySize;
1983
1984 return VOS_STATUS_SUCCESS;
1985}
1986
1987VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
1988{
1989 if (MAGIC_NUMBER == magicNumber)
1990 {
1991 return VOS_STATUS_SUCCESS;
1992 }
1993
1994 return VOS_STATUS_E_FAILURE;
1995}
1996
1997VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
1998{
1999 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2000 (size-sizeof(v_U32_t)));
2001
2002 return VOS_STATUS_SUCCESS;
2003}
2004
2005/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002006 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 \param rfChannel - input channel enum to know evabled state
2008 \return eNVChannelEnabledType enabled state for channel
2009 * enabled
2010 * disabled
2011 * DFS
2012 \sa
2013 -------------------------------------------------------------------------*/
2014eNVChannelEnabledType vos_nv_getChannelEnabledState
2015(
2016 v_U32_t rfChannel
2017)
2018{
2019 v_U32_t channelLoop;
2020 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2021
2022 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2023 {
2024 if(rfChannels[channelLoop].channelNum == rfChannel)
2025 {
2026 channelEnum = (eRfChannels)channelLoop;
2027 break;
2028 }
2029 }
2030
2031 if(INVALID_RF_CHANNEL == channelEnum)
2032 {
2033 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002034 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 return NV_CHANNEL_INVALID;
2036 }
2037
2038 return regChannels[channelEnum].enabled;
2039}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002040
2041/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002042 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002043*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002044
2045static int bw20_ch_index_to_bw40_ch_index(int k)
2046{
2047 int m = -1;
2048 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2049 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002050 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2051 if (m > RF_CHAN_BOND_11)
2052 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002053 }
2054 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2055 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002056 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2057 if (m > RF_CHAN_BOND_214)
2058 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002059 }
2060 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2061 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002062 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2063 if (m > RF_CHAN_BOND_62)
2064 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002065 }
2066 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
2067 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002068 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
2069 if (m > RF_CHAN_BOND_138)
2070 m = RF_CHAN_BOND_138;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002071 }
2072 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2073 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002074 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2075 if (m > RF_CHAN_BOND_163)
2076 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002077 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002078return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002079}
2080
Amar Singhala49cbc52013-10-08 18:37:44 -07002081void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002082{
Amar Singhala49cbc52013-10-08 18:37:44 -07002083 int k;
2084 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2085 countryCode[0], countryCode[1], domain_id);
2086 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2087 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2088 NV_CHANNEL_ENABLE;
2089 /* Max Tx Power 20dBm */
2090 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2091 }
2092 /* enable ch 12 to ch 14 passive scan */
2093 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2094 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2095 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2096 NV_CHANNEL_DFS;
2097 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2098 }
2099 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2100 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2101 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2102 NV_CHANNEL_DFS;
2103 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2104 }
2105#ifdef PASSIVE_SCAN_4_9GHZ
2106 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2107 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2108 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2109 NV_CHANNEL_DFS;
2110 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2111 }
2112#endif
2113 if (domain_id == NUM_REG_DOMAINS-1)
2114 { /* init time */
2115 crda_alpha2[0] = countryCode[0];
2116 crda_alpha2[1] = countryCode[1];
2117 crda_regulatory_entry_valid = VOS_TRUE;
2118 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2119 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2120 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2121 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2122 }
2123 if (domain_id == NUM_REG_DOMAINS-2)
2124 { /* none-default country */
2125 run_time_alpha2[0] = countryCode[0];
2126 run_time_alpha2[1] = countryCode[1];
2127 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2128 }
2129}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002130
Amar Singhala49cbc52013-10-08 18:37:44 -07002131static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2132 struct regulatory_request *request,
2133 v_U8_t nBandCapability,
2134 int domain_id)
2135{
2136 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2137 pr_info("Country 00 special handling to enable passive scan.\n");
2138 crda_regulatory_entry_default(request->alpha2, domain_id);
2139 }
2140 return 0;
2141}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002142
Amar Singhala49cbc52013-10-08 18:37:44 -07002143/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2144static int create_crda_regulatory_entry(struct wiphy *wiphy,
2145 struct regulatory_request *request,
2146 v_U8_t nBandCapability)
2147{
2148 int i, j, m;
2149 int k = 0, n = 0;
2150
2151 if (run_time_alpha2[0]==request->alpha2[0] &&
2152 run_time_alpha2[1]==request->alpha2[1] &&
2153 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2154 return 0; /* already created */
2155
2156 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002157 if (nBandCapability == eCSR_BAND_24)
2158 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002159 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002160 {
2161 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2162 continue;
2163 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2164 continue;
2165 if (wiphy->bands[i] == NULL)
2166 {
2167 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2168 return -1;
2169 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002170 // internal channels[] is one continous array for both 2G and 5G bands
2171 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002172 if (i == 0)
2173 m = 0;
2174 else
2175 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002176 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002177 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002178 // k = (m + j) is internal current channel index for 20MHz channel
2179 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002180 k = m + j;
2181 n = bw20_ch_index_to_bw40_ch_index(k);
2182 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002183 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002184 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2185 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002186 if (pnvEFSTable == NULL)
2187 {
2188 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2189 return -1;
2190 }
2191 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2192 NV_CHANNEL_DISABLE;
2193 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2194 NV_CHANNEL_DISABLE;
2195 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2196 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002197 }
2198 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2199 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002200 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2201 NV_CHANNEL_DFS;
2202 // max_power is in mBm = 100 * dBm
2203 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2204 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2205 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2206 {
2207 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2208 NV_CHANNEL_DFS;
2209 // 40MHz channel power is half of 20MHz (-3dB) ??
2210 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2211 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2212 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002213 }
2214 else // Enable is only last flag we support
2215 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002216 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2217 NV_CHANNEL_ENABLE;
2218 // max_power is in dBm
2219 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2220 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2221 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2222 {
2223 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2224 NV_CHANNEL_ENABLE;
2225 // 40MHz channel power is half of 20MHz (-3dB) ??
2226 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2227 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2228 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002229 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002230 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2231 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002232 }
2233 }
2234 if (k == 0)
2235 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002236 run_time_alpha2[0] = request->alpha2[0];
2237 run_time_alpha2[1] = request->alpha2[1];
2238 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2239 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2240return 0;
2241}
2242v_BOOL_t is_crda_regulatory_entry_valid(void)
2243{
2244return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002245}
2246
Amar Singhala49cbc52013-10-08 18:37:44 -07002247/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2248start freq + 10000 = center freq of the 20MHz start channel
2249end freq - 10000 = center freq of the 20MHz end channel
2250start freq + 20000 = center freq of the 40MHz start channel
2251end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002252*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002253static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002254{
Amar Singhala49cbc52013-10-08 18:37:44 -07002255int i;
2256u32 center_freq = freq_khz + 10000;
2257 //Has to compare from low freq to high freq
2258 //RF_SUBBAND_2_4_GHZ
2259 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2260 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2261 return i;
2262 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2263 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2264 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2265 return i;
2266 //RF_SUBBAND_5_LOW_GHZ
2267 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2268 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2269 return i;
2270 //RF_SUBBAND_5_MID_GHZ
2271 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
2272 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2273 return i;
2274 //RF_SUBBAND_5_HIGH_GHZ
2275 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2276 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2277 return i;
2278return -1;
2279}
2280
2281static int bw20_end_freq_to_channel_index(u32 freq_khz)
2282{
2283int i;
2284u32 center_freq = freq_khz - 10000;
2285 //Has to compare from high freq to low freq
2286 //RF_SUBBAND_5_HIGH_GHZ
2287 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2288 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2289 return i;
2290 //RF_SUBBAND_5_MID_GHZ
2291 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
2292 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2293 return i;
2294 //RF_SUBBAND_5_LOW_GHZ
2295 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2296 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2297 return i;
2298 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2299 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2300 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2301 return i;
2302 //RF_SUBBAND_2_4_GHZ
2303 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2304 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2305 return i;
2306return -1;
2307}
2308
2309static int bw40_start_freq_to_channel_index(u32 freq_khz)
2310{
2311int i;
2312u32 center_freq = freq_khz + 20000;
2313 //Has to compare from low freq to high freq
2314 //RF_SUBBAND_2_4_GHZ
2315 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2316 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2317 return i;
2318 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2319 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2320 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2321 return i;
2322 //RF_SUBBAND_5_LOW_GHZ
2323 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2324 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2325 return i;
2326 //RF_SUBBAND_5_MID_GHZ
2327 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
2328 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2329 return i;
2330 //RF_SUBBAND_5_HIGH_GHZ
2331 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2332 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2333 return i;
2334return -1;
2335}
2336
2337static int bw40_end_freq_to_channel_index(u32 freq_khz)
2338{
2339int i;
2340u32 center_freq = freq_khz - 20000;
2341 //Has to compare from high freq to low freq
2342 //RF_SUBBAND_5_HIGH_GHZ
2343 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2344 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2345 return i;
2346 //RF_SUBBAND_5_MID_GHZ
2347 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
2348 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2349 return i;
2350 //RF_SUBBAND_5_LOW_GHZ
2351 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2352 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2353 return i;
2354 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2355 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2356 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2357 return i;
2358 //RF_SUBBAND_2_4_GHZ
2359 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2360 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2361 return i;
2362return -1;
2363}
2364
2365static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2366{
2367 switch (nBandCapability)
2368 {
2369 case eCSR_BAND_ALL:
2370 return VOS_TRUE;
2371 case eCSR_BAND_24:
2372 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2373 return VOS_TRUE;
2374 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2375 return VOS_TRUE; // 2.4G 40MHz channel
2376 break;
2377 case eCSR_BAND_5G:
2378 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2379 return VOS_TRUE;
2380 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2381 return VOS_TRUE; // 2.4G 40MHz channel
2382 break;
2383 default:
2384 break;
2385 }
2386 return VOS_FALSE;
2387}
2388
2389/* create_crda_regulatory_entry_from_regd should be called during init time */
2390static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2391 struct regulatory_request *request,
2392 v_U8_t nBandCapability)
2393{
2394 int i, j, n, domain_id;
2395 int bw20_start_channel_index, bw20_end_channel_index;
2396 int bw40_start_channel_index, bw40_end_channel_index;
2397
2398 if (wiphy == NULL || wiphy->regd == NULL)
2399 {
2400 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2401 return -1;
2402 }
2403 if (crda_regulatory_entry_valid == VOS_FALSE)
2404 domain_id = NUM_REG_DOMAINS-1; /* init time */
2405 else
2406 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2407 for (n = 0; n < NUM_RF_CHANNELS; n++)
2408 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2409
2410 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2411 {
2412 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2413 bw20_start_channel_index =
2414 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2415 bw20_end_channel_index =
2416 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2417 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2418 {
2419 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2420 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2421 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2422 continue; // skip this rull, but continue to next rule
2423 }
2424 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2425 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2426 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2427 bw20_start_channel_index, bw20_end_channel_index);
2428 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2429 {
2430 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2431 {
2432 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2433 rfChannels[j].channelNum);
2434 continue; // skip this channel, continue to next
2435 }
2436 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2437 {
2438 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2439 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2440 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2441 }
2442 else
2443 {
2444 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2445 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2446 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2447 }
2448 /* max_eirp is in mBm (= 100 * dBm) unit */
2449 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2450 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2451 }
2452 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2453 real gain which should be provided by the real design */
2454 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2455 {
2456 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2457 bw40_start_channel_index =
2458 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2459 bw40_end_channel_index =
2460 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2461 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2462 {
2463 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2464 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2465 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2466 continue; // skip this rull, but continue to next rule
2467 }
2468 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2469 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2470 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2471 bw40_start_channel_index, bw40_end_channel_index);
2472 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2473 {
2474 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2475 continue; // skip this channel, continue to next
2476 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2477 {
2478 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2479 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2480 }
2481 else
2482 {
2483 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2484 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2485 }
2486 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2487 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2488 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2489 }
2490 }
2491 }
2492 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
2493 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
2494 these flags and has no implementation yet. */
2495 if (crda_regulatory_entry_valid == VOS_FALSE)
2496 { /* init time */
2497 crda_alpha2[0] = request->alpha2[0];
2498 crda_alpha2[1] = request->alpha2[1];
2499 crda_regulatory_entry_valid = VOS_TRUE;
2500 }
2501 else
2502 { /* none-default country */
2503 run_time_alpha2[0] = request->alpha2[0];
2504 run_time_alpha2[1] = request->alpha2[1];
2505 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2506 }
2507 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
2508 return 0;
2509}
2510
2511#ifdef CONFIG_ENABLE_LINUX_REG
2512
2513/**------------------------------------------------------------------------
2514 \brief vos_nv_setRegDomain -
2515 \param clientCtxt - Client Context, Not used for PRIMA
2516 regId - Regulatory Domain ID
2517 \return status set REG domain operation
2518 \sa
2519 -------------------------------------------------------------------------*/
2520VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
2521{
2522
2523 if (regId >= REGDOMAIN_COUNT)
2524 {
2525 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2526 "VOS set reg domain, invalid REG domain ID %d", regId);
2527 return VOS_STATUS_E_INVAL;
2528 }
2529
2530 /* Set correct channel information based on REG Domain */
2531 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
2532
2533 return VOS_STATUS_SUCCESS;
2534}
2535
2536/**------------------------------------------------------------------------
2537 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
2538 a country given its country code
2539 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
2540 a country given its country code. This is done from reading a cached
2541 copy of the binary file.
2542 \param pRegDomain - pointer to regulatory domain
2543 \param countryCode - country code
2544 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
2545 VOS_STATUS_E_FAULT - invalid pointer error
2546 VOS_STATUS_E_EMPTY - country code table is empty
2547 VOS_STATUS_E_EXISTS - given country code does not exist in table
2548 \sa
2549 -------------------------------------------------------------------------*/
2550VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
2551 const v_COUNTRYCODE_t country_code)
2552{
2553
Amar Singhalfddc28c2013-09-05 13:03:40 -07002554 v_CONTEXT_t pVosContext = NULL;
2555 hdd_context_t *pHddCtx = NULL;
2556 struct wiphy *wiphy = NULL;
2557 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07002558 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002559
Amar Singhalfddc28c2013-09-05 13:03:40 -07002560 /* sanity checks */
2561 if (NULL == pRegDomain)
2562 {
2563 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2564 ("Invalid reg domain pointer") );
2565 return VOS_STATUS_E_FAULT;
2566 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002567
Amar Singhalfddc28c2013-09-05 13:03:40 -07002568 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002569
Amar Singhala49cbc52013-10-08 18:37:44 -07002570 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07002571 {
2572 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2573 ("Country code array is NULL"));
2574 return VOS_STATUS_E_FAULT;
2575 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002576
Amar Singhalfddc28c2013-09-05 13:03:40 -07002577 if (0 == countryInfoTable.countryCount)
2578 {
2579 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2580 ("Reg domain table is empty") );
2581 return VOS_STATUS_E_EMPTY;
2582 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002583
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002584
Amar Singhalfddc28c2013-09-05 13:03:40 -07002585 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002586
Amar Singhalfddc28c2013-09-05 13:03:40 -07002587 if (NULL != pVosContext)
2588 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2589 else
2590 return VOS_STATUS_E_EXISTS;
2591
2592 if (NULL == pHddCtx)
2593 {
2594 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2595 ("Invalid pHddCtx pointer") );
2596 return VOS_STATUS_E_FAULT;
2597 }
2598
2599 wiphy = pHddCtx->wiphy;
2600
Amar Singhala49cbc52013-10-08 18:37:44 -07002601 if (false == wiphy->registered)
2602 {
2603 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2604 ("wiphy is not yet registered with the kernel") );
2605 return VOS_STATUS_E_FAULT;
2606 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002607
2608 /* We need to query the kernel to get the regulatory information
2609 for this country */
2610
Amar Singhalfddc28c2013-09-05 13:03:40 -07002611 if (VOS_FALSE == linux_regulatory_init) {
2612
Amar Singhala49cbc52013-10-08 18:37:44 -07002613 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2614 ("init time regdomain request") );
2615
Amar Singhalfddc28c2013-09-05 13:03:40 -07002616 /* linux regulatory has not been initialized yet; so the country
2617 information stored with us would not be correct */
2618
2619 /* lookup the country in the local database */
2620
Amar Singhalfddc28c2013-09-05 13:03:40 -07002621 temp_reg_domain = REGDOMAIN_COUNT;
2622 for (i = 0; i < countryInfoTable.countryCount &&
2623 REGDOMAIN_COUNT == temp_reg_domain; i++)
2624 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002625 if (memcmp(country_code,countryInfoTable.countryInfo[i].countryCode,
Amar Singhalfddc28c2013-09-05 13:03:40 -07002626 VOS_COUNTRY_CODE_LEN) == 0)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002627 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002628 /* country code is found
2629 record the temporary regulatory_domain as well */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002630 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
Amar Singhala49cbc52013-10-08 18:37:44 -07002631 break;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002632 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002633 }
2634
2635 if (REGDOMAIN_COUNT == temp_reg_domain) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002636
Amar Singhala49cbc52013-10-08 18:37:44 -07002637 /* the country was not found in the driver database
2638 therefore return failure to the SME/CSR */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002639
Amar Singhala49cbc52013-10-08 18:37:44 -07002640 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2641 ("init time regdomain request"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002642
Amar Singhalfddc28c2013-09-05 13:03:40 -07002643 return VOS_STATUS_E_EXISTS;
2644 }
2645
2646 else {
Amar Singhala49cbc52013-10-08 18:37:44 -07002647
2648 /* the country code was found in the driver database
2649 now get the regulatory information from the kernel
Amar Singhalfddc28c2013-09-05 13:03:40 -07002650 database */
2651
2652 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2653 ("country code found in driver db"));
2654
Amar Singhala49cbc52013-10-08 18:37:44 -07002655 INIT_COMPLETION(pHddCtx->linux_reg_req);
2656 regulatory_hint(wiphy, country_code);
2657 wait_result = wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2658 LINUX_REG_WAIT_TIME);
Amar Singhalfddc28c2013-09-05 13:03:40 -07002659
2660 /* if the country information does not exist with the kernel, then
2661 the driver callback would not be called */
2662
Amar Singhala49cbc52013-10-08 18:37:44 -07002663 if (0 == wait_result) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002664
2665 /* the driver callback was called. this means the country
2666 regulatory information was found in the kernel database.
2667 The callback would have updated the internal database. Here
2668 update the country and the return value for the regulatory
2669 domain */
2670
Amar Singhalfddc28c2013-09-05 13:03:40 -07002671 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2672 ("country code is found in kernel db"));
2673
Amar Singhala49cbc52013-10-08 18:37:44 -07002674 *pRegDomain = temp_reg_domain;
2675 cur_reg_domain = temp_reg_domain;
2676 linux_reg_cc[0] = country_code[0];
2677 linux_reg_cc[1] = country_code[1];
2678 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
2679 *pRegDomain;
2680
Amar Singhalfddc28c2013-09-05 13:03:40 -07002681 linux_regulatory_init = VOS_TRUE;
2682 return VOS_STATUS_SUCCESS;
2683 }
2684 else {
2685
2686 /* the country information has not been found in the kernel
Amar Singhala49cbc52013-10-08 18:37:44 -07002687 database, return failure */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002688
Amar Singhala49cbc52013-10-08 18:37:44 -07002689 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07002690 ("country code is not found in kernel db"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002691 return VOS_STATUS_E_EXISTS;
2692 }
2693 }
2694 }
2695 else {
Amar Singhala49cbc52013-10-08 18:37:44 -07002696
Amar Singhalfddc28c2013-09-05 13:03:40 -07002697 /* it is not the init time query but a runtime query. So first
2698 compare the country code with the existing current country code
2699 . If both are same there is no need to query any database */
2700
2701 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2702 ("run time regdomain request"));
2703
Amar Singhala49cbc52013-10-08 18:37:44 -07002704 if ((country_code[0] == linux_reg_cc[0]) &&
2705 (country_code[1] == linux_reg_cc[1])) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002706
2707 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002708
2709 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07002710 (" country code already exists"));
2711
2712 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002713
2714 return VOS_STATUS_SUCCESS;
2715 }
2716 else {
2717
2718 /* first lookup the country in the local database */
2719
2720 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07002721 (" new runtime country code"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002722
2723 for (i = 0; i < countryInfoTable.countryCount &&
2724 REGDOMAIN_COUNT == temp_reg_domain; i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002725 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002726 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
2727 VOS_COUNTRY_CODE_LEN) == 0)
Amar Singhalfddc28c2013-09-05 13:03:40 -07002728 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002729 /* country code is found
2730 record the temporary regulatory_domain as well */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002731 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
Amar Singhala49cbc52013-10-08 18:37:44 -07002732 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002733 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002734 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002735
2736 if (REGDOMAIN_COUNT == temp_reg_domain) {
2737
Amar Singhala49cbc52013-10-08 18:37:44 -07002738 /* the country was not found in the driver database
2739 return failure */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002740
2741 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Amar Singhala49cbc52013-10-08 18:37:44 -07002742 ("runtime country code is not found in driver db"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002743
2744 return VOS_STATUS_E_EXISTS;
2745 }
2746
2747 else {
2748
Amar Singhala49cbc52013-10-08 18:37:44 -07002749 /* the country code was found in the driver database
2750 now get the regulatory information from the kernel
Amar Singhalfddc28c2013-09-05 13:03:40 -07002751 database */
2752
2753 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Amar Singhala49cbc52013-10-08 18:37:44 -07002754 ("runtime country code found in driver db"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002755
Amar Singhala49cbc52013-10-08 18:37:44 -07002756 INIT_COMPLETION(pHddCtx->linux_reg_req);
2757 regulatory_hint(wiphy, country_code);
2758 wait_result = wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2759 LINUX_REG_WAIT_TIME);
Amar Singhalfddc28c2013-09-05 13:03:40 -07002760
2761 /* if the country information does not exist with the kernel,
2762 then the driver callback would not be called */
2763
Amar Singhala49cbc52013-10-08 18:37:44 -07002764 if (0 == wait_result) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002765
2766 /* the driver callback was called. this means the country
2767 regulatory information was found in the kernel database.
2768 The callback would have updated the internal database. Here
2769 update the country and the return value for the regulatory
2770 domain */
2771
Amar Singhala49cbc52013-10-08 18:37:44 -07002772 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2773 ("runtime country code is found in kernel db"));
2774
Amar Singhalfddc28c2013-09-05 13:03:40 -07002775 *pRegDomain = temp_reg_domain;
2776 cur_reg_domain = temp_reg_domain;
Amar Singhala49cbc52013-10-08 18:37:44 -07002777 linux_reg_cc[0] = country_code[0];
2778 linux_reg_cc[1] = country_code[1];
Amar Singhalfddc28c2013-09-05 13:03:40 -07002779
2780 return VOS_STATUS_SUCCESS;
2781 }
2782 else {
2783
2784 /* the country information has not been found in the kernel
Amar Singhala49cbc52013-10-08 18:37:44 -07002785 database, return failure */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002786
2787 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Amar Singhala49cbc52013-10-08 18:37:44 -07002788 ("runtime country code is not found in kernel db"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002789
2790 return VOS_STATUS_E_EXISTS;
2791 }
2792 }
2793 }
2794 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002795}
2796
Amar Singhala49cbc52013-10-08 18:37:44 -07002797
2798/* create_crda_regulatory_entry_from_regd should be called during init time */
2799static int create_linux_regulatory_entry_from_regd(struct wiphy *wiphy,
2800 struct regulatory_request *request,
2801 v_U8_t nBandCapability)
2802{
2803 int i, j, n, domain_id;
2804 int bw20_start_channel_index, bw20_end_channel_index;
2805 int bw40_start_channel_index, bw40_end_channel_index;
2806
2807 if (wiphy->regd == NULL)
2808 {
2809 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2810 return -1;
2811 }
2812
2813 domain_id = temp_reg_domain;
2814
2815 for (n = 0; n < NUM_RF_CHANNELS; n++)
2816 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2817
2818 for (i = 0; i < wiphy->regd->n_reg_rules; i++)
2819 {
2820
2821 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2822 bw20_start_channel_index =
2823 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2824 bw20_end_channel_index =
2825 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2826
2827 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2828 {
2829 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2830 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2831 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2832 continue; // skip this rull, but continue to next rule
2833 }
2834
2835 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2836 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2837 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2838 bw20_start_channel_index, bw20_end_channel_index);
2839
2840 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2841 {
2842 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2843 {
2844 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2845 rfChannels[j].channelNum);
2846 continue; // skip this channel, continue to next
2847 }
2848
2849 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2850 {
2851 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2852 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2853 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2854 }
2855 else
2856 {
2857 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2858 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2859 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2860 }
2861
2862 /* max_eirp is in mBm (= 100 * dBm) unit */
2863 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2864 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2865 }
2866
2867 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2868 real gain which should be provided by the real design */
2869 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2870 {
2871 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2872 bw40_start_channel_index =
2873 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2874 bw40_end_channel_index =
2875 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2876 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2877 {
2878 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2879 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2880 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2881 continue; // skip this rull, but continue to next rule
2882 }
2883
2884 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2885 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2886 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2887 bw40_start_channel_index, bw40_end_channel_index);
2888 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2889 {
2890 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2891 continue; // skip this channel, continue to next
2892 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2893 {
2894 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2895 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2896 }
2897 else
2898 {
2899 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2900 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2901 }
2902 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2903 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2904 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2905 }
2906 }
2907 }
2908
2909 return 0;
2910}
2911
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002912/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07002913 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002914 * This function is called from cfg80211 core to provide regulatory settings
2915 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07002916 * This function is used to create a CRDA regulatory settings entry into internal
2917 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002918 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Amar Singhalfddc28c2013-09-05 13:03:40 -07002920void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07002921 struct regulatory_request *request)
2922#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002923int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002924 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07002925#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002926{
2927 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Amar Singhala49cbc52013-10-08 18:37:44 -07002928 tANI_U8 nBandCapability;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002929
Amar Singhala49cbc52013-10-08 18:37:44 -07002930 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2931 ("cfg80211 reg notifier callback for country"));
Amar Singhalfddc28c2013-09-05 13:03:40 -07002932
Arif Hussainec3fbb32013-10-03 11:49:23 -07002933 if (pHddCtx->isLoadUnloadInProgress)
2934 {
2935 wiphy_dbg(wiphy, "info: %s: Unloading/Loading in Progress. Ignore!!!",
2936 __func__);
2937 return;
2938 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002939 /* first check if this callback is in response to the driver callback */
2940
Amar Singhalfddc28c2013-09-05 13:03:40 -07002941
Amar Singhala49cbc52013-10-08 18:37:44 -07002942 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
2943 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002944
Amar Singhala49cbc52013-10-08 18:37:44 -07002945 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002946
Amar Singhala49cbc52013-10-08 18:37:44 -07002947 if (create_linux_regulatory_entry_from_regd(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
2948 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002949
Amar Singhala49cbc52013-10-08 18:37:44 -07002950 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2951 (" regulatory entry created"));
2952 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002953
Amar Singhala49cbc52013-10-08 18:37:44 -07002954 complete(&pHddCtx->linux_reg_req);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002955 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05302956
Amar Singhala49cbc52013-10-08 18:37:44 -07002957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07002958 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07002959#else
2960 return 0;
2961#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002962}
Amar Singhalfddc28c2013-09-05 13:03:40 -07002963
Amar Singhalfddc28c2013-09-05 13:03:40 -07002964#else
2965
2966/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07002967 \brief vos_nv_setRegDomain -
2968 \param clientCtxt - Client Context, Not used for PRIMA
2969 regId - Regulatory Domain ID
2970 \return status set REG domain operation
2971 \sa
2972 -------------------------------------------------------------------------*/
2973VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
2974{
2975 v_CONTEXT_t pVosContext = NULL;
2976 hdd_context_t *pHddCtx = NULL;
2977 struct wiphy *wiphy = NULL;
2978 /* Client Context Argumant not used for PRIMA */
2979 if (regId >= REGDOMAIN_COUNT)
2980 {
2981 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2982 "VOS set reg domain, invalid REG domain ID %d", regId);
2983 return VOS_STATUS_E_INVAL;
2984 }
2985
2986 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2987 if (NULL != pVosContext)
2988 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2989 else
2990 return VOS_STATUS_E_EXISTS;
2991 /* Set correct channel information based on REG Domain */
2992 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
2993
2994 /* when CRDA is not running then we are world roaming.
2995 In this case if 11d is enabled, then country code should
2996 be update on basis of world roaming */
2997 if (NULL != pHddCtx)
2998 {
2999 wiphy = pHddCtx->wiphy;
3000 regulatory_hint(wiphy, "00");
3001 }
3002 return VOS_STATUS_SUCCESS;
3003}
3004
3005
3006/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07003007 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3008 a country given its country code
3009 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3010 a country given its country code. This is done from reading a cached
3011 copy of the binary file.
3012 \param pRegDomain - pointer to regulatory domain
3013 \param countryCode - country code
3014 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3015 VOS_STATUS_E_FAULT - invalid pointer error
3016 VOS_STATUS_E_EMPTY - country code table is empty
3017 VOS_STATUS_E_EXISTS - given country code does not exist in table
3018 \sa
3019 -------------------------------------------------------------------------*/
3020VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
3021 const v_COUNTRYCODE_t countryCode )
3022{
Amar Singhala49cbc52013-10-08 18:37:44 -07003023 int i;
3024 v_CONTEXT_t pVosContext = NULL;
3025 hdd_context_t *pHddCtx = NULL;
3026 struct wiphy *wiphy = NULL;
3027 int status;
3028 // sanity checks
3029 if (NULL == pRegDomain)
3030 {
3031 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3032 ("Invalid reg domain pointer\n") );
3033 return VOS_STATUS_E_FAULT;
3034 }
3035 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003036
Amar Singhala49cbc52013-10-08 18:37:44 -07003037 if (NULL == countryCode)
3038 {
3039 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3040 ("Country code array is NULL\r\n") );
3041 return VOS_STATUS_E_FAULT;
3042 }
3043 if (0 == countryInfoTable.countryCount)
3044 {
3045 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3046 ("Reg domain table is empty\r\n") );
3047 return VOS_STATUS_E_EMPTY;
3048 }
3049 /* If CRDA regulatory settings is valid, i.e. crda is enabled
3050 and reg_notifier is called back.
3051 Intercept here and redirect to the Reg domain table's CRDA
3052 entry if country code is crda's country.
3053 last one NUM_REG_DOMAINS-1 is reserved for crda */
3054 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
3055 "vos_nv_getRegDomainFromCountryCode %c%c\n",
3056 countryCode[0], countryCode[1]);
3057
3058 if (crda_regulatory_entry_valid == VOS_TRUE)
3059 {
3060 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
3061 {
3062 *pRegDomain = NUM_REG_DOMAINS-1;
3063 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
3064 "vos_nv_getRegDomainFromCountryCode return crda init entry\n");
3065 return VOS_STATUS_SUCCESS;
3066 }
3067 if (run_time_alpha2[0]==countryCode[0] &&
3068 run_time_alpha2[1]==countryCode[1] &&
3069 crda_regulatory_run_time_entry_valid == VOS_TRUE)
3070 {
3071 *pRegDomain = NUM_REG_DOMAINS-2;
3072 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
3073 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry\n");
3074 return VOS_STATUS_SUCCESS;
3075 }
3076 else
3077 {
3078 crda_regulatory_run_time_entry_valid = VOS_FALSE;
3079 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3080 if (NULL != pVosContext)
3081 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3082 else
3083 return VOS_STATUS_E_EXISTS;
3084 if (NULL == pHddCtx)
3085 {
3086 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3087 ("Invalid pHddCtx pointer\r\n") );
3088 return VOS_STATUS_E_FAULT;
3089 }
3090
3091 wiphy = pHddCtx->wiphy;
3092
3093 INIT_COMPLETION(pHddCtx->driver_crda_req);
3094 regulatory_hint(wiphy, countryCode);
3095 status = wait_for_completion_interruptible_timeout(
3096 &pHddCtx->driver_crda_req,
3097 msecs_to_jiffies(CRDA_WAIT_TIME));
3098 if (!status)
3099 {
3100 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3101 "%s: Timeout waiting for CRDA REQ", __func__);
3102 }
3103
3104 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
3105 {
3106 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
3107 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry\n");
3108 return VOS_STATUS_SUCCESS;
3109 }
3110 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3111 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry\n");
3112 return VOS_STATUS_E_EXISTS;
3113 }
3114 }
3115
3116 // iterate the country info table until end of table or the country code
3117 // is found
3118 for (i = 0; i < countryInfoTable.countryCount &&
3119 REGDOMAIN_COUNT == *pRegDomain; i++)
3120 {
3121 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
3122 VOS_COUNTRY_CODE_LEN) == 0)
3123 {
3124 // country code is found
3125 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
3126 }
3127 }
3128 if (REGDOMAIN_COUNT != *pRegDomain)
3129 {
3130 return VOS_STATUS_SUCCESS;
3131 }
3132 else
3133 {
3134 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3135 ("country code is not found\r\n"));
3136 return VOS_STATUS_E_EXISTS;
3137 }
3138}
3139
3140
3141/*
3142 * Function: wlan_hdd_crda_reg_notifier
3143 * This function is called from cfg80211 core to provide regulatory settings
3144 * after new country is requested or intersected (init, user input or 11d)
3145 * This function is used to create a CRDA regulatory settings entry into internal
3146 * regulatory setting table.
3147 */
3148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3149void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3150 struct regulatory_request *request)
3151#else
3152int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3153 struct regulatory_request *request)
3154#endif
3155{
3156 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3157 v_REGDOMAIN_t domainIdCurrent;
3158 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
3159 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
3160 tANI_U8 nBandCapability;
3161 int i,j,k,m;
3162
3163 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
3164 " %c%c\n", request->alpha2[0], request->alpha2[1]);
3165 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003166 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003167 wiphy_dbg(wiphy, "info: set by user\n");
3168 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
3169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3170 return;
3171#else
3172 return 0;
3173#endif
3174 // ToDo
3175 /* Don't change default country code to CRDA country code by user req */
3176 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
3177 regd for new country settings */
3178 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3179 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003180 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003181 else if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003182 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003183 wiphy_dbg(wiphy, "info: set by country IE\n");
3184 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
3185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3186 return;
3187#else
3188 return 0;
3189#endif
3190 // ToDo
3191 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003192
Amar Singhala49cbc52013-10-08 18:37:44 -07003193 /* Don't change default country code to CRDA country code by 11d req */
3194 /* for every adapter call sme_ChangeCountryCode to trigger read regd
3195 for intersected new country settings */
3196 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3197 // &country_code[0], pAdapter, pHddCtx->pvosContext);
3198 }
3199 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
3200 (request->initiator == NL80211_REGDOM_SET_BY_CORE))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003201 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003202 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
3203 {
3204 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
3205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3206 return;
3207#else
3208 return 0;
3209#endif
3210 }
3211 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
3212 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
3213 {
3214 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
3215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3216 return;
3217#else
3218 return 0;
3219#endif
3220 }
3221
3222 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
3223 /* if set by driver itself, it means driver can accept the crda
3224 regulatory settings and wiphy->regd should be populated with crda
3225 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
3226 correctly, this may be fixed by later kernel */
3227
3228 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
3229 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
3230 {
3231 if (NULL == wiphy->bands[i])
3232 {
3233 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3234 "error: wiphy->bands[i] is NULL, i = %d", i);
3235 continue;
3236 }
3237
3238 // internal channels[] is one continous array for both 2G and 5G bands
3239 // m is internal starting channel index for each band
3240 if (0 == i)
3241 {
3242 m = 0;
3243 }
3244 else
3245 {
3246 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
3247 }
3248
3249 for (j=0; j<wiphy->bands[i]->n_channels; j++)
3250 {
3251 // k = (m + j) is internal current channel index for 20MHz channel
3252 // n is internal channel index for corresponding 40MHz channel
3253 k = m + j;
3254 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
3255 {
3256 // Enable social channels for P2P
3257 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
3258 2437 == wiphy->bands[i]->channels[j].center_freq ||
3259 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
3260 NV_CHANNEL_ENABLE == regChannels[k].enabled)
3261 {
3262 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
3263 }
3264 else
3265 {
3266 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3267 }
3268 continue;
3269 }
3270 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
3271 {
3272 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3273 continue;
3274 }
3275
3276 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
3277 NV_CHANNEL_INVALID == regChannels[k].enabled)
3278 {
3279 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3280 }
3281 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
3282 {
3283 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
3284 |IEEE80211_CHAN_RADAR);
3285 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3286 }
3287 else
3288 {
3289 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
3290 |IEEE80211_CHAN_PASSIVE_SCAN
3291 |IEEE80211_CHAN_NO_IBSS
3292 |IEEE80211_CHAN_RADAR);
3293 }
3294 }
3295 }
3296
3297 /* Haven't seen any condition that will set by driver after init.
3298 If we do, then we should also call sme_ChangeCountryCode */
3299 if (wiphy->bands[IEEE80211_BAND_5GHZ])
3300 {
3301 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
3302 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303303 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07003304 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
3305 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
3306 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
3307 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303308 ((ccode[0]== 'U'&& ccode[1]=='S') && pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07003309 {
3310 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3311 }
3312 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
3313 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
3314 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
3315 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303316 ((ccode[0]!= 'U'&& ccode[1]!='S') || !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07003317 {
3318 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3319 }
3320 }
3321 }
3322
3323 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
3324 {
3325 request->processed = 1;
3326 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003327 }
3328
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303329 complete(&pHddCtx->wiphy_channel_update_event);
3330
Amar Singhala49cbc52013-10-08 18:37:44 -07003331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3332 return;
3333#else
3334 return 0;
3335#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07003336}
3337
3338#endif