blob: cfb62b7ab5a75934d62b5c41540e40e9ca7cc4ad [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
567const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
568{
569 //RF_SUBBAND_2_4_GHZ
570 //freq, chan#, band
571 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
572 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
573 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
574 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
575 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
576 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
577 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
578 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
579 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
580 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
581 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
582 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
583 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
584 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700585 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
586 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
587 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
588 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
589 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
590 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
591 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
593 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
594 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
595 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
596 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
597 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
598 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
599 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
600 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
601 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
602 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
603 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
604 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
605 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
606 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
607 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
608 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
609 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
610 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
611 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
612 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
613 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
614 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
615 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700616 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
617 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
618 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
619 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
620 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
621 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
622 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
623 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
624 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
625 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
626 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
627 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
628 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
629 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
630 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
631 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
632 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
633 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
634 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
635 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
636 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
637 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
638 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
639 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
640 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
641 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
642 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
643 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
644 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
645 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
646 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
647 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
648 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
649 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
650 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700651};
652
653extern const sHalNv nvDefaults;
654
655const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
656
657/*----------------------------------------------------------------------------
658 Function Definitions and Documentation
659 * -------------------------------------------------------------------------*/
660VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
661/**------------------------------------------------------------------------
662 \brief vos_nv_init() - initialize the NV module
663 The \a vos_nv_init() initializes the NV module. This read the binary
664 file for country code and regulatory domain information.
665 \return VOS_STATUS_SUCCESS - module is initialized successfully
666 otherwise - module is not initialized
667 \sa
668 -------------------------------------------------------------------------*/
669VOS_STATUS vos_nv_init(void)
670{
671 return VOS_STATUS_SUCCESS;
672}
673
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700674/**------------------------------------------------------------------------
675 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
676 \ tools
677 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
678 otherwise - not successful
679 \sa
680-------------------------------------------------------------------------*/
681VOS_STATUS vos_nv_get_dictionary_data(void)
682{
683 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
684
685 if (MAGIC_NUMBER != magicNumber)
686 {
687 return VOS_STATUS_SUCCESS;
688 }
689
690 nDictionarySize = 0;
691
692 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
693 &nDictionarySize );
694 if (VOS_STATUS_E_NOMEM != vosStatus)
695 {
696 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
697 "Error obtaining binary size" );
698/// NOTE:
699/// We can still work without a dictionary file..
700 return VOS_STATUS_SUCCESS;
701 }
702
703 // malloc a buffer to read in the Configuration binary file.
704 pDictFile = vos_mem_malloc( nDictionarySize );
705 if (NULL == pDictFile)
706 {
707 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
708 "Unable to allocate memory for the CFG binary [size= %d bytes]",
709 nDictionarySize );
710 vosStatus = VOS_STATUS_E_NOMEM;
711 goto fail;
712 }
713
714 /* Get the entire CFG file image... */
715 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
716 &nDictionarySize );
717 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
718 {
719 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
720 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
721 nDictionarySize );
722 return VOS_STATUS_SUCCESS;
723 }
724
725 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
726 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
727
728fail:
729 return vosStatus;
730}
731
Jeff Johnson295189b2012-06-20 16:38:30 -0700732VOS_STATUS vos_nv_open(void)
733{
734 VOS_STATUS status = VOS_STATUS_SUCCESS;
735 v_CONTEXT_t pVosContext= NULL;
736 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700737 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700739 v_U32_t dataOffset;
740 sHalNv *pnvData = NULL;
741
Jeff Johnson295189b2012-06-20 16:38:30 -0700742 /*Get the global context */
743 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700744
745 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800746 {
747 return (eHAL_STATUS_FAILURE);
748 }
749
Jeff Johnson295189b2012-06-20 16:38:30 -0700750 bufSize = sizeof(nvEFSTable_t);
751 status = hdd_request_firmware(WLAN_NV_FILE,
752 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700753 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700754
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700755 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700757 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700759 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700760 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -0700761 }
762
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700763 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
764
765 /// Allocate buffer with maximum length..
766 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
767
768 if (NULL == pEncodedBuf)
769 {
770 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
771 "%s : failed to allocate memory for NV", __func__);
772 return VOS_STATUS_E_NOMEM;
773 }
774
775 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
776
777 if (MAGIC_NUMBER == magicNumber)
778 {
779 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
780
781 if (NULL == pnvData)
782 {
783 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
784 "%s : failed to allocate memory for NV", __func__);
785 return VOS_STATUS_E_NOMEM;
786 }
787
788 memset(pnvData, 0, sizeof(sHalNv));
789
790 /// Data starts from offset of validity bit map + magic number..
791 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
792
793 status = nvParser(&pnvEncodedBuf[dataOffset],
794 (nvReadBufSize-dataOffset), pnvData);
795
796 ///ignore validity bit map
797 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
798
799 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
800 nvReadEncodeBufSize);
801
802 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
803 "readEncodeBufSize %d",nvReadEncodeBufSize);
804
805 if (VOS_STATUS_SUCCESS == status) {
806 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
807 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
808 pnvData->fields.productId,
809 pnvData->fields.couplerType,
810 pnvData->fields.wlanNvRevId);
811
812 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
813
814 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
815 }
816 else
817 {
818 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
819 "nvParser failed %d",status);
820
821 nvReadBufSize = 0;
822
823 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
824
825 nvReadEncodeBufSize = sizeof(sHalNv);
826 }
827 }
828 else
829 {
830 dataOffset = sizeof(v_U32_t);
831 nvReadEncodeBufSize = sizeof(sHalNv);
832 memcpy(pEncodedBuf, &pnvEncodedBuf[dataOffset], nvReadEncodeBufSize);
833 }
834
835 if (NULL != pnvData)
836 {
837 vos_mem_free(pnvData);
838 }
839
840 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -0800841 "INFO: NV binary file version=%d Driver default NV version=%d, continue...",
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800842 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
843
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 /* Copying the read nv data to the globa NV EFS table */
845 {
846 /* Allocate memory to global NV table */
847 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700848 if ( NULL == pnvEFSTable )
Jeff Johnson295189b2012-06-20 16:38:30 -0700849 {
850 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700851 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 return VOS_STATUS_E_NOMEM;
853 }
854
855 /*Copying the NV defaults */
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700856 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800857
858 /* Size mismatch */
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700859 if ( nvReadBufSize != bufSize)
860 {
861 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
862 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
863 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
864 nvReadBufSize, bufSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800865 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700866 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700867
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800868 /* Version mismatch */
869 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
870 {
871 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
872 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
873 {
874 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
875 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
Arif Hussain02882402013-11-17 21:55:29 -0800876 "Make sure that this is intended or may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800877 }
878 else
879 {
880 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
881 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
Arif Hussain02882402013-11-17 21:55:29 -0800882 "Driver NV defaults will be used, may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800883
884 return VOS_STATUS_SUCCESS;
885 }
886 }
887
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700888 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700889 /* Copy the valid fields to the NV Global structure */
890 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 VOS_STATUS_SUCCESS)
892 {
893 if (itemIsValid == VOS_TRUE) {
894
895 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
896 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800897 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 }
899 }
900
Amar Singhalfddc28c2013-09-05 13:03:40 -0700901 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700902 VOS_STATUS_SUCCESS)
903 {
904 if (itemIsValid == VOS_TRUE)
905 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700906 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
908 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800909 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700910 }
911 }
912
Amar Singhalfddc28c2013-09-05 13:03:40 -0700913 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 VOS_STATUS_SUCCESS)
915 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700916
Jeff Johnson295189b2012-06-20 16:38:30 -0700917 if (itemIsValid == VOS_TRUE)
918 {
919 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
920 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
921 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800922 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924 }
925
Amar Singhalfddc28c2013-09-05 13:03:40 -0700926 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700927 VOS_STATUS_SUCCESS)
928 {
929 if (itemIsValid == VOS_TRUE)
930 {
931 if(vos_nv_read( VNV_DEFAULT_LOCATION,
932 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
933 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800934 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 }
936 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700937
938 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 VOS_STATUS_SUCCESS)
940 {
941 if (itemIsValid == VOS_TRUE)
942 {
Amar Singhalfddc28c2013-09-05 13:03:40 -0700943 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
945 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800946 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700947 }
948 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700949
950 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 VOS_STATUS_SUCCESS)
952 {
953 if (itemIsValid == VOS_TRUE)
954 {
955 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
956 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
957 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800958 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 }
960 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700961 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 VOS_STATUS_SUCCESS)
963 {
964 if (itemIsValid == VOS_TRUE)
965 {
966 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
967 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
968 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800969 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 }
971 }
Amar Singhalfddc28c2013-09-05 13:03:40 -0700972
973 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700974 VOS_STATUS_SUCCESS)
975 {
976 if (itemIsValid == VOS_TRUE)
977 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800978 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
979 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
980 goto error;
981 }
982 }
983
Amar Singhalfddc28c2013-09-05 13:03:40 -0700984 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800985 VOS_STATUS_SUCCESS)
986 {
987 if (itemIsValid == VOS_TRUE)
988 {
989 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
990 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800991 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 }
993 }
994
Amar Singhalfddc28c2013-09-05 13:03:40 -0700995 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 VOS_STATUS_SUCCESS)
997 {
998 if (itemIsValid == VOS_TRUE)
999 {
1000 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001001 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001003 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001004 }
1005 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001006 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 VOS_STATUS_SUCCESS)
1008 {
1009 if (itemIsValid == VOS_TRUE)
1010 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001011 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1012 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001013 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001014 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 }
1016 }
1017
Amar Singhalfddc28c2013-09-05 13:03:40 -07001018 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001019 VOS_STATUS_SUCCESS)
1020 {
1021 if (itemIsValid == VOS_TRUE)
1022 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001023 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1024 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001025 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001026 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001027 }
1028 }
1029
Amar Singhalfddc28c2013-09-05 13:03:40 -07001030 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 VOS_STATUS_SUCCESS)
1032 {
1033 if (itemIsValid == VOS_TRUE)
1034 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001035 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1036 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001037 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001038 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001039 }
1040 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001041 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 VOS_STATUS_SUCCESS)
1043 {
1044 if (itemIsValid == VOS_TRUE)
1045 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001046 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1047 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001049 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 }
1051 }
1052 }
1053
1054 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001055error:
1056 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001057 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001058 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001059}
1060
1061VOS_STATUS vos_nv_close(void)
1062{
1063 VOS_STATUS status = VOS_STATUS_SUCCESS;
1064 v_CONTEXT_t pVosContext= NULL;
1065 /*Get the global context */
1066 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1067 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1068 if ( !VOS_IS_STATUS_SUCCESS( status ))
1069 {
1070 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001071 "%s : vos_open failed",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 return VOS_STATUS_E_FAILURE;
1073 }
1074 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001075 vos_mem_free(pEncodedBuf);
1076 vos_mem_free(pDictFile);
1077
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 gnvEFSTable=NULL;
1079 return VOS_STATUS_SUCCESS;
1080}
Jeff Johnson295189b2012-06-20 16:38:30 -07001081
Jeff Johnson295189b2012-06-20 16:38:30 -07001082/**------------------------------------------------------------------------
1083 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1084 country codes
1085 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1086 country codes with paddings in the provided buffer
1087 \param pBuffer - pointer to buffer where supported country codes
1088 and paddings are encoded; this may be set to NULL
1089 if user wishes to query the required buffer size to
1090 get the country code list
1091 \param pBufferSize - this is the provided buffer size on input;
1092 this is the required or consumed buffer size on output
1093 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1094 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1095 the buffer is NULL or buffer size is
1096 sufficient
1097 \sa
1098 -------------------------------------------------------------------------*/
1099VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1100 v_SIZE_t paddingSize )
1101{
1102 v_SIZE_t providedBufferSize = *pBufferSize;
1103 int i;
1104 // pBufferSize now points to the required buffer size
1105 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1106 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1107 {
1108 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08001109 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 return VOS_STATUS_E_NOMEM;
1111 }
1112 for (i = 0; i < countryInfoTable.countryCount; i++)
1113 {
1114 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1115 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1116 }
1117 return VOS_STATUS_SUCCESS;
1118}
1119/**------------------------------------------------------------------------
1120 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1121 \param pTxAntennaCount - antenna count
1122 \return status of the NV read operation
1123 \sa
1124 -------------------------------------------------------------------------*/
1125VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1126{
1127 sNvFields fieldImage;
1128 VOS_STATUS status;
1129 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1130 sizeof(fieldImage) );
1131 if (VOS_STATUS_SUCCESS == status)
1132 {
1133 *pTxAntennaCount = fieldImage.numOfTxChains;
1134 }
1135 return status;
1136}
1137/**------------------------------------------------------------------------
1138 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1139 \param pRxAntennaCount - antenna count
1140 \return status of the NV read operation
1141 \sa
1142 -------------------------------------------------------------------------*/
1143VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1144{
1145 sNvFields fieldImage;
1146 VOS_STATUS status;
1147 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1148 sizeof(fieldImage) );
1149 if (VOS_STATUS_SUCCESS == status)
1150 {
1151 *pRxAntennaCount = fieldImage.numOfRxChains;
1152 }
1153 return status;
1154}
1155
1156/**------------------------------------------------------------------------
1157 \brief vos_nv_readMacAddress() - return the MAC address
1158 \param pMacAddress - MAC address
1159 \return status of the NV read operation
1160 \sa
1161 -------------------------------------------------------------------------*/
1162VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1163{
1164 sNvFields fieldImage;
1165 VOS_STATUS status;
1166 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1167 sizeof(fieldImage) );
1168 if (VOS_STATUS_SUCCESS == status)
1169 {
1170 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1171 }
1172 else
1173 {
1174 //This part of the code can be removed when NV is programmed
1175 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1176 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
Arif Hussaina7c8e412013-11-20 11:06:42 -08001177 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1178 "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR,
1179 MAC_ADDR_ARRAY(macAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 status = VOS_STATUS_SUCCESS;
1181 }
1182 return status;
1183}
1184
1185/**------------------------------------------------------------------------
1186
1187 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1188
1189 \param pMacAddress - MAC address
1190 \param macCount - Count of valid MAC addresses to get from NV field
1191
1192 \return status of the NV read operation
1193
1194 \sa
1195
1196 -------------------------------------------------------------------------*/
1197VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1198 v_U8_t macCount )
1199{
1200 sNvFields fieldImage;
1201 VOS_STATUS status;
1202 v_U8_t countLoop;
1203 v_U8_t *pNVMacAddress;
1204
1205 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1206 (NULL == pMacAddress))
1207 {
1208 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301209 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001210 macCount, pMacAddress);
1211 }
1212
1213 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1214 sizeof(fieldImage) );
1215 if (VOS_STATUS_SUCCESS == status)
1216 {
1217 pNVMacAddress = fieldImage.macAddr;
1218 for(countLoop = 0; countLoop < macCount; countLoop++)
1219 {
1220 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1221 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1222 VOS_MAC_ADDRESS_LEN);
1223 }
1224 }
1225 else
1226 {
1227 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1228 "vos_nv_readMultiMacAddress Get NV Field Fail");
1229 }
1230
1231 return status;
1232}
1233
1234/**------------------------------------------------------------------------
1235 \brief vos_nv_setValidity() - set the validity of an NV item.
1236 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1237 validity information is stored in NV memory.
1238 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1239 An item becomes valid when one has written to it successfully.
1240 \param type - NV item type
1241 \param itemIsValid - boolean value indicating the item's validity
1242 \return VOS_STATUS_SUCCESS - validity is set successfully
1243 VOS_STATUS_E_INVAL - one of the parameters is invalid
1244 VOS_STATUS_E_FAILURE - unknown error
1245 \sa
1246 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001247
1248VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1249{
1250 v_U32_t lastNvValidityBitmap;
1251 v_U32_t newNvValidityBitmap;
1252 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001253
Jeff Johnson295189b2012-06-20 16:38:30 -07001254 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001255 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001256 {
1257 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001258 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 return VOS_STATUS_E_INVAL;
1260 }
1261 // read the validity bitmap
1262 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1263 // modify the validity bitmap
1264 if (itemIsValid)
1265 {
1266 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1267 // commit to NV store if bitmap has been modified
1268 if (newNvValidityBitmap != lastNvValidityBitmap)
1269 {
1270 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1271 }
1272 }
1273 else
1274 {
1275 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1276 if (newNvValidityBitmap != lastNvValidityBitmap)
1277 {
1278 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1279 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1280 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001281 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 status = VOS_STATUS_E_FAULT;
1283 }
1284 }
1285 }
1286
1287 return status;
1288}
Jeff Johnson295189b2012-06-20 16:38:30 -07001289/**------------------------------------------------------------------------
1290 \brief vos_nv_getValidity() - get the validity of an NV item.
1291 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1292 validity information is stored in NV memory.
1293 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1294 An item becomes valid when one has written to it successfully.
1295 \param type - NV item type
1296 \param pItemIsValid- pointer to the boolean value indicating the item's
1297 validity
1298 \return VOS_STATUS_SUCCESS - validity is determined successfully
1299 VOS_STATUS_E_INVAL - one of the parameters is invalid
1300 VOS_STATUS_E_FAILURE - unknown error
1301 \sa
1302 -------------------------------------------------------------------------*/
1303VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1304{
1305 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1306 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001307 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 {
1309 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001310 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001311 return VOS_STATUS_E_INVAL;
1312 }
1313 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1314 return VOS_STATUS_SUCCESS;
1315}
1316/**------------------------------------------------------------------------
1317 \brief vos_nv_read() - read a NV item to an output buffer
1318 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1319 an array, this function would read the entire array. One would get a
1320 VOS_STATUS_E_EXISTS error when reading an invalid item.
1321 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1322 if a default buffer is provided (with a non-NULL value),
1323 the default buffer content is copied to the output buffer.
1324 \param type - NV item type
1325 \param outputBuffer - output buffer
1326 \param defaultBuffer - default buffer
1327 \param bufferSize - output buffer size
1328 \return VOS_STATUS_SUCCESS - NV item is read successfully
1329 VOS_STATUS_E_INVAL - one of the parameters is invalid
1330 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1331 VOS_STATUS_E_EXISTS - NV type is unsupported
1332 VOS_STATUS_E_FAILURE - unknown error
1333 \sa
1334 -------------------------------------------------------------------------*/
1335VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1336 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1337{
1338 VOS_STATUS status = VOS_STATUS_SUCCESS;
1339 v_SIZE_t itemSize;
1340 v_BOOL_t itemIsValid = VOS_TRUE;
1341
Amar Singhala49cbc52013-10-08 18:37:44 -07001342 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001343 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 {
1345 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001346 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 return VOS_STATUS_E_INVAL;
1348 }
1349 if (NULL == outputVoidBuffer)
1350 {
1351 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001352 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 return VOS_STATUS_E_FAULT;
1354 }
1355 if (0 == bufferSize)
1356 {
1357 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001358 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 return VOS_STATUS_E_INVAL;
1360 }
1361 // check if the NV item has valid data
1362 status = vos_nv_getValidity( type, &itemIsValid );
1363 if (!itemIsValid)
1364 {
1365 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08001366 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 return VOS_STATUS_E_EMPTY;
1368 }
1369 switch(type)
1370 {
1371 case VNV_FIELD_IMAGE:
1372 itemSize = sizeof(gnvEFSTable->halnv.fields);
1373 if(bufferSize != itemSize) {
1374 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001375 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001376 itemSize);
1377 status = VOS_STATUS_E_INVAL;
1378 }
1379 else {
1380 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1381 }
1382 break;
1383 case VNV_RATE_TO_POWER_TABLE:
1384 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1385 if(bufferSize != itemSize) {
1386 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001387 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 itemSize);
1389 status = VOS_STATUS_E_INVAL;
1390 }
1391 else {
1392 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1393 }
1394 break;
1395 case VNV_REGULARTORY_DOMAIN_TABLE:
1396 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1397 if(bufferSize != itemSize) {
1398 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001399 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001400 itemSize);
1401 status = VOS_STATUS_E_INVAL;
1402 }
1403 else {
1404 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1405 }
1406 break;
1407 case VNV_DEFAULT_LOCATION:
1408 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1409 if(bufferSize != itemSize) {
1410 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001411 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 itemSize);
1413 status = VOS_STATUS_E_INVAL;
1414 }
1415 else {
1416 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1417 }
1418 break;
1419 case VNV_TPC_POWER_TABLE:
1420 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1421 if(bufferSize != itemSize) {
1422 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001423 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001424 itemSize);
1425 status = VOS_STATUS_E_INVAL;
1426 }
1427 else {
1428 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1429 }
1430 break;
1431 case VNV_TPC_PDADC_OFFSETS:
1432 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1433 if(bufferSize != itemSize) {
1434 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001435 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001436 itemSize);
1437 status = VOS_STATUS_E_INVAL;
1438 }
1439 else {
1440 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1441 }
1442 break;
1443 case VNV_RSSI_CHANNEL_OFFSETS:
1444
1445 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1446
1447 if(bufferSize != itemSize) {
1448
1449 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001450 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 itemSize);
1452 status = VOS_STATUS_E_INVAL;
1453 }
1454 else {
1455 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1456 }
1457 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001458 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001459
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001460 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001461
1462 if(bufferSize != itemSize) {
1463
1464 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001465 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 itemSize);
1467 status = VOS_STATUS_E_INVAL;
1468 }
1469 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001470 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1471 }
1472 break;
1473 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001474
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001475 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001476
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001477 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001478
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001479 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001480 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001481 itemSize);
1482 status = VOS_STATUS_E_INVAL;
1483 }
1484 else {
1485 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 }
1487 break;
1488 case VNV_ANTENNA_PATH_LOSS:
1489 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1490 if(bufferSize != itemSize) {
1491 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001492 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001493 itemSize);
1494 status = VOS_STATUS_E_INVAL;
1495 }
1496 else {
1497 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1498 }
1499 break;
1500 case VNV_PACKET_TYPE_POWER_LIMITS:
1501 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1502 if(bufferSize != itemSize) {
1503 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001504 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001505 itemSize);
1506 status = VOS_STATUS_E_INVAL;
1507 }
1508 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001509 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001510 }
1511 break;
1512 case VNV_OFDM_CMD_PWR_OFFSET:
1513 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1514 if(bufferSize != itemSize) {
1515 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001516 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001517 itemSize);
1518 status = VOS_STATUS_E_INVAL;
1519 }
1520 else {
1521 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1522 }
1523 break;
1524 case VNV_TX_BB_FILTER_MODE:
1525 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1526 if(bufferSize != itemSize) {
1527 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001528 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 itemSize);
1530 status = VOS_STATUS_E_INVAL;
1531 }
1532 else {
1533 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1534 }
1535 break;
1536
Jeff Johnson295189b2012-06-20 16:38:30 -07001537
1538 case VNV_TABLE_VIRTUAL_RATE:
1539 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1540 if(bufferSize != itemSize) {
1541 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001542 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 itemSize);
1544 status = VOS_STATUS_E_INVAL;
1545 }
1546 else {
1547 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1548 }
1549 break;
1550
1551 default:
1552 break;
1553 }
1554 return status;
1555}
Jeff Johnson295189b2012-06-20 16:38:30 -07001556
1557/**------------------------------------------------------------------------
1558 \brief vos_nv_write() - write to a NV item from an input buffer
1559 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1560 validate the NV item if the write operation is successful.
1561 \param type - NV item type
1562 \param inputBuffer - input buffer
1563 \param inputBufferSize - input buffer size
1564 \return VOS_STATUS_SUCCESS - NV item is read successfully
1565 VOS_STATUS_E_INVAL - one of the parameters is invalid
1566 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1567 VOS_STATUS_E_EXISTS - NV type is unsupported
1568 VOS_STATUS_E_FAILURE - unknown error
1569 \sa
1570 -------------------------------------------------------------------------*/
1571VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1572 v_SIZE_t bufferSize )
1573{
1574 VOS_STATUS status = VOS_STATUS_SUCCESS;
1575 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001576
Amar Singhala49cbc52013-10-08 18:37:44 -07001577 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001578 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 {
1580 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001581 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 return VOS_STATUS_E_INVAL;
1583 }
1584 if (NULL == inputVoidBuffer)
1585 {
1586 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001587 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 return VOS_STATUS_E_FAULT;
1589 }
1590 if (0 == bufferSize)
1591 {
1592 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001593 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 return VOS_STATUS_E_INVAL;
1595 }
1596 switch(type)
1597 {
1598 case VNV_FIELD_IMAGE:
1599 itemSize = sizeof(gnvEFSTable->halnv.fields);
1600 if(bufferSize != itemSize) {
1601 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001602 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 itemSize);
1604 status = VOS_STATUS_E_INVAL;
1605 }
1606 else {
1607 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1608 }
1609 break;
1610 case VNV_RATE_TO_POWER_TABLE:
1611 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1612 if(bufferSize != itemSize) {
1613 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001614 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001615 itemSize);
1616 status = VOS_STATUS_E_INVAL;
1617 }
1618 else {
1619 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1620 }
1621 break;
1622 case VNV_REGULARTORY_DOMAIN_TABLE:
1623 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1624 if(bufferSize != itemSize) {
1625 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001626 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 itemSize);
1628 status = VOS_STATUS_E_INVAL;
1629 }
1630 else {
1631 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1632 }
1633 break;
1634 case VNV_DEFAULT_LOCATION:
1635 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1636 if(bufferSize != itemSize) {
1637 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001638 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001639 itemSize);
1640 status = VOS_STATUS_E_INVAL;
1641 }
1642 else {
1643 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1644 }
1645 break;
1646 case VNV_TPC_POWER_TABLE:
1647 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1648 if(bufferSize != itemSize) {
1649 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001650 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 itemSize);
1652 status = VOS_STATUS_E_INVAL;
1653 }
1654 else {
1655 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1656 }
1657 break;
1658 case VNV_TPC_PDADC_OFFSETS:
1659 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1660 if(bufferSize != itemSize) {
1661 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001662 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 itemSize);
1664 status = VOS_STATUS_E_INVAL;
1665 }
1666 else {
1667 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1668 }
1669 break;
1670 case VNV_RSSI_CHANNEL_OFFSETS:
1671
1672 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1673
1674 if(bufferSize != itemSize) {
1675
1676 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001677 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 itemSize);
1679 status = VOS_STATUS_E_INVAL;
1680 }
1681 else {
1682 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1683 }
1684 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001685 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001686
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001687 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001688
1689 if(bufferSize != itemSize) {
1690
1691 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001692 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001693 itemSize);
1694 status = VOS_STATUS_E_INVAL;
1695 }
1696 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001697 memcpy(&gnvEFSTable->halnv.tables.hwCalValues,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 }
1699 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001700 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001701
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001702 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001703
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001704 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001705
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001706 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001707 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001708 itemSize);
1709 status = VOS_STATUS_E_INVAL;
1710 }
1711 else {
1712 memcpy(&gnvEFSTable->halnv.tables.fwConfig,inputVoidBuffer,bufferSize);
1713 }
1714 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 case VNV_ANTENNA_PATH_LOSS:
1716 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1717 if(bufferSize != itemSize) {
1718 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001719 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001720 itemSize);
1721 status = VOS_STATUS_E_INVAL;
1722 }
1723 else {
1724 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1725 }
1726 break;
1727
1728 case VNV_PACKET_TYPE_POWER_LIMITS:
1729 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1730 if(bufferSize != itemSize) {
1731 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001732 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001733 itemSize);
1734 status = VOS_STATUS_E_INVAL;
1735 }
1736 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001737 memcpy(gnvEFSTable->halnv.tables.pktTypePwrLimits,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001738 }
1739 break;
1740
1741 case VNV_OFDM_CMD_PWR_OFFSET:
1742 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1743 if(bufferSize != itemSize) {
1744 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001745 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 itemSize);
1747 status = VOS_STATUS_E_INVAL;
1748 }
1749 else {
1750 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1751 }
1752 break;
1753
1754 case VNV_TX_BB_FILTER_MODE:
1755 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1756 if(bufferSize != itemSize) {
1757 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001758 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001759 itemSize);
1760 status = VOS_STATUS_E_INVAL;
1761 }
1762 else {
1763 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1764 }
1765 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001766
Jeff Johnson295189b2012-06-20 16:38:30 -07001767
1768 case VNV_TABLE_VIRTUAL_RATE:
1769 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1770 if(bufferSize != itemSize) {
1771 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001772 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001773 itemSize);
1774 status = VOS_STATUS_E_INVAL;
1775 }
1776 else {
1777 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1778 }
1779 break;
1780
1781 default:
1782 break;
1783 }
1784 if (VOS_STATUS_SUCCESS == status)
1785 {
1786 // set NV item to have valid data
1787 status = vos_nv_setValidity( type, VOS_TRUE );
1788 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001789 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 status = VOS_STATUS_E_FAULT;
1791 }
1792 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1793
1794 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001795 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 status = VOS_STATUS_E_FAULT;
1797 }
1798 }
1799 return status;
1800}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08001801
Jeff Johnson295189b2012-06-20 16:38:30 -07001802/**------------------------------------------------------------------------
1803 \brief vos_nv_getChannelListWithPower() - function to return the list of
1804 supported channels with the power limit info too.
1805 \param pChannels20MHz - list of 20 Mhz channels
1806 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1807 \param pChannels40MHz - list of 20 Mhz channels
1808 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1809 \return status of the NV read operation
1810 \Note: 40Mhz not currently supported
1811 \sa
1812 -------------------------------------------------------------------------*/
1813VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1814 tANI_U8 *num20MHzChannelsFound,
1815 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1816 tANI_U8 *num40MHzChannelsFound
1817 )
1818{
1819 VOS_STATUS status = VOS_STATUS_SUCCESS;
1820 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001821
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1823 // or pass it as a parameter to NV from SME?
1824
1825 if( channels20MHz && num20MHzChannelsFound )
1826 {
1827 count = 0;
1828 for( i = 0; i <= RF_CHAN_14; i++ )
1829 {
1830 if( regChannels[i].enabled )
1831 {
1832 channels20MHz[count].chanId = rfChannels[i].channelNum;
1833 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1834 }
1835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1837 {
1838 if( regChannels[i].enabled )
1839 {
1840 channels20MHz[count].chanId = rfChannels[i].channelNum;
1841 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1842 }
1843 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 *num20MHzChannelsFound = (tANI_U8)count;
1845 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001846
1847 if( channels40MHz && num40MHzChannelsFound )
1848 {
1849 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07001850 //center channels for 2.4 Ghz 40 MHz channels
1851 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1852 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001853
Jeff Johnsone7245742012-09-05 17:12:55 -07001854 if( regChannels[i].enabled )
1855 {
1856 channels40MHz[count].chanId = rfChannels[i].channelNum;
1857 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1858 }
1859 }
1860 //center channels for 5 Ghz 40 MHz channels
1861 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1862 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001863
Jeff Johnsone7245742012-09-05 17:12:55 -07001864 if( regChannels[i].enabled )
1865 {
1866 channels40MHz[count].chanId = rfChannels[i].channelNum;
1867 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1868 }
1869 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001870 *num40MHzChannelsFound = (tANI_U8)count;
1871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001872 return (status);
1873}
1874
1875/**------------------------------------------------------------------------
1876 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1877 \return default regulatory domain
1878 \sa
1879 -------------------------------------------------------------------------*/
1880
1881v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1882{
1883 return countryInfoTable.countryInfo[0].regDomain;
1884}
1885
1886/**------------------------------------------------------------------------
1887 \brief vos_nv_getSupportedChannels() - function to return the list of
1888 supported channels
1889 \param p20MhzChannels - list of 20 Mhz channels
1890 \param pNum20MhzChannels - number of 20 Mhz channels
1891 \param p40MhzChannels - list of 40 Mhz channels
1892 \param pNum40MhzChannels - number of 40 Mhz channels
1893 \return status of the NV read operation
1894 \Note: 40Mhz not currently supported
1895 \sa
1896 -------------------------------------------------------------------------*/
1897VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1898 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1899{
1900 VOS_STATUS status = VOS_STATUS_E_INVAL;
1901 int i, count = 0;
1902
1903 if( p20MhzChannels && pNum20MhzChannels )
1904 {
1905 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1906 {
1907 for( i = 0; i <= RF_CHAN_14; i++ )
1908 {
1909 p20MhzChannels[count++] = rfChannels[i].channelNum;
1910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001911 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1912 {
1913 p20MhzChannels[count++] = rfChannels[i].channelNum;
1914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 status = VOS_STATUS_SUCCESS;
1916 }
1917 *pNum20MhzChannels = count;
1918 }
1919
1920 return (status);
1921}
1922
1923/**------------------------------------------------------------------------
1924 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1925 \param table data - a union to return the default country table data in.
1926 \return status of the NV read operation
1927 \sa
1928 -------------------------------------------------------------------------*/
1929VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1930{
Amar Singhalfddc28c2013-09-05 13:03:40 -07001931
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001932 VOS_STATUS status = VOS_STATUS_SUCCESS;
1933 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1934 pr_info("DefaultCountry is %c%c\n",
1935 tableData->defaultCountryTable.countryCode[0],
1936 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001937 return status;
1938}
1939
1940/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07001941 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07001942 \param pBuffer - to return the buffer address
1943 pSize - buffer size.
1944 \return status of the NV read operation
1945 \sa
1946 -------------------------------------------------------------------------*/
1947VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1948{
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 /* Send the NV structure and size */
1950 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1951 *pSize = sizeof(sHalNv);
1952
1953 return VOS_STATUS_SUCCESS;
1954}
1955
Jeff Johnson295189b2012-06-20 16:38:30 -07001956/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001957 \brief vos_nv_getBuffer -
1958 \param pBuffer - to return the buffer address
1959 pSize - buffer size.
1960 \return status of the NV read operation
1961 \sa
1962 -------------------------------------------------------------------------*/
1963VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1964{
1965 /* Send the NV structure and size */
1966 VOS_STATUS status;
1967
1968 status = vos_nv_isEmbeddedNV();
1969
1970 if (VOS_STATUS_SUCCESS == status)
1971 {
1972 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
1973 *pSize = nvReadEncodeBufSize;
1974 }
1975 else
1976 {
1977 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1978 *pSize = sizeof(sHalNv);
1979 }
1980
1981 return VOS_STATUS_SUCCESS;
1982}
1983
1984
1985VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1986{
1987 /* Send the NV structure and size */
1988 *pNvBuffer = (v_VOID_t *)(pDictFile);
1989 *pSize = nDictionarySize;
1990
1991 return VOS_STATUS_SUCCESS;
1992}
1993
1994VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
1995{
1996 if (MAGIC_NUMBER == magicNumber)
1997 {
1998 return VOS_STATUS_SUCCESS;
1999 }
2000
2001 return VOS_STATUS_E_FAILURE;
2002}
2003
2004VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
2005{
2006 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2007 (size-sizeof(v_U32_t)));
2008
2009 return VOS_STATUS_SUCCESS;
2010}
2011
2012/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002013 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 \param rfChannel - input channel enum to know evabled state
2015 \return eNVChannelEnabledType enabled state for channel
2016 * enabled
2017 * disabled
2018 * DFS
2019 \sa
2020 -------------------------------------------------------------------------*/
2021eNVChannelEnabledType vos_nv_getChannelEnabledState
2022(
2023 v_U32_t rfChannel
2024)
2025{
2026 v_U32_t channelLoop;
2027 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2028
2029 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2030 {
2031 if(rfChannels[channelLoop].channelNum == rfChannel)
2032 {
2033 channelEnum = (eRfChannels)channelLoop;
2034 break;
2035 }
2036 }
2037
2038 if(INVALID_RF_CHANNEL == channelEnum)
2039 {
2040 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002041 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 return NV_CHANNEL_INVALID;
2043 }
2044
2045 return regChannels[channelEnum].enabled;
2046}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002047
2048/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002049 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002050*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002051
2052static int bw20_ch_index_to_bw40_ch_index(int k)
2053{
2054 int m = -1;
2055 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2056 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002057 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2058 if (m > RF_CHAN_BOND_11)
2059 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002060 }
2061 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2062 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002063 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2064 if (m > RF_CHAN_BOND_214)
2065 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002066 }
2067 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2068 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002069 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2070 if (m > RF_CHAN_BOND_62)
2071 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002072 }
2073 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
2074 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002075 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
2076 if (m > RF_CHAN_BOND_138)
2077 m = RF_CHAN_BOND_138;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002078 }
2079 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2080 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002081 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2082 if (m > RF_CHAN_BOND_163)
2083 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002084 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002085return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002086}
2087
Amar Singhala49cbc52013-10-08 18:37:44 -07002088void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002089{
Amar Singhala49cbc52013-10-08 18:37:44 -07002090 int k;
2091 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2092 countryCode[0], countryCode[1], domain_id);
2093 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2094 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2095 NV_CHANNEL_ENABLE;
2096 /* Max Tx Power 20dBm */
2097 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2098 }
2099 /* enable ch 12 to ch 14 passive scan */
2100 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2101 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2102 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2103 NV_CHANNEL_DFS;
2104 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2105 }
2106 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2107 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2108 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2109 NV_CHANNEL_DFS;
2110 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2111 }
2112#ifdef PASSIVE_SCAN_4_9GHZ
2113 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2114 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2115 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2116 NV_CHANNEL_DFS;
2117 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2118 }
2119#endif
2120 if (domain_id == NUM_REG_DOMAINS-1)
2121 { /* init time */
2122 crda_alpha2[0] = countryCode[0];
2123 crda_alpha2[1] = countryCode[1];
2124 crda_regulatory_entry_valid = VOS_TRUE;
2125 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2126 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2127 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2128 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2129 }
2130 if (domain_id == NUM_REG_DOMAINS-2)
2131 { /* none-default country */
2132 run_time_alpha2[0] = countryCode[0];
2133 run_time_alpha2[1] = countryCode[1];
2134 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2135 }
2136}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002137
Amar Singhala49cbc52013-10-08 18:37:44 -07002138static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2139 struct regulatory_request *request,
2140 v_U8_t nBandCapability,
2141 int domain_id)
2142{
2143 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2144 pr_info("Country 00 special handling to enable passive scan.\n");
2145 crda_regulatory_entry_default(request->alpha2, domain_id);
2146 }
2147 return 0;
2148}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002149
Amar Singhala49cbc52013-10-08 18:37:44 -07002150/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2151static int create_crda_regulatory_entry(struct wiphy *wiphy,
2152 struct regulatory_request *request,
2153 v_U8_t nBandCapability)
2154{
2155 int i, j, m;
2156 int k = 0, n = 0;
2157
2158 if (run_time_alpha2[0]==request->alpha2[0] &&
2159 run_time_alpha2[1]==request->alpha2[1] &&
2160 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2161 return 0; /* already created */
2162
2163 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002164 if (nBandCapability == eCSR_BAND_24)
2165 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002166 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002167 {
2168 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2169 continue;
2170 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2171 continue;
2172 if (wiphy->bands[i] == NULL)
2173 {
2174 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2175 return -1;
2176 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002177 // internal channels[] is one continous array for both 2G and 5G bands
2178 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002179 if (i == 0)
2180 m = 0;
2181 else
2182 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002183 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002184 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002185 // k = (m + j) is internal current channel index for 20MHz channel
2186 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002187 k = m + j;
2188 n = bw20_ch_index_to_bw40_ch_index(k);
2189 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002190 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002191 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2192 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002193 if (pnvEFSTable == NULL)
2194 {
2195 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2196 return -1;
2197 }
2198 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2199 NV_CHANNEL_DISABLE;
2200 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2201 NV_CHANNEL_DISABLE;
2202 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2203 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002204 }
2205 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2206 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002207 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2208 NV_CHANNEL_DFS;
2209 // max_power is in mBm = 100 * dBm
2210 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2211 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2212 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2213 {
2214 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2215 NV_CHANNEL_DFS;
2216 // 40MHz channel power is half of 20MHz (-3dB) ??
2217 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2218 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2219 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002220 }
2221 else // Enable is only last flag we support
2222 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002223 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2224 NV_CHANNEL_ENABLE;
2225 // max_power is in dBm
2226 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2227 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2228 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2229 {
2230 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2231 NV_CHANNEL_ENABLE;
2232 // 40MHz channel power is half of 20MHz (-3dB) ??
2233 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2234 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2235 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002236 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002237 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2238 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002239 }
2240 }
2241 if (k == 0)
2242 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002243 run_time_alpha2[0] = request->alpha2[0];
2244 run_time_alpha2[1] = request->alpha2[1];
2245 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2246 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2247return 0;
2248}
Amar Singhal0d15bd52013-10-12 23:13:13 -07002249
2250
Amar Singhala49cbc52013-10-08 18:37:44 -07002251v_BOOL_t is_crda_regulatory_entry_valid(void)
2252{
2253return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002254}
2255
Amar Singhala49cbc52013-10-08 18:37:44 -07002256/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2257start freq + 10000 = center freq of the 20MHz start channel
2258end freq - 10000 = center freq of the 20MHz end channel
2259start freq + 20000 = center freq of the 40MHz start channel
2260end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002261*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002262static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002263{
Amar Singhala49cbc52013-10-08 18:37:44 -07002264int i;
2265u32 center_freq = freq_khz + 10000;
2266 //Has to compare from low freq to high freq
2267 //RF_SUBBAND_2_4_GHZ
2268 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2269 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2270 return i;
2271 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2272 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2273 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2274 return i;
2275 //RF_SUBBAND_5_LOW_GHZ
2276 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2277 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2278 return i;
2279 //RF_SUBBAND_5_MID_GHZ
2280 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
2281 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2282 return i;
2283 //RF_SUBBAND_5_HIGH_GHZ
2284 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2285 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2286 return i;
2287return -1;
2288}
2289
2290static int bw20_end_freq_to_channel_index(u32 freq_khz)
2291{
2292int i;
2293u32 center_freq = freq_khz - 10000;
2294 //Has to compare from high freq to low freq
2295 //RF_SUBBAND_5_HIGH_GHZ
2296 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2297 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2298 return i;
2299 //RF_SUBBAND_5_MID_GHZ
2300 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
2301 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2302 return i;
2303 //RF_SUBBAND_5_LOW_GHZ
2304 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2305 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2306 return i;
2307 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2308 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2309 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2310 return i;
2311 //RF_SUBBAND_2_4_GHZ
2312 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2313 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2314 return i;
2315return -1;
2316}
2317
2318static int bw40_start_freq_to_channel_index(u32 freq_khz)
2319{
2320int i;
2321u32 center_freq = freq_khz + 20000;
2322 //Has to compare from low freq to high freq
2323 //RF_SUBBAND_2_4_GHZ
2324 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2325 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2326 return i;
2327 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2328 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2329 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2330 return i;
2331 //RF_SUBBAND_5_LOW_GHZ
2332 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2333 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2334 return i;
2335 //RF_SUBBAND_5_MID_GHZ
2336 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
2337 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2338 return i;
2339 //RF_SUBBAND_5_HIGH_GHZ
2340 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2341 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2342 return i;
2343return -1;
2344}
2345
2346static int bw40_end_freq_to_channel_index(u32 freq_khz)
2347{
2348int i;
2349u32 center_freq = freq_khz - 20000;
2350 //Has to compare from high freq to low freq
2351 //RF_SUBBAND_5_HIGH_GHZ
2352 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2353 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2354 return i;
2355 //RF_SUBBAND_5_MID_GHZ
2356 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
2357 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2358 return i;
2359 //RF_SUBBAND_5_LOW_GHZ
2360 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2361 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2362 return i;
2363 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2364 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2365 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2366 return i;
2367 //RF_SUBBAND_2_4_GHZ
2368 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2369 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2370 return i;
2371return -1;
2372}
2373
2374static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2375{
2376 switch (nBandCapability)
2377 {
2378 case eCSR_BAND_ALL:
2379 return VOS_TRUE;
2380 case eCSR_BAND_24:
2381 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2382 return VOS_TRUE;
2383 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2384 return VOS_TRUE; // 2.4G 40MHz channel
2385 break;
2386 case eCSR_BAND_5G:
2387 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2388 return VOS_TRUE;
2389 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2390 return VOS_TRUE; // 2.4G 40MHz channel
2391 break;
2392 default:
2393 break;
2394 }
2395 return VOS_FALSE;
2396}
2397
2398/* create_crda_regulatory_entry_from_regd should be called during init time */
2399static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2400 struct regulatory_request *request,
2401 v_U8_t nBandCapability)
2402{
2403 int i, j, n, domain_id;
2404 int bw20_start_channel_index, bw20_end_channel_index;
2405 int bw40_start_channel_index, bw40_end_channel_index;
2406
2407 if (wiphy == NULL || wiphy->regd == NULL)
2408 {
2409 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2410 return -1;
2411 }
2412 if (crda_regulatory_entry_valid == VOS_FALSE)
2413 domain_id = NUM_REG_DOMAINS-1; /* init time */
2414 else
2415 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2416 for (n = 0; n < NUM_RF_CHANNELS; n++)
2417 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2418
2419 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2420 {
2421 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2422 bw20_start_channel_index =
2423 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2424 bw20_end_channel_index =
2425 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2426 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2427 {
2428 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2429 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2430 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2431 continue; // skip this rull, but continue to next rule
2432 }
2433 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2434 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2435 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2436 bw20_start_channel_index, bw20_end_channel_index);
2437 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2438 {
2439 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2440 {
2441 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2442 rfChannels[j].channelNum);
2443 continue; // skip this channel, continue to next
2444 }
2445 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2446 {
2447 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2448 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2449 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2450 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05302451 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN)
2452 {
2453 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2454 wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2455 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2456 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002457 else
2458 {
2459 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2460 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2461 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2462 }
2463 /* max_eirp is in mBm (= 100 * dBm) unit */
2464 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2465 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2466 }
2467 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2468 real gain which should be provided by the real design */
2469 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2470 {
2471 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2472 bw40_start_channel_index =
2473 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2474 bw40_end_channel_index =
2475 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2476 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2477 {
2478 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2479 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2480 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2481 continue; // skip this rull, but continue to next rule
2482 }
2483 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2484 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2485 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2486 bw40_start_channel_index, bw40_end_channel_index);
2487 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2488 {
2489 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2490 continue; // skip this channel, continue to next
2491 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2492 {
2493 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2494 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2495 }
2496 else
2497 {
2498 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2499 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2500 }
2501 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2502 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2503 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2504 }
2505 }
2506 }
2507 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
2508 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
2509 these flags and has no implementation yet. */
2510 if (crda_regulatory_entry_valid == VOS_FALSE)
2511 { /* init time */
2512 crda_alpha2[0] = request->alpha2[0];
2513 crda_alpha2[1] = request->alpha2[1];
2514 crda_regulatory_entry_valid = VOS_TRUE;
2515 }
2516 else
2517 { /* none-default country */
2518 run_time_alpha2[0] = request->alpha2[0];
2519 run_time_alpha2[1] = request->alpha2[1];
2520 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2521 }
2522 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
2523 return 0;
2524}
2525
2526#ifdef CONFIG_ENABLE_LINUX_REG
2527
2528/**------------------------------------------------------------------------
2529 \brief vos_nv_setRegDomain -
2530 \param clientCtxt - Client Context, Not used for PRIMA
2531 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05302532 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07002533 \return status set REG domain operation
2534 \sa
2535 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05302536VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
2537 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07002538{
2539
2540 if (regId >= REGDOMAIN_COUNT)
2541 {
2542 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2543 "VOS set reg domain, invalid REG domain ID %d", regId);
2544 return VOS_STATUS_E_INVAL;
2545 }
2546
2547 /* Set correct channel information based on REG Domain */
2548 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
2549
2550 return VOS_STATUS_SUCCESS;
2551}
2552
2553/**------------------------------------------------------------------------
2554 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
2555 a country given its country code
2556 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
2557 a country given its country code. This is done from reading a cached
2558 copy of the binary file.
2559 \param pRegDomain - pointer to regulatory domain
2560 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05302561 \param source - source of the country code
Amar Singhala49cbc52013-10-08 18:37:44 -07002562 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
2563 VOS_STATUS_E_FAULT - invalid pointer error
2564 VOS_STATUS_E_EMPTY - country code table is empty
2565 VOS_STATUS_E_EXISTS - given country code does not exist in table
2566 \sa
2567 -------------------------------------------------------------------------*/
2568VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05302569 const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source)
Amar Singhala49cbc52013-10-08 18:37:44 -07002570{
2571
Amar Singhalfddc28c2013-09-05 13:03:40 -07002572 v_CONTEXT_t pVosContext = NULL;
2573 hdd_context_t *pHddCtx = NULL;
2574 struct wiphy *wiphy = NULL;
2575 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07002576 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002577
Amar Singhalfddc28c2013-09-05 13:03:40 -07002578 /* sanity checks */
2579 if (NULL == pRegDomain)
2580 {
2581 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2582 ("Invalid reg domain pointer") );
2583 return VOS_STATUS_E_FAULT;
2584 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002585
Amar Singhalfddc28c2013-09-05 13:03:40 -07002586 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002587
Amar Singhala49cbc52013-10-08 18:37:44 -07002588 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07002589 {
2590 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2591 ("Country code array is NULL"));
2592 return VOS_STATUS_E_FAULT;
2593 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002594
Amar Singhalfddc28c2013-09-05 13:03:40 -07002595 if (0 == countryInfoTable.countryCount)
2596 {
2597 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2598 ("Reg domain table is empty") );
2599 return VOS_STATUS_E_EMPTY;
2600 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002601
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002602
Amar Singhalfddc28c2013-09-05 13:03:40 -07002603 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002604
Amar Singhalfddc28c2013-09-05 13:03:40 -07002605 if (NULL != pVosContext)
2606 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2607 else
2608 return VOS_STATUS_E_EXISTS;
2609
2610 if (NULL == pHddCtx)
2611 {
2612 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2613 ("Invalid pHddCtx pointer") );
2614 return VOS_STATUS_E_FAULT;
2615 }
2616
Kiet Lam6c583332013-10-14 05:37:09 +05302617 temp_reg_domain = REGDOMAIN_COUNT;
2618 /* lookup the country in the local database */
2619 for (i = 0; i < countryInfoTable.countryCount &&
2620 REGDOMAIN_COUNT == temp_reg_domain; i++)
2621 {
2622 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
2623 VOS_COUNTRY_CODE_LEN) == 0)
2624 {
2625 /* country code is found */
2626 /* record the temporary regulatory_domain as well */
2627 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
2628 break;
2629 }
2630 }
2631
2632 if (REGDOMAIN_COUNT == temp_reg_domain) {
2633
2634 /* the country was not found in the driver database */
2635 /* so we will return the REGDOMAIN_WORLD to SME/CSR */
2636
2637 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2638 ("Country does not map to any Regulatory domain"));
2639
2640 temp_reg_domain = REGDOMAIN_WORLD;
2641 }
2642
2643 if (COUNTRY_QUERY == source)
2644 {
2645 *pRegDomain = temp_reg_domain;
2646 return VOS_STATUS_SUCCESS;
2647 }
2648
Amar Singhalfddc28c2013-09-05 13:03:40 -07002649 wiphy = pHddCtx->wiphy;
2650
Amar Singhala49cbc52013-10-08 18:37:44 -07002651 if (false == wiphy->registered)
2652 {
2653 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2654 ("wiphy is not yet registered with the kernel") );
2655 return VOS_STATUS_E_FAULT;
2656 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002657
2658 /* We need to query the kernel to get the regulatory information
2659 for this country */
2660
Amar Singhal0d15bd52013-10-12 23:13:13 -07002661
2662 /* First compare the country code with the existing current country code
2663 . If both are same there is no need to query any database */
2664
2665 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2666 ("regdomain request"));
2667
2668 if ((country_code[0] == linux_reg_cc[0]) &&
2669 (country_code[1] == linux_reg_cc[1])) {
2670
2671 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002672
Amar Singhala49cbc52013-10-08 18:37:44 -07002673 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhal0d15bd52013-10-12 23:13:13 -07002674 (" country code already exists"));
Amar Singhala49cbc52013-10-08 18:37:44 -07002675
Amar Singhal0d15bd52013-10-12 23:13:13 -07002676 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002677
Amar Singhal0d15bd52013-10-12 23:13:13 -07002678 return VOS_STATUS_SUCCESS;
2679 }
2680 else {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002681
Amar Singhal0d15bd52013-10-12 23:13:13 -07002682 /* get the regulatory information from the kernel
2683 database */
Amar Singhala49cbc52013-10-08 18:37:44 -07002684
Amar Singhal0d15bd52013-10-12 23:13:13 -07002685 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2686 (" get country information from kernel db"));
2687
Amar Singhal0d15bd52013-10-12 23:13:13 -07002688
Kiet Lam6c583332013-10-14 05:37:09 +05302689 if (COUNTRY_NV == source)
2690 {
2691 INIT_COMPLETION(pHddCtx->linux_reg_req);
2692 regulatory_hint(wiphy, country_code);
2693 wait_result = wait_for_completion_interruptible_timeout(
2694 &pHddCtx->linux_reg_req,
2695 LINUX_REG_WAIT_TIME);
Amar Singhal0d15bd52013-10-12 23:13:13 -07002696
Kiet Lam6c583332013-10-14 05:37:09 +05302697 /* if the country information does not exist with the kernel,
2698 then the driver callback would not be called */
Amar Singhal0d15bd52013-10-12 23:13:13 -07002699
Kiet Lam6c583332013-10-14 05:37:09 +05302700 if (wait_result >= 0) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002701
Kiet Lam6c583332013-10-14 05:37:09 +05302702 /* the driver callback was called. this means the country
2703 regulatory information was found in the kernel database.
2704 The callback would have updated the internal database. Here
2705 update the country and the return value for the regulatory
2706 domain */
Amar Singhalfddc28c2013-09-05 13:03:40 -07002707
Kiet Lam6c583332013-10-14 05:37:09 +05302708 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2709 ("runtime country code is found in kernel db"));
2710
2711 *pRegDomain = temp_reg_domain;
2712 cur_reg_domain = temp_reg_domain;
2713 linux_reg_cc[0] = country_code[0];
2714 linux_reg_cc[1] = country_code[1];
2715
2716 return VOS_STATUS_SUCCESS;
2717 }
2718 else {
2719
2720 /* the country information has not been found in the kernel
2721 database, return failure */
2722
2723 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2724 ("runtime country code is not found in kernel db"));
2725
2726 return VOS_STATUS_E_EXISTS;
2727 }
2728 }
2729 else if (COUNTRY_IE == source || COUNTRY_USER == source)
2730 {
2731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2732 regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER);
2733#else
2734 regulatory_hint_user(country_code);
2735#endif
Amar Singhal0d15bd52013-10-12 23:13:13 -07002736 *pRegDomain = temp_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002737 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002738
Kiet Lam6c583332013-10-14 05:37:09 +05302739 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002740
Kiet Lam6c583332013-10-14 05:37:09 +05302741 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002742}
2743
Amar Singhal0d15bd52013-10-12 23:13:13 -07002744/* create_linux_regulatory_entry to populate internal structures from wiphy */
2745static int create_linux_regulatory_entry(struct wiphy *wiphy,
2746 struct regulatory_request *request,
2747 v_U8_t nBandCapability)
2748{
2749 int i, j, m;
2750 int k = 0, n = 0;
Kiet Lam5cb90e82013-10-25 19:35:12 +05302751#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
2752 int err;
2753#endif
2754 const struct ieee80211_reg_rule *reg_rule;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002755 v_CONTEXT_t pVosContext = NULL;
2756 hdd_context_t *pHddCtx = NULL;
2757
2758 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2759
2760 if (NULL != pVosContext)
2761 {
2762 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2763 if (NULL == pHddCtx)
2764 {
2765 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2766 ("Invalid pHddCtx pointer") );
2767 }
2768 else
2769 {
2770 pHddCtx->isVHT80Allowed = 0;
2771 }
2772 }
2773 else
2774 {
2775 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2776 ("Invalid pVosContext pointer") );
2777 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07002778
2779 /* 20MHz channels */
2780 if (nBandCapability == eCSR_BAND_24)
2781 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08002782 "BandCapability is set to 2G only");
Amar Singhal0d15bd52013-10-12 23:13:13 -07002783
2784 for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++)
2785 {
2786 /* 5G only */
2787 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G)
2788 continue;
2789
2790 /* 2G only */
2791 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24)
2792 continue;
2793
2794 if (wiphy->bands[i] == NULL)
2795 {
2796
2797 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08002798 "error: wiphy->bands is NULL, i = %d", i);
Amar Singhal0d15bd52013-10-12 23:13:13 -07002799 return -1;
2800 }
2801
2802 /* internal channels[] is one continous array for both 2G and 5G bands
2803 m is internal starting channel index for each band */
2804
2805 if (i == 0)
2806 m = 0;
2807 else
2808 m = wiphy->bands[i-1]->n_channels + m;
2809
2810 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
2811 {
2812 /* k = (m + j) is internal current channel index for 20MHz channel
2813 n is internal channel index for corresponding 40MHz channel */
2814
2815 k = m + j;
2816 n = bw20_ch_index_to_bw40_ch_index(k);
2817
2818 if (n == -1)
2819 return -1;
2820
Kiet Lam5cb90e82013-10-25 19:35:12 +05302821 /* If the regulatory rules for a country do not explicilty
2822 * require a passive scan on a frequency, lift the passive
2823 * scan restriction
2824 */
2825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2826 reg_rule = freq_reg_info(wiphy,
2827 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq));
2828#else
2829 err = freq_reg_info(wiphy,
2830 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq),
2831 0, &reg_rule);
2832#endif
2833
2834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2835 if (!IS_ERR(reg_rule))
2836#else
2837 if (0 == err)
2838#endif
2839 {
2840 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
2841 {
2842 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2843 "%s: Remove passive scan restriction for %u",
2844 __func__, wiphy->bands[i]->channels[j].center_freq);
2845 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
2846 }
2847 }
2848
Amar Singhal0d15bd52013-10-12 23:13:13 -07002849 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2850 {
2851 if (pnvEFSTable == NULL)
2852 {
2853 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08002854 "error: pnvEFSTable is NULL, probably not parsed nv.bin yet");
Amar Singhal0d15bd52013-10-12 23:13:13 -07002855 return -1;
2856 }
2857 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
2858 NV_CHANNEL_DISABLE;
2859 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
2860 NV_CHANNEL_DISABLE;
2861 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05302862 /* nv cannot distinguish between DFS and passive channels */
2863 else if (wiphy->bands[i]->channels[j].flags &
2864 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
Amar Singhal0d15bd52013-10-12 23:13:13 -07002865 {
2866 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
2867 NV_CHANNEL_DFS;
2868
2869 /* max_power is in mBm = 100 * dBm */
2870 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08002871 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07002872 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2873 {
2874 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
2875 NV_CHANNEL_DFS;
2876
2877 /* 40MHz channel power is half of 20MHz (-3dB) ?? */
2878 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08002879 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07002880 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002881 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
2882 {
2883 if (NULL == pHddCtx)
2884 {
2885 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2886 ("Invalid pHddCtx pointer") );
2887 }
2888 else
2889 {
2890 pHddCtx->isVHT80Allowed = 1;
2891 }
2892 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07002893 }
2894 else /* Enable is only last flag we support */
2895 {
2896 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
2897 NV_CHANNEL_ENABLE;
2898
2899 /* max_power is in dBm */
2900 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08002901 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07002902 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2903 {
2904 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
2905 NV_CHANNEL_ENABLE;
2906 /* 40MHz channel power is half of 20MHz (-3dB) */
2907 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08002908 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07002909 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002910 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
2911 {
2912 if (NULL == pHddCtx)
2913 {
2914 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2915 ("Invalid pHddCtx pointer") );
2916 }
2917 else
2918 {
2919 pHddCtx->isVHT80Allowed = 1;
2920 }
2921 }
2922
Amar Singhal0d15bd52013-10-12 23:13:13 -07002923 }
2924
Kiet Lam5cb90e82013-10-25 19:35:12 +05302925
Amar Singhal0d15bd52013-10-12 23:13:13 -07002926 }
2927 }
2928
2929 if (k == 0)
2930 return -1;
2931
2932 return 0;
2933}
2934
2935
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002936/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07002937 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002938 * This function is called from cfg80211 core to provide regulatory settings
2939 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07002940 * This function is used to create a CRDA regulatory settings entry into internal
2941 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002942 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Amar Singhalfddc28c2013-09-05 13:03:40 -07002944void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07002945 struct regulatory_request *request)
2946#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002947int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002948 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07002949#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002950{
2951 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Amar Singhala49cbc52013-10-08 18:37:44 -07002952 tANI_U8 nBandCapability;
Amar Singhal0d15bd52013-10-12 23:13:13 -07002953 v_COUNTRYCODE_t country_code;
2954 int i;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002955 v_BOOL_t isVHT80Allowed;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002956
Amar Singhala49cbc52013-10-08 18:37:44 -07002957 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07002958 "cfg80211 reg notifier callback for country for initiator %d", request->initiator);
Amar Singhalfddc28c2013-09-05 13:03:40 -07002959
Arif Hussainec3fbb32013-10-03 11:49:23 -07002960 if (pHddCtx->isLoadUnloadInProgress)
2961 {
2962 wiphy_dbg(wiphy, "info: %s: Unloading/Loading in Progress. Ignore!!!",
2963 __func__);
Kiet Lamcffc5862013-10-30 16:28:45 +05302964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Arif Hussainec3fbb32013-10-03 11:49:23 -07002965 return;
Kiet Lamcffc5862013-10-30 16:28:45 +05302966#else
2967 return 0;
2968#endif
2969 }
2970
2971 if (NULL == pHddCtx)
2972 {
2973 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2974 ("Invalid pHddCtx pointer") );
2975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2976 return;
2977#else
2978 return 0;
2979#endif
Arif Hussainec3fbb32013-10-03 11:49:23 -07002980 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002981 /* first check if this callback is in response to the driver callback */
2982
Amar Singhala49cbc52013-10-08 18:37:44 -07002983 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
2984 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002985
Amar Singhal0d15bd52013-10-12 23:13:13 -07002986 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002987 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07002988 if (create_linux_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
2989 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002990
Amar Singhal0d15bd52013-10-12 23:13:13 -07002991 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07002992 (" regulatory entry created"));
Amar Singhal0d15bd52013-10-12 23:13:13 -07002993 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002994 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
2995 {
2996 hdd_checkandupdate_phymode( pHddCtx);
2997 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07002998
Amar Singhal0d15bd52013-10-12 23:13:13 -07002999 complete(&pHddCtx->linux_reg_req);
3000 }
3001
Kiet Lamcffc5862013-10-30 16:28:45 +05303002 else if (request->initiator == NL80211_REGDOM_SET_BY_USER ||
3003 request->initiator == NL80211_REGDOM_SET_BY_CORE)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003004 {
3005
3006 /* first lookup the country in the local database */
3007
3008 country_code[0] = request->alpha2[0];
3009 country_code[1] = request->alpha2[1];
3010
3011 temp_reg_domain = REGDOMAIN_COUNT;
3012 for (i = 0; i < countryInfoTable.countryCount &&
3013 REGDOMAIN_COUNT == temp_reg_domain; i++)
3014 {
3015 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3016 VOS_COUNTRY_CODE_LEN) == 0)
3017 {
3018 /* country code is found */
3019 /* record the temporary regulatory_domain as well */
3020 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3021 break;
3022 }
3023 }
3024
3025 if (REGDOMAIN_COUNT == temp_reg_domain)
3026 temp_reg_domain = REGDOMAIN_WORLD;
3027
3028 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003029 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003030 if (create_linux_regulatory_entry(wiphy, request,
3031 pHddCtx->cfg_ini->nBandCapability) == 0)
3032 {
3033 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3034 (" regulatory entry created"));
3035
3036 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003037 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3038 {
3039 hdd_checkandupdate_phymode( pHddCtx);
3040 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003041
3042 cur_reg_domain = temp_reg_domain;
3043 linux_reg_cc[0] = country_code[0];
3044 linux_reg_cc[1] = country_code[1];
3045
3046 /* now pass the new country information to sme */
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003047 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
3048 {
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003049 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3050 REGDOMAIN_COUNT);
3051 }
Kiet Lamcffc5862013-10-30 16:28:45 +05303052 else
3053 {
3054 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3055 temp_reg_domain);
3056 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05303057
Kiet Lamcffc5862013-10-30 16:28:45 +05303058 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07003060 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07003061#else
3062 return 0;
3063#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003064}
Amar Singhalfddc28c2013-09-05 13:03:40 -07003065
Amar Singhal0d15bd52013-10-12 23:13:13 -07003066
Amar Singhal0a402232013-10-11 20:57:16 -07003067/* initialize wiphy from NV.bin */
3068VOS_STATUS vos_init_wiphy_from_nv_bin(void)
3069{
3070 int i, j, m;
3071 int k = 0;
3072 v_REGDOMAIN_t reg_domain;
3073 v_CONTEXT_t pVosContext = NULL;
3074 hdd_context_t *pHddCtx = NULL;
3075 struct wiphy *wiphy = NULL;
3076
3077 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3078
3079 if (NULL != pVosContext)
3080 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3081 else
3082 return VOS_STATUS_E_EXISTS;
3083
3084 if (NULL == pHddCtx)
3085 {
3086 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3087 ("Invalid pHddCtx pointer") );
3088 return VOS_STATUS_E_FAULT;
3089 }
3090
3091 wiphy = pHddCtx->wiphy;
3092
3093 if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0])
3094 &&
3095 ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]))
3096 {
3097 /* default country is world roaming */
3098
3099 reg_domain = REGDOMAIN_WORLD;
3100 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3101 }
3102 else if (REGDOMAIN_WORLD ==
3103 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) {
3104
3105 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3106 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3107 }
3108 else {
3109
3110 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3111 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
3112 }
3113
Amar Singhala1829502013-11-16 13:57:41 -08003114 m = 0;
Amar Singhal0a402232013-10-11 20:57:16 -07003115 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3116 {
3117
3118 if (wiphy->bands[i] == NULL)
3119 {
3120 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
Amar Singhala1829502013-11-16 13:57:41 -08003121 continue;
Amar Singhal0a402232013-10-11 20:57:16 -07003122 }
3123
3124 /* internal channels[] is one continous array for both 2G and 5G bands
3125 m is internal starting channel index for each band */
Amar Singhal0a402232013-10-11 20:57:16 -07003126
3127 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3128 {
3129 /* k = (m + j) is internal current channel index */
3130 k = m + j;
3131
3132 if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3133 NV_CHANNEL_DISABLE)
3134 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3135
3136 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3137 NV_CHANNEL_DFS) {
3138
3139 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3140
3141 wiphy->bands[i]->channels[j].max_power =
3142 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3143 }
3144
3145 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3146 NV_CHANNEL_ENABLE) {
3147
3148 wiphy->bands[i]->channels[j].max_power =
3149 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3150 }
3151 }
Amar Singhala1829502013-11-16 13:57:41 -08003152
3153 m += wiphy->bands[i]->n_channels;
Amar Singhal0a402232013-10-11 20:57:16 -07003154 }
3155
3156 return VOS_STATUS_SUCCESS;
3157}
3158
3159
Amar Singhalfddc28c2013-09-05 13:03:40 -07003160#else
3161
3162/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07003163 \brief vos_nv_setRegDomain -
3164 \param clientCtxt - Client Context, Not used for PRIMA
3165 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303166 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003167 \return status set REG domain operation
3168 \sa
3169 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303170VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3171 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003172{
3173 v_CONTEXT_t pVosContext = NULL;
3174 hdd_context_t *pHddCtx = NULL;
3175 struct wiphy *wiphy = NULL;
3176 /* Client Context Argumant not used for PRIMA */
3177 if (regId >= REGDOMAIN_COUNT)
3178 {
3179 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3180 "VOS set reg domain, invalid REG domain ID %d", regId);
3181 return VOS_STATUS_E_INVAL;
3182 }
3183
3184 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3185 if (NULL != pVosContext)
3186 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3187 else
3188 return VOS_STATUS_E_EXISTS;
3189 /* Set correct channel information based on REG Domain */
3190 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3191
3192 /* when CRDA is not running then we are world roaming.
3193 In this case if 11d is enabled, then country code should
3194 be update on basis of world roaming */
Abhishek Singha306a442013-11-07 18:39:01 +05303195 if (NULL != pHddCtx && sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003196 {
3197 wiphy = pHddCtx->wiphy;
3198 regulatory_hint(wiphy, "00");
3199 }
3200 return VOS_STATUS_SUCCESS;
3201}
3202
3203
3204/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07003205 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3206 a country given its country code
3207 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3208 a country given its country code. This is done from reading a cached
3209 copy of the binary file.
3210 \param pRegDomain - pointer to regulatory domain
3211 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303212 \param source - source of the country code
Amar Singhalfddc28c2013-09-05 13:03:40 -07003213 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3214 VOS_STATUS_E_FAULT - invalid pointer error
3215 VOS_STATUS_E_EMPTY - country code table is empty
3216 VOS_STATUS_E_EXISTS - given country code does not exist in table
3217 \sa
3218 -------------------------------------------------------------------------*/
3219VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303220 const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003221{
Amar Singhala49cbc52013-10-08 18:37:44 -07003222 int i;
3223 v_CONTEXT_t pVosContext = NULL;
3224 hdd_context_t *pHddCtx = NULL;
3225 struct wiphy *wiphy = NULL;
3226 int status;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003227
Amar Singhala49cbc52013-10-08 18:37:44 -07003228 // sanity checks
3229 if (NULL == pRegDomain)
3230 {
3231 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003232 ("Invalid reg domain pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003233 return VOS_STATUS_E_FAULT;
3234 }
3235 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003236
Amar Singhala49cbc52013-10-08 18:37:44 -07003237 if (NULL == countryCode)
3238 {
3239 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003240 ("Country code array is NULL") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003241 return VOS_STATUS_E_FAULT;
3242 }
3243 if (0 == countryInfoTable.countryCount)
3244 {
3245 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003246 ("Reg domain table is empty") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003247 return VOS_STATUS_E_EMPTY;
3248 }
3249 /* If CRDA regulatory settings is valid, i.e. crda is enabled
3250 and reg_notifier is called back.
3251 Intercept here and redirect to the Reg domain table's CRDA
3252 entry if country code is crda's country.
3253 last one NUM_REG_DOMAINS-1 is reserved for crda */
3254 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003255 "vos_nv_getRegDomainFromCountryCode %c%c",
Amar Singhala49cbc52013-10-08 18:37:44 -07003256 countryCode[0], countryCode[1]);
3257
3258 if (crda_regulatory_entry_valid == VOS_TRUE)
3259 {
3260 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
3261 {
3262 *pRegDomain = NUM_REG_DOMAINS-1;
3263 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003264 "vos_nv_getRegDomainFromCountryCode return crda init entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003265 return VOS_STATUS_SUCCESS;
3266 }
3267 if (run_time_alpha2[0]==countryCode[0] &&
3268 run_time_alpha2[1]==countryCode[1] &&
3269 crda_regulatory_run_time_entry_valid == VOS_TRUE)
3270 {
3271 *pRegDomain = NUM_REG_DOMAINS-2;
3272 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003273 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003274 return VOS_STATUS_SUCCESS;
3275 }
3276 else
3277 {
3278 crda_regulatory_run_time_entry_valid = VOS_FALSE;
3279 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3280 if (NULL != pVosContext)
3281 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3282 else
3283 return VOS_STATUS_E_EXISTS;
3284 if (NULL == pHddCtx)
3285 {
3286 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003287 ("Invalid pHddCtx pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003288 return VOS_STATUS_E_FAULT;
3289 }
3290
3291 wiphy = pHddCtx->wiphy;
3292
3293 INIT_COMPLETION(pHddCtx->driver_crda_req);
3294 regulatory_hint(wiphy, countryCode);
3295 status = wait_for_completion_interruptible_timeout(
3296 &pHddCtx->driver_crda_req,
3297 msecs_to_jiffies(CRDA_WAIT_TIME));
3298 if (!status)
3299 {
3300 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3301 "%s: Timeout waiting for CRDA REQ", __func__);
3302 }
3303
3304 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
3305 {
3306 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003307 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003308 return VOS_STATUS_SUCCESS;
3309 }
3310 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003311 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003312 return VOS_STATUS_E_EXISTS;
3313 }
3314 }
3315
3316 // iterate the country info table until end of table or the country code
3317 // is found
3318 for (i = 0; i < countryInfoTable.countryCount &&
3319 REGDOMAIN_COUNT == *pRegDomain; i++)
3320 {
3321 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
3322 VOS_COUNTRY_CODE_LEN) == 0)
3323 {
3324 // country code is found
3325 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
3326 }
3327 }
3328 if (REGDOMAIN_COUNT != *pRegDomain)
3329 {
3330 return VOS_STATUS_SUCCESS;
3331 }
3332 else
3333 {
3334 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08003335 ("country code is not found"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003336 return VOS_STATUS_E_EXISTS;
3337 }
3338}
Abhishek Singha306a442013-11-07 18:39:01 +05303339/* FUNCTION: vos_nv_change_country_code_cb
3340* to wait for contry code completion
3341*/
3342void* vos_nv_change_country_code_cb(void *pAdapter)
3343{
3344 struct completion *change_code_cng = pAdapter;
3345 complete(change_code_cng);
3346 return NULL;
3347}
Amar Singhala49cbc52013-10-08 18:37:44 -07003348
3349/*
3350 * Function: wlan_hdd_crda_reg_notifier
3351 * This function is called from cfg80211 core to provide regulatory settings
3352 * after new country is requested or intersected (init, user input or 11d)
3353 * This function is used to create a CRDA regulatory settings entry into internal
3354 * regulatory setting table.
3355 */
3356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3357void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3358 struct regulatory_request *request)
3359#else
3360int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3361 struct regulatory_request *request)
3362#endif
3363{
3364 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3365 v_REGDOMAIN_t domainIdCurrent;
3366 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
3367 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
3368 tANI_U8 nBandCapability;
3369 int i,j,k,m;
3370
3371 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
3372 " %c%c\n", request->alpha2[0], request->alpha2[1]);
3373 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003374 {
Abhishek Singha306a442013-11-07 18:39:01 +05303375 int status;
Amar Singhala49cbc52013-10-08 18:37:44 -07003376 wiphy_dbg(wiphy, "info: set by user\n");
Abhishek Singha306a442013-11-07 18:39:01 +05303377 init_completion(&change_country_code);
3378 /* We will process hints by user from nl80211 in driver.
3379 * sme_ChangeCountryCode will set the country to driver
3380 * and update the regdomain.
3381 * when we return back to nl80211 from this callback, the nl80211 will
3382 * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to
3383 * query channel list from nl80211. Thus we need to update the channels
3384 * according to reg domain set by user before returning to nl80211 so
3385 * that hostapd will gets the updated channels.
3386 * The argument sendRegHint in sme_ChangeCountryCode is
3387 * set to eSIR_FALSE (hint is from nl80211 and thus
3388 * no need to notify nl80211 back)*/
3389 status = sme_ChangeCountryCode(pHddCtx->hHal,
3390 (void *)(tSmeChangeCountryCallback)
3391 vos_nv_change_country_code_cb,
3392 request->alpha2,
3393 &change_country_code,
3394 pHddCtx->pvosContext,
3395 eSIR_FALSE,
3396 eSIR_FALSE);
3397 if (eHAL_STATUS_SUCCESS == status)
3398 {
3399 status = wait_for_completion_interruptible_timeout(
3400 &change_country_code,
3401 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3402 if(status <= 0)
3403 {
3404 wiphy_dbg(wiphy, "info: set country timed out\n");
3405 }
3406 }
3407 else
3408 {
3409 wiphy_dbg(wiphy, "info: unable to set country by user\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07003410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3411 return;
3412#else
3413 return 0;
3414#endif
Abhishek Singha306a442013-11-07 18:39:01 +05303415 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003416 // ToDo
3417 /* Don't change default country code to CRDA country code by user req */
3418 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
3419 regd for new country settings */
3420 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3421 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003422 }
Abhishek Singha306a442013-11-07 18:39:01 +05303423
3424 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003425 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003426 wiphy_dbg(wiphy, "info: set by country IE\n");
3427 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
3428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3429 return;
3430#else
3431 return 0;
3432#endif
3433 // ToDo
3434 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003435
Amar Singhala49cbc52013-10-08 18:37:44 -07003436 /* Don't change default country code to CRDA country code by 11d req */
3437 /* for every adapter call sme_ChangeCountryCode to trigger read regd
3438 for intersected new country settings */
3439 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3440 // &country_code[0], pAdapter, pHddCtx->pvosContext);
3441 }
3442 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
Abhishek Singha306a442013-11-07 18:39:01 +05303443 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
3444 (request->initiator == NL80211_REGDOM_SET_BY_USER))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003445 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003446 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
3447 {
3448 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
3449#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3450 return;
3451#else
3452 return 0;
3453#endif
3454 }
3455 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
3456 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
3457 {
3458 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
3459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3460 return;
3461#else
3462 return 0;
3463#endif
3464 }
3465
3466 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
3467 /* if set by driver itself, it means driver can accept the crda
3468 regulatory settings and wiphy->regd should be populated with crda
3469 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
3470 correctly, this may be fixed by later kernel */
3471
3472 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
3473 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
3474 {
3475 if (NULL == wiphy->bands[i])
3476 {
3477 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3478 "error: wiphy->bands[i] is NULL, i = %d", i);
3479 continue;
3480 }
3481
3482 // internal channels[] is one continous array for both 2G and 5G bands
3483 // m is internal starting channel index for each band
3484 if (0 == i)
3485 {
3486 m = 0;
3487 }
3488 else
3489 {
3490 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
3491 }
3492
3493 for (j=0; j<wiphy->bands[i]->n_channels; j++)
3494 {
3495 // k = (m + j) is internal current channel index for 20MHz channel
3496 // n is internal channel index for corresponding 40MHz channel
3497 k = m + j;
3498 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
3499 {
3500 // Enable social channels for P2P
3501 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
3502 2437 == wiphy->bands[i]->channels[j].center_freq ||
3503 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
3504 NV_CHANNEL_ENABLE == regChannels[k].enabled)
3505 {
3506 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
3507 }
3508 else
3509 {
3510 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3511 }
3512 continue;
3513 }
3514 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
3515 {
3516 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3517 continue;
3518 }
3519
3520 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
3521 NV_CHANNEL_INVALID == regChannels[k].enabled)
3522 {
3523 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3524 }
3525 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
3526 {
3527 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
3528 |IEEE80211_CHAN_RADAR);
3529 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3530 }
3531 else
3532 {
3533 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
3534 |IEEE80211_CHAN_PASSIVE_SCAN
3535 |IEEE80211_CHAN_NO_IBSS
3536 |IEEE80211_CHAN_RADAR);
3537 }
3538 }
3539 }
3540
3541 /* Haven't seen any condition that will set by driver after init.
3542 If we do, then we should also call sme_ChangeCountryCode */
3543 if (wiphy->bands[IEEE80211_BAND_5GHZ])
3544 {
3545 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
3546 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303547 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07003548 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
3549 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
3550 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
3551 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303552 ((ccode[0]== 'U'&& ccode[1]=='S') && pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07003553 {
3554 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3555 }
3556 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
3557 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
3558 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
3559 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303560 ((ccode[0]!= 'U'&& ccode[1]!='S') || !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07003561 {
3562 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3563 }
3564 }
3565 }
3566
3567 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
3568 {
3569 request->processed = 1;
3570 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003571 }
3572
Kiet Lam46b8e4e2013-11-06 21:49:53 +05303573 complete(&pHddCtx->wiphy_channel_update_event);
3574
Amar Singhala49cbc52013-10-08 18:37:44 -07003575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3576 return;
3577#else
3578 return 0;
3579#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07003580}
3581
3582#endif