blob: 31686d437b3523a29e85971bdbbc458e8e460abe [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
70static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
71#ifdef CONFIG_ENABLE_LINUX_REG
72static v_BOOL_t kernel_reg_request_made = VOS_FALSE;
73static v_BOOL_t driver_callback_called = VOS_FALSE;
74static 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;
77#else
78static v_BOOL_t driver_regulatory_init = VOS_FALSE;
79static char driver_reg_cc[2] = {0, 0};
80#endif
81
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070082
Jeff Johnson295189b2012-06-20 16:38:30 -070083/*----------------------------------------------------------------------------
84 * Preprocessor Definitions and Constants
85 * -------------------------------------------------------------------------*/
86#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
87#define VALIDITY_BITMAP_SIZE 32
88#define MAX_COUNTRY_COUNT 300
89//To be removed when NV support is fully functional
90#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070091
92#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070093#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070094
Jeff Johnson295189b2012-06-20 16:38:30 -070095/*----------------------------------------------------------------------------
96 * Type Declarations
97 * -------------------------------------------------------------------------*/
98// this wrapper structure is identical to nv_cmd_type except the
99// data_ptr type is changed void* to avoid exceeding the debug information
100// module size as there are too many elements within nv_items_type union
101
102// structure for code and regulatory domain of a single country
103typedef struct
104{
105 v_U8_t regDomain;
106 v_COUNTRYCODE_t countryCode;
107} CountryInfo_t;
108// structure of table to map country code and regulatory domain
109typedef struct
110{
111 v_U16_t countryCount;
112 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
113} CountryInfoTable_t;
114/*----------------------------------------------------------------------------
115 * Global Data Definitions
116 * -------------------------------------------------------------------------*/
117/*----------------------------------------------------------------------------
118 * Static Variable Definitions
119 * -------------------------------------------------------------------------*/
Amar Singhalfddc28c2013-09-05 13:03:40 -0700120
121#ifdef CONFIG_ENABLE_LINUX_REG
122
123static CountryInfoTable_t countryInfoTable =
124{
125 /* the first entry in the table is always the world domain */
126 138,
127 {
128 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
129 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
130 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
131 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
132 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
133 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
134 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
135 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
136 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
137 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
138 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
139 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
140 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
141 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
142 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
143 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
144 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
145 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
146 {REGDOMAIN_ETSI, {'B', 'L'}}, //
147 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
148 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
149 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
150 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
151 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
152 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
153 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
154 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
155 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
156 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
157 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
158 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
159 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
160 {REGDOMAIN_ETSI, {'C', 'S'}},
161 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
162 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
163 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
164 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
165 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
166 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
167 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
168 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
169 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
170 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
171 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
172 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
173 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
174 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
175 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
176 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
177 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
178 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
179 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
180 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
181 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
182 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
183 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
184 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
185 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
186 {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
187 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
188 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
189 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
190 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
191 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
192 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
193 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
194 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
195 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
196 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
197 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
198 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
199 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
200 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
201 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
202 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
203 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
204 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
205 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
206 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
207 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
208 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
209 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
210 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
211 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
212 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
213 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
214 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
215 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
216 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
217 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
218 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
219 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
220 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
221 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
222 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
223 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
224 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
225 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
226 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
227 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
228 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
229 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
230 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
231 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
232 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
233 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
234 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
235 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
236 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
237 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
238 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
239 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
240 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
241 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
242 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
243 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
244 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
245 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
246 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
247 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
248 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
249 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
250 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
251 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
252 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
253 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
254 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
255 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
256 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
257 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
258 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
259 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
260 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
261 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
262 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
263 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
264 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
265 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
266 }
267};
268
269#else
270
Jeff Johnson295189b2012-06-20 16:38:30 -0700271// cache of country info table;
272// this is re-initialized from data on binary file
273// loaded on driver initialization if available
274static CountryInfoTable_t countryInfoTable =
275{
276 254,
277 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700278 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
279 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
280 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
281 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
282 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
283 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700284 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700285 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
286 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
287 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
288 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
289 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
290 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
291 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530292 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700293 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
294 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
295 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
296 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
297 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700298 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700299 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
300 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
301 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
302 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
303 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
304 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
305 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
306 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
307 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
308 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
309 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
310 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
311 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
312 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
313 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
314 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
315 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
316 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
317 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
318 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
319 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
320 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
321 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
322 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
323 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
324 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530325 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700326 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
327 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
328 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
329 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
330 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
331 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
332 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
333 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
334 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
335 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
336 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
337 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700338 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700339 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
340 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
341 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
342 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
343 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
344 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
345 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
346 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
347 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
348 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
349 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
350 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
351 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
352 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
353 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
354 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
355 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
356 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
357 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
358 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
359 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
360 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
361 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
362 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
363 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
364 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
365 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
366 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
367 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
368 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700369 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700370 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
371 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
372 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
373 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
374 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
375 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
376 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
377 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
378 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
379 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700380 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700381 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
382 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
383 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
384 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
385 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
386 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
387 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
388 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
389 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
390 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
391 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
392 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
393 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
394 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700395 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700396 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
397 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
398 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
399 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
400 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700401 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700402 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
403 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
404 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
405 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
406 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
407 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
408 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
409 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
410 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700411 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700412 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700413 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700414 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
415 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
416 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
417 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
418 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
419 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
420 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
421 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
422 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700423 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700424 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700425 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
426 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
427 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
428 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
429 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
430 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
431 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700432 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700433 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
434 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
435 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
436 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
437 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
438 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
439 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
440 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
441 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
442 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
443 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
444 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
445 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
446 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
447 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
448 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
449 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
450 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
451 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
452 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700453 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700454 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
455 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
456 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700457 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700458 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700459 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700460 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700461 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
462 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700463 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
464 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
465 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
466 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
467 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
468 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
469 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
470 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
471 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
472 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
473 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
474 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
475 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700476 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
477 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
478 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700479 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
480 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
481 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
482 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
483 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
484 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
485 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
486 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
487 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
488 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
489 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
490 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
491 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
492 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
493 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
494 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
495 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
496 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
497 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
498 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
499 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
500 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
501 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
502 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
503 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
504 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
505 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
506 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
507 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700508 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700509 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
510 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700511 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700512 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700513 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
514 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700515 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
516 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700517 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700518 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
519 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
520 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
521 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
522 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700523 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700524 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
525 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
526 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
527 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
528 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
529 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
530 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700531 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700532 }
533};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700534
535#endif
536
Jeff Johnson295189b2012-06-20 16:38:30 -0700537typedef struct nvEFSTable_s
538{
539 v_U32_t nvValidityBitmap;
540 sHalNv halnv;
541} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700542nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700543/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700544static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700545static v_U8_t *pnvEncodedBuf;
546static v_U8_t *pDictFile;
547static v_U8_t *pEncodedBuf;
548static v_SIZE_t nvReadEncodeBufSize;
549static v_SIZE_t nDictionarySize;
550static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
552const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
553{
554 //RF_SUBBAND_2_4_GHZ
555 //freq, chan#, band
556 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
557 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
558 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
559 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
560 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
561 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
562 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
563 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
564 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
565 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
566 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
567 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
568 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
569 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700570 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
571 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
572 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
573 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
574 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
575 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
576 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700577 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
578 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
579 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
580 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
581 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
582 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
583 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
584 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
585 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
586 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
587 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
588 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
589 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
590 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
591 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
592 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
593 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
594 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
595 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
596 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
597 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
598 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
599 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
600 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700601 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
602 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
603 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
604 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
605 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
606 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
607 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
608 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
609 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
610 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
611 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
612 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
613 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
614 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
615 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
616 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
617 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
618 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
619 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
620 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
621 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
622 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
623 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
624 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
625 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
626 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
627 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
628 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
629 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
630 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
631 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
632 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
633 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
634 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
635 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700636};
637
638extern const sHalNv nvDefaults;
639
640const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
641
642/*----------------------------------------------------------------------------
643 Function Definitions and Documentation
644 * -------------------------------------------------------------------------*/
645VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
646/**------------------------------------------------------------------------
647 \brief vos_nv_init() - initialize the NV module
648 The \a vos_nv_init() initializes the NV module. This read the binary
649 file for country code and regulatory domain information.
650 \return VOS_STATUS_SUCCESS - module is initialized successfully
651 otherwise - module is not initialized
652 \sa
653 -------------------------------------------------------------------------*/
654VOS_STATUS vos_nv_init(void)
655{
656 return VOS_STATUS_SUCCESS;
657}
658
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700659/**------------------------------------------------------------------------
660 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
661 \ tools
662 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
663 otherwise - not successful
664 \sa
665-------------------------------------------------------------------------*/
666VOS_STATUS vos_nv_get_dictionary_data(void)
667{
668 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
669
670 if (MAGIC_NUMBER != magicNumber)
671 {
672 return VOS_STATUS_SUCCESS;
673 }
674
675 nDictionarySize = 0;
676
677 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
678 &nDictionarySize );
679 if (VOS_STATUS_E_NOMEM != vosStatus)
680 {
681 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
682 "Error obtaining binary size" );
683/// NOTE:
684/// We can still work without a dictionary file..
685 return VOS_STATUS_SUCCESS;
686 }
687
688 // malloc a buffer to read in the Configuration binary file.
689 pDictFile = vos_mem_malloc( nDictionarySize );
690 if (NULL == pDictFile)
691 {
692 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
693 "Unable to allocate memory for the CFG binary [size= %d bytes]",
694 nDictionarySize );
695 vosStatus = VOS_STATUS_E_NOMEM;
696 goto fail;
697 }
698
699 /* Get the entire CFG file image... */
700 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
701 &nDictionarySize );
702 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
703 {
704 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
705 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
706 nDictionarySize );
707 return VOS_STATUS_SUCCESS;
708 }
709
710 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
711 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
712
713fail:
714 return vosStatus;
715}
716
Jeff Johnson295189b2012-06-20 16:38:30 -0700717VOS_STATUS vos_nv_open(void)
718{
719 VOS_STATUS status = VOS_STATUS_SUCCESS;
720 v_CONTEXT_t pVosContext= NULL;
721 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700722 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700723 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700724 v_U32_t dataOffset;
725 sHalNv *pnvData = NULL;
726
Jeff Johnson295189b2012-06-20 16:38:30 -0700727 /*Get the global context */
728 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700729
730 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800731 {
732 return (eHAL_STATUS_FAILURE);
733 }
734
Jeff Johnson295189b2012-06-20 16:38:30 -0700735 bufSize = sizeof(nvEFSTable_t);
736 status = hdd_request_firmware(WLAN_NV_FILE,
737 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700738 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700739
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700740 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700742 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700743 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700744 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700745 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 }
747
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700748 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
749
750 /// Allocate buffer with maximum length..
751 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
752
753 if (NULL == pEncodedBuf)
754 {
755 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
756 "%s : failed to allocate memory for NV", __func__);
757 return VOS_STATUS_E_NOMEM;
758 }
759
760 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
761
762 if (MAGIC_NUMBER == magicNumber)
763 {
764 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
765
766 if (NULL == pnvData)
767 {
768 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
769 "%s : failed to allocate memory for NV", __func__);
770 return VOS_STATUS_E_NOMEM;
771 }
772
773 memset(pnvData, 0, sizeof(sHalNv));
774
775 /// Data starts from offset of validity bit map + magic number..
776 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
777
778 status = nvParser(&pnvEncodedBuf[dataOffset],
779 (nvReadBufSize-dataOffset), pnvData);
780
781 ///ignore validity bit map
782 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
783
784 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
785 nvReadEncodeBufSize);
786
787 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
788 "readEncodeBufSize %d",nvReadEncodeBufSize);
789
790 if (VOS_STATUS_SUCCESS == status) {
791 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
792 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
793 pnvData->fields.productId,
794 pnvData->fields.couplerType,
795 pnvData->fields.wlanNvRevId);
796
797 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
798
799 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
800 }
801 else
802 {
803 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
804 "nvParser failed %d",status);
805
806 nvReadBufSize = 0;
807
808 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
809
810 nvReadEncodeBufSize = sizeof(sHalNv);
811 }
812 }
813 else
814 {
815 dataOffset = sizeof(v_U32_t);
816 nvReadEncodeBufSize = sizeof(sHalNv);
817 memcpy(pEncodedBuf, &pnvEncodedBuf[dataOffset], nvReadEncodeBufSize);
818 }
819
820 if (NULL != pnvData)
821 {
822 vos_mem_free(pnvData);
823 }
824
825 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800826 "INFO: NV binary file version=%d Driver default NV version=%d, continue...\n",
827 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
828
Jeff Johnson295189b2012-06-20 16:38:30 -0700829 /* Copying the read nv data to the globa NV EFS table */
830 {
831 /* Allocate memory to global NV table */
832 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700833 if ( NULL == pnvEFSTable )
Jeff Johnson295189b2012-06-20 16:38:30 -0700834 {
835 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700836 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 return VOS_STATUS_E_NOMEM;
838 }
839
840 /*Copying the NV defaults */
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700841 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800842
843 /* Size mismatch */
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700844 if ( nvReadBufSize != bufSize)
845 {
846 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
847 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
848 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
849 nvReadBufSize, bufSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800850 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700851 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700852
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800853 /* Version mismatch */
854 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
855 {
856 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
857 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
858 {
859 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
860 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
861 "Make sure that this is intented or may impact performance!!!\n");
862 }
863 else
864 {
865 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
866 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
867 "Driver NV defaults will be used, may impact performance!!!\n");
868
869 return VOS_STATUS_SUCCESS;
870 }
871 }
872
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700873 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700874 /* Copy the valid fields to the NV Global structure */
875 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700876 VOS_STATUS_SUCCESS)
877 {
878 if (itemIsValid == VOS_TRUE) {
879
880 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
881 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800882 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 }
884 }
885
Amar Singhalfddc28c2013-09-05 13:03:40 -0700886 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 VOS_STATUS_SUCCESS)
888 {
889 if (itemIsValid == VOS_TRUE)
890 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700891 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700892 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
893 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800894 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 }
896 }
897
Amar Singhalfddc28c2013-09-05 13:03:40 -0700898 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700899 VOS_STATUS_SUCCESS)
900 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700901
Jeff Johnson295189b2012-06-20 16:38:30 -0700902 if (itemIsValid == VOS_TRUE)
903 {
904 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
905 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
906 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800907 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700908 }
909 }
910
Amar Singhalfddc28c2013-09-05 13:03:40 -0700911 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 VOS_STATUS_SUCCESS)
913 {
914 if (itemIsValid == VOS_TRUE)
915 {
916 if(vos_nv_read( VNV_DEFAULT_LOCATION,
917 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
918 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800919 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 }
921 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700922
923 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 VOS_STATUS_SUCCESS)
925 {
926 if (itemIsValid == VOS_TRUE)
927 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700928 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
930 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800931 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 }
933 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700934
935 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 VOS_STATUS_SUCCESS)
937 {
938 if (itemIsValid == VOS_TRUE)
939 {
940 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
941 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
942 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800943 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 }
945 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700946 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700947 VOS_STATUS_SUCCESS)
948 {
949 if (itemIsValid == VOS_TRUE)
950 {
951 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
952 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
953 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800954 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 }
956 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700957
958 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 VOS_STATUS_SUCCESS)
960 {
961 if (itemIsValid == VOS_TRUE)
962 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800963 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
964 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
965 goto error;
966 }
967 }
968
Amar Singhalfddc28c2013-09-05 13:03:40 -0700969 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800970 VOS_STATUS_SUCCESS)
971 {
972 if (itemIsValid == VOS_TRUE)
973 {
974 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
975 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800976 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 }
978 }
979
Amar Singhalfddc28c2013-09-05 13:03:40 -0700980 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 VOS_STATUS_SUCCESS)
982 {
983 if (itemIsValid == VOS_TRUE)
984 {
985 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -0700986 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800988 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 }
990 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700991 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 VOS_STATUS_SUCCESS)
993 {
994 if (itemIsValid == VOS_TRUE)
995 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700996 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
997 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800999 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 }
1001 }
1002
Amar Singhalfddc28c2013-09-05 13:03:40 -07001003 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001004 VOS_STATUS_SUCCESS)
1005 {
1006 if (itemIsValid == VOS_TRUE)
1007 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001008 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1009 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001011 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 }
1013 }
1014
Amar Singhalfddc28c2013-09-05 13:03:40 -07001015 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001016 VOS_STATUS_SUCCESS)
1017 {
1018 if (itemIsValid == VOS_TRUE)
1019 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001020 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1021 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001022 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001023 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 }
1025 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001026 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001027 VOS_STATUS_SUCCESS)
1028 {
1029 if (itemIsValid == VOS_TRUE)
1030 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001031 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1032 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001033 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001034 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 }
1036 }
1037 }
1038
1039 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001040error:
1041 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001042 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001043 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001044}
1045
1046VOS_STATUS vos_nv_close(void)
1047{
1048 VOS_STATUS status = VOS_STATUS_SUCCESS;
1049 v_CONTEXT_t pVosContext= NULL;
1050 /*Get the global context */
1051 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1052 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1053 if ( !VOS_IS_STATUS_SUCCESS( status ))
1054 {
1055 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1056 "%s : vos_open failed\n",__func__);
1057 return VOS_STATUS_E_FAILURE;
1058 }
1059 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001060 vos_mem_free(pEncodedBuf);
1061 vos_mem_free(pDictFile);
1062
Jeff Johnson295189b2012-06-20 16:38:30 -07001063 gnvEFSTable=NULL;
1064 return VOS_STATUS_SUCCESS;
1065}
Jeff Johnson295189b2012-06-20 16:38:30 -07001066
Jeff Johnson295189b2012-06-20 16:38:30 -07001067/**------------------------------------------------------------------------
1068 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1069 country codes
1070 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1071 country codes with paddings in the provided buffer
1072 \param pBuffer - pointer to buffer where supported country codes
1073 and paddings are encoded; this may be set to NULL
1074 if user wishes to query the required buffer size to
1075 get the country code list
1076 \param pBufferSize - this is the provided buffer size on input;
1077 this is the required or consumed buffer size on output
1078 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1079 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1080 the buffer is NULL or buffer size is
1081 sufficient
1082 \sa
1083 -------------------------------------------------------------------------*/
Amar Singhalfddc28c2013-09-05 13:03:40 -07001084
Jeff Johnson295189b2012-06-20 16:38:30 -07001085VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1086 v_SIZE_t paddingSize )
1087{
1088 v_SIZE_t providedBufferSize = *pBufferSize;
1089 int i;
1090 // pBufferSize now points to the required buffer size
1091 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1092 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1093 {
1094 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001095 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 return VOS_STATUS_E_NOMEM;
1097 }
1098 for (i = 0; i < countryInfoTable.countryCount; i++)
1099 {
1100 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1101 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1102 }
1103 return VOS_STATUS_SUCCESS;
1104}
1105/**------------------------------------------------------------------------
1106 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1107 \param pTxAntennaCount - antenna count
1108 \return status of the NV read operation
1109 \sa
1110 -------------------------------------------------------------------------*/
1111VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1112{
1113 sNvFields fieldImage;
1114 VOS_STATUS status;
1115 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1116 sizeof(fieldImage) );
1117 if (VOS_STATUS_SUCCESS == status)
1118 {
1119 *pTxAntennaCount = fieldImage.numOfTxChains;
1120 }
1121 return status;
1122}
1123/**------------------------------------------------------------------------
1124 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1125 \param pRxAntennaCount - antenna count
1126 \return status of the NV read operation
1127 \sa
1128 -------------------------------------------------------------------------*/
1129VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1130{
1131 sNvFields fieldImage;
1132 VOS_STATUS status;
1133 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1134 sizeof(fieldImage) );
1135 if (VOS_STATUS_SUCCESS == status)
1136 {
1137 *pRxAntennaCount = fieldImage.numOfRxChains;
1138 }
1139 return status;
1140}
1141
1142/**------------------------------------------------------------------------
1143 \brief vos_nv_readMacAddress() - return the MAC address
1144 \param pMacAddress - MAC address
1145 \return status of the NV read operation
1146 \sa
1147 -------------------------------------------------------------------------*/
1148VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1149{
1150 sNvFields fieldImage;
1151 VOS_STATUS status;
1152 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1153 sizeof(fieldImage) );
1154 if (VOS_STATUS_SUCCESS == status)
1155 {
1156 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1157 }
1158 else
1159 {
1160 //This part of the code can be removed when NV is programmed
1161 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1162 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
1163 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1164 " fail to get MAC address from NV, hardcoded to %02X-%02X-%02X-%02X-%02X%02X",
1165 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
1166 status = VOS_STATUS_SUCCESS;
1167 }
1168 return status;
1169}
1170
1171/**------------------------------------------------------------------------
1172
1173 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1174
1175 \param pMacAddress - MAC address
1176 \param macCount - Count of valid MAC addresses to get from NV field
1177
1178 \return status of the NV read operation
1179
1180 \sa
1181
1182 -------------------------------------------------------------------------*/
1183VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1184 v_U8_t macCount )
1185{
1186 sNvFields fieldImage;
1187 VOS_STATUS status;
1188 v_U8_t countLoop;
1189 v_U8_t *pNVMacAddress;
1190
1191 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1192 (NULL == pMacAddress))
1193 {
1194 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301195 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 macCount, pMacAddress);
1197 }
1198
1199 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1200 sizeof(fieldImage) );
1201 if (VOS_STATUS_SUCCESS == status)
1202 {
1203 pNVMacAddress = fieldImage.macAddr;
1204 for(countLoop = 0; countLoop < macCount; countLoop++)
1205 {
1206 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1207 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1208 VOS_MAC_ADDRESS_LEN);
1209 }
1210 }
1211 else
1212 {
1213 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1214 "vos_nv_readMultiMacAddress Get NV Field Fail");
1215 }
1216
1217 return status;
1218}
1219
1220/**------------------------------------------------------------------------
1221 \brief vos_nv_setValidity() - set the validity of an NV item.
1222 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1223 validity information is stored in NV memory.
1224 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1225 An item becomes valid when one has written to it successfully.
1226 \param type - NV item type
1227 \param itemIsValid - boolean value indicating the item's validity
1228 \return VOS_STATUS_SUCCESS - validity is set successfully
1229 VOS_STATUS_E_INVAL - one of the parameters is invalid
1230 VOS_STATUS_E_FAILURE - unknown error
1231 \sa
1232 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001233
1234VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1235{
1236 v_U32_t lastNvValidityBitmap;
1237 v_U32_t newNvValidityBitmap;
1238 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001239
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001241 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 {
1243 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001244 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001245 return VOS_STATUS_E_INVAL;
1246 }
1247 // read the validity bitmap
1248 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1249 // modify the validity bitmap
1250 if (itemIsValid)
1251 {
1252 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1253 // commit to NV store if bitmap has been modified
1254 if (newNvValidityBitmap != lastNvValidityBitmap)
1255 {
1256 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1257 }
1258 }
1259 else
1260 {
1261 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1262 if (newNvValidityBitmap != lastNvValidityBitmap)
1263 {
1264 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1265 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1266 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001267 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 status = VOS_STATUS_E_FAULT;
1269 }
1270 }
1271 }
1272
1273 return status;
1274}
Jeff Johnson295189b2012-06-20 16:38:30 -07001275/**------------------------------------------------------------------------
1276 \brief vos_nv_getValidity() - get the validity of an NV item.
1277 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1278 validity information is stored in NV memory.
1279 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1280 An item becomes valid when one has written to it successfully.
1281 \param type - NV item type
1282 \param pItemIsValid- pointer to the boolean value indicating the item's
1283 validity
1284 \return VOS_STATUS_SUCCESS - validity is determined successfully
1285 VOS_STATUS_E_INVAL - one of the parameters is invalid
1286 VOS_STATUS_E_FAILURE - unknown error
1287 \sa
1288 -------------------------------------------------------------------------*/
1289VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1290{
1291 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1292 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001293 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 {
1295 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001296 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 return VOS_STATUS_E_INVAL;
1298 }
1299 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1300 return VOS_STATUS_SUCCESS;
1301}
1302/**------------------------------------------------------------------------
1303 \brief vos_nv_read() - read a NV item to an output buffer
1304 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1305 an array, this function would read the entire array. One would get a
1306 VOS_STATUS_E_EXISTS error when reading an invalid item.
1307 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1308 if a default buffer is provided (with a non-NULL value),
1309 the default buffer content is copied to the output buffer.
1310 \param type - NV item type
1311 \param outputBuffer - output buffer
1312 \param defaultBuffer - default buffer
1313 \param bufferSize - output buffer size
1314 \return VOS_STATUS_SUCCESS - NV item is read successfully
1315 VOS_STATUS_E_INVAL - one of the parameters is invalid
1316 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1317 VOS_STATUS_E_EXISTS - NV type is unsupported
1318 VOS_STATUS_E_FAILURE - unknown error
1319 \sa
1320 -------------------------------------------------------------------------*/
1321VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1322 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1323{
1324 VOS_STATUS status = VOS_STATUS_SUCCESS;
1325 v_SIZE_t itemSize;
1326 v_BOOL_t itemIsValid = VOS_TRUE;
1327
Amar Singhalfddc28c2013-09-05 13:03:40 -07001328 /* sanity check */
Jeff Johnson43971f52012-07-17 12:26:56 -07001329 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 {
1331 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001332 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 return VOS_STATUS_E_INVAL;
1334 }
1335 if (NULL == outputVoidBuffer)
1336 {
1337 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001338 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001339 return VOS_STATUS_E_FAULT;
1340 }
1341 if (0 == bufferSize)
1342 {
1343 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001344 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001345 return VOS_STATUS_E_INVAL;
1346 }
1347 // check if the NV item has valid data
1348 status = vos_nv_getValidity( type, &itemIsValid );
1349 if (!itemIsValid)
1350 {
1351 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001352 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 return VOS_STATUS_E_EMPTY;
1354 }
1355 switch(type)
1356 {
1357 case VNV_FIELD_IMAGE:
1358 itemSize = sizeof(gnvEFSTable->halnv.fields);
1359 if(bufferSize != itemSize) {
1360 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001361 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 itemSize);
1363 status = VOS_STATUS_E_INVAL;
1364 }
1365 else {
1366 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1367 }
1368 break;
1369 case VNV_RATE_TO_POWER_TABLE:
1370 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1371 if(bufferSize != itemSize) {
1372 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001373 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 itemSize);
1375 status = VOS_STATUS_E_INVAL;
1376 }
1377 else {
1378 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1379 }
1380 break;
1381 case VNV_REGULARTORY_DOMAIN_TABLE:
1382 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1383 if(bufferSize != itemSize) {
1384 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001385 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 itemSize);
1387 status = VOS_STATUS_E_INVAL;
1388 }
1389 else {
1390 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1391 }
1392 break;
1393 case VNV_DEFAULT_LOCATION:
1394 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1395 if(bufferSize != itemSize) {
1396 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001397 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 itemSize);
1399 status = VOS_STATUS_E_INVAL;
1400 }
1401 else {
1402 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1403 }
1404 break;
1405 case VNV_TPC_POWER_TABLE:
1406 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1407 if(bufferSize != itemSize) {
1408 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001409 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001410 itemSize);
1411 status = VOS_STATUS_E_INVAL;
1412 }
1413 else {
1414 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1415 }
1416 break;
1417 case VNV_TPC_PDADC_OFFSETS:
1418 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1419 if(bufferSize != itemSize) {
1420 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001421 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001422 itemSize);
1423 status = VOS_STATUS_E_INVAL;
1424 }
1425 else {
1426 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1427 }
1428 break;
1429 case VNV_RSSI_CHANNEL_OFFSETS:
1430
1431 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1432
1433 if(bufferSize != itemSize) {
1434
1435 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001436 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 itemSize);
1438 status = VOS_STATUS_E_INVAL;
1439 }
1440 else {
1441 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1442 }
1443 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001444 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001445
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001446 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001447
1448 if(bufferSize != itemSize) {
1449
1450 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001451 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 itemSize);
1453 status = VOS_STATUS_E_INVAL;
1454 }
1455 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001456 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1457 }
1458 break;
1459 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001460
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001461 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001462
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001463 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001464
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001465 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001466 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001467 itemSize);
1468 status = VOS_STATUS_E_INVAL;
1469 }
1470 else {
1471 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 }
1473 break;
1474 case VNV_ANTENNA_PATH_LOSS:
1475 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1476 if(bufferSize != itemSize) {
1477 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001478 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 itemSize);
1480 status = VOS_STATUS_E_INVAL;
1481 }
1482 else {
1483 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1484 }
1485 break;
1486 case VNV_PACKET_TYPE_POWER_LIMITS:
1487 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1488 if(bufferSize != itemSize) {
1489 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001490 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 itemSize);
1492 status = VOS_STATUS_E_INVAL;
1493 }
1494 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001495 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001496 }
1497 break;
1498 case VNV_OFDM_CMD_PWR_OFFSET:
1499 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1500 if(bufferSize != itemSize) {
1501 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001502 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001503 itemSize);
1504 status = VOS_STATUS_E_INVAL;
1505 }
1506 else {
1507 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1508 }
1509 break;
1510 case VNV_TX_BB_FILTER_MODE:
1511 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1512 if(bufferSize != itemSize) {
1513 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001514 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 itemSize);
1516 status = VOS_STATUS_E_INVAL;
1517 }
1518 else {
1519 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1520 }
1521 break;
1522
Jeff Johnson295189b2012-06-20 16:38:30 -07001523
1524 case VNV_TABLE_VIRTUAL_RATE:
1525 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1526 if(bufferSize != itemSize) {
1527 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001528 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 itemSize);
1530 status = VOS_STATUS_E_INVAL;
1531 }
1532 else {
1533 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1534 }
1535 break;
1536
1537 default:
1538 break;
1539 }
1540 return status;
1541}
Jeff Johnson295189b2012-06-20 16:38:30 -07001542
1543/**------------------------------------------------------------------------
1544 \brief vos_nv_write() - write to a NV item from an input buffer
1545 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1546 validate the NV item if the write operation is successful.
1547 \param type - NV item type
1548 \param inputBuffer - input buffer
1549 \param inputBufferSize - input buffer size
1550 \return VOS_STATUS_SUCCESS - NV item is read successfully
1551 VOS_STATUS_E_INVAL - one of the parameters is invalid
1552 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1553 VOS_STATUS_E_EXISTS - NV type is unsupported
1554 VOS_STATUS_E_FAILURE - unknown error
1555 \sa
1556 -------------------------------------------------------------------------*/
1557VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1558 v_SIZE_t bufferSize )
1559{
1560 VOS_STATUS status = VOS_STATUS_SUCCESS;
1561 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001562
Amar Singhalfddc28c2013-09-05 13:03:40 -07001563 /* sanity check */
Jeff Johnson43971f52012-07-17 12:26:56 -07001564 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 {
1566 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001567 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 return VOS_STATUS_E_INVAL;
1569 }
1570 if (NULL == inputVoidBuffer)
1571 {
1572 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001573 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001574 return VOS_STATUS_E_FAULT;
1575 }
1576 if (0 == bufferSize)
1577 {
1578 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001579 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 return VOS_STATUS_E_INVAL;
1581 }
1582 switch(type)
1583 {
1584 case VNV_FIELD_IMAGE:
1585 itemSize = sizeof(gnvEFSTable->halnv.fields);
1586 if(bufferSize != itemSize) {
1587 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001588 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001589 itemSize);
1590 status = VOS_STATUS_E_INVAL;
1591 }
1592 else {
1593 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1594 }
1595 break;
1596 case VNV_RATE_TO_POWER_TABLE:
1597 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1598 if(bufferSize != itemSize) {
1599 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001600 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001601 itemSize);
1602 status = VOS_STATUS_E_INVAL;
1603 }
1604 else {
1605 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1606 }
1607 break;
1608 case VNV_REGULARTORY_DOMAIN_TABLE:
1609 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1610 if(bufferSize != itemSize) {
1611 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001612 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001613 itemSize);
1614 status = VOS_STATUS_E_INVAL;
1615 }
1616 else {
1617 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1618 }
1619 break;
1620 case VNV_DEFAULT_LOCATION:
1621 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1622 if(bufferSize != itemSize) {
1623 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001624 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 itemSize);
1626 status = VOS_STATUS_E_INVAL;
1627 }
1628 else {
1629 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1630 }
1631 break;
1632 case VNV_TPC_POWER_TABLE:
1633 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1634 if(bufferSize != itemSize) {
1635 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001636 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 itemSize);
1638 status = VOS_STATUS_E_INVAL;
1639 }
1640 else {
1641 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1642 }
1643 break;
1644 case VNV_TPC_PDADC_OFFSETS:
1645 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1646 if(bufferSize != itemSize) {
1647 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001648 ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001649 itemSize);
1650 status = VOS_STATUS_E_INVAL;
1651 }
1652 else {
1653 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1654 }
1655 break;
1656 case VNV_RSSI_CHANNEL_OFFSETS:
1657
1658 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1659
1660 if(bufferSize != itemSize) {
1661
1662 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001663 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 itemSize);
1665 status = VOS_STATUS_E_INVAL;
1666 }
1667 else {
1668 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1669 }
1670 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001671 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001672
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001673 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001674
1675 if(bufferSize != itemSize) {
1676
1677 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001678 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 itemSize);
1680 status = VOS_STATUS_E_INVAL;
1681 }
1682 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001683 memcpy(&gnvEFSTable->halnv.tables.hwCalValues,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001684 }
1685 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001686 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001687
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001688 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001689
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001690 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001691
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001692 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001693 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001694 itemSize);
1695 status = VOS_STATUS_E_INVAL;
1696 }
1697 else {
1698 memcpy(&gnvEFSTable->halnv.tables.fwConfig,inputVoidBuffer,bufferSize);
1699 }
1700 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 case VNV_ANTENNA_PATH_LOSS:
1702 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1703 if(bufferSize != itemSize) {
1704 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001705 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 itemSize);
1707 status = VOS_STATUS_E_INVAL;
1708 }
1709 else {
1710 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1711 }
1712 break;
1713
1714 case VNV_PACKET_TYPE_POWER_LIMITS:
1715 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1716 if(bufferSize != itemSize) {
1717 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001718 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 itemSize);
1720 status = VOS_STATUS_E_INVAL;
1721 }
1722 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001723 memcpy(gnvEFSTable->halnv.tables.pktTypePwrLimits,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 }
1725 break;
1726
1727 case VNV_OFDM_CMD_PWR_OFFSET:
1728 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1729 if(bufferSize != itemSize) {
1730 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001731 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001732 itemSize);
1733 status = VOS_STATUS_E_INVAL;
1734 }
1735 else {
1736 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1737 }
1738 break;
1739
1740 case VNV_TX_BB_FILTER_MODE:
1741 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1742 if(bufferSize != itemSize) {
1743 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001744 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 itemSize);
1746 status = VOS_STATUS_E_INVAL;
1747 }
1748 else {
1749 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1750 }
1751 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001752
Jeff Johnson295189b2012-06-20 16:38:30 -07001753
1754 case VNV_TABLE_VIRTUAL_RATE:
1755 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1756 if(bufferSize != itemSize) {
1757 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001758 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001759 itemSize);
1760 status = VOS_STATUS_E_INVAL;
1761 }
1762 else {
1763 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1764 }
1765 break;
1766
1767 default:
1768 break;
1769 }
1770 if (VOS_STATUS_SUCCESS == status)
1771 {
1772 // set NV item to have valid data
1773 status = vos_nv_setValidity( type, VOS_TRUE );
1774 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001775 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001776 status = VOS_STATUS_E_FAULT;
1777 }
1778 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1779
1780 if (! VOS_IS_STATUS_SUCCESS(status)) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001781 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 status = VOS_STATUS_E_FAULT;
1783 }
1784 }
1785 return status;
1786}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08001787
Jeff Johnson295189b2012-06-20 16:38:30 -07001788/**------------------------------------------------------------------------
1789 \brief vos_nv_getChannelListWithPower() - function to return the list of
1790 supported channels with the power limit info too.
1791 \param pChannels20MHz - list of 20 Mhz channels
1792 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1793 \param pChannels40MHz - list of 20 Mhz channels
1794 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1795 \return status of the NV read operation
1796 \Note: 40Mhz not currently supported
1797 \sa
1798 -------------------------------------------------------------------------*/
1799VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1800 tANI_U8 *num20MHzChannelsFound,
1801 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1802 tANI_U8 *num40MHzChannelsFound
1803 )
1804{
1805 VOS_STATUS status = VOS_STATUS_SUCCESS;
1806 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001807
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1809 // or pass it as a parameter to NV from SME?
1810
1811 if( channels20MHz && num20MHzChannelsFound )
1812 {
1813 count = 0;
1814 for( i = 0; i <= RF_CHAN_14; i++ )
1815 {
1816 if( regChannels[i].enabled )
1817 {
1818 channels20MHz[count].chanId = rfChannels[i].channelNum;
1819 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1820 }
1821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1823 {
1824 if( regChannels[i].enabled )
1825 {
1826 channels20MHz[count].chanId = rfChannels[i].channelNum;
1827 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1828 }
1829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 *num20MHzChannelsFound = (tANI_U8)count;
1831 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001832
1833 if( channels40MHz && num40MHzChannelsFound )
1834 {
1835 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07001836 //center channels for 2.4 Ghz 40 MHz channels
1837 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1838 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001839
Jeff Johnsone7245742012-09-05 17:12:55 -07001840 if( regChannels[i].enabled )
1841 {
1842 channels40MHz[count].chanId = rfChannels[i].channelNum;
1843 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1844 }
1845 }
1846 //center channels for 5 Ghz 40 MHz channels
1847 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1848 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001849
Jeff Johnsone7245742012-09-05 17:12:55 -07001850 if( regChannels[i].enabled )
1851 {
1852 channels40MHz[count].chanId = rfChannels[i].channelNum;
1853 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1854 }
1855 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001856 *num40MHzChannelsFound = (tANI_U8)count;
1857 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001858 return (status);
1859}
1860
1861/**------------------------------------------------------------------------
1862 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1863 \return default regulatory domain
1864 \sa
1865 -------------------------------------------------------------------------*/
1866
1867v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1868{
1869 return countryInfoTable.countryInfo[0].regDomain;
1870}
1871
1872/**------------------------------------------------------------------------
1873 \brief vos_nv_getSupportedChannels() - function to return the list of
1874 supported channels
1875 \param p20MhzChannels - list of 20 Mhz channels
1876 \param pNum20MhzChannels - number of 20 Mhz channels
1877 \param p40MhzChannels - list of 40 Mhz channels
1878 \param pNum40MhzChannels - number of 40 Mhz channels
1879 \return status of the NV read operation
1880 \Note: 40Mhz not currently supported
1881 \sa
1882 -------------------------------------------------------------------------*/
1883VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1884 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1885{
1886 VOS_STATUS status = VOS_STATUS_E_INVAL;
1887 int i, count = 0;
1888
1889 if( p20MhzChannels && pNum20MhzChannels )
1890 {
1891 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1892 {
1893 for( i = 0; i <= RF_CHAN_14; i++ )
1894 {
1895 p20MhzChannels[count++] = rfChannels[i].channelNum;
1896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1898 {
1899 p20MhzChannels[count++] = rfChannels[i].channelNum;
1900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001901 status = VOS_STATUS_SUCCESS;
1902 }
1903 *pNum20MhzChannels = count;
1904 }
1905
1906 return (status);
1907}
1908
1909/**------------------------------------------------------------------------
1910 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1911 \param table data - a union to return the default country table data in.
1912 \return status of the NV read operation
1913 \sa
1914 -------------------------------------------------------------------------*/
1915VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1916{
Amar Singhalfddc28c2013-09-05 13:03:40 -07001917
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001918 VOS_STATUS status = VOS_STATUS_SUCCESS;
1919 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1920 pr_info("DefaultCountry is %c%c\n",
1921 tableData->defaultCountryTable.countryCode[0],
1922 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 return status;
1924}
1925
1926/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07001927 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 \param pBuffer - to return the buffer address
1929 pSize - buffer size.
1930 \return status of the NV read operation
1931 \sa
1932 -------------------------------------------------------------------------*/
1933VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1934{
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 /* Send the NV structure and size */
1936 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1937 *pSize = sizeof(sHalNv);
1938
1939 return VOS_STATUS_SUCCESS;
1940}
1941
Jeff Johnson295189b2012-06-20 16:38:30 -07001942/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001943 \brief vos_nv_getBuffer -
1944 \param pBuffer - to return the buffer address
1945 pSize - buffer size.
1946 \return status of the NV read operation
1947 \sa
1948 -------------------------------------------------------------------------*/
1949VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1950{
1951 /* Send the NV structure and size */
1952 VOS_STATUS status;
1953
1954 status = vos_nv_isEmbeddedNV();
1955
1956 if (VOS_STATUS_SUCCESS == status)
1957 {
1958 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
1959 *pSize = nvReadEncodeBufSize;
1960 }
1961 else
1962 {
1963 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1964 *pSize = sizeof(sHalNv);
1965 }
1966
1967 return VOS_STATUS_SUCCESS;
1968}
1969
1970
1971VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1972{
1973 /* Send the NV structure and size */
1974 *pNvBuffer = (v_VOID_t *)(pDictFile);
1975 *pSize = nDictionarySize;
1976
1977 return VOS_STATUS_SUCCESS;
1978}
1979
1980VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
1981{
1982 if (MAGIC_NUMBER == magicNumber)
1983 {
1984 return VOS_STATUS_SUCCESS;
1985 }
1986
1987 return VOS_STATUS_E_FAILURE;
1988}
1989
1990VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
1991{
1992 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
1993 (size-sizeof(v_U32_t)));
1994
1995 return VOS_STATUS_SUCCESS;
1996}
1997
1998/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07001999 \brief vos_nv_setRegDomain -
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 \param clientCtxt - Client Context, Not used for PRIMA
2001 regId - Regulatory Domain ID
2002 \return status set REG domain operation
2003 \sa
2004 -------------------------------------------------------------------------*/
2005VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
2006{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05302007 v_CONTEXT_t pVosContext = NULL;
2008 hdd_context_t *pHddCtx = NULL;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002009
Jeff Johnson295189b2012-06-20 16:38:30 -07002010 /* Client Context Argumant not used for PRIMA */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302011 if (regId >= REGDOMAIN_COUNT)
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 {
2013 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2014 "VOS set reg domain, invalid REG domain ID %d", regId);
2015 return VOS_STATUS_E_INVAL;
2016 }
2017
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302018 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2019 if (NULL != pVosContext)
2020 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2021 else
2022 return VOS_STATUS_E_EXISTS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 /* Set correct channel information based on REG Domain */
2024 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
2025
2026 return VOS_STATUS_SUCCESS;
2027}
2028
2029/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002030 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 \param rfChannel - input channel enum to know evabled state
2032 \return eNVChannelEnabledType enabled state for channel
2033 * enabled
2034 * disabled
2035 * DFS
2036 \sa
2037 -------------------------------------------------------------------------*/
2038eNVChannelEnabledType vos_nv_getChannelEnabledState
2039(
2040 v_U32_t rfChannel
2041)
2042{
2043 v_U32_t channelLoop;
2044 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2045
2046 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2047 {
2048 if(rfChannels[channelLoop].channelNum == rfChannel)
2049 {
2050 channelEnum = (eRfChannels)channelLoop;
2051 break;
2052 }
2053 }
2054
2055 if(INVALID_RF_CHANNEL == channelEnum)
2056 {
2057 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002058 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 return NV_CHANNEL_INVALID;
2060 }
2061
2062 return regChannels[channelEnum].enabled;
2063}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002064
2065/******************************************************************
Amar Singhalfddc28c2013-09-05 13:03:40 -07002066 Add driver/linux regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002067*******************************************************************/
Amar Singhalfddc28c2013-09-05 13:03:40 -07002068#ifdef CONFIG_ENABLE_LINUX_REG
2069
2070/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2071 start freq + 10000 = center freq of the 20MHz start channel
2072 end freq - 10000 = center freq of the 20MHz end channel
2073 start freq + 20000 = center freq of the 40MHz start channel
2074 end freq - 20000 = center freq of the 40MHz end channel
2075*/
2076static int bw20_start_freq_to_channel_index(u32 freq_khz)
2077{
2078 int i;
2079 u32 center_freq = freq_khz + 10000;
2080
2081 /* Has to compare from low freq to high freq */
2082
2083 /* RF_SUBBAND_2_4_GHZ */
2084 for (i = RF_CHAN_1; i <= RF_CHAN_14; i++)
2085 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2086 return i;
2087
2088 /* RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216 */
2089 for (i = RF_CHAN_240; i <= RF_CHAN_216; i++)
2090 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2091 return i;
2092
2093 /* RF_SUBBAND_5_LOW_GHZ */
2094 for (i = RF_CHAN_36; i <= RF_CHAN_64; i++)
2095 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2096 return i;
2097
2098 /* RF_SUBBAND_5_MID_GHZ */
2099 for (i = RF_CHAN_100; i <= RF_CHAN_140; i++)
2100 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2101 return i;
2102
2103 /* RF_SUBBAND_5_HIGH_GHZ */
2104 for (i = RF_CHAN_149; i <= RF_CHAN_165; i++)
2105 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2106 return i;
2107
2108 return -1;
2109}
2110
2111static int bw20_end_freq_to_channel_index(u32 freq_khz)
2112{
2113 int i;
2114 u32 center_freq = freq_khz - 10000;
2115
2116 /* Has to compare from high freq to low freq */
2117
2118 /* RF_SUBBAND_5_HIGH_GHZ */
2119 for (i = RF_CHAN_165; i >= RF_CHAN_149; i--)
2120 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2121 return i;
2122
2123 /* RF_SUBBAND_5_MID_GHZ */
2124 for (i = RF_CHAN_140; i >= RF_CHAN_100; i--)
2125 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2126 return i;
2127
2128 /* RF_SUBBAND_5_LOW_GHZ */
2129 for (i = RF_CHAN_64; i >= RF_CHAN_36; i--)
2130 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2131 return i;
2132
2133 /* RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240 */
2134 for (i = RF_CHAN_216;i >= RF_CHAN_240; i--)
2135 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2136 return i;
2137
2138 /* RF_SUBBAND_2_4_GHZ */
2139 for (i = RF_CHAN_14; i >= RF_CHAN_1; i--)
2140 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2141 return i;
2142
2143 return -1;
2144}
2145
2146static int bw40_start_freq_to_channel_index(u32 freq_khz)
2147{
2148 int i;
2149 u32 center_freq = freq_khz + 20000;
2150
2151 /* Has to compare from low freq to high freq */
2152
2153 /* RF_SUBBAND_2_4_GHZ */
2154 for (i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++)
2155 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2156 return i;
2157
2158 /* RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214 */
2159 for (i = RF_CHAN_BOND_242; i <= RF_CHAN_BOND_214; i++)
2160 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2161 return i;
2162
2163 /* RF_SUBBAND_5_LOW_GHZ */
2164 for (i = RF_CHAN_BOND_38; i<= RF_CHAN_BOND_62; i++)
2165 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2166 return i;
2167
2168 /* RF_SUBBAND_5_MID_GHZ */
2169 for (i = RF_CHAN_BOND_102; i <= RF_CHAN_BOND_138; i++)
2170 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2171 return i;
2172
2173 /* RF_SUBBAND_5_HIGH_GHZ */
2174 for (i = RF_CHAN_BOND_151;i <= RF_CHAN_BOND_163; i++)
2175 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2176 return i;
2177
2178 return -1;
2179}
2180
2181static int bw40_end_freq_to_channel_index(u32 freq_khz)
2182{
2183 int i;
2184 u32 center_freq = freq_khz - 20000;
2185
2186 /* Has to compare from high freq to low freq */
2187
2188 /* RF_SUBBAND_5_HIGH_GHZ */
2189 for (i = RF_CHAN_BOND_163; i >= RF_CHAN_BOND_151; i--)
2190 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2191 return i;
2192
2193 /* RF_SUBBAND_5_MID_GHZ */
2194 for (i = RF_CHAN_BOND_138; i >= RF_CHAN_BOND_102; i--)
2195 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2196 return i;
2197
2198 /* RF_SUBBAND_5_LOW_GHZ */
2199 for (i = RF_CHAN_BOND_62; i >= RF_CHAN_BOND_38; i--)
2200 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2201 return i;
2202
2203 /* RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242 */
2204 for (i = RF_CHAN_BOND_214; i >= RF_CHAN_BOND_242; i--)
2205 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2206 return i;
2207
2208 /* RF_SUBBAND_2_4_GHZ */
2209 for (i = RF_CHAN_BOND_11; i >= RF_CHAN_BOND_3; i--)
2210 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2211 return i;
2212
2213 return -1;
2214}
2215
2216static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2217{
2218 switch (nBandCapability)
2219 {
2220 case eCSR_BAND_ALL:
2221 return VOS_TRUE;
2222
2223 case eCSR_BAND_24:
2224 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2225 return VOS_TRUE;
2226 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2227 return VOS_TRUE; /* 2.4G 40MHz channel */
2228 break;
2229
2230 case eCSR_BAND_5G:
2231 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2232 return VOS_TRUE;
2233 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2234 return VOS_TRUE; /* 5G 40MHz channel */
2235 break;
2236 default:
2237 break;
2238 }
2239 return VOS_FALSE;
2240}
2241
2242
2243/* create_linux_regulatory_entry should */
2244static void create_linux_regulatory_entry_driver(struct wiphy *wiphy,
2245 struct regulatory_request *request,
2246 v_U8_t nBandCapability,
2247 v_REGDOMAIN_t domain_id)
2248{
2249 int i, j, n;
2250 int bw20_start_channel_index, bw20_end_channel_index;
2251 int bw40_start_channel_index, bw40_end_channel_index;
2252
Amar Singhalf0073192013-09-20 12:34:56 -07002253 if (NULL == wiphy->regd)
2254 return;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002255
2256 for (n = 0; n < NUM_RF_CHANNELS; n++)
2257 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
2258 NV_CHANNEL_DISABLE;
2259
2260 for (i = 0; i < wiphy->regd->n_reg_rules; i++)
2261 {
2262
2263 wiphy_dbg(wiphy, "info: rule %d --------------------------------------------\n", i);
2264
2265 bw20_start_channel_index =
2266 bw20_start_freq_to_channel_index(
2267 wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2268
2269 bw20_end_channel_index =
2270 bw20_end_freq_to_channel_index(
2271 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2272
2273 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2274 {
2275 wiphy_dbg(wiphy, "error: freq not supported, start freq (KHz) %d end freq %d\n",
2276 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2277 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2278 continue; /* skip this rule, but continue to next rule */
2279 }
2280
2281 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2282 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2283 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2284 bw20_start_channel_index, bw20_end_channel_index);
2285
2286 for (j = bw20_start_channel_index; j <= bw20_end_channel_index; j++)
2287 {
2288
2289 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2290 {
2291 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2292 rfChannels[j].channelNum);
2293 continue; /* skip this channel, continue to next */
2294 }
2295
2296 if ((wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_PASSIVE_SCAN) ||
2297 (wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_RADAR))
2298 {
2299 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2300 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2301 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2302 }
2303 else
2304 {
2305 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2306 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2307 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2308 }
2309
2310 /* max_eirp is in mBm (= 100 * dBm) unit */
2311 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2312 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2313 }
2314
2315 /* ignore max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2316 real gain which should be provided by the real design */
2317 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz >= 40000)
2318 {
2319
2320 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2321 bw40_start_channel_index =
2322 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2323 bw40_end_channel_index =
2324 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2325
2326 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2327 {
2328 wiphy_dbg(wiphy, "error: req not supported, start_freq_khz %d end_freq_khz %d\n",
2329 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2330 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2331 continue; /* skip this rull, but continue to next rule */
2332 }
2333
2334 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2335 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2336 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2337 bw40_start_channel_index, bw40_end_channel_index);
2338
2339 for (j = bw40_start_channel_index; j <= bw40_end_channel_index; j++)
2340 {
2341 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2342 continue; /* skip this channel, continue to next */
2343
2344 if ((wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_PASSIVE_SCAN) ||
2345 (wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_RADAR))
2346 {
2347 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2348 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2349 }
2350 else
2351 {
2352 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2353 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2354 }
2355
2356 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2357 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2358 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2359 }
2360 }
2361 }
2362
2363}
2364
2365/*
2366 note: these functions may get used at a later point in time
2367
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002368
2369static int bw20_ch_index_to_bw40_ch_index(int k)
2370{
2371 int m = -1;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002372
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002373 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2374 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002375 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2376 if (m > RF_CHAN_BOND_11)
2377 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002378 }
2379 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2380 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002381 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2382 if (m > RF_CHAN_BOND_214)
2383 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002384 }
2385 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2386 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002387 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2388 if (m > RF_CHAN_BOND_62)
2389 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002390 }
2391 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
2392 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002393 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
2394 if (m > RF_CHAN_BOND_138)
2395 m = RF_CHAN_BOND_138;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002396 }
2397 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2398 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002399 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2400 if (m > RF_CHAN_BOND_163)
2401 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002402 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002403
2404 return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002405}
2406
Amar Singhalfddc28c2013-09-05 13:03:40 -07002407
2408static int create_linux_regulatory_entry_other(struct wiphy *wiphy,
2409 struct regulatory_request *request,
2410 v_U8_t nBandCapability,
2411 v_REGDOMAIN_t domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002412{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002413 int i, j, m;
2414 int k = 0, n = 0;
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002415
Amar Singhalfddc28c2013-09-05 13:03:40 -07002416 if (pnvEFSTable == NULL)
2417 {
2418 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2419 return -1;
2420 }
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002421
Amar Singhalfddc28c2013-09-05 13:03:40 -07002422 //20MHz channels
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002423 if (nBandCapability == eCSR_BAND_24)
2424 pr_info("BandCapability is set to 2G only.\n");
Amar Singhalfddc28c2013-09-05 13:03:40 -07002425
2426 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002427 {
2428 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2429 continue;
2430 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2431 continue;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002432
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002433 if (wiphy->bands[i] == NULL)
2434 {
2435 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2436 return -1;
2437 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002438
2439 //internal channels[] is one continous array for both 2G and 5G bands
2440 //m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002441 if (i == 0)
2442 m = 0;
2443 else
2444 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002445
2446 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002447 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002448 //k = (m + j) is internal current channel index for 20MHz channel
2449 //n is internal channel index for corresponding 40MHz channel
2450
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002451 k = m + j;
2452 n = bw20_ch_index_to_bw40_ch_index(k);
Amar Singhalfddc28c2013-09-05 13:03:40 -07002453
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002454 if (n == -1)
Amar Singhalfddc28c2013-09-05 13:03:40 -07002455 return -1;
2456
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002457 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2458 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002459
2460 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2461 NV_CHANNEL_DISABLE;
2462 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
2463 NV_CHANNEL_DISABLE;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002464 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002465
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002466 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2467 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002468 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2469 NV_CHANNEL_DFS;
2470
2471 // max_power is in mBm = 100 * dBm
2472 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit =
2473 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2474 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2475 {
2476 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
2477 NV_CHANNEL_DFS;
2478 // 40MHz channel power is half of 20MHz (-3dB) ??
2479 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].pwrLimit =
2480 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2481 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002482 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002483
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002484 else // Enable is only last flag we support
2485 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002486 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2487 NV_CHANNEL_ENABLE;
2488
2489 // max_power is in dBm
2490 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit =
2491 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2492 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2493 {
2494 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
2495 NV_CHANNEL_ENABLE;
2496
2497 // 40MHz channel power is half of 20MHz (-3dB) ??
2498 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].pwrLimit =
2499 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2500 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002501 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002502
2503 // ignore max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2504 // real gain which should be provided by the real design
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002505 }
2506 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002507
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002508 if (k == 0)
2509 return -1;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002510
2511 return 0;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002512}
2513
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002514*/
Amar Singhalfddc28c2013-09-05 13:03:40 -07002515/**------------------------------------------------------------------------
2516 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
2517 a country given its country code
2518 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
2519 a country given its country code. This is done from reading a cached
2520 copy of the binary file.
2521 \param pRegDomain - pointer to regulatory domain
2522 \param countryCode - country code
2523 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
2524 VOS_STATUS_E_FAULT - invalid pointer error
2525 VOS_STATUS_E_EMPTY - country code table is empty
2526 VOS_STATUS_E_EXISTS - given country code does not exist in table
2527 \sa
2528 -------------------------------------------------------------------------*/
2529VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
2530 const v_COUNTRYCODE_t countryCode )
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002531{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002532 v_CONTEXT_t pVosContext = NULL;
2533 hdd_context_t *pHddCtx = NULL;
2534 struct wiphy *wiphy = NULL;
2535 int i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002536
Amar Singhalfddc28c2013-09-05 13:03:40 -07002537 /* sanity checks */
2538 if (NULL == pRegDomain)
2539 {
2540 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2541 ("Invalid reg domain pointer") );
2542 return VOS_STATUS_E_FAULT;
2543 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002544
Amar Singhalfddc28c2013-09-05 13:03:40 -07002545 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002546
Amar Singhalfddc28c2013-09-05 13:03:40 -07002547 if (NULL == countryCode)
2548 {
2549 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2550 ("Country code array is NULL"));
2551 return VOS_STATUS_E_FAULT;
2552 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002553
Amar Singhalfddc28c2013-09-05 13:03:40 -07002554 if (0 == countryInfoTable.countryCount)
2555 {
2556 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2557 ("Reg domain table is empty") );
2558 return VOS_STATUS_E_EMPTY;
2559 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002560
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002561
Amar Singhalfddc28c2013-09-05 13:03:40 -07002562 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002563
Amar Singhalfddc28c2013-09-05 13:03:40 -07002564 if (NULL != pVosContext)
2565 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2566 else
2567 return VOS_STATUS_E_EXISTS;
2568
2569 if (NULL == pHddCtx)
2570 {
2571 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2572 ("Invalid pHddCtx pointer") );
2573 return VOS_STATUS_E_FAULT;
2574 }
2575
2576 wiphy = pHddCtx->wiphy;
2577
2578
2579 /* We need to query the kernel to get the regulatory information
2580 for this country */
2581
2582
2583 if (VOS_FALSE == linux_regulatory_init) {
2584
2585 /* linux regulatory has not been initialized yet; so the country
2586 information stored with us would not be correct */
2587
2588 /* lookup the country in the local database */
2589
2590 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2591 ("init time regdomain request") );
2592
2593 temp_reg_domain = REGDOMAIN_COUNT;
2594 for (i = 0; i < countryInfoTable.countryCount &&
2595 REGDOMAIN_COUNT == temp_reg_domain; i++)
2596 {
2597 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
2598 VOS_COUNTRY_CODE_LEN) == 0)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002599 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002600 /* country code is found */
2601 /* record the temporary regulatory_domain as well */
2602 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002603 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002604 }
2605
2606 if (REGDOMAIN_COUNT == temp_reg_domain) {
2607 /* the country was not found in the driver database */
2608 /* therefore switch to world regulatory domain */
2609
2610 *pRegDomain = REGDOMAIN_WORLD;
2611 cur_reg_domain = *pRegDomain;
2612 linux_reg_cc[0] = '0';
2613 linux_reg_cc[1] = '0';
2614 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
2615 *pRegDomain;
2616
2617 /* since it is the world domain, we are guaranteed
2618 the entry exists in the kernel regulatory database */
2619
2620 kernel_reg_request_made = VOS_TRUE;
2621 driver_callback_called = VOS_FALSE;
2622
2623 init_completion(&pHddCtx->linux_reg_req);
2624 regulatory_hint(wiphy, linux_reg_cc);
2625 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2626 LINUX_REG_WAIT_TIME);
2627
2628 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2629 ("country code is not found in driver db"));
2630
2631 linux_regulatory_init = VOS_TRUE;
2632 return VOS_STATUS_E_EXISTS;
2633 }
2634
2635 else {
2636 /* the country code was found in the driver database */
2637 /* now get the regulatory information from the kernel
2638 database */
2639
2640 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2641 ("country code found in driver db"));
2642
2643 kernel_reg_request_made = VOS_TRUE;
2644 driver_callback_called = VOS_FALSE;
2645
2646 init_completion(&pHddCtx->linux_reg_req);
2647 regulatory_hint(wiphy, countryCode);
2648 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2649 LINUX_REG_WAIT_TIME);
2650
2651 /* if the country information does not exist with the kernel, then
2652 the driver callback would not be called */
2653
2654 if (VOS_TRUE == driver_callback_called) {
2655
2656 /* the driver callback was called. this means the country
2657 regulatory information was found in the kernel database.
2658 The callback would have updated the internal database. Here
2659 update the country and the return value for the regulatory
2660 domain */
2661
2662 *pRegDomain = temp_reg_domain;
2663 cur_reg_domain = temp_reg_domain;
2664 linux_reg_cc[0] = countryCode[0];
2665 linux_reg_cc[1] = countryCode[1];
2666 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
2667 *pRegDomain;
2668
2669 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2670 ("country code is found in kernel db"));
2671
2672 linux_regulatory_init = VOS_TRUE;
2673 return VOS_STATUS_SUCCESS;
2674 }
2675 else {
2676
2677 /* the country information has not been found in the kernel
2678 database, revert to world domain */
2679
2680 *pRegDomain = REGDOMAIN_WORLD;
2681 cur_reg_domain = *pRegDomain;
2682 linux_reg_cc[0] = '0';
2683 linux_reg_cc[1] = '0';
2684 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
2685 *pRegDomain;
2686
2687 /* since it is the world domain, we are guaranteed
2688 the entry exists in the kernel regulatory database */
2689
2690 kernel_reg_request_made = VOS_TRUE;
2691 driver_callback_called = VOS_FALSE;
2692
2693 init_completion(&pHddCtx->linux_reg_req);
2694 regulatory_hint(wiphy, linux_reg_cc);
2695 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2696 LINUX_REG_WAIT_TIME);
2697
2698 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2699 ("country code is not found in kernel db"));
2700
2701 linux_regulatory_init = VOS_TRUE;
2702 return VOS_STATUS_E_EXISTS;
2703 }
2704 }
2705 }
2706 else {
2707 /* it is not the init time query but a runtime query. So first
2708 compare the country code with the existing current country code
2709 . If both are same there is no need to query any database */
2710
2711 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2712 ("run time regdomain request"));
2713
2714 if ((countryCode[0] == linux_reg_cc[0]) &&
2715 (countryCode[1] == linux_reg_cc[1])) {
2716
2717 /* country code already exists */
2718 *pRegDomain = cur_reg_domain;
2719
2720 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2721 ("NOT NEW country code"));
2722
2723 return VOS_STATUS_SUCCESS;
2724 }
2725 else {
2726
2727 /* first lookup the country in the local database */
2728
2729 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2730 ("NEW country code"));
2731
2732 for (i = 0; i < countryInfoTable.countryCount &&
2733 REGDOMAIN_COUNT == temp_reg_domain; i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002734 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002735 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
2736 VOS_COUNTRY_CODE_LEN) == 0)
2737 {
2738 /* country code is found */
2739 /* record the temporary regulatory_domain as well */
2740 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
2741 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002742 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002743
2744 if (REGDOMAIN_COUNT == temp_reg_domain) {
2745
2746 /* the country was not found in the driver database */
2747 /* therefore switch to world regulatory domain */
2748
2749 *pRegDomain = REGDOMAIN_WORLD;
2750 cur_reg_domain = *pRegDomain;
2751 linux_reg_cc[0] = countryCode[0];
2752 linux_reg_cc[1] = countryCode[1];
2753
2754 /* since it is the world domain, we are guaranteed
2755 the entry exists in the kernel regulatory database */
2756
2757 kernel_reg_request_made = VOS_TRUE;
2758 driver_callback_called = VOS_FALSE;
2759
2760 init_completion(&pHddCtx->linux_reg_req);
2761 regulatory_hint(wiphy, linux_reg_cc);
2762 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2763 LINUX_REG_WAIT_TIME);
2764
2765 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2766 ("country code is not found in driver db"));
2767
2768 return VOS_STATUS_E_EXISTS;
2769 }
2770
2771 else {
2772
2773 /* the country code was found in the driver database */
2774 /* now get the regulatory information from the kernel
2775 database */
2776
2777 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2778 ("country code found in driver db"));
2779
2780 kernel_reg_request_made = VOS_TRUE;
2781 driver_callback_called = VOS_FALSE;
2782
2783 init_completion(&pHddCtx->linux_reg_req);
2784 regulatory_hint(wiphy, countryCode);
2785 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2786 LINUX_REG_WAIT_TIME);
2787
2788 /* if the country information does not exist with the kernel,
2789 then the driver callback would not be called */
2790
2791 if (VOS_TRUE == driver_callback_called) {
2792
2793 /* the driver callback was called. this means the country
2794 regulatory information was found in the kernel database.
2795 The callback would have updated the internal database. Here
2796 update the country and the return value for the regulatory
2797 domain */
2798
2799 *pRegDomain = temp_reg_domain;
2800 cur_reg_domain = temp_reg_domain;
2801 linux_reg_cc[0] = countryCode[0];
2802 linux_reg_cc[1] = countryCode[1];
2803
2804 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2805 ("country code is found in kernel db"));
2806
2807 return VOS_STATUS_SUCCESS;
2808 }
2809 else {
2810
2811 /* the country information has not been found in the kernel
2812 database, revert to world domain */
2813
2814 *pRegDomain = REGDOMAIN_WORLD;
2815 cur_reg_domain = *pRegDomain;
2816 linux_reg_cc[0] = countryCode[0];
2817 linux_reg_cc[1] = countryCode[1];
2818
2819 /* since it is the world domain, we are guaranteed
2820 the entry exists in the kernel regulatory database */
2821
2822 kernel_reg_request_made = VOS_TRUE;
2823 driver_callback_called = VOS_FALSE;
2824
2825 init_completion(&pHddCtx->linux_reg_req);
2826 regulatory_hint(wiphy, linux_reg_cc);
2827 wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
2828 LINUX_REG_WAIT_TIME);
2829
2830 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2831 ("country code is not found in kernel db"));
2832
2833 return VOS_STATUS_E_EXISTS;
2834 }
2835 }
2836 }
2837 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002838}
2839
2840/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07002841 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002842 * This function is called from cfg80211 core to provide regulatory settings
2843 * after new country is requested or intersected (init, user input or 11d)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002844 */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2846void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07002847 struct regulatory_request *request)
2848#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07002849void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002850 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07002851#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002852{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002853
2854 v_REGDOMAIN_t reg_domain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002855 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Amar Singhalfddc28c2013-09-05 13:03:40 -07002856
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002857 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
Amar Singhalfddc28c2013-09-05 13:03:40 -07002858 " %c%c\n", request->alpha2[0], request->alpha2[1]);
2859
2860 /* first check if this callback is in response to the driver callback */
2861
2862 if (VOS_TRUE == kernel_reg_request_made) {
2863
2864
2865 /* this is the driver query to the kernel. the regulatory domain was
2866 temporarily calculated by the entity that made the kernel query.
2867 Use that to update the internal database */
2868
2869 reg_domain = temp_reg_domain;
2870 create_linux_regulatory_entry_driver(wiphy, request,
2871 pHddCtx->cfg_ini->nBandCapability,
2872 reg_domain);
2873
2874 driver_callback_called = VOS_TRUE;
2875 kernel_reg_request_made = VOS_FALSE;
2876
Amar Singhalf0073192013-09-20 12:34:56 -07002877 complete(&pHddCtx->linux_reg_req);
2878
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002879 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002880 else {
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002881
Amar Singhalfddc28c2013-09-05 13:03:40 -07002882
2883 /* this callback is not in response to driver callback.
2884 we should contact the lower layers(sme_ChangeCountryCode ??)
2885 with this information. Depending on whether the lower layer
2886 recommends changing the country code or not, we can update the
2887 internal database */
2888
2889 /*
2890 ret_val = create_linux_regulatory_entry_other(wiphy, request,
2891 pHddCtx->cfg_ini->nBandCapability,
2892 reg_domain);
2893 */
2894
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002895 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05302896
Yue Maf49ba872013-08-19 12:04:25 -07002897 return;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002898}
Amar Singhalfddc28c2013-09-05 13:03:40 -07002899
2900
2901#else
2902
2903/**------------------------------------------------------------------------
2904 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
2905 a country given its country code
2906 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
2907 a country given its country code. This is done from reading a cached
2908 copy of the binary file.
2909 \param pRegDomain - pointer to regulatory domain
2910 \param countryCode - country code
2911 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
2912 VOS_STATUS_E_FAULT - invalid pointer error
2913 VOS_STATUS_E_EMPTY - country code table is empty
2914 VOS_STATUS_E_EXISTS - given country code does not exist in table
2915 \sa
2916 -------------------------------------------------------------------------*/
2917VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
2918 const v_COUNTRYCODE_t countryCode )
2919{
2920 int i;
2921
2922 if (NULL == pRegDomain)
2923 {
2924 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2925 ("Invalid reg domain pointer") );
2926 return VOS_STATUS_E_FAULT;
2927 }
2928
2929 *pRegDomain = REGDOMAIN_COUNT;
2930
2931 if (NULL == countryCode)
2932 {
2933 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2934 ("Country code array is NULL") );
2935 return VOS_STATUS_E_FAULT;
2936 }
2937
2938 if (0 == countryInfoTable.countryCount)
2939 {
2940 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2941 ("Reg domain table is empty") );
2942 return VOS_STATUS_E_EMPTY;
2943 }
2944
2945 if (VOS_FALSE == driver_regulatory_init) {
2946
2947 /*
2948 iterate the country info table until end of table or the country code
2949 is found
2950 */
2951
2952 for (i = 0; i < countryInfoTable.countryCount &&
2953 REGDOMAIN_COUNT == *pRegDomain; i++)
2954 {
2955 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
2956 VOS_COUNTRY_CODE_LEN) == 0)
2957 {
2958 /* country code is found */
2959 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
2960 }
2961 }
2962
2963 if (REGDOMAIN_COUNT != *pRegDomain)
2964 {
2965 driver_reg_cc[0] = countryCode[0];
2966 driver_reg_cc[1] = countryCode[1];
2967 cur_reg_domain = *pRegDomain;
2968 driver_regulatory_init = VOS_TRUE;
2969
2970 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2971 ("init time country code is found in driver db"));
2972
2973 return VOS_STATUS_SUCCESS;
2974 }
2975 else
2976 {
2977 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2978 ("init time country code is not found in driver db"));
2979
2980 return VOS_STATUS_E_EXISTS;
2981 }
2982 }
2983 else {
2984 if ((countryCode[0] == driver_reg_cc[0]) &&
2985 (countryCode[1] == driver_reg_cc[1])) {
2986
2987 *pRegDomain = cur_reg_domain;
2988
2989 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2990 ("run time country code has not changed"));
2991
2992 return VOS_STATUS_SUCCESS;
2993 }
2994 else {
2995
2996 /* iterate the country info table until end of table or the
2997 country code is found
2998 */
2999
3000 for (i = 0; i < countryInfoTable.countryCount &&
3001 REGDOMAIN_COUNT == *pRegDomain; i++)
3002 {
3003 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
3004 VOS_COUNTRY_CODE_LEN) == 0)
3005 {
3006 /* country code is found */
3007 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
3008 }
3009 }
3010
3011 if (REGDOMAIN_COUNT != *pRegDomain)
3012 {
3013 driver_reg_cc[0] = countryCode[0];
3014 driver_reg_cc[1] = countryCode[1];
3015 cur_reg_domain = *pRegDomain;
3016
3017 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3018 ("run time country code is found in driver db"));
3019
3020 return VOS_STATUS_SUCCESS;
3021 }
3022 else
3023 {
3024 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3025 ("run time country code is not found in driver db"));
3026
3027 driver_reg_cc[0] = 0;
3028 driver_reg_cc[1] = 0;
3029 driver_regulatory_init = VOS_FALSE;
3030
3031 return VOS_STATUS_E_EXISTS;
3032 }
3033 }
3034 }
3035}
3036
3037#endif