blob: 2410a58e3caec016e2eda682ea267307f31c9692 [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"
Amar Singhal0d15bd52013-10-12 23:13:13 -070066#include "sme_Api.h"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070067#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070068#include "wlan_hdd_main.h"
69#include <net/cfg80211.h>
Amar Singhalfddc28c2013-09-05 13:03:40 -070070
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -070071#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
72#define IEEE80211_CHAN_NO_80MHZ 1<<7
73#endif
Amar Singhala49cbc52013-10-08 18:37:44 -070074
Amar Singhalfddc28c2013-09-05 13:03:40 -070075#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhala49cbc52013-10-08 18:37:44 -070076
77static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -070078static char linux_reg_cc[2] = {0, 0};
Amar Singhalfddc28c2013-09-05 13:03:40 -070079static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
Amar Singhala49cbc52013-10-08 18:37:44 -070080
Abhishek Singha306a442013-11-07 18:39:01 +053081#else
82
83/* Cant access pAdapter in this file so defining a new variable to wait when changing country*/
84static struct completion change_country_code;
85
Amar Singhalfddc28c2013-09-05 13:03:40 -070086#endif
87
Amar Singhala49cbc52013-10-08 18:37:44 -070088static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
89static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
90static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
91static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
92
93
Jeff Johnson295189b2012-06-20 16:38:30 -070094/*----------------------------------------------------------------------------
95 * Preprocessor Definitions and Constants
96 * -------------------------------------------------------------------------*/
97#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
98#define VALIDITY_BITMAP_SIZE 32
99#define MAX_COUNTRY_COUNT 300
100//To be removed when NV support is fully functional
101#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700102
103#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700104#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700105
Jeff Johnson295189b2012-06-20 16:38:30 -0700106/*----------------------------------------------------------------------------
107 * Type Declarations
108 * -------------------------------------------------------------------------*/
109// this wrapper structure is identical to nv_cmd_type except the
110// data_ptr type is changed void* to avoid exceeding the debug information
111// module size as there are too many elements within nv_items_type union
112
113// structure for code and regulatory domain of a single country
114typedef struct
115{
116 v_U8_t regDomain;
117 v_COUNTRYCODE_t countryCode;
118} CountryInfo_t;
119// structure of table to map country code and regulatory domain
120typedef struct
121{
122 v_U16_t countryCount;
123 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
124} CountryInfoTable_t;
125/*----------------------------------------------------------------------------
126 * Global Data Definitions
127 * -------------------------------------------------------------------------*/
128/*----------------------------------------------------------------------------
129 * Static Variable Definitions
130 * -------------------------------------------------------------------------*/
Amar Singhala49cbc52013-10-08 18:37:44 -0700131// cache of country info table;
132// this is re-initialized from data on binary file
133// loaded on driver initialization if available
Amar Singhalfddc28c2013-09-05 13:03:40 -0700134
135#ifdef CONFIG_ENABLE_LINUX_REG
136
137static CountryInfoTable_t countryInfoTable =
138{
139 /* the first entry in the table is always the world domain */
140 138,
141 {
142 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
143 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
144 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
145 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
146 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
147 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
148 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
149 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
150 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
151 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
152 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
153 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
154 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
155 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
156 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
157 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
158 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
159 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
160 {REGDOMAIN_ETSI, {'B', 'L'}}, //
161 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
162 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
163 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
164 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
165 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
166 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
167 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
168 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
169 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
170 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
171 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
172 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
173 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
174 {REGDOMAIN_ETSI, {'C', 'S'}},
175 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
176 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
177 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
178 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
179 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
180 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
181 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
182 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
183 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
184 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
185 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
186 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
187 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
188 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
189 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
190 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
191 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
192 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
193 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
194 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
195 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
196 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
197 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
198 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
199 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
200 {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
201 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
202 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
203 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
204 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
205 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
206 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
207 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
208 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
209 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
210 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
211 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
212 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
213 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
214 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
215 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
216 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
217 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
218 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
219 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
220 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
221 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
222 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
223 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
224 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
225 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
226 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
227 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
228 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
229 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
230 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
231 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
232 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
233 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
234 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
235 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
236 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
237 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
238 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
239 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
240 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
241 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
242 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
243 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
244 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
245 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
246 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
247 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
248 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
249 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
250 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
251 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
252 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
253 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
254 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
255 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
256 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
257 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
258 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
259 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
260 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
261 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
262 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
263 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
264 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
265 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
266 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
267 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
268 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
269 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
270 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
271 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
272 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
273 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
274 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
275 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
276 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
277 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
278 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
279 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
280 }
281};
282
283#else
284
Jeff Johnson295189b2012-06-20 16:38:30 -0700285// cache of country info table;
286// this is re-initialized from data on binary file
287// loaded on driver initialization if available
288static CountryInfoTable_t countryInfoTable =
289{
290 254,
291 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700292 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
293 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
294 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
295 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
296 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
297 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700298 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700299 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
300 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
301 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
302 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
303 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
304 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
305 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530306 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700307 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
308 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
309 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
310 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
311 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700312 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700313 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
314 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
315 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
316 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
317 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
318 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
319 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
320 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
321 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
322 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
323 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
324 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
325 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
326 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
327 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
328 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
329 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
330 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
331 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
332 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
333 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
334 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
335 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
336 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
337 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
338 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530339 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700340 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
341 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
342 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
343 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
344 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
345 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
346 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
347 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
348 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
349 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
350 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
351 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700352 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700353 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
354 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
355 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
356 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
357 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
358 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
359 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
360 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
361 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
362 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
363 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
364 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
365 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
366 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
367 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
368 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
369 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
370 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
371 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
372 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
373 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
374 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
375 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
376 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
377 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
378 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
379 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
380 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
381 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
382 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700383 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700384 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
385 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
386 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
387 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
388 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
389 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
390 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
391 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
392 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
393 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700394 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700395 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
396 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
397 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
398 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
399 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
400 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
401 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
402 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
403 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
404 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
405 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
406 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
407 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
408 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700409 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700410 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
411 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
412 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
413 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
414 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700415 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700416 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
417 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
418 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
419 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
420 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
421 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
422 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
423 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
424 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700425 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700426 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700427 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700428 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
429 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
430 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
431 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
432 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
433 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
434 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
435 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
436 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700437 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700438 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700439 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
440 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
441 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
442 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
443 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
444 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
445 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700446 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700447 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
448 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
449 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
450 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
451 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
452 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
453 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
454 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
455 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
456 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
457 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
458 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
459 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
460 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
461 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
462 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
463 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
464 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
465 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
466 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700467 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700468 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
469 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
470 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700471 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700472 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700473 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700474 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700475 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
476 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700477 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
478 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
479 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
480 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
481 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
482 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
483 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
484 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
485 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
486 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
487 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
488 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
489 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700490 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
491 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
492 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700493 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
494 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
495 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
496 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
497 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
498 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
499 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
500 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
501 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
502 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
503 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
504 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
505 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
506 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
507 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
508 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
509 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
510 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
511 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
512 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
513 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
514 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
515 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
516 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
517 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
518 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
519 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
520 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
521 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700522 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700523 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
524 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700525 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700526 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700527 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
528 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700529 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
530 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700531 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700532 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
533 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
534 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
535 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
536 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700537 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700538 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
539 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
540 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
541 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
542 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
543 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
544 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700545 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700546 }
547};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700548
549#endif
550
Amar Singhala49cbc52013-10-08 18:37:44 -0700551
Jeff Johnson295189b2012-06-20 16:38:30 -0700552typedef struct nvEFSTable_s
553{
554 v_U32_t nvValidityBitmap;
555 sHalNv halnv;
556} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700557nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700558/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700559static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700560static v_U8_t *pnvEncodedBuf;
561static v_U8_t *pDictFile;
562static v_U8_t *pEncodedBuf;
563static v_SIZE_t nvReadEncodeBufSize;
564static v_SIZE_t nDictionarySize;
565static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang80de3c22013-11-26 10:52:12 -0800567/* NV2 specific, No CH 144 support
568 * For NV_FTM operation, NV2 structure should be maintained
569 * This will be used only for the NV_FTM operation */
570typedef struct nvEFSTableV2_s
571{
572 v_U32_t nvValidityBitmap;
573 sHalNvV2 halnvV2;
574} nvEFSTableV2_t;
575nvEFSTableV2_t *gnvEFSTableV2;
576
Jeff Johnson295189b2012-06-20 16:38:30 -0700577const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
578{
579 //RF_SUBBAND_2_4_GHZ
580 //freq, chan#, band
581 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
582 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
583 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
584 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
585 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
586 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
587 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
588 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
589 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
590 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
591 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
592 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
593 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
594 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700595 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
596 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
597 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
598 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
599 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
600 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
601 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
603 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
604 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
605 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
606 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
607 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
608 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
609 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
610 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
611 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
612 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
613 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
614 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
615 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
616 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
617 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
618 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
619 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
620 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
Leo Chang80de3c22013-11-26 10:52:12 -0800621#ifdef FEATURE_WLAN_CH144
622 { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144,
623#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
625 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
626 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
627 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
628 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700629 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
630 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
631 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
632 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
633 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
634 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
635 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
636 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
637 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
638 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
639 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
640 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
641 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
642 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
643 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
644 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
645 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
646 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
647 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
648 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
649 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
650 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
651 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
652 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
653 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
654 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
655 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
656 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
657 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
658 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
659 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
Leo Chang80de3c22013-11-26 10:52:12 -0800660#ifdef FEATURE_WLAN_CH144
661 { 5730, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142,
662#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700663 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
664 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
665 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
666 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700667};
668
669extern const sHalNv nvDefaults;
670
671const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
672
673/*----------------------------------------------------------------------------
674 Function Definitions and Documentation
675 * -------------------------------------------------------------------------*/
676VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
677/**------------------------------------------------------------------------
678 \brief vos_nv_init() - initialize the NV module
679 The \a vos_nv_init() initializes the NV module. This read the binary
680 file for country code and regulatory domain information.
681 \return VOS_STATUS_SUCCESS - module is initialized successfully
682 otherwise - module is not initialized
683 \sa
684 -------------------------------------------------------------------------*/
685VOS_STATUS vos_nv_init(void)
686{
687 return VOS_STATUS_SUCCESS;
688}
689
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700690/**------------------------------------------------------------------------
691 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
692 \ tools
693 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
694 otherwise - not successful
695 \sa
696-------------------------------------------------------------------------*/
697VOS_STATUS vos_nv_get_dictionary_data(void)
698{
699 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
700
701 if (MAGIC_NUMBER != magicNumber)
702 {
703 return VOS_STATUS_SUCCESS;
704 }
705
706 nDictionarySize = 0;
707
708 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
709 &nDictionarySize );
710 if (VOS_STATUS_E_NOMEM != vosStatus)
711 {
712 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
713 "Error obtaining binary size" );
714/// NOTE:
715/// We can still work without a dictionary file..
716 return VOS_STATUS_SUCCESS;
717 }
718
719 // malloc a buffer to read in the Configuration binary file.
720 pDictFile = vos_mem_malloc( nDictionarySize );
721 if (NULL == pDictFile)
722 {
723 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
724 "Unable to allocate memory for the CFG binary [size= %d bytes]",
725 nDictionarySize );
726 vosStatus = VOS_STATUS_E_NOMEM;
727 goto fail;
728 }
729
730 /* Get the entire CFG file image... */
731 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
732 &nDictionarySize );
733 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
734 {
735 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
736 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
737 nDictionarySize );
738 return VOS_STATUS_SUCCESS;
739 }
740
741 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
742 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
743
744fail:
745 return vosStatus;
746}
747
Leo Chang80de3c22013-11-26 10:52:12 -0800748/**------------------------------------------------------------------------
749 \brief vos_nv_parseV2bin() - Parse NV2 binary
750 Parse NV2 BIN, and assign contents to common NV structure.
751 \param pnvEncodedBuf
752 NV Bin read buffer
753 \param nvReadBufSize
754 NV Bin read size
755 \param halNv
756 common NV structure storage pointer
757 \return VOS_STATUS_SUCCESS - module is initialized successfully
758 otherwise - module is not initialized
759 \sa
760 -------------------------------------------------------------------------*/
761VOS_STATUS vos_nv_parseV2bin(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
762 sHalNv *halNv)
763{
764 sHalNvV2 *nv2Table;
765 tANI_U16 copyLoop;
766 tANI_U16 channelLoop;
767 void *targetPtr;
768 void *sourcePtr;
769
770 v_U32_t structSize = 0;
771
772 nv2Table = (sHalNvV2 *)pnvEncodedBuf;
773 /* NV Field Default Copy */
774 vos_mem_copy((char *)&halNv->fields,
775 (char *)&nv2Table->fields,
776 sizeof(sNvFields));
777 structSize += sizeof(sNvFields);
778 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
779 "%s: sizeof(sNvFields) %zu, structSize %d",
780 __func__, sizeof(sNvFields), structSize);
781
782 /* NV Table, tRateGroupPwr, NOT depends on channel count */
783 vos_mem_copy((char *)halNv->tables.pwrOptimum,
784 (char *)nv2Table->tables.pwrOptimum,
785 sizeof(halNv->tables.pwrOptimum));
786 structSize += sizeof(halNv->tables.pwrOptimum);
787 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
788 "%s: sizeof(halNv->tables.pwrOptimum) %zu, structSize %d",
789 __func__, sizeof(halNv->tables.pwrOptimum), structSize);
790
791 /* NV Table, regDomains, edepends on channel count */
792 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
793 {
794 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].antennaGain,
795 (char *)nv2Table->tables.regDomains[copyLoop].antennaGain,
796 sizeof(halNv->tables.regDomains[copyLoop].antennaGain));
797 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
798
799 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].bRatePowerOffset,
800 (char *)nv2Table->tables.regDomains[copyLoop].bRatePowerOffset,
801 sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset));
802 structSize += sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset);
803 }
804
805 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
806 {
807 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].channels[0]);
808 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].channels[0]);
809 /* Cannot blindly copy
810 * Each single CH should be assigned */
811 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
812 {
813#ifdef FEATURE_WLAN_CH144
814 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
815 {
816 /* NV2 CH144 is disabled */
817 halNv->tables.regDomains[copyLoop].channels[channelLoop].enabled =
818 NV_CHANNEL_DISABLE;
819 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
820 }
821 else
822#endif /* FEATURE_WLAN_CH144 */
823 {
824
825 vos_mem_copy(targetPtr, sourcePtr, sizeof(sRegulatoryChannel));
826 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
827 sourcePtr = sourcePtr + sizeof(sRegulatoryChannel);
828 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
829 }
830 }
831 }
832 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
833 "%s: sizeof(halNv->tables.regDomains[copyLoop].antennaGain) %zu, structSize %d",
834 __func__, sizeof(halNv->tables.regDomains[copyLoop].antennaGain), structSize);
835
836 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
837 {
838 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
839 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
840 /* Cannot blindly copy
841 * Each single CH should be assigned */
842 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
843 {
844#ifdef FEATURE_WLAN_CH144
845 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
846 {
847 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
848 }
849 else
850#endif /* FEATURE_WLAN_CH144 */
851 {
852 vos_mem_copy(targetPtr, sourcePtr, sizeof(uAbsPwrPrecision));
853 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
854 sourcePtr = sourcePtr + sizeof(uAbsPwrPrecision);
855 structSize += sizeof(sizeof(uAbsPwrPrecision));
856 }
857 }
858 }
859 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
860 "%s: sizeof(uAbsPwrPrecision) %zu, structSize %d",
861 __func__, sizeof(uAbsPwrPrecision), structSize);
862
863 /* nvTable, defaultCountryTable, NOT depends on channel counts */
864 vos_mem_copy((char *)&halNv->tables.defaultCountryTable,
865 (char *)&nv2Table->tables.defaultCountryTable,
866 sizeof(halNv->tables.defaultCountryTable));
867 structSize += sizeof(halNv->tables.defaultCountryTable);
868 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
869 "%s: sizeof(halNv->tables.defaultCountryTable) %zu, structSize %d",
870 __func__, sizeof(halNv->tables.defaultCountryTable), structSize);
871
872 /* NV Table, plutCharacterized, depends on channel count
873 * Cannot blindly copy
874 * Each single CH should be assigned */
875 targetPtr = (char *)&(halNv->tables.plutCharacterized[0]);
876 sourcePtr = (char *)&(nv2Table->tables.plutCharacterized[0]);
877 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
878 {
879#ifdef FEATURE_WLAN_CH144
880 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
881 {
882 targetPtr = targetPtr + sizeof(tTpcPowerTable);
883 }
884 else
885#endif /* FEATURE_WLAN_CH144 */
886 {
887 vos_mem_copy(targetPtr, sourcePtr, sizeof(tTpcPowerTable));
888 targetPtr = targetPtr + sizeof(tTpcPowerTable);
889 sourcePtr = sourcePtr + sizeof(tTpcPowerTable);
890 structSize += sizeof(tTpcPowerTable);
891 }
892 }
893 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
894 "%s: sizeof(tTpcPowerTable) %zu, structSize %d",
895 __func__, sizeof(tTpcPowerTable), structSize);
896
897 /* NV Table, plutPdadcOffset, depends on channel count
898 * Cannot blindly copy
899 * Each single CH should be assigned */
900 targetPtr = (char *)&(halNv->tables.plutPdadcOffset[0]);
901 sourcePtr = (char *)&(nv2Table->tables.plutPdadcOffset[0]);
902 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
903 {
904#ifdef FEATURE_WLAN_CH144
905 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
906 {
907 targetPtr = targetPtr + sizeof(int16);
908 }
909 else
910#endif /* FEATURE_WLAN_CH144 */
911 {
912 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
913 targetPtr = targetPtr + sizeof(int16);
914 sourcePtr = sourcePtr + sizeof(int16);
915 structSize += sizeof(int16);
916 }
917 }
918 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
919 "%s: sizeof(halNv->tables.plutPdadcOffset) %zu, structSize %d",
920 __func__, sizeof(int16), structSize);
921
922 /* NV Table, pwrOptimum_virtualRate, NOT depends on channel count */
923 vos_mem_copy((char *)halNv->tables.pwrOptimum_virtualRate,
924 (char *)nv2Table->tables.pwrOptimum_virtualRate,
925 sizeof(halNv->tables.pwrOptimum_virtualRate));
926 structSize += sizeof(halNv->tables.pwrOptimum_virtualRate);
927 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
928 "%s: sizeof(halNv->tables.pwrOptimum_virtualRate) %zu, structSize %d",
929 __func__, sizeof(halNv->tables.pwrOptimum_virtualRate), structSize);
930
931 /* NV Table, fwConfig, NOT depends on channel count */
932 vos_mem_copy((char *)&halNv->tables.fwConfig,
933 (char *)&nv2Table->tables.fwConfig,
934 sizeof(halNv->tables.fwConfig));
935 structSize += sizeof(halNv->tables.fwConfig);
936 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
937 "%s: sizeof(halNv->tables.fwConfig) %zu, structSize %d",
938 __func__, sizeof(halNv->tables.fwConfig), structSize);
939
940 /* NV Table, rssiChanOffsets, depends on channel count
941 * Cannot blindly copy
942 * Each single CH should be assigned */
943 for (copyLoop = 0; copyLoop < 2; copyLoop++)
944 {
945 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
946 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
947 /* Cannot blindly copy
948 * Each single CH should be assigned */
949 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
950 {
951#ifdef FEATURE_WLAN_CH144
952 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
953 {
954 targetPtr = targetPtr + sizeof(int16);
955 }
956 else
957#endif /* FEATURE_WLAN_CH144 */
958 {
959 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
960 targetPtr = targetPtr + sizeof(int16);
961 sourcePtr = sourcePtr + sizeof(int16);
962 structSize += sizeof(int16);
963 }
964 }
965 }
966 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
967 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
968 __func__, sizeof(int16), structSize);
969
970 for (copyLoop = 0; copyLoop < 2; copyLoop++)
971 {
972 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
973 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
974 /* Cannot blindly copy
975 * Each single CH should be assigned */
976 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
977 {
978#ifdef FEATURE_WLAN_CH144
979 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
980 {
981 targetPtr = targetPtr + sizeof(int16);
982 }
983 else
984#endif /* FEATURE_WLAN_CH144 */
985 {
986 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
987 targetPtr = targetPtr + sizeof(int16);
988 sourcePtr = sourcePtr + sizeof(int16);
989 structSize += sizeof(int16);
990 }
991 }
992 }
993 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
994 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
995 __func__, sizeof(int16), structSize);
996
997 /* NV Table, hwCalValues, NOT depends on channel count */
998 vos_mem_copy((char *)&halNv->tables.hwCalValues,
999 (char *)&nv2Table->tables.hwCalValues,
1000 sizeof(halNv->tables.hwCalValues));
1001 structSize += sizeof(halNv->tables.fwConfig);
1002 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1003 "%s: sizeof(halNv->tables.hwCalValues) %zu, structSize %d",
1004 __func__, sizeof(halNv->tables.hwCalValues), structSize);
1005
1006 /* NV Table, antennaPathLoss, depends on channel count
1007 * Cannot blindly copy
1008 * Each single CH should be assigned */
1009 targetPtr = (char *)&(halNv->tables.antennaPathLoss[0]);
1010 sourcePtr = (char *)&(nv2Table->tables.antennaPathLoss[0]);
1011 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1012 {
1013#ifdef FEATURE_WLAN_CH144
1014 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1015 {
1016 targetPtr = targetPtr + sizeof(int16);
1017 }
1018 else
1019#endif /* FEATURE_WLAN_CH144 */
1020 {
1021 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1022 targetPtr = targetPtr + sizeof(int16);
1023 sourcePtr = sourcePtr + sizeof(int16);
1024 structSize += sizeof(int16);
1025 }
1026 }
1027 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1028 "%s: sizeof(halNv->tables.antennaPathLoss) %zu, structSize %d",
1029 __func__, sizeof(int16), structSize);
1030
1031 /* NV Table, pktTypePwrLimits, depends on channel count
1032 * Cannot blindly copy
1033 * Each single CH should be assigned */
1034 for (copyLoop = 0; copyLoop < NUM_802_11_MODES; copyLoop++)
1035 {
1036 targetPtr = (char *)&(halNv->tables.pktTypePwrLimits[copyLoop][0]);
1037 sourcePtr = (char *)&(nv2Table->tables.pktTypePwrLimits[copyLoop][0]);
1038 /* Cannot blindly copy
1039 * Each single CH should be assigned */
1040 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1041 {
1042#ifdef FEATURE_WLAN_CH144
1043 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1044 {
1045 targetPtr = targetPtr + sizeof(int16);
1046 }
1047 else
1048#endif /* FEATURE_WLAN_CH144 */
1049 {
1050 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1051 targetPtr = targetPtr + sizeof(int16);
1052 sourcePtr = sourcePtr + sizeof(int16);
1053 structSize += sizeof(int16);
1054 }
1055 }
1056 }
1057 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1058 "%s: sizeof(halNv->tables.pktTypePwrLimits) %zu, structSize %d",
1059 __func__, sizeof(int16), structSize);
1060
1061 /* NV Table, ofdmCmdPwrOffset, NOT depends on channel count */
1062 vos_mem_copy((char *)&halNv->tables.ofdmCmdPwrOffset,
1063 (char *)&nv2Table->tables.ofdmCmdPwrOffset,
1064 sizeof(halNv->tables.ofdmCmdPwrOffset));
1065 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1066 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1067 "%s: sizeof(halNv->tables.ofdmCmdPwrOffset) %zu, structSize %d",
1068 __func__, sizeof(halNv->tables.ofdmCmdPwrOffset), structSize);
1069
1070 /* NV Table, txbbFilterMode, NOT depends on channel count */
1071 vos_mem_copy((char *)&halNv->tables.txbbFilterMode,
1072 (char *)&nv2Table->tables.txbbFilterMode,
1073 sizeof(halNv->tables.txbbFilterMode));
1074 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1075 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1076 "%s: sizeof(halNv->tables.txbbFilterMode) %zu, structSize %d",
1077 __func__, sizeof(halNv->tables.txbbFilterMode), structSize);
1078
1079 return VOS_STATUS_SUCCESS;
1080}
1081
1082/**------------------------------------------------------------------------
1083 \brief vos_nv_open() - Open NV operation
1084 Read NV bin file and prepare NV common structure
1085 \return VOS_STATUS_SUCCESS - module is initialized successfully
1086 otherwise - module is not initialized
1087 \sa
1088 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001089VOS_STATUS vos_nv_open(void)
1090{
1091 VOS_STATUS status = VOS_STATUS_SUCCESS;
1092 v_CONTEXT_t pVosContext= NULL;
1093 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001094 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001096 v_U32_t dataOffset;
1097 sHalNv *pnvData = NULL;
1098
Jeff Johnson295189b2012-06-20 16:38:30 -07001099 /*Get the global context */
1100 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001101
1102 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001103 {
1104 return (eHAL_STATUS_FAILURE);
1105 }
1106
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 status = hdd_request_firmware(WLAN_NV_FILE,
1108 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001109 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001110
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001111 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001113 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001115 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001116 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 }
1118
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001119 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
1120
1121 /// Allocate buffer with maximum length..
1122 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
1123
1124 if (NULL == pEncodedBuf)
1125 {
1126 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1127 "%s : failed to allocate memory for NV", __func__);
1128 return VOS_STATUS_E_NOMEM;
1129 }
1130
Leo Chang80de3c22013-11-26 10:52:12 -08001131 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1132 "NV Table Size %zu", sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001133
Leo Chang80de3c22013-11-26 10:52:12 -08001134 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
1135 if (NULL == pnvEFSTable)
1136 {
1137 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1138 "%s : failed to allocate memory for NV", __func__);
1139 return VOS_STATUS_E_NOMEM;
1140 }
1141 vos_mem_zero((void *)pnvEFSTable, sizeof(nvEFSTable_t));
1142
1143 // Default NV version, NOT_VALID
1144 ((VosContextType*)(pVosContext))->nvVersion = E_NV_INVALID;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001145 if (MAGIC_NUMBER == magicNumber)
1146 {
Leo Chang80de3c22013-11-26 10:52:12 -08001147 bufSize = sizeof(nvEFSTable_t);
1148 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001149 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
1150
1151 if (NULL == pnvData)
1152 {
1153 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1154 "%s : failed to allocate memory for NV", __func__);
1155 return VOS_STATUS_E_NOMEM;
1156 }
1157
1158 memset(pnvData, 0, sizeof(sHalNv));
1159
1160 /// Data starts from offset of validity bit map + magic number..
1161 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
1162
1163 status = nvParser(&pnvEncodedBuf[dataOffset],
1164 (nvReadBufSize-dataOffset), pnvData);
1165
1166 ///ignore validity bit map
1167 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
1168
1169 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
1170 nvReadEncodeBufSize);
1171
Leo Chang80de3c22013-11-26 10:52:12 -08001172 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001173 "readEncodeBufSize %d",nvReadEncodeBufSize);
1174
1175 if (VOS_STATUS_SUCCESS == status) {
1176 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1177 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
1178 pnvData->fields.productId,
1179 pnvData->fields.couplerType,
1180 pnvData->fields.wlanNvRevId);
1181
1182 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
1183
1184 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
1185 }
1186 else
1187 {
1188 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1189 "nvParser failed %d",status);
1190
1191 nvReadBufSize = 0;
1192
1193 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
1194
1195 nvReadEncodeBufSize = sizeof(sHalNv);
1196 }
Leo Chang80de3c22013-11-26 10:52:12 -08001197 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1198
1199 /* NV verion is NV3 */
1200 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V3;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001201 }
1202 else
1203 {
Leo Chang80de3c22013-11-26 10:52:12 -08001204 bufSize = sizeof(nvEFSTableV2_t);
1205
1206 /*Copying the NV defaults */
1207 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1208 /* NV2 structure should be maintained to support NV_FTM */
1209 gnvEFSTableV2 = (nvEFSTableV2_t * )pnvEncodedBuf;
1210
1211 /* Size mismatch
1212 * NV 1 case, use default NV table */
1213 if (nvReadBufSize != bufSize)
1214 {
1215 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
1216 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1217 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
1218 nvReadBufSize, bufSize);
1219 return VOS_STATUS_SUCCESS;
1220 }
1221
1222 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1223 "NV_2: readBufferSize %zu, EFSV2DefaultSize %zu",
1224 nvReadBufSize, sizeof(nvEFSTableV2_t));
1225
1226 /* From here, NV2 will be stored into NV3 structure */
1227 dataOffset = sizeof(v_U32_t);
1228 nvReadEncodeBufSize = sizeof(sHalNvV2);
1229 vos_mem_copy(pEncodedBuf,
1230 &pnvEncodedBuf[dataOffset],
1231 nvReadBufSize - dataOffset);
1232
1233#ifdef FEATURE_WLAN_CH144
1234 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1235 "Default NV2 size %zu", sizeof(nvDefaultsV2));
1236#else
1237 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1238 "Default NV2 size %zu", sizeof(nvDefaults));
1239#endif /* FEATURE_WLAN_CH144 */
1240 /* First assign value with NV default */
1241#ifdef FEATURE_WLAN_CH144
1242 vos_nv_parseV2bin((tANI_U8 *)&nvDefaultsV2,
1243 sizeof(sHalNvV2),
1244 &pnvEFSTable->halnv);
1245#else
1246 vos_nv_parseV2bin((tANI_U8 *)&nvDefaults,
1247 sizeof(sHalNvV2),
1248 &pnvEFSTable->halnv);
1249#endif /* FEATURE_WLAN_CH144 */
1250
1251 /* Actual update from NV.bin */
1252 vos_nv_parseV2bin(pEncodedBuf,
1253 nvReadEncodeBufSize,
1254 &pnvEFSTable->halnv);
1255
1256 vos_mem_copy((void *)&pnvEFSTable->nvValidityBitmap,
1257 pnvEncodedBuf, sizeof(v_U32_t));
1258 gnvEFSTable = pnvEFSTable;
1259
1260 /* NV verion is NV2 */
1261 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V2;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001262 }
1263
1264 if (NULL != pnvData)
1265 {
1266 vos_mem_free(pnvData);
1267 }
1268
1269 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001270 "INFO: NV binary file version=%d Driver default NV version=%d, continue...",
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001271 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
1272
Jeff Johnson295189b2012-06-20 16:38:30 -07001273 /* Copying the read nv data to the globa NV EFS table */
1274 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001275 /* Version mismatch */
1276 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
1277 {
1278 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
1279 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
1280 {
1281 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1282 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
Arif Hussain02882402013-11-17 21:55:29 -08001283 "Make sure that this is intended or may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001284 }
Leo Chang80de3c22013-11-26 10:52:12 -08001285#ifdef FEATURE_WLAN_CH144
1286 else if ((WLAN_NV_VERSION == NV_VERSION_CH144_CONFIG) &&
1287 (((VosContextType*)(pVosContext))->nvVersion == E_NV_V2))
1288 {
1289 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1290 "!!!WARNING: Default NV is NV3 CH144 "
1291 "BIN is NV2, NV2 contents will be used!!!");
1292 }
1293#endif /* FEATURE_WLAN_CH144 */
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001294 else
1295 {
1296 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1297 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
Arif Hussain02882402013-11-17 21:55:29 -08001298 "Driver NV defaults will be used, may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001299
1300 return VOS_STATUS_SUCCESS;
1301 }
1302 }
1303
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001304 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001305 /* Copy the valid fields to the NV Global structure */
1306 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 VOS_STATUS_SUCCESS)
1308 {
1309 if (itemIsValid == VOS_TRUE) {
1310
1311 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
1312 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001313 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 }
1315 }
1316
Amar Singhalfddc28c2013-09-05 13:03:40 -07001317 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001318 VOS_STATUS_SUCCESS)
1319 {
1320 if (itemIsValid == VOS_TRUE)
1321 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001322 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
1324 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001325 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001326 }
1327 }
1328
Amar Singhalfddc28c2013-09-05 13:03:40 -07001329 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 VOS_STATUS_SUCCESS)
1331 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001332
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 if (itemIsValid == VOS_TRUE)
1334 {
1335 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
1336 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
1337 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001338 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001339 }
1340 }
1341
Amar Singhalfddc28c2013-09-05 13:03:40 -07001342 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001343 VOS_STATUS_SUCCESS)
1344 {
1345 if (itemIsValid == VOS_TRUE)
1346 {
1347 if(vos_nv_read( VNV_DEFAULT_LOCATION,
1348 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
1349 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001350 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001351 }
1352 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001353
1354 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001355 VOS_STATUS_SUCCESS)
1356 {
1357 if (itemIsValid == VOS_TRUE)
1358 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001359 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
1361 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001362 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001363 }
1364 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001365
1366 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 VOS_STATUS_SUCCESS)
1368 {
1369 if (itemIsValid == VOS_TRUE)
1370 {
1371 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
1372 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
1373 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001374 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001375 }
1376 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001377 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 VOS_STATUS_SUCCESS)
1379 {
1380 if (itemIsValid == VOS_TRUE)
1381 {
1382 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
1383 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
1384 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001385 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 }
1387 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001388
1389 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 VOS_STATUS_SUCCESS)
1391 {
1392 if (itemIsValid == VOS_TRUE)
1393 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001394 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
1395 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
1396 goto error;
1397 }
1398 }
1399
Amar Singhalfddc28c2013-09-05 13:03:40 -07001400 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001401 VOS_STATUS_SUCCESS)
1402 {
1403 if (itemIsValid == VOS_TRUE)
1404 {
1405 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
1406 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001407 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 }
1409 }
1410
Amar Singhalfddc28c2013-09-05 13:03:40 -07001411 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 VOS_STATUS_SUCCESS)
1413 {
1414 if (itemIsValid == VOS_TRUE)
1415 {
1416 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001417 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001418 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001419 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 }
1421 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001422 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 VOS_STATUS_SUCCESS)
1424 {
1425 if (itemIsValid == VOS_TRUE)
1426 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001427 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1428 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001430 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 }
1432 }
1433
Amar Singhalfddc28c2013-09-05 13:03:40 -07001434 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 VOS_STATUS_SUCCESS)
1436 {
1437 if (itemIsValid == VOS_TRUE)
1438 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001439 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1440 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001441 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001442 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 }
1444 }
1445
Amar Singhalfddc28c2013-09-05 13:03:40 -07001446 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 VOS_STATUS_SUCCESS)
1448 {
1449 if (itemIsValid == VOS_TRUE)
1450 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001451 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1452 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001453 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001454 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001455 }
1456 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001457 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 VOS_STATUS_SUCCESS)
1459 {
1460 if (itemIsValid == VOS_TRUE)
1461 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001462 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1463 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001464 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001465 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 }
1467 }
1468 }
1469
1470 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001471error:
1472 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001473 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001474 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001475}
1476
1477VOS_STATUS vos_nv_close(void)
1478{
1479 VOS_STATUS status = VOS_STATUS_SUCCESS;
1480 v_CONTEXT_t pVosContext= NULL;
1481 /*Get the global context */
1482 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1483 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1484 if ( !VOS_IS_STATUS_SUCCESS( status ))
1485 {
1486 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001487 "%s : vos_open failed",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 return VOS_STATUS_E_FAILURE;
1489 }
1490 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001491 vos_mem_free(pEncodedBuf);
1492 vos_mem_free(pDictFile);
1493
Jeff Johnson295189b2012-06-20 16:38:30 -07001494 gnvEFSTable=NULL;
1495 return VOS_STATUS_SUCCESS;
1496}
Jeff Johnson295189b2012-06-20 16:38:30 -07001497
Jeff Johnson295189b2012-06-20 16:38:30 -07001498/**------------------------------------------------------------------------
1499 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1500 country codes
1501 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1502 country codes with paddings in the provided buffer
1503 \param pBuffer - pointer to buffer where supported country codes
1504 and paddings are encoded; this may be set to NULL
1505 if user wishes to query the required buffer size to
1506 get the country code list
1507 \param pBufferSize - this is the provided buffer size on input;
1508 this is the required or consumed buffer size on output
1509 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1510 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1511 the buffer is NULL or buffer size is
1512 sufficient
1513 \sa
1514 -------------------------------------------------------------------------*/
1515VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1516 v_SIZE_t paddingSize )
1517{
1518 v_SIZE_t providedBufferSize = *pBufferSize;
1519 int i;
1520 // pBufferSize now points to the required buffer size
1521 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1522 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1523 {
1524 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08001525 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 return VOS_STATUS_E_NOMEM;
1527 }
1528 for (i = 0; i < countryInfoTable.countryCount; i++)
1529 {
1530 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1531 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1532 }
1533 return VOS_STATUS_SUCCESS;
1534}
1535/**------------------------------------------------------------------------
1536 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1537 \param pTxAntennaCount - antenna count
1538 \return status of the NV read operation
1539 \sa
1540 -------------------------------------------------------------------------*/
1541VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1542{
1543 sNvFields fieldImage;
1544 VOS_STATUS status;
1545 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1546 sizeof(fieldImage) );
1547 if (VOS_STATUS_SUCCESS == status)
1548 {
1549 *pTxAntennaCount = fieldImage.numOfTxChains;
1550 }
1551 return status;
1552}
1553/**------------------------------------------------------------------------
1554 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1555 \param pRxAntennaCount - antenna count
1556 \return status of the NV read operation
1557 \sa
1558 -------------------------------------------------------------------------*/
1559VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1560{
1561 sNvFields fieldImage;
1562 VOS_STATUS status;
1563 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1564 sizeof(fieldImage) );
1565 if (VOS_STATUS_SUCCESS == status)
1566 {
1567 *pRxAntennaCount = fieldImage.numOfRxChains;
1568 }
1569 return status;
1570}
1571
1572/**------------------------------------------------------------------------
1573 \brief vos_nv_readMacAddress() - return the MAC address
1574 \param pMacAddress - MAC address
1575 \return status of the NV read operation
1576 \sa
1577 -------------------------------------------------------------------------*/
1578VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1579{
1580 sNvFields fieldImage;
1581 VOS_STATUS status;
1582 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1583 sizeof(fieldImage) );
1584 if (VOS_STATUS_SUCCESS == status)
1585 {
1586 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1587 }
1588 else
1589 {
1590 //This part of the code can be removed when NV is programmed
1591 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1592 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
Arif Hussaina7c8e412013-11-20 11:06:42 -08001593 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1594 "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR,
1595 MAC_ADDR_ARRAY(macAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 status = VOS_STATUS_SUCCESS;
1597 }
1598 return status;
1599}
1600
1601/**------------------------------------------------------------------------
1602
1603 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1604
1605 \param pMacAddress - MAC address
1606 \param macCount - Count of valid MAC addresses to get from NV field
1607
1608 \return status of the NV read operation
1609
1610 \sa
1611
1612 -------------------------------------------------------------------------*/
1613VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1614 v_U8_t macCount )
1615{
1616 sNvFields fieldImage;
1617 VOS_STATUS status;
1618 v_U8_t countLoop;
1619 v_U8_t *pNVMacAddress;
1620
1621 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1622 (NULL == pMacAddress))
1623 {
1624 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301625 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001626 macCount, pMacAddress);
1627 }
1628
1629 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1630 sizeof(fieldImage) );
1631 if (VOS_STATUS_SUCCESS == status)
1632 {
1633 pNVMacAddress = fieldImage.macAddr;
1634 for(countLoop = 0; countLoop < macCount; countLoop++)
1635 {
1636 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1637 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1638 VOS_MAC_ADDRESS_LEN);
1639 }
1640 }
1641 else
1642 {
1643 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1644 "vos_nv_readMultiMacAddress Get NV Field Fail");
1645 }
1646
1647 return status;
1648}
1649
1650/**------------------------------------------------------------------------
1651 \brief vos_nv_setValidity() - set the validity of an NV item.
1652 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1653 validity information is stored in NV memory.
1654 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1655 An item becomes valid when one has written to it successfully.
1656 \param type - NV item type
1657 \param itemIsValid - boolean value indicating the item's validity
1658 \return VOS_STATUS_SUCCESS - validity is set successfully
1659 VOS_STATUS_E_INVAL - one of the parameters is invalid
1660 VOS_STATUS_E_FAILURE - unknown error
1661 \sa
1662 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001663
1664VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1665{
1666 v_U32_t lastNvValidityBitmap;
1667 v_U32_t newNvValidityBitmap;
1668 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001669
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001671 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 {
1673 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001674 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 return VOS_STATUS_E_INVAL;
1676 }
1677 // read the validity bitmap
1678 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1679 // modify the validity bitmap
1680 if (itemIsValid)
1681 {
1682 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1683 // commit to NV store if bitmap has been modified
1684 if (newNvValidityBitmap != lastNvValidityBitmap)
1685 {
1686 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1687 }
1688 }
1689 else
1690 {
1691 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1692 if (newNvValidityBitmap != lastNvValidityBitmap)
1693 {
1694 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1695 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1696 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001697 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 status = VOS_STATUS_E_FAULT;
1699 }
1700 }
1701 }
1702
1703 return status;
1704}
Jeff Johnson295189b2012-06-20 16:38:30 -07001705/**------------------------------------------------------------------------
1706 \brief vos_nv_getValidity() - get the validity of an NV item.
1707 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1708 validity information is stored in NV memory.
1709 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1710 An item becomes valid when one has written to it successfully.
1711 \param type - NV item type
1712 \param pItemIsValid- pointer to the boolean value indicating the item's
1713 validity
1714 \return VOS_STATUS_SUCCESS - validity is determined successfully
1715 VOS_STATUS_E_INVAL - one of the parameters is invalid
1716 VOS_STATUS_E_FAILURE - unknown error
1717 \sa
1718 -------------------------------------------------------------------------*/
1719VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1720{
1721 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1722 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001723 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 {
1725 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001726 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 return VOS_STATUS_E_INVAL;
1728 }
1729 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1730 return VOS_STATUS_SUCCESS;
1731}
1732/**------------------------------------------------------------------------
1733 \brief vos_nv_read() - read a NV item to an output buffer
1734 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1735 an array, this function would read the entire array. One would get a
1736 VOS_STATUS_E_EXISTS error when reading an invalid item.
1737 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1738 if a default buffer is provided (with a non-NULL value),
1739 the default buffer content is copied to the output buffer.
1740 \param type - NV item type
1741 \param outputBuffer - output buffer
1742 \param defaultBuffer - default buffer
1743 \param bufferSize - output buffer size
1744 \return VOS_STATUS_SUCCESS - NV item is read successfully
1745 VOS_STATUS_E_INVAL - one of the parameters is invalid
1746 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1747 VOS_STATUS_E_EXISTS - NV type is unsupported
1748 VOS_STATUS_E_FAILURE - unknown error
1749 \sa
1750 -------------------------------------------------------------------------*/
1751VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1752 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1753{
1754 VOS_STATUS status = VOS_STATUS_SUCCESS;
1755 v_SIZE_t itemSize;
1756 v_BOOL_t itemIsValid = VOS_TRUE;
1757
Amar Singhala49cbc52013-10-08 18:37:44 -07001758 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001759 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001760 {
1761 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001762 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 return VOS_STATUS_E_INVAL;
1764 }
1765 if (NULL == outputVoidBuffer)
1766 {
1767 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001768 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 return VOS_STATUS_E_FAULT;
1770 }
1771 if (0 == bufferSize)
1772 {
1773 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001774 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 return VOS_STATUS_E_INVAL;
1776 }
1777 // check if the NV item has valid data
1778 status = vos_nv_getValidity( type, &itemIsValid );
1779 if (!itemIsValid)
1780 {
1781 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08001782 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 return VOS_STATUS_E_EMPTY;
1784 }
1785 switch(type)
1786 {
1787 case VNV_FIELD_IMAGE:
1788 itemSize = sizeof(gnvEFSTable->halnv.fields);
1789 if(bufferSize != itemSize) {
1790 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001791 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 itemSize);
1793 status = VOS_STATUS_E_INVAL;
1794 }
1795 else {
1796 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1797 }
1798 break;
1799 case VNV_RATE_TO_POWER_TABLE:
1800 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1801 if(bufferSize != itemSize) {
1802 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001803 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001804 itemSize);
1805 status = VOS_STATUS_E_INVAL;
1806 }
1807 else {
1808 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1809 }
1810 break;
1811 case VNV_REGULARTORY_DOMAIN_TABLE:
1812 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1813 if(bufferSize != itemSize) {
1814 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001815 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001816 itemSize);
1817 status = VOS_STATUS_E_INVAL;
1818 }
1819 else {
1820 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1821 }
1822 break;
1823 case VNV_DEFAULT_LOCATION:
1824 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1825 if(bufferSize != itemSize) {
1826 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001827 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001828 itemSize);
1829 status = VOS_STATUS_E_INVAL;
1830 }
1831 else {
1832 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1833 }
1834 break;
1835 case VNV_TPC_POWER_TABLE:
1836 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1837 if(bufferSize != itemSize) {
1838 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001839 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001840 itemSize);
1841 status = VOS_STATUS_E_INVAL;
1842 }
1843 else {
1844 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1845 }
1846 break;
1847 case VNV_TPC_PDADC_OFFSETS:
1848 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1849 if(bufferSize != itemSize) {
1850 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001851 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 itemSize);
1853 status = VOS_STATUS_E_INVAL;
1854 }
1855 else {
1856 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1857 }
1858 break;
1859 case VNV_RSSI_CHANNEL_OFFSETS:
1860
1861 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1862
1863 if(bufferSize != itemSize) {
1864
1865 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001866 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001867 itemSize);
1868 status = VOS_STATUS_E_INVAL;
1869 }
1870 else {
1871 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1872 }
1873 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001874 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001875
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001876 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001877
1878 if(bufferSize != itemSize) {
1879
1880 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001881 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 itemSize);
1883 status = VOS_STATUS_E_INVAL;
1884 }
1885 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001886 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1887 }
1888 break;
1889 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001890
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001891 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001892
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001893 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001894
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001895 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001896 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001897 itemSize);
1898 status = VOS_STATUS_E_INVAL;
1899 }
1900 else {
1901 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 }
1903 break;
1904 case VNV_ANTENNA_PATH_LOSS:
1905 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1906 if(bufferSize != itemSize) {
1907 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001908 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001909 itemSize);
1910 status = VOS_STATUS_E_INVAL;
1911 }
1912 else {
1913 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1914 }
1915 break;
1916 case VNV_PACKET_TYPE_POWER_LIMITS:
1917 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1918 if(bufferSize != itemSize) {
1919 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001920 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 itemSize);
1922 status = VOS_STATUS_E_INVAL;
1923 }
1924 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001925 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 }
1927 break;
1928 case VNV_OFDM_CMD_PWR_OFFSET:
1929 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1930 if(bufferSize != itemSize) {
1931 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001932 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001933 itemSize);
1934 status = VOS_STATUS_E_INVAL;
1935 }
1936 else {
1937 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1938 }
1939 break;
1940 case VNV_TX_BB_FILTER_MODE:
1941 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1942 if(bufferSize != itemSize) {
1943 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001944 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 itemSize);
1946 status = VOS_STATUS_E_INVAL;
1947 }
1948 else {
1949 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1950 }
1951 break;
1952
Jeff Johnson295189b2012-06-20 16:38:30 -07001953
1954 case VNV_TABLE_VIRTUAL_RATE:
1955 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1956 if(bufferSize != itemSize) {
1957 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001958 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 itemSize);
1960 status = VOS_STATUS_E_INVAL;
1961 }
1962 else {
1963 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1964 }
1965 break;
1966
1967 default:
1968 break;
1969 }
1970 return status;
1971}
Jeff Johnson295189b2012-06-20 16:38:30 -07001972
1973/**------------------------------------------------------------------------
1974 \brief vos_nv_write() - write to a NV item from an input buffer
1975 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1976 validate the NV item if the write operation is successful.
Leo Chang80de3c22013-11-26 10:52:12 -08001977 NV2 dedicated operation
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 \param type - NV item type
1979 \param inputBuffer - input buffer
1980 \param inputBufferSize - input buffer size
1981 \return VOS_STATUS_SUCCESS - NV item is read successfully
1982 VOS_STATUS_E_INVAL - one of the parameters is invalid
1983 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1984 VOS_STATUS_E_EXISTS - NV type is unsupported
1985 VOS_STATUS_E_FAILURE - unknown error
1986 \sa
1987 -------------------------------------------------------------------------*/
Leo Chang80de3c22013-11-26 10:52:12 -08001988VOS_STATUS vos_nv_write(VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1989 v_SIZE_t bufferSize)
Jeff Johnson295189b2012-06-20 16:38:30 -07001990{
1991 VOS_STATUS status = VOS_STATUS_SUCCESS;
1992 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001993
Amar Singhala49cbc52013-10-08 18:37:44 -07001994 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001995 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 {
Leo Chang80de3c22013-11-26 10:52:12 -08001997 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1998 "%s: invalid type=%d", __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 return VOS_STATUS_E_INVAL;
2000 }
2001 if (NULL == inputVoidBuffer)
2002 {
Leo Chang80de3c22013-11-26 10:52:12 -08002003 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2004 "Buffer provided is NULL");
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 return VOS_STATUS_E_FAULT;
2006 }
2007 if (0 == bufferSize)
2008 {
Leo Chang80de3c22013-11-26 10:52:12 -08002009 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2010 "NV type=%d is invalid", type);
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 return VOS_STATUS_E_INVAL;
2012 }
Leo Chang80de3c22013-11-26 10:52:12 -08002013
2014 switch (type)
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 {
2016 case VNV_FIELD_IMAGE:
Leo Chang80de3c22013-11-26 10:52:12 -08002017 itemSize = sizeof(gnvEFSTableV2->halnvV2.fields);
2018 if (bufferSize != itemSize)
2019 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002021 "type = %d buffer size=%d is less than data size=%d",
2022 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 status = VOS_STATUS_E_INVAL;
2024 }
Leo Chang80de3c22013-11-26 10:52:12 -08002025 else
2026 {
2027 memcpy(&gnvEFSTableV2->halnvV2.fields,
2028 inputVoidBuffer,
2029 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 }
2031 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002032
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 case VNV_RATE_TO_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002034 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum);
2035 if (bufferSize != itemSize)
2036 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002037 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002038 "type = %d buffer size=%d is less than data size=%d",
2039 type, bufferSize,itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002040 status = VOS_STATUS_E_INVAL;
2041 }
Leo Chang80de3c22013-11-26 10:52:12 -08002042 else
2043 {
2044 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum[0],
2045 inputVoidBuffer,
2046 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002047 }
2048 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002049
Jeff Johnson295189b2012-06-20 16:38:30 -07002050 case VNV_REGULARTORY_DOMAIN_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002051 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.regDomains);
2052 if (bufferSize != itemSize)
2053 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002055 "type = %d buffer size=%d is less than data size=%d",
2056 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 status = VOS_STATUS_E_INVAL;
2058 }
Leo Chang80de3c22013-11-26 10:52:12 -08002059 else
2060 {
2061 memcpy(&gnvEFSTableV2->halnvV2.tables.regDomains[0],
2062 inputVoidBuffer,
2063 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 }
2065 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002066
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 case VNV_DEFAULT_LOCATION:
Leo Chang80de3c22013-11-26 10:52:12 -08002068 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.defaultCountryTable);
2069 if (bufferSize != itemSize)
2070 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002072 "type = %d buffer size=%d is less than data size=%d",
2073 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 status = VOS_STATUS_E_INVAL;
2075 }
Leo Chang80de3c22013-11-26 10:52:12 -08002076 else
2077 {
2078 memcpy(&gnvEFSTableV2->halnvV2.tables.defaultCountryTable,
2079 inputVoidBuffer,
2080 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 }
2082 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002083
Jeff Johnson295189b2012-06-20 16:38:30 -07002084 case VNV_TPC_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002085 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutCharacterized);
2086 if (bufferSize != itemSize)
2087 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002088 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002089 "type = %d buffer size=%d is less than data size=%d",
2090 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 status = VOS_STATUS_E_INVAL;
2092 }
Leo Chang80de3c22013-11-26 10:52:12 -08002093 else
2094 {
2095 memcpy(&gnvEFSTableV2->halnvV2.tables.plutCharacterized[0],
2096 inputVoidBuffer,
2097 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 }
2099 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002100
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 case VNV_TPC_PDADC_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002102 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutPdadcOffset);
2103 if (bufferSize != itemSize)
2104 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002105 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002106 "type = %d buffer size=%d is less than data size=%d",
2107 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 status = VOS_STATUS_E_INVAL;
2109 }
Leo Chang80de3c22013-11-26 10:52:12 -08002110 else
2111 {
2112 memcpy(&gnvEFSTableV2->halnvV2.tables.plutPdadcOffset[0],
2113 inputVoidBuffer,
2114 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 }
2116 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002117
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 case VNV_RSSI_CHANNEL_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002119 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.rssiChanOffsets);
2120 if (bufferSize != itemSize)
2121 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002123 "type = %d buffer size=%d is less than data size=%d",
2124 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002125 status = VOS_STATUS_E_INVAL;
2126 }
Leo Chang80de3c22013-11-26 10:52:12 -08002127 else
2128 {
2129 memcpy(&gnvEFSTableV2->halnvV2.tables.rssiChanOffsets[0],
2130 inputVoidBuffer,
2131 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 }
2133 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002134
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002135 case VNV_HW_CAL_VALUES:
Leo Chang80de3c22013-11-26 10:52:12 -08002136 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.hwCalValues);
2137 if (bufferSize != itemSize)
2138 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002140 "type = %d buffer size=%d is less than data size=%d",
2141 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 status = VOS_STATUS_E_INVAL;
2143 }
Leo Chang80de3c22013-11-26 10:52:12 -08002144 else
2145 {
2146 memcpy(&gnvEFSTableV2->halnvV2.tables.hwCalValues,
2147 inputVoidBuffer,
2148 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 }
2150 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002151
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002152 case VNV_FW_CONFIG:
Leo Chang80de3c22013-11-26 10:52:12 -08002153 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.fwConfig);
2154 if (bufferSize != itemSize)
2155 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002156 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002157 "type = %d buffer size=%d is less than data size=%d",
2158 type, bufferSize, itemSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002159 status = VOS_STATUS_E_INVAL;
2160 }
Leo Chang80de3c22013-11-26 10:52:12 -08002161 else
2162 {
2163 memcpy(&gnvEFSTableV2->halnvV2.tables.fwConfig,
2164 inputVoidBuffer,
2165 bufferSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002166 }
2167 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002168
Jeff Johnson295189b2012-06-20 16:38:30 -07002169 case VNV_ANTENNA_PATH_LOSS:
Leo Chang80de3c22013-11-26 10:52:12 -08002170 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.antennaPathLoss);
2171 if (bufferSize != itemSize)
2172 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002174 "type = %d buffer size=%d is less than data size=%d",
2175 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 status = VOS_STATUS_E_INVAL;
2177 }
Leo Chang80de3c22013-11-26 10:52:12 -08002178 else
2179 {
2180 memcpy(&gnvEFSTableV2->halnvV2.tables.antennaPathLoss[0],
2181 inputVoidBuffer,
2182 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 }
2184 break;
2185
2186 case VNV_PACKET_TYPE_POWER_LIMITS:
Leo Chang80de3c22013-11-26 10:52:12 -08002187 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits);
2188 if (bufferSize != itemSize)
2189 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002191 "type = %d buffer size=%d is less than data size=%d",
2192 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 status = VOS_STATUS_E_INVAL;
2194 }
Leo Chang80de3c22013-11-26 10:52:12 -08002195 else
2196 {
2197 memcpy(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits,
2198 inputVoidBuffer,
2199 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 }
2201 break;
2202
2203 case VNV_OFDM_CMD_PWR_OFFSET:
Leo Chang80de3c22013-11-26 10:52:12 -08002204 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset);
2205 if (bufferSize != itemSize)
2206 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002207 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002208 "type = %d buffer size=%d is less than data size=%d",
2209 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002210 status = VOS_STATUS_E_INVAL;
2211 }
Leo Chang80de3c22013-11-26 10:52:12 -08002212 else
2213 {
2214 memcpy(&gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset,
2215 inputVoidBuffer,
2216 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 }
2218 break;
2219
2220 case VNV_TX_BB_FILTER_MODE:
Leo Chang80de3c22013-11-26 10:52:12 -08002221 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.txbbFilterMode);
2222 if (bufferSize != itemSize)
2223 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002225 "type = %d buffer size=%d is less than data size=%d",
2226 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 status = VOS_STATUS_E_INVAL;
2228 }
Leo Chang80de3c22013-11-26 10:52:12 -08002229 else
2230 {
2231 memcpy(&gnvEFSTableV2->halnvV2.tables.txbbFilterMode,
2232 inputVoidBuffer,
2233 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002234 }
2235 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002236
Jeff Johnson295189b2012-06-20 16:38:30 -07002237 case VNV_TABLE_VIRTUAL_RATE:
Leo Chang80de3c22013-11-26 10:52:12 -08002238 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate);
2239 if (bufferSize != itemSize)
2240 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002242 "type = %d buffer size=%d is less than data size=%d",
2243 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 status = VOS_STATUS_E_INVAL;
2245 }
Leo Chang80de3c22013-11-26 10:52:12 -08002246 else
2247 {
2248 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate,
2249 inputVoidBuffer,
2250 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 }
2252 break;
2253
2254 default:
2255 break;
2256 }
Leo Chang80de3c22013-11-26 10:52:12 -08002257
Jeff Johnson295189b2012-06-20 16:38:30 -07002258 if (VOS_STATUS_SUCCESS == status)
2259 {
2260 // set NV item to have valid data
Leo Chang80de3c22013-11-26 10:52:12 -08002261 status = vos_nv_setValidity(type, VOS_TRUE);
2262 if (! VOS_IS_STATUS_SUCCESS(status))
2263 {
2264 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2265 "vos_nv_setValidity failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 status = VOS_STATUS_E_FAULT;
2267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002268
Leo Chang80de3c22013-11-26 10:52:12 -08002269 status = wlan_write_to_efs((v_U8_t*)gnvEFSTableV2, sizeof(nvEFSTable_t));
2270 if (!VOS_IS_STATUS_SUCCESS(status))
2271 {
2272 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2273 "vos_nv_write_to_efs failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 status = VOS_STATUS_E_FAULT;
2275 }
2276 }
Leo Chang80de3c22013-11-26 10:52:12 -08002277
Jeff Johnson295189b2012-06-20 16:38:30 -07002278 return status;
2279}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08002280
Jeff Johnson295189b2012-06-20 16:38:30 -07002281/**------------------------------------------------------------------------
2282 \brief vos_nv_getChannelListWithPower() - function to return the list of
2283 supported channels with the power limit info too.
2284 \param pChannels20MHz - list of 20 Mhz channels
2285 \param pNum20MHzChannelsFound - number of 20 Mhz channels
2286 \param pChannels40MHz - list of 20 Mhz channels
2287 \param pNum40MHzChannelsFound - number of 20 Mhz channels
2288 \return status of the NV read operation
2289 \Note: 40Mhz not currently supported
2290 \sa
2291 -------------------------------------------------------------------------*/
2292VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
2293 tANI_U8 *num20MHzChannelsFound,
2294 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
2295 tANI_U8 *num40MHzChannelsFound
2296 )
2297{
2298 VOS_STATUS status = VOS_STATUS_SUCCESS;
2299 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002300
Jeff Johnson295189b2012-06-20 16:38:30 -07002301 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
2302 // or pass it as a parameter to NV from SME?
2303
2304 if( channels20MHz && num20MHzChannelsFound )
2305 {
2306 count = 0;
2307 for( i = 0; i <= RF_CHAN_14; i++ )
2308 {
2309 if( regChannels[i].enabled )
2310 {
2311 channels20MHz[count].chanId = rfChannels[i].channelNum;
2312 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2313 }
2314 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002315 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2316 {
2317 if( regChannels[i].enabled )
2318 {
2319 channels20MHz[count].chanId = rfChannels[i].channelNum;
2320 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2321 }
2322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002323 *num20MHzChannelsFound = (tANI_U8)count;
2324 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002325
2326 if( channels40MHz && num40MHzChannelsFound )
2327 {
2328 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002329 //center channels for 2.4 Ghz 40 MHz channels
2330 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
2331 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002332
Jeff Johnsone7245742012-09-05 17:12:55 -07002333 if( regChannels[i].enabled )
2334 {
2335 channels40MHz[count].chanId = rfChannels[i].channelNum;
2336 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2337 }
2338 }
2339 //center channels for 5 Ghz 40 MHz channels
2340 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
2341 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002342
Jeff Johnsone7245742012-09-05 17:12:55 -07002343 if( regChannels[i].enabled )
2344 {
2345 channels40MHz[count].chanId = rfChannels[i].channelNum;
2346 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2347 }
2348 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002349 *num40MHzChannelsFound = (tANI_U8)count;
2350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 return (status);
2352}
2353
2354/**------------------------------------------------------------------------
2355 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
2356 \return default regulatory domain
2357 \sa
2358 -------------------------------------------------------------------------*/
2359
2360v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
2361{
2362 return countryInfoTable.countryInfo[0].regDomain;
2363}
2364
2365/**------------------------------------------------------------------------
2366 \brief vos_nv_getSupportedChannels() - function to return the list of
2367 supported channels
2368 \param p20MhzChannels - list of 20 Mhz channels
2369 \param pNum20MhzChannels - number of 20 Mhz channels
2370 \param p40MhzChannels - list of 40 Mhz channels
2371 \param pNum40MhzChannels - number of 40 Mhz channels
2372 \return status of the NV read operation
2373 \Note: 40Mhz not currently supported
2374 \sa
2375 -------------------------------------------------------------------------*/
2376VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
2377 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
2378{
2379 VOS_STATUS status = VOS_STATUS_E_INVAL;
2380 int i, count = 0;
2381
2382 if( p20MhzChannels && pNum20MhzChannels )
2383 {
2384 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
2385 {
2386 for( i = 0; i <= RF_CHAN_14; i++ )
2387 {
2388 p20MhzChannels[count++] = rfChannels[i].channelNum;
2389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2391 {
2392 p20MhzChannels[count++] = rfChannels[i].channelNum;
2393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002394 status = VOS_STATUS_SUCCESS;
2395 }
2396 *pNum20MhzChannels = count;
2397 }
2398
2399 return (status);
2400}
2401
2402/**------------------------------------------------------------------------
2403 \brief vos_nv_readDefaultCountryTable() - return the default Country table
2404 \param table data - a union to return the default country table data in.
2405 \return status of the NV read operation
2406 \sa
2407 -------------------------------------------------------------------------*/
2408VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
2409{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002410
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002411 VOS_STATUS status = VOS_STATUS_SUCCESS;
2412 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
2413 pr_info("DefaultCountry is %c%c\n",
2414 tableData->defaultCountryTable.countryCode[0],
2415 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 return status;
2417}
2418
2419/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002420 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 \param pBuffer - to return the buffer address
2422 pSize - buffer size.
2423 \return status of the NV read operation
2424 \sa
2425 -------------------------------------------------------------------------*/
2426VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2427{
Leo Chang80de3c22013-11-26 10:52:12 -08002428 eNvVersionType nvVersion;
2429
2430 nvVersion = vos_nv_getNvVersion();
2431
2432 if (E_NV_V3 == nvVersion)
2433 {
2434 /* Send the NV V3 structure and size */
2435 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
2436 *pSize = sizeof(sHalNv);
2437 }
2438 else if (E_NV_V2 == nvVersion)
2439 {
2440 /* Send the NV V2 structure and size */
2441 *pNvBuffer = (v_VOID_t *)(&gnvEFSTableV2->halnvV2);
2442 *pSize = sizeof(sHalNvV2);
2443 }
2444 else
2445 {
2446 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2447 "%s : Invalid NV version %d", __func__, nvVersion);
2448 return VOS_STATUS_E_INVAL;
2449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002450
2451 return VOS_STATUS_SUCCESS;
2452}
2453
Jeff Johnson295189b2012-06-20 16:38:30 -07002454/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002455 \brief vos_nv_getBuffer -
2456 \param pBuffer - to return the buffer address
2457 pSize - buffer size.
2458 \return status of the NV read operation
2459 \sa
2460 -------------------------------------------------------------------------*/
2461VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2462{
2463 /* Send the NV structure and size */
2464 VOS_STATUS status;
2465
2466 status = vos_nv_isEmbeddedNV();
2467
2468 if (VOS_STATUS_SUCCESS == status)
2469 {
2470 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
2471 *pSize = nvReadEncodeBufSize;
2472 }
2473 else
2474 {
2475 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
2476 *pSize = sizeof(sHalNv);
2477 }
2478
2479 return VOS_STATUS_SUCCESS;
2480}
2481
2482
2483VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2484{
2485 /* Send the NV structure and size */
2486 *pNvBuffer = (v_VOID_t *)(pDictFile);
2487 *pSize = nDictionarySize;
2488
2489 return VOS_STATUS_SUCCESS;
2490}
2491
2492VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
2493{
2494 if (MAGIC_NUMBER == magicNumber)
2495 {
2496 return VOS_STATUS_SUCCESS;
2497 }
2498
2499 return VOS_STATUS_E_FAILURE;
2500}
2501
2502VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
2503{
2504 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2505 (size-sizeof(v_U32_t)));
2506
2507 return VOS_STATUS_SUCCESS;
2508}
2509
2510/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002511 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 \param rfChannel - input channel enum to know evabled state
2513 \return eNVChannelEnabledType enabled state for channel
2514 * enabled
2515 * disabled
2516 * DFS
2517 \sa
2518 -------------------------------------------------------------------------*/
2519eNVChannelEnabledType vos_nv_getChannelEnabledState
2520(
2521 v_U32_t rfChannel
2522)
2523{
2524 v_U32_t channelLoop;
2525 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2526
2527 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2528 {
2529 if(rfChannels[channelLoop].channelNum == rfChannel)
2530 {
2531 channelEnum = (eRfChannels)channelLoop;
2532 break;
2533 }
2534 }
2535
2536 if(INVALID_RF_CHANNEL == channelEnum)
2537 {
2538 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002539 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002540 return NV_CHANNEL_INVALID;
2541 }
2542
2543 return regChannels[channelEnum].enabled;
2544}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002545
Leo Chang80de3c22013-11-26 10:52:12 -08002546/**------------------------------------------------------------------------
2547 \brief vos_nv_getNvVersion -
2548 \param NONE
2549 \return eNvVersionType NV.bin version
2550 * E_NV_V2
2551 * E_NV_V3
2552 * E_NV_INVALID
2553 \sa
2554 -------------------------------------------------------------------------*/
2555eNvVersionType vos_nv_getNvVersion
2556(
2557 void
2558)
2559{
2560 VosContextType *vosCtxt = NULL;
2561
2562 vosCtxt = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2563 if (vosCtxt)
2564 {
2565 return vosCtxt->nvVersion;
2566 }
2567
2568 return E_NV_INVALID;
2569}
2570
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002571/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002572 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002573*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002574
2575static int bw20_ch_index_to_bw40_ch_index(int k)
2576{
2577 int m = -1;
2578 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2579 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002580 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2581 if (m > RF_CHAN_BOND_11)
2582 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002583 }
2584 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2585 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002586 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2587 if (m > RF_CHAN_BOND_214)
2588 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002589 }
2590 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2591 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002592 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2593 if (m > RF_CHAN_BOND_62)
2594 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002595 }
Leo Chang80de3c22013-11-26 10:52:12 -08002596#ifdef FEATURE_WLAN_CH144
2597 else if (k >= RF_CHAN_100 && k <= RF_CHAN_144)
2598#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002599 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
Leo Chang80de3c22013-11-26 10:52:12 -08002600#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002601 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002602 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
Leo Chang80de3c22013-11-26 10:52:12 -08002603#ifdef FEATURE_WLAN_CH144
2604 if (m > RF_CHAN_BOND_142)
2605 m = RF_CHAN_BOND_142;
2606#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002607 if (m > RF_CHAN_BOND_138)
2608 m = RF_CHAN_BOND_138;
Leo Chang80de3c22013-11-26 10:52:12 -08002609#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002610 }
2611 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2612 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002613 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2614 if (m > RF_CHAN_BOND_163)
2615 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002616 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002617return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002618}
2619
Amar Singhala49cbc52013-10-08 18:37:44 -07002620void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002621{
Amar Singhala49cbc52013-10-08 18:37:44 -07002622 int k;
2623 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2624 countryCode[0], countryCode[1], domain_id);
2625 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2626 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2627 NV_CHANNEL_ENABLE;
2628 /* Max Tx Power 20dBm */
2629 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2630 }
2631 /* enable ch 12 to ch 14 passive scan */
2632 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2633 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2634 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2635 NV_CHANNEL_DFS;
2636 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2637 }
2638 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2639 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2640 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2641 NV_CHANNEL_DFS;
2642 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2643 }
2644#ifdef PASSIVE_SCAN_4_9GHZ
2645 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2646 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2647 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2648 NV_CHANNEL_DFS;
2649 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2650 }
2651#endif
2652 if (domain_id == NUM_REG_DOMAINS-1)
2653 { /* init time */
2654 crda_alpha2[0] = countryCode[0];
2655 crda_alpha2[1] = countryCode[1];
2656 crda_regulatory_entry_valid = VOS_TRUE;
2657 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2658 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2659 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2660 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2661 }
2662 if (domain_id == NUM_REG_DOMAINS-2)
2663 { /* none-default country */
2664 run_time_alpha2[0] = countryCode[0];
2665 run_time_alpha2[1] = countryCode[1];
2666 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2667 }
2668}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002669
Amar Singhala49cbc52013-10-08 18:37:44 -07002670static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2671 struct regulatory_request *request,
2672 v_U8_t nBandCapability,
2673 int domain_id)
2674{
2675 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2676 pr_info("Country 00 special handling to enable passive scan.\n");
2677 crda_regulatory_entry_default(request->alpha2, domain_id);
2678 }
2679 return 0;
2680}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002681
Amar Singhala49cbc52013-10-08 18:37:44 -07002682/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2683static int create_crda_regulatory_entry(struct wiphy *wiphy,
2684 struct regulatory_request *request,
2685 v_U8_t nBandCapability)
2686{
2687 int i, j, m;
2688 int k = 0, n = 0;
2689
2690 if (run_time_alpha2[0]==request->alpha2[0] &&
2691 run_time_alpha2[1]==request->alpha2[1] &&
2692 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2693 return 0; /* already created */
2694
2695 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002696 if (nBandCapability == eCSR_BAND_24)
2697 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002698 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002699 {
2700 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2701 continue;
2702 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2703 continue;
2704 if (wiphy->bands[i] == NULL)
2705 {
2706 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2707 return -1;
2708 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002709 // internal channels[] is one continous array for both 2G and 5G bands
2710 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002711 if (i == 0)
2712 m = 0;
2713 else
2714 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002715 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002716 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002717 // k = (m + j) is internal current channel index for 20MHz channel
2718 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002719 k = m + j;
2720 n = bw20_ch_index_to_bw40_ch_index(k);
2721 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002722 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002723 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2724 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002725 if (pnvEFSTable == NULL)
2726 {
2727 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2728 return -1;
2729 }
2730 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2731 NV_CHANNEL_DISABLE;
2732 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2733 NV_CHANNEL_DISABLE;
2734 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2735 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002736 }
2737 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2738 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002739 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2740 NV_CHANNEL_DFS;
2741 // max_power is in mBm = 100 * dBm
2742 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2743 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2744 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2745 {
2746 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2747 NV_CHANNEL_DFS;
2748 // 40MHz channel power is half of 20MHz (-3dB) ??
2749 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2750 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2751 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002752 }
2753 else // Enable is only last flag we support
2754 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002755 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2756 NV_CHANNEL_ENABLE;
2757 // max_power is in dBm
2758 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2759 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2760 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2761 {
2762 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2763 NV_CHANNEL_ENABLE;
2764 // 40MHz channel power is half of 20MHz (-3dB) ??
2765 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2766 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2767 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002768 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002769 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2770 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002771 }
2772 }
2773 if (k == 0)
2774 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002775 run_time_alpha2[0] = request->alpha2[0];
2776 run_time_alpha2[1] = request->alpha2[1];
2777 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2778 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2779return 0;
2780}
Amar Singhal0d15bd52013-10-12 23:13:13 -07002781
2782
Amar Singhala49cbc52013-10-08 18:37:44 -07002783v_BOOL_t is_crda_regulatory_entry_valid(void)
2784{
2785return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002786}
2787
Amar Singhala49cbc52013-10-08 18:37:44 -07002788/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2789start freq + 10000 = center freq of the 20MHz start channel
2790end freq - 10000 = center freq of the 20MHz end channel
2791start freq + 20000 = center freq of the 40MHz start channel
2792end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002793*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002794static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002795{
Leo Chang80de3c22013-11-26 10:52:12 -08002796 int i;
2797 u32 center_freq = freq_khz + 10000;
2798
Amar Singhala49cbc52013-10-08 18:37:44 -07002799 //Has to compare from low freq to high freq
2800 //RF_SUBBAND_2_4_GHZ
2801 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2802 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2803 return i;
2804 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2805 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2806 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2807 return i;
2808 //RF_SUBBAND_5_LOW_GHZ
2809 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2810 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2811 return i;
2812 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002813#ifdef FEATURE_WLAN_CH144
2814 for (i=RF_CHAN_100;i<=RF_CHAN_144;i++)
2815#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002816 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002817#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002818 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2819 return i;
2820 //RF_SUBBAND_5_HIGH_GHZ
2821 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2822 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2823 return i;
2824return -1;
2825}
2826
2827static int bw20_end_freq_to_channel_index(u32 freq_khz)
2828{
Leo Chang80de3c22013-11-26 10:52:12 -08002829 int i;
2830 u32 center_freq = freq_khz - 10000;
2831
Amar Singhala49cbc52013-10-08 18:37:44 -07002832 //Has to compare from high freq to low freq
2833 //RF_SUBBAND_5_HIGH_GHZ
2834 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2835 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2836 return i;
2837 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002838#ifdef FEATURE_WLAN_CH144
2839 for (i=RF_CHAN_144;i>=RF_CHAN_100;i--)
2840#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002841 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002842#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002843 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2844 return i;
2845 //RF_SUBBAND_5_LOW_GHZ
2846 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2847 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2848 return i;
2849 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2850 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2851 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2852 return i;
2853 //RF_SUBBAND_2_4_GHZ
2854 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2855 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2856 return i;
Leo Chang80de3c22013-11-26 10:52:12 -08002857 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002858}
2859
2860static int bw40_start_freq_to_channel_index(u32 freq_khz)
2861{
Leo Chang80de3c22013-11-26 10:52:12 -08002862 int i;
2863 u32 center_freq = freq_khz + 20000;
2864
Amar Singhala49cbc52013-10-08 18:37:44 -07002865 //Has to compare from low freq to high freq
2866 //RF_SUBBAND_2_4_GHZ
2867 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2868 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2869 return i;
2870 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2871 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2872 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2873 return i;
2874 //RF_SUBBAND_5_LOW_GHZ
2875 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2876 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2877 return i;
2878 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002879#ifdef FEATURE_WLAN_CH144
2880 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_142;i++)
2881#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002882 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002883#endif /* RF_CHAN_BOND_142 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002884 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2885 return i;
2886 //RF_SUBBAND_5_HIGH_GHZ
2887 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2888 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2889 return i;
2890return -1;
2891}
2892
2893static int bw40_end_freq_to_channel_index(u32 freq_khz)
2894{
Leo Chang80de3c22013-11-26 10:52:12 -08002895 int i;
2896 u32 center_freq = freq_khz - 20000;
2897
Amar Singhala49cbc52013-10-08 18:37:44 -07002898 //Has to compare from high freq to low freq
2899 //RF_SUBBAND_5_HIGH_GHZ
2900 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2901 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2902 return i;
2903 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002904#ifdef FEATURE_WLAN_CH144
2905 for (i=RF_CHAN_BOND_142;i>=RF_CHAN_BOND_102;i--)
2906#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002907 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002908#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002909 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2910 return i;
2911 //RF_SUBBAND_5_LOW_GHZ
2912 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2913 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2914 return i;
2915 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2916 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2917 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2918 return i;
2919 //RF_SUBBAND_2_4_GHZ
2920 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2921 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2922 return i;
2923return -1;
2924}
2925
2926static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2927{
2928 switch (nBandCapability)
2929 {
2930 case eCSR_BAND_ALL:
2931 return VOS_TRUE;
2932 case eCSR_BAND_24:
2933 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2934 return VOS_TRUE;
2935 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2936 return VOS_TRUE; // 2.4G 40MHz channel
2937 break;
2938 case eCSR_BAND_5G:
2939 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2940 return VOS_TRUE;
2941 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2942 return VOS_TRUE; // 2.4G 40MHz channel
2943 break;
2944 default:
2945 break;
2946 }
2947 return VOS_FALSE;
2948}
2949
2950/* create_crda_regulatory_entry_from_regd should be called during init time */
2951static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2952 struct regulatory_request *request,
2953 v_U8_t nBandCapability)
2954{
2955 int i, j, n, domain_id;
2956 int bw20_start_channel_index, bw20_end_channel_index;
2957 int bw40_start_channel_index, bw40_end_channel_index;
2958
2959 if (wiphy == NULL || wiphy->regd == NULL)
2960 {
2961 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2962 return -1;
2963 }
2964 if (crda_regulatory_entry_valid == VOS_FALSE)
2965 domain_id = NUM_REG_DOMAINS-1; /* init time */
2966 else
2967 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2968 for (n = 0; n < NUM_RF_CHANNELS; n++)
2969 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2970
2971 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2972 {
2973 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2974 bw20_start_channel_index =
2975 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2976 bw20_end_channel_index =
2977 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2978 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2979 {
2980 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2981 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2982 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2983 continue; // skip this rull, but continue to next rule
2984 }
2985 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2986 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2987 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2988 bw20_start_channel_index, bw20_end_channel_index);
2989 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2990 {
2991 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2992 {
2993 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2994 rfChannels[j].channelNum);
2995 continue; // skip this channel, continue to next
2996 }
2997 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2998 {
2999 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3000 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3001 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3002 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303003 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN)
3004 {
3005 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3006 wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3007 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3008 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003009 else
3010 {
3011 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3012 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3013 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3014 }
3015 /* max_eirp is in mBm (= 100 * dBm) unit */
3016 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3017 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
3018 }
3019 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
3020 real gain which should be provided by the real design */
3021 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
3022 {
3023 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
3024 bw40_start_channel_index =
3025 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
3026 bw40_end_channel_index =
3027 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3028 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
3029 {
3030 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
3031 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3032 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3033 continue; // skip this rull, but continue to next rule
3034 }
3035 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3036 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3037 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3038 bw40_start_channel_index, bw40_end_channel_index);
3039 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
3040 {
3041 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3042 continue; // skip this channel, continue to next
3043 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3044 {
3045 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3046 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
3047 }
3048 else
3049 {
3050 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3051 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
3052 }
3053 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
3054 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3055 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
3056 }
3057 }
3058 }
3059 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
3060 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
3061 these flags and has no implementation yet. */
3062 if (crda_regulatory_entry_valid == VOS_FALSE)
3063 { /* init time */
3064 crda_alpha2[0] = request->alpha2[0];
3065 crda_alpha2[1] = request->alpha2[1];
3066 crda_regulatory_entry_valid = VOS_TRUE;
3067 }
3068 else
3069 { /* none-default country */
3070 run_time_alpha2[0] = request->alpha2[0];
3071 run_time_alpha2[1] = request->alpha2[1];
3072 crda_regulatory_run_time_entry_valid = VOS_TRUE;
3073 }
3074 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
3075 return 0;
3076}
3077
3078#ifdef CONFIG_ENABLE_LINUX_REG
3079
3080/**------------------------------------------------------------------------
3081 \brief vos_nv_setRegDomain -
3082 \param clientCtxt - Client Context, Not used for PRIMA
3083 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303084 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003085 \return status set REG domain operation
3086 \sa
3087 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303088VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3089 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003090{
3091
3092 if (regId >= REGDOMAIN_COUNT)
3093 {
3094 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3095 "VOS set reg domain, invalid REG domain ID %d", regId);
3096 return VOS_STATUS_E_INVAL;
3097 }
3098
3099 /* Set correct channel information based on REG Domain */
3100 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3101
3102 return VOS_STATUS_SUCCESS;
3103}
3104
3105/**------------------------------------------------------------------------
3106 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3107 a country given its country code
3108 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3109 a country given its country code. This is done from reading a cached
3110 copy of the binary file.
3111 \param pRegDomain - pointer to regulatory domain
3112 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303113 \param source - source of the country code
Amar Singhala49cbc52013-10-08 18:37:44 -07003114 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3115 VOS_STATUS_E_FAULT - invalid pointer error
3116 VOS_STATUS_E_EMPTY - country code table is empty
3117 VOS_STATUS_E_EXISTS - given country code does not exist in table
3118 \sa
3119 -------------------------------------------------------------------------*/
3120VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303121 const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source)
Amar Singhala49cbc52013-10-08 18:37:44 -07003122{
3123
Amar Singhalfddc28c2013-09-05 13:03:40 -07003124 v_CONTEXT_t pVosContext = NULL;
3125 hdd_context_t *pHddCtx = NULL;
3126 struct wiphy *wiphy = NULL;
3127 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07003128 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003129
Amar Singhalfddc28c2013-09-05 13:03:40 -07003130 /* sanity checks */
3131 if (NULL == pRegDomain)
3132 {
3133 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3134 ("Invalid reg domain pointer") );
3135 return VOS_STATUS_E_FAULT;
3136 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003137
Amar Singhalfddc28c2013-09-05 13:03:40 -07003138 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003139
Amar Singhala49cbc52013-10-08 18:37:44 -07003140 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003141 {
3142 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3143 ("Country code array is NULL"));
3144 return VOS_STATUS_E_FAULT;
3145 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003146
Amar Singhalfddc28c2013-09-05 13:03:40 -07003147 if (0 == countryInfoTable.countryCount)
3148 {
3149 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3150 ("Reg domain table is empty") );
3151 return VOS_STATUS_E_EMPTY;
3152 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003153
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003154
Amar Singhalfddc28c2013-09-05 13:03:40 -07003155 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003156
Amar Singhalfddc28c2013-09-05 13:03:40 -07003157 if (NULL != pVosContext)
3158 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3159 else
3160 return VOS_STATUS_E_EXISTS;
3161
3162 if (NULL == pHddCtx)
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3165 ("Invalid pHddCtx pointer") );
3166 return VOS_STATUS_E_FAULT;
3167 }
3168
Kiet Lam6c583332013-10-14 05:37:09 +05303169 temp_reg_domain = REGDOMAIN_COUNT;
3170 /* lookup the country in the local database */
3171 for (i = 0; i < countryInfoTable.countryCount &&
3172 REGDOMAIN_COUNT == temp_reg_domain; i++)
3173 {
3174 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3175 VOS_COUNTRY_CODE_LEN) == 0)
3176 {
3177 /* country code is found */
3178 /* record the temporary regulatory_domain as well */
3179 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3180 break;
3181 }
3182 }
3183
3184 if (REGDOMAIN_COUNT == temp_reg_domain) {
3185
3186 /* the country was not found in the driver database */
3187 /* so we will return the REGDOMAIN_WORLD to SME/CSR */
3188
3189 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3190 ("Country does not map to any Regulatory domain"));
3191
3192 temp_reg_domain = REGDOMAIN_WORLD;
3193 }
3194
3195 if (COUNTRY_QUERY == source)
3196 {
3197 *pRegDomain = temp_reg_domain;
3198 return VOS_STATUS_SUCCESS;
3199 }
3200
Amar Singhalfddc28c2013-09-05 13:03:40 -07003201 wiphy = pHddCtx->wiphy;
3202
Amar Singhala49cbc52013-10-08 18:37:44 -07003203 if (false == wiphy->registered)
3204 {
3205 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3206 ("wiphy is not yet registered with the kernel") );
3207 return VOS_STATUS_E_FAULT;
3208 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003209
3210 /* We need to query the kernel to get the regulatory information
3211 for this country */
3212
Amar Singhal0d15bd52013-10-12 23:13:13 -07003213
3214 /* First compare the country code with the existing current country code
3215 . If both are same there is no need to query any database */
3216
3217 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3218 ("regdomain request"));
3219
3220 if ((country_code[0] == linux_reg_cc[0]) &&
3221 (country_code[1] == linux_reg_cc[1])) {
3222
3223 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003224
Amar Singhala49cbc52013-10-08 18:37:44 -07003225 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhal0d15bd52013-10-12 23:13:13 -07003226 (" country code already exists"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003227
Amar Singhal0d15bd52013-10-12 23:13:13 -07003228 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003229
Amar Singhal0d15bd52013-10-12 23:13:13 -07003230 return VOS_STATUS_SUCCESS;
3231 }
3232 else {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003233
Amar Singhal0d15bd52013-10-12 23:13:13 -07003234 /* get the regulatory information from the kernel
3235 database */
Amar Singhala49cbc52013-10-08 18:37:44 -07003236
Amar Singhal0d15bd52013-10-12 23:13:13 -07003237 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3238 (" get country information from kernel db"));
3239
Amar Singhal0d15bd52013-10-12 23:13:13 -07003240
Kiet Lam6c583332013-10-14 05:37:09 +05303241 if (COUNTRY_NV == source)
3242 {
3243 INIT_COMPLETION(pHddCtx->linux_reg_req);
3244 regulatory_hint(wiphy, country_code);
3245 wait_result = wait_for_completion_interruptible_timeout(
3246 &pHddCtx->linux_reg_req,
3247 LINUX_REG_WAIT_TIME);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003248
Kiet Lam6c583332013-10-14 05:37:09 +05303249 /* if the country information does not exist with the kernel,
3250 then the driver callback would not be called */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003251
Kiet Lam6c583332013-10-14 05:37:09 +05303252 if (wait_result >= 0) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003253
Kiet Lam6c583332013-10-14 05:37:09 +05303254 /* the driver callback was called. this means the country
3255 regulatory information was found in the kernel database.
3256 The callback would have updated the internal database. Here
3257 update the country and the return value for the regulatory
3258 domain */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003259
Kiet Lam6c583332013-10-14 05:37:09 +05303260 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3261 ("runtime country code is found in kernel db"));
3262
3263 *pRegDomain = temp_reg_domain;
3264 cur_reg_domain = temp_reg_domain;
3265 linux_reg_cc[0] = country_code[0];
3266 linux_reg_cc[1] = country_code[1];
3267
3268 return VOS_STATUS_SUCCESS;
3269 }
3270 else {
3271
3272 /* the country information has not been found in the kernel
3273 database, return failure */
3274
3275 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3276 ("runtime country code is not found in kernel db"));
3277
3278 return VOS_STATUS_E_EXISTS;
3279 }
3280 }
3281 else if (COUNTRY_IE == source || COUNTRY_USER == source)
3282 {
3283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3284 regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER);
3285#else
3286 regulatory_hint_user(country_code);
3287#endif
Amar Singhal0d15bd52013-10-12 23:13:13 -07003288 *pRegDomain = temp_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003289 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003290
Kiet Lam6c583332013-10-14 05:37:09 +05303291 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003292
Kiet Lam6c583332013-10-14 05:37:09 +05303293 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003294}
3295
Amar Singhal0d15bd52013-10-12 23:13:13 -07003296/* create_linux_regulatory_entry to populate internal structures from wiphy */
3297static int create_linux_regulatory_entry(struct wiphy *wiphy,
3298 struct regulatory_request *request,
3299 v_U8_t nBandCapability)
3300{
3301 int i, j, m;
3302 int k = 0, n = 0;
Kiet Lam5cb90e82013-10-25 19:35:12 +05303303#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
3304 int err;
3305#endif
3306 const struct ieee80211_reg_rule *reg_rule;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003307 v_CONTEXT_t pVosContext = NULL;
3308 hdd_context_t *pHddCtx = NULL;
3309
3310 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3311
3312 if (NULL != pVosContext)
3313 {
3314 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3315 if (NULL == pHddCtx)
3316 {
3317 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3318 ("Invalid pHddCtx pointer") );
3319 }
3320 else
3321 {
3322 pHddCtx->isVHT80Allowed = 0;
3323 }
3324 }
3325 else
3326 {
3327 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3328 ("Invalid pVosContext pointer") );
3329 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003330
3331 /* 20MHz channels */
3332 if (nBandCapability == eCSR_BAND_24)
3333 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08003334 "BandCapability is set to 2G only");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003335
3336 for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++)
3337 {
3338 /* 5G only */
3339 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G)
3340 continue;
3341
3342 /* 2G only */
3343 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24)
3344 continue;
3345
3346 if (wiphy->bands[i] == NULL)
3347 {
3348
3349 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003350 "error: wiphy->bands is NULL, i = %d", i);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003351 return -1;
3352 }
3353
3354 /* internal channels[] is one continous array for both 2G and 5G bands
3355 m is internal starting channel index for each band */
3356
3357 if (i == 0)
3358 m = 0;
3359 else
3360 m = wiphy->bands[i-1]->n_channels + m;
3361
3362 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3363 {
3364 /* k = (m + j) is internal current channel index for 20MHz channel
3365 n is internal channel index for corresponding 40MHz channel */
3366
3367 k = m + j;
3368 n = bw20_ch_index_to_bw40_ch_index(k);
3369
3370 if (n == -1)
3371 return -1;
3372
Kiet Lam5cb90e82013-10-25 19:35:12 +05303373 /* If the regulatory rules for a country do not explicilty
3374 * require a passive scan on a frequency, lift the passive
3375 * scan restriction
3376 */
3377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3378 reg_rule = freq_reg_info(wiphy,
3379 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq));
3380#else
3381 err = freq_reg_info(wiphy,
3382 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq),
3383 0, &reg_rule);
3384#endif
3385
3386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3387 if (!IS_ERR(reg_rule))
3388#else
3389 if (0 == err)
3390#endif
3391 {
3392 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
3393 {
3394 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3395 "%s: Remove passive scan restriction for %u",
3396 __func__, wiphy->bands[i]->channels[j].center_freq);
3397 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3398 }
3399 }
3400
Amar Singhal0d15bd52013-10-12 23:13:13 -07003401 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
3402 {
3403 if (pnvEFSTable == NULL)
3404 {
3405 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003406 "error: pnvEFSTable is NULL, probably not parsed nv.bin yet");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003407 return -1;
3408 }
3409 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3410 NV_CHANNEL_DISABLE;
3411 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3412 NV_CHANNEL_DISABLE;
3413 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303414 /* nv cannot distinguish between DFS and passive channels */
3415 else if (wiphy->bands[i]->channels[j].flags &
3416 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
Amar Singhal0d15bd52013-10-12 23:13:13 -07003417 {
3418 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3419 NV_CHANNEL_DFS;
3420
3421 /* max_power is in mBm = 100 * dBm */
3422 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003423 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003424 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
3425 {
3426 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3427 NV_CHANNEL_DFS;
3428
3429 /* 40MHz channel power is half of 20MHz (-3dB) ?? */
3430 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003431 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003432 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003433 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3434 {
3435 if (NULL == pHddCtx)
3436 {
3437 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3438 ("Invalid pHddCtx pointer") );
3439 }
3440 else
3441 {
3442 pHddCtx->isVHT80Allowed = 1;
3443 }
3444 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003445 }
3446 else /* Enable is only last flag we support */
3447 {
3448 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3449 NV_CHANNEL_ENABLE;
3450
3451 /* max_power is in dBm */
3452 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003453 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003454 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
3455 {
3456 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3457 NV_CHANNEL_ENABLE;
3458 /* 40MHz channel power is half of 20MHz (-3dB) */
3459 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003460 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003461 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003462 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3463 {
3464 if (NULL == pHddCtx)
3465 {
3466 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3467 ("Invalid pHddCtx pointer") );
3468 }
3469 else
3470 {
3471 pHddCtx->isVHT80Allowed = 1;
3472 }
3473 }
3474
Amar Singhal0d15bd52013-10-12 23:13:13 -07003475 }
3476
Kiet Lam5cb90e82013-10-25 19:35:12 +05303477
Amar Singhal0d15bd52013-10-12 23:13:13 -07003478 }
3479 }
3480
3481 if (k == 0)
3482 return -1;
3483
3484 return 0;
3485}
3486
3487
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003488/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07003489 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003490 * This function is called from cfg80211 core to provide regulatory settings
3491 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07003492 * This function is used to create a CRDA regulatory settings entry into internal
3493 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003494 */
Amar Singhala49cbc52013-10-08 18:37:44 -07003495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003496void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07003497 struct regulatory_request *request)
3498#else
Amar Singhala49cbc52013-10-08 18:37:44 -07003499int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003500 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07003501#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003502{
3503 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Amar Singhala49cbc52013-10-08 18:37:44 -07003504 tANI_U8 nBandCapability;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003505 v_COUNTRYCODE_t country_code;
3506 int i;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003507 v_BOOL_t isVHT80Allowed;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003508
Amar Singhala49cbc52013-10-08 18:37:44 -07003509 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003510 "cfg80211 reg notifier callback for country for initiator %d", request->initiator);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003511
Arif Hussainec3fbb32013-10-03 11:49:23 -07003512 if (pHddCtx->isLoadUnloadInProgress)
3513 {
3514 wiphy_dbg(wiphy, "info: %s: Unloading/Loading in Progress. Ignore!!!",
3515 __func__);
Kiet Lamcffc5862013-10-30 16:28:45 +05303516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Arif Hussainec3fbb32013-10-03 11:49:23 -07003517 return;
Kiet Lamcffc5862013-10-30 16:28:45 +05303518#else
3519 return 0;
3520#endif
3521 }
3522
3523 if (NULL == pHddCtx)
3524 {
3525 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3526 ("Invalid pHddCtx pointer") );
3527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3528 return;
3529#else
3530 return 0;
3531#endif
Arif Hussainec3fbb32013-10-03 11:49:23 -07003532 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003533 /* first check if this callback is in response to the driver callback */
3534
Amar Singhala49cbc52013-10-08 18:37:44 -07003535 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
3536 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003537
Amar Singhal0d15bd52013-10-12 23:13:13 -07003538 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003539 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003540 if (create_linux_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
3541 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003542
Amar Singhal0d15bd52013-10-12 23:13:13 -07003543 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07003544 (" regulatory entry created"));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003545 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003546 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3547 {
3548 hdd_checkandupdate_phymode( pHddCtx);
3549 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003550
Amar Singhal0d15bd52013-10-12 23:13:13 -07003551 complete(&pHddCtx->linux_reg_req);
3552 }
3553
Kiet Lamcffc5862013-10-30 16:28:45 +05303554 else if (request->initiator == NL80211_REGDOM_SET_BY_USER ||
3555 request->initiator == NL80211_REGDOM_SET_BY_CORE)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003556 {
3557
3558 /* first lookup the country in the local database */
3559
3560 country_code[0] = request->alpha2[0];
3561 country_code[1] = request->alpha2[1];
3562
3563 temp_reg_domain = REGDOMAIN_COUNT;
3564 for (i = 0; i < countryInfoTable.countryCount &&
3565 REGDOMAIN_COUNT == temp_reg_domain; i++)
3566 {
3567 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3568 VOS_COUNTRY_CODE_LEN) == 0)
3569 {
3570 /* country code is found */
3571 /* record the temporary regulatory_domain as well */
3572 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3573 break;
3574 }
3575 }
3576
3577 if (REGDOMAIN_COUNT == temp_reg_domain)
3578 temp_reg_domain = REGDOMAIN_WORLD;
3579
3580 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003581 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003582 if (create_linux_regulatory_entry(wiphy, request,
3583 pHddCtx->cfg_ini->nBandCapability) == 0)
3584 {
3585 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3586 (" regulatory entry created"));
3587
3588 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003589 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3590 {
3591 hdd_checkandupdate_phymode( pHddCtx);
3592 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003593
3594 cur_reg_domain = temp_reg_domain;
3595 linux_reg_cc[0] = country_code[0];
3596 linux_reg_cc[1] = country_code[1];
3597
3598 /* now pass the new country information to sme */
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003599 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
3600 {
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003601 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3602 REGDOMAIN_COUNT);
3603 }
Kiet Lamcffc5862013-10-30 16:28:45 +05303604 else
3605 {
3606 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3607 temp_reg_domain);
3608 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05303609
Kiet Lamcffc5862013-10-30 16:28:45 +05303610 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07003612 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07003613#else
3614 return 0;
3615#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003616}
Amar Singhalfddc28c2013-09-05 13:03:40 -07003617
Amar Singhal0d15bd52013-10-12 23:13:13 -07003618
Amar Singhal0a402232013-10-11 20:57:16 -07003619/* initialize wiphy from NV.bin */
3620VOS_STATUS vos_init_wiphy_from_nv_bin(void)
3621{
3622 int i, j, m;
3623 int k = 0;
3624 v_REGDOMAIN_t reg_domain;
3625 v_CONTEXT_t pVosContext = NULL;
3626 hdd_context_t *pHddCtx = NULL;
3627 struct wiphy *wiphy = NULL;
3628
3629 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3630
3631 if (NULL != pVosContext)
3632 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3633 else
3634 return VOS_STATUS_E_EXISTS;
3635
3636 if (NULL == pHddCtx)
3637 {
3638 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3639 ("Invalid pHddCtx pointer") );
3640 return VOS_STATUS_E_FAULT;
3641 }
3642
3643 wiphy = pHddCtx->wiphy;
3644
3645 if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0])
3646 &&
3647 ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]))
3648 {
3649 /* default country is world roaming */
3650
3651 reg_domain = REGDOMAIN_WORLD;
3652 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3653 }
3654 else if (REGDOMAIN_WORLD ==
3655 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) {
3656
3657 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3658 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3659 }
3660 else {
3661
3662 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3663 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
3664 }
3665
Amar Singhala1829502013-11-16 13:57:41 -08003666 m = 0;
Amar Singhal0a402232013-10-11 20:57:16 -07003667 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3668 {
3669
3670 if (wiphy->bands[i] == NULL)
3671 {
3672 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
Amar Singhala1829502013-11-16 13:57:41 -08003673 continue;
Amar Singhal0a402232013-10-11 20:57:16 -07003674 }
3675
3676 /* internal channels[] is one continous array for both 2G and 5G bands
3677 m is internal starting channel index for each band */
Amar Singhal0a402232013-10-11 20:57:16 -07003678
3679 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3680 {
3681 /* k = (m + j) is internal current channel index */
3682 k = m + j;
3683
3684 if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3685 NV_CHANNEL_DISABLE)
3686 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3687
3688 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3689 NV_CHANNEL_DFS) {
3690
3691 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3692
3693 wiphy->bands[i]->channels[j].max_power =
3694 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3695 }
3696
3697 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3698 NV_CHANNEL_ENABLE) {
3699
3700 wiphy->bands[i]->channels[j].max_power =
3701 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3702 }
3703 }
Amar Singhala1829502013-11-16 13:57:41 -08003704
3705 m += wiphy->bands[i]->n_channels;
Amar Singhal0a402232013-10-11 20:57:16 -07003706 }
3707
3708 return VOS_STATUS_SUCCESS;
3709}
3710
3711
Amar Singhalfddc28c2013-09-05 13:03:40 -07003712#else
3713
3714/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07003715 \brief vos_nv_setRegDomain -
3716 \param clientCtxt - Client Context, Not used for PRIMA
3717 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303718 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003719 \return status set REG domain operation
3720 \sa
3721 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303722VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3723 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003724{
3725 v_CONTEXT_t pVosContext = NULL;
3726 hdd_context_t *pHddCtx = NULL;
3727 struct wiphy *wiphy = NULL;
3728 /* Client Context Argumant not used for PRIMA */
3729 if (regId >= REGDOMAIN_COUNT)
3730 {
3731 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3732 "VOS set reg domain, invalid REG domain ID %d", regId);
3733 return VOS_STATUS_E_INVAL;
3734 }
3735
3736 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3737 if (NULL != pVosContext)
3738 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3739 else
3740 return VOS_STATUS_E_EXISTS;
3741 /* Set correct channel information based on REG Domain */
3742 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3743
3744 /* when CRDA is not running then we are world roaming.
3745 In this case if 11d is enabled, then country code should
3746 be update on basis of world roaming */
Abhishek Singha306a442013-11-07 18:39:01 +05303747 if (NULL != pHddCtx && sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003748 {
3749 wiphy = pHddCtx->wiphy;
3750 regulatory_hint(wiphy, "00");
3751 }
3752 return VOS_STATUS_SUCCESS;
3753}
3754
3755
3756/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07003757 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3758 a country given its country code
3759 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3760 a country given its country code. This is done from reading a cached
3761 copy of the binary file.
3762 \param pRegDomain - pointer to regulatory domain
3763 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303764 \param source - source of the country code
Amar Singhalfddc28c2013-09-05 13:03:40 -07003765 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3766 VOS_STATUS_E_FAULT - invalid pointer error
3767 VOS_STATUS_E_EMPTY - country code table is empty
3768 VOS_STATUS_E_EXISTS - given country code does not exist in table
3769 \sa
3770 -------------------------------------------------------------------------*/
3771VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303772 const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003773{
Amar Singhala49cbc52013-10-08 18:37:44 -07003774 int i;
3775 v_CONTEXT_t pVosContext = NULL;
3776 hdd_context_t *pHddCtx = NULL;
3777 struct wiphy *wiphy = NULL;
3778 int status;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003779
Amar Singhala49cbc52013-10-08 18:37:44 -07003780 // sanity checks
3781 if (NULL == pRegDomain)
3782 {
3783 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003784 ("Invalid reg domain pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003785 return VOS_STATUS_E_FAULT;
3786 }
3787 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003788
Amar Singhala49cbc52013-10-08 18:37:44 -07003789 if (NULL == countryCode)
3790 {
3791 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003792 ("Country code array is NULL") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003793 return VOS_STATUS_E_FAULT;
3794 }
3795 if (0 == countryInfoTable.countryCount)
3796 {
3797 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003798 ("Reg domain table is empty") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003799 return VOS_STATUS_E_EMPTY;
3800 }
3801 /* If CRDA regulatory settings is valid, i.e. crda is enabled
3802 and reg_notifier is called back.
3803 Intercept here and redirect to the Reg domain table's CRDA
3804 entry if country code is crda's country.
3805 last one NUM_REG_DOMAINS-1 is reserved for crda */
3806 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003807 "vos_nv_getRegDomainFromCountryCode %c%c",
Amar Singhala49cbc52013-10-08 18:37:44 -07003808 countryCode[0], countryCode[1]);
3809
3810 if (crda_regulatory_entry_valid == VOS_TRUE)
3811 {
3812 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
3813 {
3814 *pRegDomain = NUM_REG_DOMAINS-1;
3815 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003816 "vos_nv_getRegDomainFromCountryCode return crda init entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003817 return VOS_STATUS_SUCCESS;
3818 }
3819 if (run_time_alpha2[0]==countryCode[0] &&
3820 run_time_alpha2[1]==countryCode[1] &&
3821 crda_regulatory_run_time_entry_valid == VOS_TRUE)
3822 {
3823 *pRegDomain = NUM_REG_DOMAINS-2;
3824 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003825 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003826 return VOS_STATUS_SUCCESS;
3827 }
3828 else
3829 {
3830 crda_regulatory_run_time_entry_valid = VOS_FALSE;
3831 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3832 if (NULL != pVosContext)
3833 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3834 else
3835 return VOS_STATUS_E_EXISTS;
3836 if (NULL == pHddCtx)
3837 {
3838 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003839 ("Invalid pHddCtx pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003840 return VOS_STATUS_E_FAULT;
3841 }
3842
3843 wiphy = pHddCtx->wiphy;
3844
3845 INIT_COMPLETION(pHddCtx->driver_crda_req);
3846 regulatory_hint(wiphy, countryCode);
3847 status = wait_for_completion_interruptible_timeout(
3848 &pHddCtx->driver_crda_req,
3849 msecs_to_jiffies(CRDA_WAIT_TIME));
3850 if (!status)
3851 {
3852 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3853 "%s: Timeout waiting for CRDA REQ", __func__);
3854 }
3855
3856 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
3857 {
3858 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003859 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003860 return VOS_STATUS_SUCCESS;
3861 }
3862 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003863 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003864 return VOS_STATUS_E_EXISTS;
3865 }
3866 }
3867
3868 // iterate the country info table until end of table or the country code
3869 // is found
3870 for (i = 0; i < countryInfoTable.countryCount &&
3871 REGDOMAIN_COUNT == *pRegDomain; i++)
3872 {
3873 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
3874 VOS_COUNTRY_CODE_LEN) == 0)
3875 {
3876 // country code is found
3877 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
3878 }
3879 }
3880 if (REGDOMAIN_COUNT != *pRegDomain)
3881 {
3882 return VOS_STATUS_SUCCESS;
3883 }
3884 else
3885 {
3886 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08003887 ("country code is not found"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003888 return VOS_STATUS_E_EXISTS;
3889 }
3890}
Abhishek Singha306a442013-11-07 18:39:01 +05303891/* FUNCTION: vos_nv_change_country_code_cb
3892* to wait for contry code completion
3893*/
3894void* vos_nv_change_country_code_cb(void *pAdapter)
3895{
3896 struct completion *change_code_cng = pAdapter;
3897 complete(change_code_cng);
3898 return NULL;
3899}
Amar Singhala49cbc52013-10-08 18:37:44 -07003900
3901/*
3902 * Function: wlan_hdd_crda_reg_notifier
3903 * This function is called from cfg80211 core to provide regulatory settings
3904 * after new country is requested or intersected (init, user input or 11d)
3905 * This function is used to create a CRDA regulatory settings entry into internal
3906 * regulatory setting table.
3907 */
3908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3909void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3910 struct regulatory_request *request)
3911#else
3912int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3913 struct regulatory_request *request)
3914#endif
3915{
3916 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3917 v_REGDOMAIN_t domainIdCurrent;
3918 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
3919 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
3920 tANI_U8 nBandCapability;
3921 int i,j,k,m;
3922
3923 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
3924 " %c%c\n", request->alpha2[0], request->alpha2[1]);
3925 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003926 {
Abhishek Singha306a442013-11-07 18:39:01 +05303927 int status;
Amar Singhala49cbc52013-10-08 18:37:44 -07003928 wiphy_dbg(wiphy, "info: set by user\n");
Abhishek Singha306a442013-11-07 18:39:01 +05303929 init_completion(&change_country_code);
3930 /* We will process hints by user from nl80211 in driver.
3931 * sme_ChangeCountryCode will set the country to driver
3932 * and update the regdomain.
3933 * when we return back to nl80211 from this callback, the nl80211 will
3934 * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to
3935 * query channel list from nl80211. Thus we need to update the channels
3936 * according to reg domain set by user before returning to nl80211 so
3937 * that hostapd will gets the updated channels.
3938 * The argument sendRegHint in sme_ChangeCountryCode is
3939 * set to eSIR_FALSE (hint is from nl80211 and thus
3940 * no need to notify nl80211 back)*/
3941 status = sme_ChangeCountryCode(pHddCtx->hHal,
3942 (void *)(tSmeChangeCountryCallback)
3943 vos_nv_change_country_code_cb,
3944 request->alpha2,
3945 &change_country_code,
3946 pHddCtx->pvosContext,
3947 eSIR_FALSE,
3948 eSIR_FALSE);
3949 if (eHAL_STATUS_SUCCESS == status)
3950 {
3951 status = wait_for_completion_interruptible_timeout(
3952 &change_country_code,
3953 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3954 if(status <= 0)
3955 {
3956 wiphy_dbg(wiphy, "info: set country timed out\n");
3957 }
3958 }
3959 else
3960 {
3961 wiphy_dbg(wiphy, "info: unable to set country by user\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07003962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3963 return;
3964#else
3965 return 0;
3966#endif
Abhishek Singha306a442013-11-07 18:39:01 +05303967 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003968 // ToDo
3969 /* Don't change default country code to CRDA country code by user req */
3970 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
3971 regd for new country settings */
3972 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3973 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003974 }
Abhishek Singha306a442013-11-07 18:39:01 +05303975
3976 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003977 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003978 wiphy_dbg(wiphy, "info: set by country IE\n");
3979 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
3980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3981 return;
3982#else
3983 return 0;
3984#endif
3985 // ToDo
3986 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003987
Amar Singhala49cbc52013-10-08 18:37:44 -07003988 /* Don't change default country code to CRDA country code by 11d req */
3989 /* for every adapter call sme_ChangeCountryCode to trigger read regd
3990 for intersected new country settings */
3991 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3992 // &country_code[0], pAdapter, pHddCtx->pvosContext);
3993 }
3994 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
Abhishek Singha306a442013-11-07 18:39:01 +05303995 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
3996 (request->initiator == NL80211_REGDOM_SET_BY_USER))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003997 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003998 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
3999 {
4000 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
4001#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4002 return;
4003#else
4004 return 0;
4005#endif
4006 }
4007 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
4008 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
4009 {
4010 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
4011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4012 return;
4013#else
4014 return 0;
4015#endif
4016 }
4017
4018 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
4019 /* if set by driver itself, it means driver can accept the crda
4020 regulatory settings and wiphy->regd should be populated with crda
4021 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
4022 correctly, this may be fixed by later kernel */
4023
4024 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
4025 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
4026 {
4027 if (NULL == wiphy->bands[i])
4028 {
4029 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4030 "error: wiphy->bands[i] is NULL, i = %d", i);
4031 continue;
4032 }
4033
4034 // internal channels[] is one continous array for both 2G and 5G bands
4035 // m is internal starting channel index for each band
4036 if (0 == i)
4037 {
4038 m = 0;
4039 }
4040 else
4041 {
4042 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
4043 }
4044
4045 for (j=0; j<wiphy->bands[i]->n_channels; j++)
4046 {
4047 // k = (m + j) is internal current channel index for 20MHz channel
4048 // n is internal channel index for corresponding 40MHz channel
4049 k = m + j;
4050 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
4051 {
4052 // Enable social channels for P2P
4053 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
4054 2437 == wiphy->bands[i]->channels[j].center_freq ||
4055 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
4056 NV_CHANNEL_ENABLE == regChannels[k].enabled)
4057 {
4058 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4059 }
4060 else
4061 {
4062 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4063 }
4064 continue;
4065 }
4066 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
4067 {
4068 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4069 continue;
4070 }
4071
4072 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
4073 NV_CHANNEL_INVALID == regChannels[k].enabled)
4074 {
4075 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4076 }
4077 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
4078 {
4079 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4080 |IEEE80211_CHAN_RADAR);
4081 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4082 }
4083 else
4084 {
4085 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4086 |IEEE80211_CHAN_PASSIVE_SCAN
4087 |IEEE80211_CHAN_NO_IBSS
4088 |IEEE80211_CHAN_RADAR);
4089 }
4090 }
4091 }
4092
4093 /* Haven't seen any condition that will set by driver after init.
4094 If we do, then we should also call sme_ChangeCountryCode */
4095 if (wiphy->bands[IEEE80211_BAND_5GHZ])
4096 {
4097 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4098 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304099 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07004100 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
4101 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4102 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4103 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304104 ((ccode[0]== 'U'&& ccode[1]=='S') && pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004105 {
4106 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4107 }
4108 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
4109 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4110 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4111 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304112 ((ccode[0]!= 'U'&& ccode[1]!='S') || !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004113 {
4114 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
4115 }
4116 }
4117 }
4118
4119 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
4120 {
4121 request->processed = 1;
4122 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07004123 }
4124
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304125 complete(&pHddCtx->wiphy_channel_update_event);
4126
Amar Singhala49cbc52013-10-08 18:37:44 -07004127#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4128 return;
4129#else
4130 return 0;
4131#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07004132}
4133
4134#endif