blob: 37ade1307016f54e6c39c981080165f6ef4e058f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam1ed83fc2014-02-19 01:15:45 -08002 * Copyright (c) 2012-2014 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
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lam1ed83fc2014-02-19 01:15:45 -080026 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*============================================================================
32 FILE: vos_nvitem.c
33 OVERVIEW: This source file contains definitions for vOS NV Item APIs
34 DEPENDENCIES: NV, remote API client, WinCE REX
35 Copyright (c) 2008 QUALCOMM Incorporated.
36 All Rights Reserved.
37 Qualcomm Confidential and Proprietary
38============================================================================*/
39/*============================================================================
40 EDIT HISTORY FOR MODULE
41============================================================================*/
42// the following is used to disable warning for having too many labels in
43// the 'nv_items_enum_type'
44
45/*----------------------------------------------------------------------------
46 * Include Files
47 * -------------------------------------------------------------------------*/
48#include "vos_types.h"
49#include "aniGlobal.h"
50#include "vos_nvitem.h"
51#include "vos_trace.h"
52#include "vos_api.h"
53#include "wlan_hdd_misc.h"
54#include "vos_sched.h"
Amar Singhal0d15bd52013-10-12 23:13:13 -070055#include "sme_Api.h"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070056#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070057#include "wlan_hdd_main.h"
58#include <net/cfg80211.h>
Amar Singhalfddc28c2013-09-05 13:03:40 -070059
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -070060#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
61#define IEEE80211_CHAN_NO_80MHZ 1<<7
62#endif
Amar Singhala49cbc52013-10-08 18:37:44 -070063
Amar Singhalfddc28c2013-09-05 13:03:40 -070064#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhala49cbc52013-10-08 18:37:44 -070065
66static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -070067static char linux_reg_cc[2] = {0, 0};
Amar Singhalfddc28c2013-09-05 13:03:40 -070068static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
Amar Singhala49cbc52013-10-08 18:37:44 -070069
Abhishek Singha306a442013-11-07 18:39:01 +053070#else
71
72/* Cant access pAdapter in this file so defining a new variable to wait when changing country*/
73static struct completion change_country_code;
74
Amar Singhalfddc28c2013-09-05 13:03:40 -070075#endif
76
Amar Singhala49cbc52013-10-08 18:37:44 -070077static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
78static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
79static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
80static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
81
Jeff Johnson295189b2012-06-20 16:38:30 -070082/*----------------------------------------------------------------------------
83 * Preprocessor Definitions and Constants
84 * -------------------------------------------------------------------------*/
85#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
86#define VALIDITY_BITMAP_SIZE 32
87#define MAX_COUNTRY_COUNT 300
88//To be removed when NV support is fully functional
89#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070090
91#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070092#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070093
Mihir Shete7f3fe0e2014-07-04 12:56:33 +053094#define MIN(a, b) (a > b ? b : a)
Jeff Johnson295189b2012-06-20 16:38:30 -070095/*----------------------------------------------------------------------------
96 * Type Declarations
97 * -------------------------------------------------------------------------*/
98// this wrapper structure is identical to nv_cmd_type except the
99// data_ptr type is changed void* to avoid exceeding the debug information
100// module size as there are too many elements within nv_items_type union
101
102// structure for code and regulatory domain of a single country
103typedef struct
104{
105 v_U8_t regDomain;
106 v_COUNTRYCODE_t countryCode;
107} CountryInfo_t;
108// structure of table to map country code and regulatory domain
109typedef struct
110{
111 v_U16_t countryCount;
112 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
113} CountryInfoTable_t;
114/*----------------------------------------------------------------------------
115 * Global Data Definitions
116 * -------------------------------------------------------------------------*/
117/*----------------------------------------------------------------------------
118 * Static Variable Definitions
119 * -------------------------------------------------------------------------*/
Amar Singhala49cbc52013-10-08 18:37:44 -0700120// cache of country info table;
121// this is re-initialized from data on binary file
122// loaded on driver initialization if available
Amar Singhalfddc28c2013-09-05 13:03:40 -0700123
124#ifdef CONFIG_ENABLE_LINUX_REG
125
126static CountryInfoTable_t countryInfoTable =
127{
128 /* the first entry in the table is always the world domain */
129 138,
130 {
131 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
132 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
133 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
134 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
135 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
136 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
137 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
138 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
139 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
140 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
141 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
142 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
143 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
144 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
145 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
146 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
147 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
148 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
149 {REGDOMAIN_ETSI, {'B', 'L'}}, //
150 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
151 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
152 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
153 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
154 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
155 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
156 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
157 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
158 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
159 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
160 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
161 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
162 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
163 {REGDOMAIN_ETSI, {'C', 'S'}},
164 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
165 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
166 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
167 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
168 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
169 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
170 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
171 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
172 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
173 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
174 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
175 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
176 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
177 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
178 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
179 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
180 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
181 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
182 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
183 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
184 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
185 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
186 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
187 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
188 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
189 {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
190 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
191 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
192 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
193 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
194 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
195 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
196 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
197 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
198 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
199 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
200 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
201 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
202 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
203 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
204 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
205 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
206 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
207 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
208 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
209 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
210 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
211 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
212 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
213 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
214 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
215 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
216 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
217 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
218 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
219 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
220 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
221 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
222 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
223 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
224 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
225 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
226 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
227 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
228 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
229 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
230 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
231 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
232 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
233 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
234 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
235 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
236 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
237 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
238 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
239 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
240 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
241 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
242 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
243 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
244 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
245 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
246 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
247 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
248 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
249 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
250 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
251 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
252 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
253 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
254 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
255 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
256 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
257 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
258 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
259 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
260 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
261 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
262 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
263 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
264 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
265 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
266 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
267 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
268 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
269 }
270};
271
272#else
273
Jeff Johnson295189b2012-06-20 16:38:30 -0700274// cache of country info table;
275// this is re-initialized from data on binary file
276// loaded on driver initialization if available
277static CountryInfoTable_t countryInfoTable =
278{
279 254,
280 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700281 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
282 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
283 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
284 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
285 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
286 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700287 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700288 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
289 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
290 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
291 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
292 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
293 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
294 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530295 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700296 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
297 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
298 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
299 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
300 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700301 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700302 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
303 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
304 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
305 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
306 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
307 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
308 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
309 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
310 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
311 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
312 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
313 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
314 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
315 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
316 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
317 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
318 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
319 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
320 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
321 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
322 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
323 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
324 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
325 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
326 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
327 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530328 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700329 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
330 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
331 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
332 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
333 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
334 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
335 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
336 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
337 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
338 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
339 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
340 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700341 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700342 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
343 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
344 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
345 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
346 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
347 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
348 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
349 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
350 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
351 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
352 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
353 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
354 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
355 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
356 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
357 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
358 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
359 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
360 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
361 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
362 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
363 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
364 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
365 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
366 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
367 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
368 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
369 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
370 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
371 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700372 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700373 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
374 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
375 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
376 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
377 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
378 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
379 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
380 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
381 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
382 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700383 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700384 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
385 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
386 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
387 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
388 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
389 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
390 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
391 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
392 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
393 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
394 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
395 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
396 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
397 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700398 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700399 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
400 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
401 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
402 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
403 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700404 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700405 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
406 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
407 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
408 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
409 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
410 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
411 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
412 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
413 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700414 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700415 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700416 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700417 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
418 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
419 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
420 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
421 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
422 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
423 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
424 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
425 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700426 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700427 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700428 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
429 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
430 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
431 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
432 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
433 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
434 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700435 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700436 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
437 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
438 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
439 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
440 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
441 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
442 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
443 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
444 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
445 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
446 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
447 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
448 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
449 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
450 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
451 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
452 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
453 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
454 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
455 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700456 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700457 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
458 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
459 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700460 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700461 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700462 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700463 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700464 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
465 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700466 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
467 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
468 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
469 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
470 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
471 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
472 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
473 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
474 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
475 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
476 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
477 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
478 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700479 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
480 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
481 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700482 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
483 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
484 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
485 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
486 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
487 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
488 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
489 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
490 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
491 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
492 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
493 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
494 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
495 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
496 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
497 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
498 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
499 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
500 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
501 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
502 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
503 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
504 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
505 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
506 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
507 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
508 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
509 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
510 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700511 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700512 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
513 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700514 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700515 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700516 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
517 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700518 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
519 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700520 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700521 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
522 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
523 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
524 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
525 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700526 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700527 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
528 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
529 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
530 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
531 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
532 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
533 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700534 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700535 }
536};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700537
538#endif
539
Amar Singhala49cbc52013-10-08 18:37:44 -0700540
Jeff Johnson295189b2012-06-20 16:38:30 -0700541typedef struct nvEFSTable_s
542{
543 v_U32_t nvValidityBitmap;
544 sHalNv halnv;
545} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700546nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700547/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700548static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700549static v_U8_t *pnvEncodedBuf;
550static v_U8_t *pDictFile;
551static v_U8_t *pEncodedBuf;
552static v_SIZE_t nvReadEncodeBufSize;
553static v_SIZE_t nDictionarySize;
554static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700555
Leo Chang80de3c22013-11-26 10:52:12 -0800556/* NV2 specific, No CH 144 support
557 * For NV_FTM operation, NV2 structure should be maintained
558 * This will be used only for the NV_FTM operation */
559typedef struct nvEFSTableV2_s
560{
561 v_U32_t nvValidityBitmap;
562 sHalNvV2 halnvV2;
563} nvEFSTableV2_t;
564nvEFSTableV2_t *gnvEFSTableV2;
565
Jeff Johnson295189b2012-06-20 16:38:30 -0700566const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
567{
568 //RF_SUBBAND_2_4_GHZ
569 //freq, chan#, band
570 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
571 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
572 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
573 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
574 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
575 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
576 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
577 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
578 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
579 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
580 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
581 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
582 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
583 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700584 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
585 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
586 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
587 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
588 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
589 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
590 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
592 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
593 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
594 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
595 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
596 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
597 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
598 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
599 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
600 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
601 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
602 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
603 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
604 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
605 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
606 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
607 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
608 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
609 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
Leo Chang80de3c22013-11-26 10:52:12 -0800610#ifdef FEATURE_WLAN_CH144
611 { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144,
612#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
614 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
615 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
616 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
617 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700618 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
619 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
620 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
621 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
622 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
623 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
624 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
625 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
626 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
627 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
628 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
629 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
630 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
631 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
632 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
633 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
634 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
635 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
636 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
637 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
638 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
639 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
640 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
641 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
642 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
643 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
644 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
645 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
646 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
647 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
648 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
Leo Chang80de3c22013-11-26 10:52:12 -0800649#ifdef FEATURE_WLAN_CH144
650 { 5730, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142,
651#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700652 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
653 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
654 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
655 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700656};
657
658extern const sHalNv nvDefaults;
659
660const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
661
Mihir Shete7f3fe0e2014-07-04 12:56:33 +0530662
Jeff Johnson295189b2012-06-20 16:38:30 -0700663/*----------------------------------------------------------------------------
664 Function Definitions and Documentation
665 * -------------------------------------------------------------------------*/
666VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
Sushant Kaushike0d2cce2014-04-10 14:36:07 +0530667const char * voss_DomainIdtoString(v_U8_t domainIdCurrent)
668{
669 switch (domainIdCurrent)
670 {
671 CASE_RETURN_STRING( REGDOMAIN_FCC );
672 CASE_RETURN_STRING( REGDOMAIN_ETSI );
673 CASE_RETURN_STRING( REGDOMAIN_JAPAN );
674 CASE_RETURN_STRING( REGDOMAIN_WORLD );
675 CASE_RETURN_STRING( REGDOMAIN_N_AMER_EXC_FCC );
676 CASE_RETURN_STRING( REGDOMAIN_APAC );
677 CASE_RETURN_STRING( REGDOMAIN_KOREA );
678 CASE_RETURN_STRING( REGDOMAIN_HI_5GHZ );
679 CASE_RETURN_STRING( REGDOMAIN_NO_5GHZ );
680 CASE_RETURN_STRING( REGDOMAIN_COUNT );
681 default:
682 return "Regulation Domain Unknown";
683 }
684}
Jeff Johnson295189b2012-06-20 16:38:30 -0700685/**------------------------------------------------------------------------
686 \brief vos_nv_init() - initialize the NV module
687 The \a vos_nv_init() initializes the NV module. This read the binary
688 file for country code and regulatory domain information.
689 \return VOS_STATUS_SUCCESS - module is initialized successfully
690 otherwise - module is not initialized
691 \sa
692 -------------------------------------------------------------------------*/
693VOS_STATUS vos_nv_init(void)
694{
695 return VOS_STATUS_SUCCESS;
696}
697
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700698/**------------------------------------------------------------------------
699 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
700 \ tools
701 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
702 otherwise - not successful
703 \sa
704-------------------------------------------------------------------------*/
705VOS_STATUS vos_nv_get_dictionary_data(void)
706{
707 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
708
709 if (MAGIC_NUMBER != magicNumber)
710 {
711 return VOS_STATUS_SUCCESS;
712 }
713
714 nDictionarySize = 0;
715
716 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
717 &nDictionarySize );
718 if (VOS_STATUS_E_NOMEM != vosStatus)
719 {
720 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
721 "Error obtaining binary size" );
722/// NOTE:
723/// We can still work without a dictionary file..
724 return VOS_STATUS_SUCCESS;
725 }
726
727 // malloc a buffer to read in the Configuration binary file.
728 pDictFile = vos_mem_malloc( nDictionarySize );
729 if (NULL == pDictFile)
730 {
731 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
732 "Unable to allocate memory for the CFG binary [size= %d bytes]",
733 nDictionarySize );
734 vosStatus = VOS_STATUS_E_NOMEM;
735 goto fail;
736 }
737
738 /* Get the entire CFG file image... */
739 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
740 &nDictionarySize );
741 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
742 {
743 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
744 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
745 nDictionarySize );
746 return VOS_STATUS_SUCCESS;
747 }
748
749 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
750 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
751
752fail:
753 return vosStatus;
754}
755
Leo Chang80de3c22013-11-26 10:52:12 -0800756/**------------------------------------------------------------------------
757 \brief vos_nv_parseV2bin() - Parse NV2 binary
758 Parse NV2 BIN, and assign contents to common NV structure.
759 \param pnvEncodedBuf
760 NV Bin read buffer
761 \param nvReadBufSize
762 NV Bin read size
763 \param halNv
764 common NV structure storage pointer
765 \return VOS_STATUS_SUCCESS - module is initialized successfully
766 otherwise - module is not initialized
767 \sa
768 -------------------------------------------------------------------------*/
769VOS_STATUS vos_nv_parseV2bin(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
770 sHalNv *halNv)
771{
772 sHalNvV2 *nv2Table;
773 tANI_U16 copyLoop;
774 tANI_U16 channelLoop;
775 void *targetPtr;
776 void *sourcePtr;
777
778 v_U32_t structSize = 0;
779
780 nv2Table = (sHalNvV2 *)pnvEncodedBuf;
781 /* NV Field Default Copy */
782 vos_mem_copy((char *)&halNv->fields,
783 (char *)&nv2Table->fields,
784 sizeof(sNvFields));
785 structSize += sizeof(sNvFields);
786 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
787 "%s: sizeof(sNvFields) %zu, structSize %d",
788 __func__, sizeof(sNvFields), structSize);
789
790 /* NV Table, tRateGroupPwr, NOT depends on channel count */
791 vos_mem_copy((char *)halNv->tables.pwrOptimum,
792 (char *)nv2Table->tables.pwrOptimum,
793 sizeof(halNv->tables.pwrOptimum));
794 structSize += sizeof(halNv->tables.pwrOptimum);
795 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
796 "%s: sizeof(halNv->tables.pwrOptimum) %zu, structSize %d",
797 __func__, sizeof(halNv->tables.pwrOptimum), structSize);
798
799 /* NV Table, regDomains, edepends on channel count */
800 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
801 {
802 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].antennaGain,
803 (char *)nv2Table->tables.regDomains[copyLoop].antennaGain,
804 sizeof(halNv->tables.regDomains[copyLoop].antennaGain));
805 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
806
807 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].bRatePowerOffset,
808 (char *)nv2Table->tables.regDomains[copyLoop].bRatePowerOffset,
809 sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset));
810 structSize += sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset);
811 }
812
813 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
814 {
815 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].channels[0]);
816 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].channels[0]);
817 /* Cannot blindly copy
818 * Each single CH should be assigned */
819 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
820 {
821#ifdef FEATURE_WLAN_CH144
822 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
823 {
824 /* NV2 CH144 is disabled */
825 halNv->tables.regDomains[copyLoop].channels[channelLoop].enabled =
826 NV_CHANNEL_DISABLE;
827 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
828 }
829 else
830#endif /* FEATURE_WLAN_CH144 */
831 {
832
833 vos_mem_copy(targetPtr, sourcePtr, sizeof(sRegulatoryChannel));
834 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
835 sourcePtr = sourcePtr + sizeof(sRegulatoryChannel);
836 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
837 }
838 }
839 }
840 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
841 "%s: sizeof(halNv->tables.regDomains[copyLoop].antennaGain) %zu, structSize %d",
842 __func__, sizeof(halNv->tables.regDomains[copyLoop].antennaGain), structSize);
843
844 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
845 {
846 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
847 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
848 /* Cannot blindly copy
849 * Each single CH should be assigned */
850 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
851 {
852#ifdef FEATURE_WLAN_CH144
853 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
854 {
855 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
856 }
857 else
858#endif /* FEATURE_WLAN_CH144 */
859 {
860 vos_mem_copy(targetPtr, sourcePtr, sizeof(uAbsPwrPrecision));
861 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
862 sourcePtr = sourcePtr + sizeof(uAbsPwrPrecision);
863 structSize += sizeof(sizeof(uAbsPwrPrecision));
864 }
865 }
866 }
867 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
868 "%s: sizeof(uAbsPwrPrecision) %zu, structSize %d",
869 __func__, sizeof(uAbsPwrPrecision), structSize);
870
871 /* nvTable, defaultCountryTable, NOT depends on channel counts */
872 vos_mem_copy((char *)&halNv->tables.defaultCountryTable,
873 (char *)&nv2Table->tables.defaultCountryTable,
874 sizeof(halNv->tables.defaultCountryTable));
875 structSize += sizeof(halNv->tables.defaultCountryTable);
876 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
877 "%s: sizeof(halNv->tables.defaultCountryTable) %zu, structSize %d",
878 __func__, sizeof(halNv->tables.defaultCountryTable), structSize);
879
880 /* NV Table, plutCharacterized, depends on channel count
881 * Cannot blindly copy
882 * Each single CH should be assigned */
883 targetPtr = (char *)&(halNv->tables.plutCharacterized[0]);
884 sourcePtr = (char *)&(nv2Table->tables.plutCharacterized[0]);
885 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
886 {
887#ifdef FEATURE_WLAN_CH144
888 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
889 {
890 targetPtr = targetPtr + sizeof(tTpcPowerTable);
891 }
892 else
893#endif /* FEATURE_WLAN_CH144 */
894 {
895 vos_mem_copy(targetPtr, sourcePtr, sizeof(tTpcPowerTable));
896 targetPtr = targetPtr + sizeof(tTpcPowerTable);
897 sourcePtr = sourcePtr + sizeof(tTpcPowerTable);
898 structSize += sizeof(tTpcPowerTable);
899 }
900 }
901 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
902 "%s: sizeof(tTpcPowerTable) %zu, structSize %d",
903 __func__, sizeof(tTpcPowerTable), structSize);
904
905 /* NV Table, plutPdadcOffset, depends on channel count
906 * Cannot blindly copy
907 * Each single CH should be assigned */
908 targetPtr = (char *)&(halNv->tables.plutPdadcOffset[0]);
909 sourcePtr = (char *)&(nv2Table->tables.plutPdadcOffset[0]);
910 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
911 {
912#ifdef FEATURE_WLAN_CH144
913 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
914 {
915 targetPtr = targetPtr + sizeof(int16);
916 }
917 else
918#endif /* FEATURE_WLAN_CH144 */
919 {
920 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
921 targetPtr = targetPtr + sizeof(int16);
922 sourcePtr = sourcePtr + sizeof(int16);
923 structSize += sizeof(int16);
924 }
925 }
926 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
927 "%s: sizeof(halNv->tables.plutPdadcOffset) %zu, structSize %d",
928 __func__, sizeof(int16), structSize);
929
930 /* NV Table, pwrOptimum_virtualRate, NOT depends on channel count */
931 vos_mem_copy((char *)halNv->tables.pwrOptimum_virtualRate,
932 (char *)nv2Table->tables.pwrOptimum_virtualRate,
933 sizeof(halNv->tables.pwrOptimum_virtualRate));
934 structSize += sizeof(halNv->tables.pwrOptimum_virtualRate);
935 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
936 "%s: sizeof(halNv->tables.pwrOptimum_virtualRate) %zu, structSize %d",
937 __func__, sizeof(halNv->tables.pwrOptimum_virtualRate), structSize);
938
939 /* NV Table, fwConfig, NOT depends on channel count */
940 vos_mem_copy((char *)&halNv->tables.fwConfig,
941 (char *)&nv2Table->tables.fwConfig,
942 sizeof(halNv->tables.fwConfig));
943 structSize += sizeof(halNv->tables.fwConfig);
944 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
945 "%s: sizeof(halNv->tables.fwConfig) %zu, structSize %d",
946 __func__, sizeof(halNv->tables.fwConfig), structSize);
947
948 /* NV Table, rssiChanOffsets, depends on channel count
949 * Cannot blindly copy
950 * Each single CH should be assigned */
951 for (copyLoop = 0; copyLoop < 2; copyLoop++)
952 {
953 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
954 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
955 /* Cannot blindly copy
956 * Each single CH should be assigned */
957 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
958 {
959#ifdef FEATURE_WLAN_CH144
960 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
961 {
962 targetPtr = targetPtr + sizeof(int16);
963 }
964 else
965#endif /* FEATURE_WLAN_CH144 */
966 {
967 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
968 targetPtr = targetPtr + sizeof(int16);
969 sourcePtr = sourcePtr + sizeof(int16);
970 structSize += sizeof(int16);
971 }
972 }
973 }
974 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
975 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
976 __func__, sizeof(int16), structSize);
977
978 for (copyLoop = 0; copyLoop < 2; copyLoop++)
979 {
980 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
981 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
982 /* Cannot blindly copy
983 * Each single CH should be assigned */
984 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
985 {
986#ifdef FEATURE_WLAN_CH144
987 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
988 {
989 targetPtr = targetPtr + sizeof(int16);
990 }
991 else
992#endif /* FEATURE_WLAN_CH144 */
993 {
994 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
995 targetPtr = targetPtr + sizeof(int16);
996 sourcePtr = sourcePtr + sizeof(int16);
997 structSize += sizeof(int16);
998 }
999 }
1000 }
1001 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1002 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
1003 __func__, sizeof(int16), structSize);
1004
1005 /* NV Table, hwCalValues, NOT depends on channel count */
1006 vos_mem_copy((char *)&halNv->tables.hwCalValues,
1007 (char *)&nv2Table->tables.hwCalValues,
1008 sizeof(halNv->tables.hwCalValues));
1009 structSize += sizeof(halNv->tables.fwConfig);
1010 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1011 "%s: sizeof(halNv->tables.hwCalValues) %zu, structSize %d",
1012 __func__, sizeof(halNv->tables.hwCalValues), structSize);
1013
1014 /* NV Table, antennaPathLoss, depends on channel count
1015 * Cannot blindly copy
1016 * Each single CH should be assigned */
1017 targetPtr = (char *)&(halNv->tables.antennaPathLoss[0]);
1018 sourcePtr = (char *)&(nv2Table->tables.antennaPathLoss[0]);
1019 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1020 {
1021#ifdef FEATURE_WLAN_CH144
1022 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1023 {
1024 targetPtr = targetPtr + sizeof(int16);
1025 }
1026 else
1027#endif /* FEATURE_WLAN_CH144 */
1028 {
1029 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1030 targetPtr = targetPtr + sizeof(int16);
1031 sourcePtr = sourcePtr + sizeof(int16);
1032 structSize += sizeof(int16);
1033 }
1034 }
1035 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1036 "%s: sizeof(halNv->tables.antennaPathLoss) %zu, structSize %d",
1037 __func__, sizeof(int16), structSize);
1038
1039 /* NV Table, pktTypePwrLimits, depends on channel count
1040 * Cannot blindly copy
1041 * Each single CH should be assigned */
1042 for (copyLoop = 0; copyLoop < NUM_802_11_MODES; copyLoop++)
1043 {
1044 targetPtr = (char *)&(halNv->tables.pktTypePwrLimits[copyLoop][0]);
1045 sourcePtr = (char *)&(nv2Table->tables.pktTypePwrLimits[copyLoop][0]);
1046 /* Cannot blindly copy
1047 * Each single CH should be assigned */
1048 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1049 {
1050#ifdef FEATURE_WLAN_CH144
1051 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1052 {
1053 targetPtr = targetPtr + sizeof(int16);
1054 }
1055 else
1056#endif /* FEATURE_WLAN_CH144 */
1057 {
1058 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1059 targetPtr = targetPtr + sizeof(int16);
1060 sourcePtr = sourcePtr + sizeof(int16);
1061 structSize += sizeof(int16);
1062 }
1063 }
1064 }
1065 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1066 "%s: sizeof(halNv->tables.pktTypePwrLimits) %zu, structSize %d",
1067 __func__, sizeof(int16), structSize);
1068
1069 /* NV Table, ofdmCmdPwrOffset, NOT depends on channel count */
1070 vos_mem_copy((char *)&halNv->tables.ofdmCmdPwrOffset,
1071 (char *)&nv2Table->tables.ofdmCmdPwrOffset,
1072 sizeof(halNv->tables.ofdmCmdPwrOffset));
1073 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1074 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1075 "%s: sizeof(halNv->tables.ofdmCmdPwrOffset) %zu, structSize %d",
1076 __func__, sizeof(halNv->tables.ofdmCmdPwrOffset), structSize);
1077
1078 /* NV Table, txbbFilterMode, NOT depends on channel count */
1079 vos_mem_copy((char *)&halNv->tables.txbbFilterMode,
1080 (char *)&nv2Table->tables.txbbFilterMode,
1081 sizeof(halNv->tables.txbbFilterMode));
1082 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1083 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1084 "%s: sizeof(halNv->tables.txbbFilterMode) %zu, structSize %d",
1085 __func__, sizeof(halNv->tables.txbbFilterMode), structSize);
1086
1087 return VOS_STATUS_SUCCESS;
1088}
1089
1090/**------------------------------------------------------------------------
1091 \brief vos_nv_open() - Open NV operation
1092 Read NV bin file and prepare NV common structure
1093 \return VOS_STATUS_SUCCESS - module is initialized successfully
1094 otherwise - module is not initialized
1095 \sa
1096 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001097VOS_STATUS vos_nv_open(void)
1098{
1099 VOS_STATUS status = VOS_STATUS_SUCCESS;
1100 v_CONTEXT_t pVosContext= NULL;
1101 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001102 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001104 v_U32_t dataOffset;
1105 sHalNv *pnvData = NULL;
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001106 hdd_context_t *pHddCtx = NULL;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001107
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 /*Get the global context */
1109 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001110
1111 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001112 {
1113 return (eHAL_STATUS_FAILURE);
1114 }
1115
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 status = hdd_request_firmware(WLAN_NV_FILE,
1117 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001118 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001119
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001120 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001122 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001124 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001125 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 }
1127
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001128 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
1129
1130 /// Allocate buffer with maximum length..
1131 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
1132
1133 if (NULL == pEncodedBuf)
1134 {
1135 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1136 "%s : failed to allocate memory for NV", __func__);
1137 return VOS_STATUS_E_NOMEM;
1138 }
1139
Leo Chang80de3c22013-11-26 10:52:12 -08001140 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1141 "NV Table Size %zu", sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001142
Leo Chang80de3c22013-11-26 10:52:12 -08001143 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
1144 if (NULL == pnvEFSTable)
1145 {
1146 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1147 "%s : failed to allocate memory for NV", __func__);
1148 return VOS_STATUS_E_NOMEM;
1149 }
1150 vos_mem_zero((void *)pnvEFSTable, sizeof(nvEFSTable_t));
1151
1152 // Default NV version, NOT_VALID
1153 ((VosContextType*)(pVosContext))->nvVersion = E_NV_INVALID;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001154 if (MAGIC_NUMBER == magicNumber)
1155 {
Leo Chang80de3c22013-11-26 10:52:12 -08001156 bufSize = sizeof(nvEFSTable_t);
1157 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001158 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
1159
1160 if (NULL == pnvData)
1161 {
1162 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1163 "%s : failed to allocate memory for NV", __func__);
1164 return VOS_STATUS_E_NOMEM;
1165 }
1166
1167 memset(pnvData, 0, sizeof(sHalNv));
1168
1169 /// Data starts from offset of validity bit map + magic number..
1170 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
1171
1172 status = nvParser(&pnvEncodedBuf[dataOffset],
1173 (nvReadBufSize-dataOffset), pnvData);
1174
1175 ///ignore validity bit map
1176 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
1177
1178 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
1179 nvReadEncodeBufSize);
1180
Leo Chang80de3c22013-11-26 10:52:12 -08001181 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001182 "readEncodeBufSize %d",nvReadEncodeBufSize);
1183
1184 if (VOS_STATUS_SUCCESS == status) {
1185 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1186 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
1187 pnvData->fields.productId,
1188 pnvData->fields.couplerType,
1189 pnvData->fields.wlanNvRevId);
1190
1191 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
1192
1193 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
1194 }
1195 else
1196 {
1197 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1198 "nvParser failed %d",status);
1199
1200 nvReadBufSize = 0;
1201
1202 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
1203
1204 nvReadEncodeBufSize = sizeof(sHalNv);
1205 }
Leo Chang80de3c22013-11-26 10:52:12 -08001206 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1207
1208 /* NV verion is NV3 */
1209 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V3;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001210 }
1211 else
1212 {
Leo Chang80de3c22013-11-26 10:52:12 -08001213 bufSize = sizeof(nvEFSTableV2_t);
1214
1215 /*Copying the NV defaults */
1216 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1217 /* NV2 structure should be maintained to support NV_FTM */
1218 gnvEFSTableV2 = (nvEFSTableV2_t * )pnvEncodedBuf;
1219
1220 /* Size mismatch
1221 * NV 1 case, use default NV table */
1222 if (nvReadBufSize != bufSize)
1223 {
1224 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
1225 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1226 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
1227 nvReadBufSize, bufSize);
1228 return VOS_STATUS_SUCCESS;
1229 }
1230
1231 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallif5c12a02014-02-25 16:50:40 +05301232 "NV_2: readBufferSize %u, EFSV2DefaultSize %zu",
Leo Chang80de3c22013-11-26 10:52:12 -08001233 nvReadBufSize, sizeof(nvEFSTableV2_t));
1234
1235 /* From here, NV2 will be stored into NV3 structure */
1236 dataOffset = sizeof(v_U32_t);
1237 nvReadEncodeBufSize = sizeof(sHalNvV2);
1238 vos_mem_copy(pEncodedBuf,
1239 &pnvEncodedBuf[dataOffset],
1240 nvReadBufSize - dataOffset);
1241
1242#ifdef FEATURE_WLAN_CH144
1243 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1244 "Default NV2 size %zu", sizeof(nvDefaultsV2));
1245#else
1246 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1247 "Default NV2 size %zu", sizeof(nvDefaults));
1248#endif /* FEATURE_WLAN_CH144 */
1249 /* First assign value with NV default */
1250#ifdef FEATURE_WLAN_CH144
1251 vos_nv_parseV2bin((tANI_U8 *)&nvDefaultsV2,
1252 sizeof(sHalNvV2),
1253 &pnvEFSTable->halnv);
1254#else
1255 vos_nv_parseV2bin((tANI_U8 *)&nvDefaults,
1256 sizeof(sHalNvV2),
1257 &pnvEFSTable->halnv);
1258#endif /* FEATURE_WLAN_CH144 */
1259
1260 /* Actual update from NV.bin */
1261 vos_nv_parseV2bin(pEncodedBuf,
1262 nvReadEncodeBufSize,
1263 &pnvEFSTable->halnv);
1264
1265 vos_mem_copy((void *)&pnvEFSTable->nvValidityBitmap,
1266 pnvEncodedBuf, sizeof(v_U32_t));
1267 gnvEFSTable = pnvEFSTable;
1268
1269 /* NV verion is NV2 */
1270 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V2;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001271 }
1272
1273 if (NULL != pnvData)
1274 {
1275 vos_mem_free(pnvData);
1276 }
1277
1278 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001279 "INFO: NV version = %d is loaded, driver supports NV version = %d",
1280 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001281
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 /* Copying the read nv data to the globa NV EFS table */
1283 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001284 /* Version mismatch */
1285 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
1286 {
1287 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
1288 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
1289 {
1290 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001291 "INFO: Using Coupler Type field instead of FW Config table, "
1292 "make sure that this is intended or may impact performance.");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001293 }
Leo Chang80de3c22013-11-26 10:52:12 -08001294#ifdef FEATURE_WLAN_CH144
1295 else if ((WLAN_NV_VERSION == NV_VERSION_CH144_CONFIG) &&
1296 (((VosContextType*)(pVosContext))->nvVersion == E_NV_V2))
1297 {
1298 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001299 "INFO: Driver supports NV3 CH144 by default, "
1300 "NV2 is currently loaded, NV2 will be used.");
Leo Chang80de3c22013-11-26 10:52:12 -08001301 }
1302#endif /* FEATURE_WLAN_CH144 */
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001303 else
1304 {
1305 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001306 "INFO: NV loaded doesn't match with driver default NV, "
1307 "driver default NV will be used, may impact performance.");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001308
1309 return VOS_STATUS_SUCCESS;
1310 }
1311 }
1312
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001313 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001314 /* Copy the valid fields to the NV Global structure */
1315 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001316 VOS_STATUS_SUCCESS)
1317 {
1318 if (itemIsValid == VOS_TRUE) {
1319
1320 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
1321 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001322 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 }
1324 }
1325
Amar Singhalfddc28c2013-09-05 13:03:40 -07001326 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 VOS_STATUS_SUCCESS)
1328 {
1329 if (itemIsValid == VOS_TRUE)
1330 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001331 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
1333 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001334 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 }
1336 }
1337
Amar Singhalfddc28c2013-09-05 13:03:40 -07001338 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001339 VOS_STATUS_SUCCESS)
1340 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001341
Jeff Johnson295189b2012-06-20 16:38:30 -07001342 if (itemIsValid == VOS_TRUE)
1343 {
1344 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
1345 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
1346 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001347 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 }
1349 }
1350
Amar Singhalfddc28c2013-09-05 13:03:40 -07001351 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 VOS_STATUS_SUCCESS)
1353 {
1354 if (itemIsValid == VOS_TRUE)
1355 {
1356 if(vos_nv_read( VNV_DEFAULT_LOCATION,
1357 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
1358 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001359 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 }
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001361 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1362 if (NULL != pHddCtx)
1363 {
1364 if (!vos_mem_compare(pHddCtx->cfg_ini->overrideCountryCode,
1365 CFG_OVERRIDE_COUNTRY_CODE_DEFAULT, 3))
1366 {
Vinay Krishna Eranna22ebc0d2014-05-09 17:20:33 +05301367 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1368 ("Overriding NV Country(%c%c) from INI (%c%c)"),
1369 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
1370 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
1371 pHddCtx->cfg_ini->overrideCountryCode[0],
1372 pHddCtx->cfg_ini->overrideCountryCode[1]);
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001373 vos_mem_copy(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode,
1374 pHddCtx->cfg_ini->overrideCountryCode,
1375 3);
1376 }
1377 }
1378 else
1379 {
1380 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1381 ("Invalid pHddCtx pointer") );
1382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001383 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001384
1385 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 VOS_STATUS_SUCCESS)
1387 {
1388 if (itemIsValid == VOS_TRUE)
1389 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001390 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
1392 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001393 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 }
1395 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001396
1397 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 VOS_STATUS_SUCCESS)
1399 {
1400 if (itemIsValid == VOS_TRUE)
1401 {
1402 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
1403 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
1404 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001405 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 }
1407 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001408 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 VOS_STATUS_SUCCESS)
1410 {
1411 if (itemIsValid == VOS_TRUE)
1412 {
1413 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
1414 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
1415 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001416 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 }
1418 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001419
1420 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 VOS_STATUS_SUCCESS)
1422 {
1423 if (itemIsValid == VOS_TRUE)
1424 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001425 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
1426 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
1427 goto error;
1428 }
1429 }
1430
Amar Singhalfddc28c2013-09-05 13:03:40 -07001431 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001432 VOS_STATUS_SUCCESS)
1433 {
1434 if (itemIsValid == VOS_TRUE)
1435 {
1436 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
1437 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001438 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 }
1440 }
1441
Amar Singhalfddc28c2013-09-05 13:03:40 -07001442 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 VOS_STATUS_SUCCESS)
1444 {
1445 if (itemIsValid == VOS_TRUE)
1446 {
1447 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001448 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001450 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 }
1452 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001453 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001454 VOS_STATUS_SUCCESS)
1455 {
1456 if (itemIsValid == VOS_TRUE)
1457 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001458 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1459 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001461 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001462 }
1463 }
1464
Amar Singhalfddc28c2013-09-05 13:03:40 -07001465 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 VOS_STATUS_SUCCESS)
1467 {
1468 if (itemIsValid == VOS_TRUE)
1469 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001470 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1471 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001473 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001474 }
1475 }
1476
Amar Singhalfddc28c2013-09-05 13:03:40 -07001477 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001478 VOS_STATUS_SUCCESS)
1479 {
1480 if (itemIsValid == VOS_TRUE)
1481 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001482 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1483 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001485 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 }
1487 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001488 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001489 VOS_STATUS_SUCCESS)
1490 {
1491 if (itemIsValid == VOS_TRUE)
1492 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001493 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1494 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001495 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001496 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001497 }
1498 }
1499 }
1500
1501 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001502error:
1503 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001504 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001505 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001506}
1507
1508VOS_STATUS vos_nv_close(void)
1509{
1510 VOS_STATUS status = VOS_STATUS_SUCCESS;
1511 v_CONTEXT_t pVosContext= NULL;
1512 /*Get the global context */
1513 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1514 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1515 if ( !VOS_IS_STATUS_SUCCESS( status ))
1516 {
1517 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001518 "%s : vos_open failed",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 return VOS_STATUS_E_FAILURE;
1520 }
1521 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001522 vos_mem_free(pEncodedBuf);
1523 vos_mem_free(pDictFile);
1524
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 gnvEFSTable=NULL;
1526 return VOS_STATUS_SUCCESS;
1527}
Jeff Johnson295189b2012-06-20 16:38:30 -07001528
Jeff Johnson295189b2012-06-20 16:38:30 -07001529/**------------------------------------------------------------------------
1530 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1531 country codes
1532 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1533 country codes with paddings in the provided buffer
1534 \param pBuffer - pointer to buffer where supported country codes
1535 and paddings are encoded; this may be set to NULL
1536 if user wishes to query the required buffer size to
1537 get the country code list
1538 \param pBufferSize - this is the provided buffer size on input;
1539 this is the required or consumed buffer size on output
1540 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1541 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1542 the buffer is NULL or buffer size is
1543 sufficient
1544 \sa
1545 -------------------------------------------------------------------------*/
1546VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1547 v_SIZE_t paddingSize )
1548{
1549 v_SIZE_t providedBufferSize = *pBufferSize;
1550 int i;
1551 // pBufferSize now points to the required buffer size
1552 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1553 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1554 {
1555 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08001556 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001557 return VOS_STATUS_E_NOMEM;
1558 }
1559 for (i = 0; i < countryInfoTable.countryCount; i++)
1560 {
1561 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1562 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1563 }
1564 return VOS_STATUS_SUCCESS;
1565}
1566/**------------------------------------------------------------------------
1567 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1568 \param pTxAntennaCount - antenna count
1569 \return status of the NV read operation
1570 \sa
1571 -------------------------------------------------------------------------*/
1572VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1573{
1574 sNvFields fieldImage;
1575 VOS_STATUS status;
1576 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1577 sizeof(fieldImage) );
1578 if (VOS_STATUS_SUCCESS == status)
1579 {
1580 *pTxAntennaCount = fieldImage.numOfTxChains;
1581 }
1582 return status;
1583}
1584/**------------------------------------------------------------------------
1585 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1586 \param pRxAntennaCount - antenna count
1587 \return status of the NV read operation
1588 \sa
1589 -------------------------------------------------------------------------*/
1590VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1591{
1592 sNvFields fieldImage;
1593 VOS_STATUS status;
1594 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1595 sizeof(fieldImage) );
1596 if (VOS_STATUS_SUCCESS == status)
1597 {
1598 *pRxAntennaCount = fieldImage.numOfRxChains;
1599 }
1600 return status;
1601}
1602
1603/**------------------------------------------------------------------------
1604 \brief vos_nv_readMacAddress() - return the MAC address
1605 \param pMacAddress - MAC address
1606 \return status of the NV read operation
1607 \sa
1608 -------------------------------------------------------------------------*/
1609VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1610{
1611 sNvFields fieldImage;
1612 VOS_STATUS status;
1613 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1614 sizeof(fieldImage) );
1615 if (VOS_STATUS_SUCCESS == status)
1616 {
1617 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1618 }
1619 else
1620 {
1621 //This part of the code can be removed when NV is programmed
1622 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1623 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
Arif Hussaina7c8e412013-11-20 11:06:42 -08001624 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1625 "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR,
1626 MAC_ADDR_ARRAY(macAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 status = VOS_STATUS_SUCCESS;
1628 }
1629 return status;
1630}
1631
1632/**------------------------------------------------------------------------
1633
1634 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1635
1636 \param pMacAddress - MAC address
1637 \param macCount - Count of valid MAC addresses to get from NV field
1638
1639 \return status of the NV read operation
1640
1641 \sa
1642
1643 -------------------------------------------------------------------------*/
1644VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1645 v_U8_t macCount )
1646{
1647 sNvFields fieldImage;
1648 VOS_STATUS status;
1649 v_U8_t countLoop;
1650 v_U8_t *pNVMacAddress;
1651
1652 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1653 (NULL == pMacAddress))
1654 {
1655 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301656 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001657 macCount, pMacAddress);
1658 }
1659
1660 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1661 sizeof(fieldImage) );
1662 if (VOS_STATUS_SUCCESS == status)
1663 {
1664 pNVMacAddress = fieldImage.macAddr;
1665 for(countLoop = 0; countLoop < macCount; countLoop++)
1666 {
1667 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1668 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1669 VOS_MAC_ADDRESS_LEN);
1670 }
1671 }
1672 else
1673 {
1674 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1675 "vos_nv_readMultiMacAddress Get NV Field Fail");
1676 }
1677
1678 return status;
1679}
1680
1681/**------------------------------------------------------------------------
1682 \brief vos_nv_setValidity() - set the validity of an NV item.
1683 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1684 validity information is stored in NV memory.
1685 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1686 An item becomes valid when one has written to it successfully.
1687 \param type - NV item type
1688 \param itemIsValid - boolean value indicating the item's validity
1689 \return VOS_STATUS_SUCCESS - validity is set successfully
1690 VOS_STATUS_E_INVAL - one of the parameters is invalid
1691 VOS_STATUS_E_FAILURE - unknown error
1692 \sa
1693 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001694
1695VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1696{
1697 v_U32_t lastNvValidityBitmap;
1698 v_U32_t newNvValidityBitmap;
1699 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001700
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001702 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001703 {
1704 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001705 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 return VOS_STATUS_E_INVAL;
1707 }
1708 // read the validity bitmap
1709 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1710 // modify the validity bitmap
1711 if (itemIsValid)
1712 {
1713 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1714 // commit to NV store if bitmap has been modified
1715 if (newNvValidityBitmap != lastNvValidityBitmap)
1716 {
1717 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1718 }
1719 }
1720 else
1721 {
1722 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1723 if (newNvValidityBitmap != lastNvValidityBitmap)
1724 {
1725 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1726 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1727 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001728 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 status = VOS_STATUS_E_FAULT;
1730 }
1731 }
1732 }
1733
1734 return status;
1735}
Jeff Johnson295189b2012-06-20 16:38:30 -07001736/**------------------------------------------------------------------------
1737 \brief vos_nv_getValidity() - get the validity of an NV item.
1738 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1739 validity information is stored in NV memory.
1740 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1741 An item becomes valid when one has written to it successfully.
1742 \param type - NV item type
1743 \param pItemIsValid- pointer to the boolean value indicating the item's
1744 validity
1745 \return VOS_STATUS_SUCCESS - validity is determined successfully
1746 VOS_STATUS_E_INVAL - one of the parameters is invalid
1747 VOS_STATUS_E_FAILURE - unknown error
1748 \sa
1749 -------------------------------------------------------------------------*/
1750VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1751{
1752 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1753 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001754 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001755 {
1756 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001757 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001758 return VOS_STATUS_E_INVAL;
1759 }
1760 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1761 return VOS_STATUS_SUCCESS;
1762}
1763/**------------------------------------------------------------------------
1764 \brief vos_nv_read() - read a NV item to an output buffer
1765 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1766 an array, this function would read the entire array. One would get a
1767 VOS_STATUS_E_EXISTS error when reading an invalid item.
1768 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1769 if a default buffer is provided (with a non-NULL value),
1770 the default buffer content is copied to the output buffer.
1771 \param type - NV item type
1772 \param outputBuffer - output buffer
1773 \param defaultBuffer - default buffer
1774 \param bufferSize - output buffer size
1775 \return VOS_STATUS_SUCCESS - NV item is read successfully
1776 VOS_STATUS_E_INVAL - one of the parameters is invalid
1777 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1778 VOS_STATUS_E_EXISTS - NV type is unsupported
1779 VOS_STATUS_E_FAILURE - unknown error
1780 \sa
1781 -------------------------------------------------------------------------*/
1782VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1783 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1784{
1785 VOS_STATUS status = VOS_STATUS_SUCCESS;
1786 v_SIZE_t itemSize;
1787 v_BOOL_t itemIsValid = VOS_TRUE;
1788
Amar Singhala49cbc52013-10-08 18:37:44 -07001789 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001790 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 {
1792 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001793 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 return VOS_STATUS_E_INVAL;
1795 }
1796 if (NULL == outputVoidBuffer)
1797 {
1798 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001799 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 return VOS_STATUS_E_FAULT;
1801 }
1802 if (0 == bufferSize)
1803 {
1804 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001805 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 return VOS_STATUS_E_INVAL;
1807 }
1808 // check if the NV item has valid data
1809 status = vos_nv_getValidity( type, &itemIsValid );
1810 if (!itemIsValid)
1811 {
1812 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08001813 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001814 return VOS_STATUS_E_EMPTY;
1815 }
1816 switch(type)
1817 {
1818 case VNV_FIELD_IMAGE:
1819 itemSize = sizeof(gnvEFSTable->halnv.fields);
1820 if(bufferSize != itemSize) {
1821 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001822 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 itemSize);
1824 status = VOS_STATUS_E_INVAL;
1825 }
1826 else {
1827 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1828 }
1829 break;
1830 case VNV_RATE_TO_POWER_TABLE:
1831 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1832 if(bufferSize != itemSize) {
1833 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001834 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001835 itemSize);
1836 status = VOS_STATUS_E_INVAL;
1837 }
1838 else {
1839 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1840 }
1841 break;
1842 case VNV_REGULARTORY_DOMAIN_TABLE:
1843 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1844 if(bufferSize != itemSize) {
1845 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001846 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 itemSize);
1848 status = VOS_STATUS_E_INVAL;
1849 }
1850 else {
1851 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1852 }
1853 break;
1854 case VNV_DEFAULT_LOCATION:
1855 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1856 if(bufferSize != itemSize) {
1857 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001858 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 itemSize);
1860 status = VOS_STATUS_E_INVAL;
1861 }
1862 else {
1863 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1864 }
1865 break;
1866 case VNV_TPC_POWER_TABLE:
1867 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1868 if(bufferSize != itemSize) {
1869 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001870 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001871 itemSize);
1872 status = VOS_STATUS_E_INVAL;
1873 }
1874 else {
1875 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1876 }
1877 break;
1878 case VNV_TPC_PDADC_OFFSETS:
1879 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1880 if(bufferSize != itemSize) {
1881 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001882 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 itemSize);
1884 status = VOS_STATUS_E_INVAL;
1885 }
1886 else {
1887 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1888 }
1889 break;
1890 case VNV_RSSI_CHANNEL_OFFSETS:
1891
1892 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1893
1894 if(bufferSize != itemSize) {
1895
1896 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001897 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001898 itemSize);
1899 status = VOS_STATUS_E_INVAL;
1900 }
1901 else {
1902 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1903 }
1904 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001905 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001906
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001907 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001908
1909 if(bufferSize != itemSize) {
1910
1911 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001912 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 itemSize);
1914 status = VOS_STATUS_E_INVAL;
1915 }
1916 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001917 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1918 }
1919 break;
1920 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001921
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001922 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001923
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001924 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001925
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001926 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001927 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001928 itemSize);
1929 status = VOS_STATUS_E_INVAL;
1930 }
1931 else {
1932 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001933 }
1934 break;
1935 case VNV_ANTENNA_PATH_LOSS:
1936 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1937 if(bufferSize != itemSize) {
1938 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001939 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 itemSize);
1941 status = VOS_STATUS_E_INVAL;
1942 }
1943 else {
1944 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1945 }
1946 break;
1947 case VNV_PACKET_TYPE_POWER_LIMITS:
1948 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1949 if(bufferSize != itemSize) {
1950 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001951 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 itemSize);
1953 status = VOS_STATUS_E_INVAL;
1954 }
1955 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001956 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 }
1958 break;
1959 case VNV_OFDM_CMD_PWR_OFFSET:
1960 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1961 if(bufferSize != itemSize) {
1962 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001963 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 itemSize);
1965 status = VOS_STATUS_E_INVAL;
1966 }
1967 else {
1968 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1969 }
1970 break;
1971 case VNV_TX_BB_FILTER_MODE:
1972 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1973 if(bufferSize != itemSize) {
1974 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001975 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 itemSize);
1977 status = VOS_STATUS_E_INVAL;
1978 }
1979 else {
1980 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1981 }
1982 break;
1983
Jeff Johnson295189b2012-06-20 16:38:30 -07001984
1985 case VNV_TABLE_VIRTUAL_RATE:
1986 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1987 if(bufferSize != itemSize) {
1988 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001989 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 itemSize);
1991 status = VOS_STATUS_E_INVAL;
1992 }
1993 else {
1994 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1995 }
1996 break;
1997
1998 default:
1999 break;
2000 }
2001 return status;
2002}
Jeff Johnson295189b2012-06-20 16:38:30 -07002003
2004/**------------------------------------------------------------------------
2005 \brief vos_nv_write() - write to a NV item from an input buffer
2006 The \a vos_nv_write() writes to a NV item from an input buffer. This would
2007 validate the NV item if the write operation is successful.
Leo Chang80de3c22013-11-26 10:52:12 -08002008 NV2 dedicated operation
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 \param type - NV item type
2010 \param inputBuffer - input buffer
2011 \param inputBufferSize - input buffer size
2012 \return VOS_STATUS_SUCCESS - NV item is read successfully
2013 VOS_STATUS_E_INVAL - one of the parameters is invalid
2014 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
2015 VOS_STATUS_E_EXISTS - NV type is unsupported
2016 VOS_STATUS_E_FAILURE - unknown error
2017 \sa
2018 -------------------------------------------------------------------------*/
Leo Chang80de3c22013-11-26 10:52:12 -08002019VOS_STATUS vos_nv_write(VNV_TYPE type, v_VOID_t *inputVoidBuffer,
2020 v_SIZE_t bufferSize)
Jeff Johnson295189b2012-06-20 16:38:30 -07002021{
2022 VOS_STATUS status = VOS_STATUS_SUCCESS;
2023 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07002024
Amar Singhala49cbc52013-10-08 18:37:44 -07002025 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07002026 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 {
Leo Chang80de3c22013-11-26 10:52:12 -08002028 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2029 "%s: invalid type=%d", __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 return VOS_STATUS_E_INVAL;
2031 }
2032 if (NULL == inputVoidBuffer)
2033 {
Leo Chang80de3c22013-11-26 10:52:12 -08002034 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2035 "Buffer provided is NULL");
Jeff Johnson295189b2012-06-20 16:38:30 -07002036 return VOS_STATUS_E_FAULT;
2037 }
2038 if (0 == bufferSize)
2039 {
Leo Chang80de3c22013-11-26 10:52:12 -08002040 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2041 "NV type=%d is invalid", type);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 return VOS_STATUS_E_INVAL;
2043 }
Leo Chang80de3c22013-11-26 10:52:12 -08002044
2045 switch (type)
Jeff Johnson295189b2012-06-20 16:38:30 -07002046 {
2047 case VNV_FIELD_IMAGE:
Leo Chang80de3c22013-11-26 10:52:12 -08002048 itemSize = sizeof(gnvEFSTableV2->halnvV2.fields);
2049 if (bufferSize != itemSize)
2050 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002051 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002052 "type = %d buffer size=%d is less than data size=%d",
2053 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 status = VOS_STATUS_E_INVAL;
2055 }
Leo Chang80de3c22013-11-26 10:52:12 -08002056 else
2057 {
2058 memcpy(&gnvEFSTableV2->halnvV2.fields,
2059 inputVoidBuffer,
2060 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002061 }
2062 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002063
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 case VNV_RATE_TO_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002065 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum);
2066 if (bufferSize != itemSize)
2067 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002068 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002069 "type = %d buffer size=%d is less than data size=%d",
2070 type, bufferSize,itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 status = VOS_STATUS_E_INVAL;
2072 }
Leo Chang80de3c22013-11-26 10:52:12 -08002073 else
2074 {
2075 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum[0],
2076 inputVoidBuffer,
2077 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002078 }
2079 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002080
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 case VNV_REGULARTORY_DOMAIN_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002082 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.regDomains);
2083 if (bufferSize != itemSize)
2084 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002086 "type = %d buffer size=%d is less than data size=%d",
2087 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002088 status = VOS_STATUS_E_INVAL;
2089 }
Leo Chang80de3c22013-11-26 10:52:12 -08002090 else
2091 {
2092 memcpy(&gnvEFSTableV2->halnvV2.tables.regDomains[0],
2093 inputVoidBuffer,
2094 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 }
2096 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002097
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 case VNV_DEFAULT_LOCATION:
Leo Chang80de3c22013-11-26 10:52:12 -08002099 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.defaultCountryTable);
2100 if (bufferSize != itemSize)
2101 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002102 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002103 "type = %d buffer size=%d is less than data size=%d",
2104 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002105 status = VOS_STATUS_E_INVAL;
2106 }
Leo Chang80de3c22013-11-26 10:52:12 -08002107 else
2108 {
2109 memcpy(&gnvEFSTableV2->halnvV2.tables.defaultCountryTable,
2110 inputVoidBuffer,
2111 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002112 }
2113 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002114
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 case VNV_TPC_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002116 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutCharacterized);
2117 if (bufferSize != itemSize)
2118 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002119 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002120 "type = %d buffer size=%d is less than data size=%d",
2121 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 status = VOS_STATUS_E_INVAL;
2123 }
Leo Chang80de3c22013-11-26 10:52:12 -08002124 else
2125 {
2126 memcpy(&gnvEFSTableV2->halnvV2.tables.plutCharacterized[0],
2127 inputVoidBuffer,
2128 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 }
2130 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002131
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 case VNV_TPC_PDADC_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002133 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutPdadcOffset);
2134 if (bufferSize != itemSize)
2135 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002137 "type = %d buffer size=%d is less than data size=%d",
2138 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 status = VOS_STATUS_E_INVAL;
2140 }
Leo Chang80de3c22013-11-26 10:52:12 -08002141 else
2142 {
2143 memcpy(&gnvEFSTableV2->halnvV2.tables.plutPdadcOffset[0],
2144 inputVoidBuffer,
2145 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 }
2147 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002148
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 case VNV_RSSI_CHANNEL_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002150 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.rssiChanOffsets);
2151 if (bufferSize != itemSize)
2152 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002154 "type = %d buffer size=%d is less than data size=%d",
2155 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 status = VOS_STATUS_E_INVAL;
2157 }
Leo Chang80de3c22013-11-26 10:52:12 -08002158 else
2159 {
2160 memcpy(&gnvEFSTableV2->halnvV2.tables.rssiChanOffsets[0],
2161 inputVoidBuffer,
2162 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002163 }
2164 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002165
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002166 case VNV_HW_CAL_VALUES:
Leo Chang80de3c22013-11-26 10:52:12 -08002167 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.hwCalValues);
2168 if (bufferSize != itemSize)
2169 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002171 "type = %d buffer size=%d is less than data size=%d",
2172 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 status = VOS_STATUS_E_INVAL;
2174 }
Leo Chang80de3c22013-11-26 10:52:12 -08002175 else
2176 {
2177 memcpy(&gnvEFSTableV2->halnvV2.tables.hwCalValues,
2178 inputVoidBuffer,
2179 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 }
2181 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002182
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002183 case VNV_FW_CONFIG:
Leo Chang80de3c22013-11-26 10:52:12 -08002184 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.fwConfig);
2185 if (bufferSize != itemSize)
2186 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002187 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002188 "type = %d buffer size=%d is less than data size=%d",
2189 type, bufferSize, itemSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002190 status = VOS_STATUS_E_INVAL;
2191 }
Leo Chang80de3c22013-11-26 10:52:12 -08002192 else
2193 {
2194 memcpy(&gnvEFSTableV2->halnvV2.tables.fwConfig,
2195 inputVoidBuffer,
2196 bufferSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002197 }
2198 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002199
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 case VNV_ANTENNA_PATH_LOSS:
Leo Chang80de3c22013-11-26 10:52:12 -08002201 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.antennaPathLoss);
2202 if (bufferSize != itemSize)
2203 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002205 "type = %d buffer size=%d is less than data size=%d",
2206 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002207 status = VOS_STATUS_E_INVAL;
2208 }
Leo Chang80de3c22013-11-26 10:52:12 -08002209 else
2210 {
2211 memcpy(&gnvEFSTableV2->halnvV2.tables.antennaPathLoss[0],
2212 inputVoidBuffer,
2213 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 }
2215 break;
2216
2217 case VNV_PACKET_TYPE_POWER_LIMITS:
Leo Chang80de3c22013-11-26 10:52:12 -08002218 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits);
2219 if (bufferSize != itemSize)
2220 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002222 "type = %d buffer size=%d is less than data size=%d",
2223 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 status = VOS_STATUS_E_INVAL;
2225 }
Leo Chang80de3c22013-11-26 10:52:12 -08002226 else
2227 {
2228 memcpy(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits,
2229 inputVoidBuffer,
2230 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 }
2232 break;
2233
2234 case VNV_OFDM_CMD_PWR_OFFSET:
Leo Chang80de3c22013-11-26 10:52:12 -08002235 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset);
2236 if (bufferSize != itemSize)
2237 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002238 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002239 "type = %d buffer size=%d is less than data size=%d",
2240 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 status = VOS_STATUS_E_INVAL;
2242 }
Leo Chang80de3c22013-11-26 10:52:12 -08002243 else
2244 {
2245 memcpy(&gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset,
2246 inputVoidBuffer,
2247 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 }
2249 break;
2250
2251 case VNV_TX_BB_FILTER_MODE:
Leo Chang80de3c22013-11-26 10:52:12 -08002252 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.txbbFilterMode);
2253 if (bufferSize != itemSize)
2254 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002256 "type = %d buffer size=%d is less than data size=%d",
2257 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002258 status = VOS_STATUS_E_INVAL;
2259 }
Leo Chang80de3c22013-11-26 10:52:12 -08002260 else
2261 {
2262 memcpy(&gnvEFSTableV2->halnvV2.tables.txbbFilterMode,
2263 inputVoidBuffer,
2264 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002265 }
2266 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002267
Jeff Johnson295189b2012-06-20 16:38:30 -07002268 case VNV_TABLE_VIRTUAL_RATE:
Leo Chang80de3c22013-11-26 10:52:12 -08002269 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate);
2270 if (bufferSize != itemSize)
2271 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002272 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002273 "type = %d buffer size=%d is less than data size=%d",
2274 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 status = VOS_STATUS_E_INVAL;
2276 }
Leo Chang80de3c22013-11-26 10:52:12 -08002277 else
2278 {
2279 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate,
2280 inputVoidBuffer,
2281 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 }
2283 break;
2284
2285 default:
2286 break;
2287 }
Leo Chang80de3c22013-11-26 10:52:12 -08002288
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 if (VOS_STATUS_SUCCESS == status)
2290 {
2291 // set NV item to have valid data
Leo Chang80de3c22013-11-26 10:52:12 -08002292 status = vos_nv_setValidity(type, VOS_TRUE);
2293 if (! VOS_IS_STATUS_SUCCESS(status))
2294 {
2295 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2296 "vos_nv_setValidity failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002297 status = VOS_STATUS_E_FAULT;
2298 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002299
Arif Hussaine46afe12014-02-14 11:55:42 -08002300 status = wlan_write_to_efs((v_U8_t*)gnvEFSTableV2, sizeof(*gnvEFSTableV2));
Leo Chang80de3c22013-11-26 10:52:12 -08002301 if (!VOS_IS_STATUS_SUCCESS(status))
2302 {
2303 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2304 "vos_nv_write_to_efs failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 status = VOS_STATUS_E_FAULT;
2306 }
2307 }
Leo Chang80de3c22013-11-26 10:52:12 -08002308
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 return status;
2310}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08002311
Jeff Johnson295189b2012-06-20 16:38:30 -07002312/**------------------------------------------------------------------------
2313 \brief vos_nv_getChannelListWithPower() - function to return the list of
2314 supported channels with the power limit info too.
2315 \param pChannels20MHz - list of 20 Mhz channels
2316 \param pNum20MHzChannelsFound - number of 20 Mhz channels
2317 \param pChannels40MHz - list of 20 Mhz channels
2318 \param pNum40MHzChannelsFound - number of 20 Mhz channels
2319 \return status of the NV read operation
2320 \Note: 40Mhz not currently supported
2321 \sa
2322 -------------------------------------------------------------------------*/
2323VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
2324 tANI_U8 *num20MHzChannelsFound,
2325 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
2326 tANI_U8 *num40MHzChannelsFound
2327 )
2328{
2329 VOS_STATUS status = VOS_STATUS_SUCCESS;
2330 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002331
Jeff Johnson295189b2012-06-20 16:38:30 -07002332 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
2333 // or pass it as a parameter to NV from SME?
2334
2335 if( channels20MHz && num20MHzChannelsFound )
2336 {
2337 count = 0;
2338 for( i = 0; i <= RF_CHAN_14; i++ )
2339 {
2340 if( regChannels[i].enabled )
2341 {
2342 channels20MHz[count].chanId = rfChannels[i].channelNum;
2343 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2344 }
2345 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2347 {
2348 if( regChannels[i].enabled )
2349 {
2350 channels20MHz[count].chanId = rfChannels[i].channelNum;
2351 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2352 }
2353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 *num20MHzChannelsFound = (tANI_U8)count;
2355 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002356
2357 if( channels40MHz && num40MHzChannelsFound )
2358 {
2359 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002360 //center channels for 2.4 Ghz 40 MHz channels
2361 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
2362 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002363
Jeff Johnsone7245742012-09-05 17:12:55 -07002364 if( regChannels[i].enabled )
2365 {
2366 channels40MHz[count].chanId = rfChannels[i].channelNum;
2367 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2368 }
2369 }
2370 //center channels for 5 Ghz 40 MHz channels
2371 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
2372 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002373
Jeff Johnsone7245742012-09-05 17:12:55 -07002374 if( regChannels[i].enabled )
2375 {
2376 channels40MHz[count].chanId = rfChannels[i].channelNum;
2377 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2378 }
2379 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002380 *num40MHzChannelsFound = (tANI_U8)count;
2381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002382 return (status);
2383}
2384
2385/**------------------------------------------------------------------------
2386 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
2387 \return default regulatory domain
2388 \sa
2389 -------------------------------------------------------------------------*/
2390
2391v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
2392{
2393 return countryInfoTable.countryInfo[0].regDomain;
2394}
2395
2396/**------------------------------------------------------------------------
2397 \brief vos_nv_getSupportedChannels() - function to return the list of
2398 supported channels
2399 \param p20MhzChannels - list of 20 Mhz channels
2400 \param pNum20MhzChannels - number of 20 Mhz channels
2401 \param p40MhzChannels - list of 40 Mhz channels
2402 \param pNum40MhzChannels - number of 40 Mhz channels
2403 \return status of the NV read operation
2404 \Note: 40Mhz not currently supported
2405 \sa
2406 -------------------------------------------------------------------------*/
2407VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
2408 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
2409{
2410 VOS_STATUS status = VOS_STATUS_E_INVAL;
2411 int i, count = 0;
2412
2413 if( p20MhzChannels && pNum20MhzChannels )
2414 {
2415 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
2416 {
2417 for( i = 0; i <= RF_CHAN_14; i++ )
2418 {
2419 p20MhzChannels[count++] = rfChannels[i].channelNum;
2420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2422 {
2423 p20MhzChannels[count++] = rfChannels[i].channelNum;
2424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 status = VOS_STATUS_SUCCESS;
2426 }
2427 *pNum20MhzChannels = count;
2428 }
2429
2430 return (status);
2431}
2432
2433/**------------------------------------------------------------------------
2434 \brief vos_nv_readDefaultCountryTable() - return the default Country table
2435 \param table data - a union to return the default country table data in.
2436 \return status of the NV read operation
2437 \sa
2438 -------------------------------------------------------------------------*/
2439VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
2440{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002441
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002442 VOS_STATUS status = VOS_STATUS_SUCCESS;
2443 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
2444 pr_info("DefaultCountry is %c%c\n",
2445 tableData->defaultCountryTable.countryCode[0],
2446 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 return status;
2448}
2449
2450/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002451 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07002452 \param pBuffer - to return the buffer address
2453 pSize - buffer size.
2454 \return status of the NV read operation
2455 \sa
2456 -------------------------------------------------------------------------*/
2457VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2458{
Leo Chang80de3c22013-11-26 10:52:12 -08002459 eNvVersionType nvVersion;
2460
2461 nvVersion = vos_nv_getNvVersion();
2462
2463 if (E_NV_V3 == nvVersion)
2464 {
2465 /* Send the NV V3 structure and size */
2466 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
2467 *pSize = sizeof(sHalNv);
2468 }
2469 else if (E_NV_V2 == nvVersion)
2470 {
2471 /* Send the NV V2 structure and size */
2472 *pNvBuffer = (v_VOID_t *)(&gnvEFSTableV2->halnvV2);
2473 *pSize = sizeof(sHalNvV2);
2474 }
2475 else
2476 {
2477 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2478 "%s : Invalid NV version %d", __func__, nvVersion);
2479 return VOS_STATUS_E_INVAL;
2480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002481
2482 return VOS_STATUS_SUCCESS;
2483}
2484
Jeff Johnson295189b2012-06-20 16:38:30 -07002485/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002486 \brief vos_nv_getBuffer -
2487 \param pBuffer - to return the buffer address
2488 pSize - buffer size.
2489 \return status of the NV read operation
2490 \sa
2491 -------------------------------------------------------------------------*/
2492VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2493{
2494 /* Send the NV structure and size */
Leo Changb1eb8812013-12-30 11:51:44 -08002495 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
2496 *pSize = nvReadEncodeBufSize;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002497 return VOS_STATUS_SUCCESS;
2498}
2499
2500
2501VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2502{
2503 /* Send the NV structure and size */
2504 *pNvBuffer = (v_VOID_t *)(pDictFile);
2505 *pSize = nDictionarySize;
2506
2507 return VOS_STATUS_SUCCESS;
2508}
2509
2510VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
2511{
2512 if (MAGIC_NUMBER == magicNumber)
2513 {
2514 return VOS_STATUS_SUCCESS;
2515 }
2516
2517 return VOS_STATUS_E_FAILURE;
2518}
2519
2520VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
2521{
2522 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2523 (size-sizeof(v_U32_t)));
2524
2525 return VOS_STATUS_SUCCESS;
2526}
2527
2528/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002529 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 \param rfChannel - input channel enum to know evabled state
2531 \return eNVChannelEnabledType enabled state for channel
2532 * enabled
2533 * disabled
2534 * DFS
2535 \sa
2536 -------------------------------------------------------------------------*/
2537eNVChannelEnabledType vos_nv_getChannelEnabledState
2538(
2539 v_U32_t rfChannel
2540)
2541{
2542 v_U32_t channelLoop;
2543 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2544
2545 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2546 {
2547 if(rfChannels[channelLoop].channelNum == rfChannel)
2548 {
2549 channelEnum = (eRfChannels)channelLoop;
2550 break;
2551 }
2552 }
2553
2554 if(INVALID_RF_CHANNEL == channelEnum)
2555 {
2556 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002557 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 return NV_CHANNEL_INVALID;
2559 }
2560
2561 return regChannels[channelEnum].enabled;
2562}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002563
Leo Chang80de3c22013-11-26 10:52:12 -08002564/**------------------------------------------------------------------------
2565 \brief vos_nv_getNvVersion -
2566 \param NONE
2567 \return eNvVersionType NV.bin version
2568 * E_NV_V2
2569 * E_NV_V3
2570 * E_NV_INVALID
2571 \sa
2572 -------------------------------------------------------------------------*/
2573eNvVersionType vos_nv_getNvVersion
2574(
2575 void
2576)
2577{
2578 VosContextType *vosCtxt = NULL;
2579
2580 vosCtxt = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2581 if (vosCtxt)
2582 {
2583 return vosCtxt->nvVersion;
2584 }
2585
2586 return E_NV_INVALID;
2587}
2588
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002589/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002590 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002591*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002592
2593static int bw20_ch_index_to_bw40_ch_index(int k)
2594{
2595 int m = -1;
2596 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2597 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002598 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2599 if (m > RF_CHAN_BOND_11)
2600 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002601 }
2602 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2603 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002604 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2605 if (m > RF_CHAN_BOND_214)
2606 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002607 }
2608 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2609 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002610 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2611 if (m > RF_CHAN_BOND_62)
2612 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002613 }
Leo Chang80de3c22013-11-26 10:52:12 -08002614#ifdef FEATURE_WLAN_CH144
2615 else if (k >= RF_CHAN_100 && k <= RF_CHAN_144)
2616#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002617 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
Leo Chang80de3c22013-11-26 10:52:12 -08002618#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002619 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002620 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
Leo Chang80de3c22013-11-26 10:52:12 -08002621#ifdef FEATURE_WLAN_CH144
2622 if (m > RF_CHAN_BOND_142)
2623 m = RF_CHAN_BOND_142;
2624#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002625 if (m > RF_CHAN_BOND_138)
2626 m = RF_CHAN_BOND_138;
Leo Chang80de3c22013-11-26 10:52:12 -08002627#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002628 }
2629 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2630 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002631 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2632 if (m > RF_CHAN_BOND_163)
2633 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002634 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002635return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002636}
2637
Amar Singhala49cbc52013-10-08 18:37:44 -07002638void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002639{
Amar Singhala49cbc52013-10-08 18:37:44 -07002640 int k;
2641 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2642 countryCode[0], countryCode[1], domain_id);
2643 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2644 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2645 NV_CHANNEL_ENABLE;
2646 /* Max Tx Power 20dBm */
2647 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2648 }
2649 /* enable ch 12 to ch 14 passive scan */
2650 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2651 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2652 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2653 NV_CHANNEL_DFS;
2654 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2655 }
2656 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2657 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2658 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2659 NV_CHANNEL_DFS;
2660 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2661 }
2662#ifdef PASSIVE_SCAN_4_9GHZ
2663 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2664 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2665 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2666 NV_CHANNEL_DFS;
2667 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2668 }
2669#endif
2670 if (domain_id == NUM_REG_DOMAINS-1)
2671 { /* init time */
2672 crda_alpha2[0] = countryCode[0];
2673 crda_alpha2[1] = countryCode[1];
2674 crda_regulatory_entry_valid = VOS_TRUE;
2675 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2676 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2677 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2678 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2679 }
2680 if (domain_id == NUM_REG_DOMAINS-2)
2681 { /* none-default country */
2682 run_time_alpha2[0] = countryCode[0];
2683 run_time_alpha2[1] = countryCode[1];
2684 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2685 }
2686}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002687
Amar Singhala49cbc52013-10-08 18:37:44 -07002688static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2689 struct regulatory_request *request,
2690 v_U8_t nBandCapability,
2691 int domain_id)
2692{
2693 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2694 pr_info("Country 00 special handling to enable passive scan.\n");
2695 crda_regulatory_entry_default(request->alpha2, domain_id);
2696 }
2697 return 0;
2698}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002699
Amar Singhala49cbc52013-10-08 18:37:44 -07002700/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2701static int create_crda_regulatory_entry(struct wiphy *wiphy,
2702 struct regulatory_request *request,
2703 v_U8_t nBandCapability)
2704{
2705 int i, j, m;
2706 int k = 0, n = 0;
2707
2708 if (run_time_alpha2[0]==request->alpha2[0] &&
2709 run_time_alpha2[1]==request->alpha2[1] &&
2710 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2711 return 0; /* already created */
2712
2713 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002714 if (nBandCapability == eCSR_BAND_24)
2715 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002716 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002717 {
2718 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2719 continue;
2720 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2721 continue;
2722 if (wiphy->bands[i] == NULL)
2723 {
2724 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2725 return -1;
2726 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002727 // internal channels[] is one continous array for both 2G and 5G bands
2728 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002729 if (i == 0)
2730 m = 0;
2731 else
2732 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002733 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002734 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002735 // k = (m + j) is internal current channel index for 20MHz channel
2736 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002737 k = m + j;
2738 n = bw20_ch_index_to_bw40_ch_index(k);
2739 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002740 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002741 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2742 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002743 if (pnvEFSTable == NULL)
2744 {
2745 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2746 return -1;
2747 }
2748 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2749 NV_CHANNEL_DISABLE;
2750 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2751 NV_CHANNEL_DISABLE;
2752 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2753 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002754 }
2755 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2756 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002757 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2758 NV_CHANNEL_DFS;
2759 // max_power is in mBm = 100 * dBm
2760 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2761 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2762 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2763 {
2764 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2765 NV_CHANNEL_DFS;
2766 // 40MHz channel power is half of 20MHz (-3dB) ??
2767 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2768 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2769 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002770 }
2771 else // Enable is only last flag we support
2772 {
Manjunathappa Prakashde7b2a52014-02-28 16:59:03 -08002773#ifdef FEATURE_WLAN_CH144
2774 if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion()))
2775 {
2776 //Do not enable channel 144 when NV version is not NV3
2777 }
2778 else
2779#endif
2780 {
2781 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].\
2782 channels[k].enabled = NV_CHANNEL_ENABLE;
2783 }
2784
Amar Singhala49cbc52013-10-08 18:37:44 -07002785 // max_power is in dBm
2786 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2787 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2788 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2789 {
2790 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2791 NV_CHANNEL_ENABLE;
2792 // 40MHz channel power is half of 20MHz (-3dB) ??
2793 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2794 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2795 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002796 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002797 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2798 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002799 }
2800 }
2801 if (k == 0)
2802 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002803 run_time_alpha2[0] = request->alpha2[0];
2804 run_time_alpha2[1] = request->alpha2[1];
2805 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2806 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2807return 0;
2808}
Amar Singhal0d15bd52013-10-12 23:13:13 -07002809
2810
Amar Singhala49cbc52013-10-08 18:37:44 -07002811v_BOOL_t is_crda_regulatory_entry_valid(void)
2812{
2813return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002814}
2815
Amar Singhala49cbc52013-10-08 18:37:44 -07002816/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2817start freq + 10000 = center freq of the 20MHz start channel
2818end freq - 10000 = center freq of the 20MHz end channel
2819start freq + 20000 = center freq of the 40MHz start channel
2820end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002821*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002822static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002823{
Leo Chang80de3c22013-11-26 10:52:12 -08002824 int i;
2825 u32 center_freq = freq_khz + 10000;
2826
Amar Singhala49cbc52013-10-08 18:37:44 -07002827 //Has to compare from low freq to high freq
2828 //RF_SUBBAND_2_4_GHZ
2829 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2830 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2831 return i;
2832 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2833 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2834 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2835 return i;
2836 //RF_SUBBAND_5_LOW_GHZ
2837 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2838 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2839 return i;
2840 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002841#ifdef FEATURE_WLAN_CH144
2842 for (i=RF_CHAN_100;i<=RF_CHAN_144;i++)
2843#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002844 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002845#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002846 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2847 return i;
2848 //RF_SUBBAND_5_HIGH_GHZ
2849 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2850 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2851 return i;
2852return -1;
2853}
2854
2855static int bw20_end_freq_to_channel_index(u32 freq_khz)
2856{
Leo Chang80de3c22013-11-26 10:52:12 -08002857 int i;
2858 u32 center_freq = freq_khz - 10000;
2859
Amar Singhala49cbc52013-10-08 18:37:44 -07002860 //Has to compare from high freq to low freq
2861 //RF_SUBBAND_5_HIGH_GHZ
2862 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2863 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2864 return i;
2865 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002866#ifdef FEATURE_WLAN_CH144
2867 for (i=RF_CHAN_144;i>=RF_CHAN_100;i--)
2868#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002869 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002870#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002871 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2872 return i;
2873 //RF_SUBBAND_5_LOW_GHZ
2874 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2875 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2876 return i;
2877 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2878 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2879 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2880 return i;
2881 //RF_SUBBAND_2_4_GHZ
2882 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2883 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2884 return i;
Leo Chang80de3c22013-11-26 10:52:12 -08002885 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002886}
2887
2888static int bw40_start_freq_to_channel_index(u32 freq_khz)
2889{
Leo Chang80de3c22013-11-26 10:52:12 -08002890 int i;
2891 u32 center_freq = freq_khz + 20000;
2892
Amar Singhala49cbc52013-10-08 18:37:44 -07002893 //Has to compare from low freq to high freq
2894 //RF_SUBBAND_2_4_GHZ
2895 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2896 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2897 return i;
2898 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2899 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2900 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2901 return i;
2902 //RF_SUBBAND_5_LOW_GHZ
2903 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2904 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2905 return i;
2906 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002907#ifdef FEATURE_WLAN_CH144
2908 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_142;i++)
2909#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002910 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002911#endif /* RF_CHAN_BOND_142 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002912 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2913 return i;
2914 //RF_SUBBAND_5_HIGH_GHZ
2915 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2916 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2917 return i;
2918return -1;
2919}
2920
2921static int bw40_end_freq_to_channel_index(u32 freq_khz)
2922{
Leo Chang80de3c22013-11-26 10:52:12 -08002923 int i;
2924 u32 center_freq = freq_khz - 20000;
2925
Amar Singhala49cbc52013-10-08 18:37:44 -07002926 //Has to compare from high freq to low freq
2927 //RF_SUBBAND_5_HIGH_GHZ
2928 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2929 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2930 return i;
2931 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002932#ifdef FEATURE_WLAN_CH144
2933 for (i=RF_CHAN_BOND_142;i>=RF_CHAN_BOND_102;i--)
2934#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002935 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002936#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002937 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2938 return i;
2939 //RF_SUBBAND_5_LOW_GHZ
2940 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2941 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2942 return i;
2943 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2944 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2945 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2946 return i;
2947 //RF_SUBBAND_2_4_GHZ
2948 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2949 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2950 return i;
2951return -1;
2952}
2953
2954static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2955{
2956 switch (nBandCapability)
2957 {
2958 case eCSR_BAND_ALL:
2959 return VOS_TRUE;
2960 case eCSR_BAND_24:
2961 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2962 return VOS_TRUE;
2963 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2964 return VOS_TRUE; // 2.4G 40MHz channel
2965 break;
2966 case eCSR_BAND_5G:
2967 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2968 return VOS_TRUE;
2969 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2970 return VOS_TRUE; // 2.4G 40MHz channel
2971 break;
2972 default:
2973 break;
2974 }
2975 return VOS_FALSE;
2976}
2977
2978/* create_crda_regulatory_entry_from_regd should be called during init time */
2979static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2980 struct regulatory_request *request,
2981 v_U8_t nBandCapability)
2982{
2983 int i, j, n, domain_id;
2984 int bw20_start_channel_index, bw20_end_channel_index;
2985 int bw40_start_channel_index, bw40_end_channel_index;
2986
2987 if (wiphy == NULL || wiphy->regd == NULL)
2988 {
2989 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2990 return -1;
2991 }
2992 if (crda_regulatory_entry_valid == VOS_FALSE)
2993 domain_id = NUM_REG_DOMAINS-1; /* init time */
2994 else
2995 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2996 for (n = 0; n < NUM_RF_CHANNELS; n++)
2997 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2998
2999 for (i=0;i<wiphy->regd->n_reg_rules;i++)
3000 {
3001 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
3002 bw20_start_channel_index =
3003 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
3004 bw20_end_channel_index =
3005 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3006 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
3007 {
3008 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
3009 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3010 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3011 continue; // skip this rull, but continue to next rule
3012 }
3013 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3014 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3015 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3016 bw20_start_channel_index, bw20_end_channel_index);
3017 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
3018 {
3019 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3020 {
3021 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
3022 rfChannels[j].channelNum);
3023 continue; // skip this channel, continue to next
3024 }
3025 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3026 {
3027 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3028 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3029 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3030 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303031 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN)
3032 {
3033 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3034 wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3035 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3036 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003037 else
3038 {
3039 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3040 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3041 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3042 }
3043 /* max_eirp is in mBm (= 100 * dBm) unit */
3044 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3045 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
3046 }
3047 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
3048 real gain which should be provided by the real design */
3049 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
3050 {
3051 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
3052 bw40_start_channel_index =
3053 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
3054 bw40_end_channel_index =
3055 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3056 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
3057 {
3058 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
3059 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3060 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3061 continue; // skip this rull, but continue to next rule
3062 }
3063 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3064 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3065 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3066 bw40_start_channel_index, bw40_end_channel_index);
3067 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
3068 {
3069 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3070 continue; // skip this channel, continue to next
3071 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3072 {
3073 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3074 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
3075 }
3076 else
3077 {
3078 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3079 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
3080 }
3081 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
3082 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3083 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
3084 }
3085 }
3086 }
3087 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
3088 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
3089 these flags and has no implementation yet. */
3090 if (crda_regulatory_entry_valid == VOS_FALSE)
3091 { /* init time */
3092 crda_alpha2[0] = request->alpha2[0];
3093 crda_alpha2[1] = request->alpha2[1];
3094 crda_regulatory_entry_valid = VOS_TRUE;
3095 }
3096 else
3097 { /* none-default country */
3098 run_time_alpha2[0] = request->alpha2[0];
3099 run_time_alpha2[1] = request->alpha2[1];
3100 crda_regulatory_run_time_entry_valid = VOS_TRUE;
3101 }
3102 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
3103 return 0;
3104}
3105
Manjunathappa Prakash73fc1982014-02-03 13:14:11 -08003106/**------------------------------------------------------------------------
3107 \brief vos_chan_to_freq -
3108 \param - input channel number to know channel frequency
3109 \return Channel frequency
3110 \sa
3111 -------------------------------------------------------------------------*/
3112v_U16_t vos_chan_to_freq(v_U8_t chanNum)
3113{
3114 int i;
3115
3116 for (i = 0; i < NUM_RF_CHANNELS; i++)
3117 {
3118 if (rfChannels[i].channelNum == chanNum)
3119 {
3120 return rfChannels[i].targetFreq;
3121 }
3122 }
3123
3124 return (0);
3125}
3126
Amar Singhala49cbc52013-10-08 18:37:44 -07003127#ifdef CONFIG_ENABLE_LINUX_REG
3128
3129/**------------------------------------------------------------------------
3130 \brief vos_nv_setRegDomain -
3131 \param clientCtxt - Client Context, Not used for PRIMA
3132 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303133 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003134 \return status set REG domain operation
3135 \sa
3136 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303137VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3138 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003139{
3140
3141 if (regId >= REGDOMAIN_COUNT)
3142 {
3143 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3144 "VOS set reg domain, invalid REG domain ID %d", regId);
3145 return VOS_STATUS_E_INVAL;
3146 }
3147
3148 /* Set correct channel information based on REG Domain */
3149 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3150
3151 return VOS_STATUS_SUCCESS;
3152}
3153
3154/**------------------------------------------------------------------------
3155 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3156 a country given its country code
3157 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3158 a country given its country code. This is done from reading a cached
3159 copy of the binary file.
3160 \param pRegDomain - pointer to regulatory domain
3161 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303162 \param source - source of the country code
Amar Singhala49cbc52013-10-08 18:37:44 -07003163 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3164 VOS_STATUS_E_FAULT - invalid pointer error
3165 VOS_STATUS_E_EMPTY - country code table is empty
3166 VOS_STATUS_E_EXISTS - given country code does not exist in table
3167 \sa
3168 -------------------------------------------------------------------------*/
3169VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303170 const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source)
Amar Singhala49cbc52013-10-08 18:37:44 -07003171{
3172
Amar Singhalfddc28c2013-09-05 13:03:40 -07003173 v_CONTEXT_t pVosContext = NULL;
3174 hdd_context_t *pHddCtx = NULL;
3175 struct wiphy *wiphy = NULL;
3176 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07003177 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003178
Amar Singhalfddc28c2013-09-05 13:03:40 -07003179 /* sanity checks */
3180 if (NULL == pRegDomain)
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3183 ("Invalid reg domain pointer") );
3184 return VOS_STATUS_E_FAULT;
3185 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003186
Amar Singhalfddc28c2013-09-05 13:03:40 -07003187 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003188
Amar Singhala49cbc52013-10-08 18:37:44 -07003189 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003190 {
3191 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3192 ("Country code array is NULL"));
3193 return VOS_STATUS_E_FAULT;
3194 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003195
Amar Singhalfddc28c2013-09-05 13:03:40 -07003196 if (0 == countryInfoTable.countryCount)
3197 {
3198 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3199 ("Reg domain table is empty") );
3200 return VOS_STATUS_E_EMPTY;
3201 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003202
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003203
Amar Singhalfddc28c2013-09-05 13:03:40 -07003204 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003205
Amar Singhalfddc28c2013-09-05 13:03:40 -07003206 if (NULL != pVosContext)
3207 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3208 else
3209 return VOS_STATUS_E_EXISTS;
3210
3211 if (NULL == pHddCtx)
3212 {
3213 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3214 ("Invalid pHddCtx pointer") );
3215 return VOS_STATUS_E_FAULT;
3216 }
3217
Kiet Lam6c583332013-10-14 05:37:09 +05303218 temp_reg_domain = REGDOMAIN_COUNT;
3219 /* lookup the country in the local database */
3220 for (i = 0; i < countryInfoTable.countryCount &&
3221 REGDOMAIN_COUNT == temp_reg_domain; i++)
3222 {
3223 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3224 VOS_COUNTRY_CODE_LEN) == 0)
3225 {
3226 /* country code is found */
3227 /* record the temporary regulatory_domain as well */
3228 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3229 break;
3230 }
3231 }
3232
3233 if (REGDOMAIN_COUNT == temp_reg_domain) {
3234
3235 /* the country was not found in the driver database */
3236 /* so we will return the REGDOMAIN_WORLD to SME/CSR */
3237
3238 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3239 ("Country does not map to any Regulatory domain"));
3240
3241 temp_reg_domain = REGDOMAIN_WORLD;
3242 }
3243
3244 if (COUNTRY_QUERY == source)
3245 {
3246 *pRegDomain = temp_reg_domain;
3247 return VOS_STATUS_SUCCESS;
3248 }
3249
Amar Singhalfddc28c2013-09-05 13:03:40 -07003250 wiphy = pHddCtx->wiphy;
3251
Amar Singhala49cbc52013-10-08 18:37:44 -07003252 if (false == wiphy->registered)
3253 {
3254 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3255 ("wiphy is not yet registered with the kernel") );
3256 return VOS_STATUS_E_FAULT;
3257 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003258
3259 /* We need to query the kernel to get the regulatory information
3260 for this country */
3261
Amar Singhal0d15bd52013-10-12 23:13:13 -07003262
3263 /* First compare the country code with the existing current country code
3264 . If both are same there is no need to query any database */
3265
3266 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3267 ("regdomain request"));
3268
3269 if ((country_code[0] == linux_reg_cc[0]) &&
3270 (country_code[1] == linux_reg_cc[1])) {
3271
3272 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003273
Amar Singhala49cbc52013-10-08 18:37:44 -07003274 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhal0d15bd52013-10-12 23:13:13 -07003275 (" country code already exists"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003276
Amar Singhal0d15bd52013-10-12 23:13:13 -07003277 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003278
Amar Singhal0d15bd52013-10-12 23:13:13 -07003279 return VOS_STATUS_SUCCESS;
3280 }
3281 else {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003282
Amar Singhal0d15bd52013-10-12 23:13:13 -07003283 /* get the regulatory information from the kernel
3284 database */
Amar Singhala49cbc52013-10-08 18:37:44 -07003285
Amar Singhal0d15bd52013-10-12 23:13:13 -07003286 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3287 (" get country information from kernel db"));
3288
Amar Singhal0d15bd52013-10-12 23:13:13 -07003289
Kiet Lam6c583332013-10-14 05:37:09 +05303290 if (COUNTRY_NV == source)
3291 {
3292 INIT_COMPLETION(pHddCtx->linux_reg_req);
3293 regulatory_hint(wiphy, country_code);
3294 wait_result = wait_for_completion_interruptible_timeout(
3295 &pHddCtx->linux_reg_req,
3296 LINUX_REG_WAIT_TIME);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003297
Kiet Lam6c583332013-10-14 05:37:09 +05303298 /* if the country information does not exist with the kernel,
3299 then the driver callback would not be called */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003300
Kiet Lam6c583332013-10-14 05:37:09 +05303301 if (wait_result >= 0) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003302
Kiet Lam6c583332013-10-14 05:37:09 +05303303 /* the driver callback was called. this means the country
3304 regulatory information was found in the kernel database.
3305 The callback would have updated the internal database. Here
3306 update the country and the return value for the regulatory
3307 domain */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003308
Kiet Lam6c583332013-10-14 05:37:09 +05303309 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3310 ("runtime country code is found in kernel db"));
3311
3312 *pRegDomain = temp_reg_domain;
3313 cur_reg_domain = temp_reg_domain;
3314 linux_reg_cc[0] = country_code[0];
3315 linux_reg_cc[1] = country_code[1];
3316
3317 return VOS_STATUS_SUCCESS;
3318 }
3319 else {
3320
3321 /* the country information has not been found in the kernel
3322 database, return failure */
3323
3324 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3325 ("runtime country code is not found in kernel db"));
3326
3327 return VOS_STATUS_E_EXISTS;
3328 }
3329 }
3330 else if (COUNTRY_IE == source || COUNTRY_USER == source)
3331 {
3332#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3333 regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER);
3334#else
3335 regulatory_hint_user(country_code);
3336#endif
Amar Singhal0d15bd52013-10-12 23:13:13 -07003337 *pRegDomain = temp_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003338 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003339
Kiet Lam6c583332013-10-14 05:37:09 +05303340 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003341
Kiet Lam6c583332013-10-14 05:37:09 +05303342 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003343}
3344
Amar Singhal0d15bd52013-10-12 23:13:13 -07003345/* create_linux_regulatory_entry to populate internal structures from wiphy */
3346static int create_linux_regulatory_entry(struct wiphy *wiphy,
3347 struct regulatory_request *request,
3348 v_U8_t nBandCapability)
3349{
3350 int i, j, m;
3351 int k = 0, n = 0;
Kiet Lam5cb90e82013-10-25 19:35:12 +05303352#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
3353 int err;
3354#endif
3355 const struct ieee80211_reg_rule *reg_rule;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003356 v_CONTEXT_t pVosContext = NULL;
3357 hdd_context_t *pHddCtx = NULL;
3358
3359 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3360
3361 if (NULL != pVosContext)
3362 {
3363 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3364 if (NULL == pHddCtx)
3365 {
3366 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3367 ("Invalid pHddCtx pointer") );
3368 }
3369 else
3370 {
3371 pHddCtx->isVHT80Allowed = 0;
3372 }
3373 }
3374 else
3375 {
3376 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3377 ("Invalid pVosContext pointer") );
3378 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003379
3380 /* 20MHz channels */
3381 if (nBandCapability == eCSR_BAND_24)
3382 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08003383 "BandCapability is set to 2G only");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003384
3385 for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++)
3386 {
3387 /* 5G only */
3388 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G)
3389 continue;
3390
3391 /* 2G only */
3392 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24)
3393 continue;
3394
3395 if (wiphy->bands[i] == NULL)
3396 {
3397
3398 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003399 "error: wiphy->bands is NULL, i = %d", i);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003400 return -1;
3401 }
3402
3403 /* internal channels[] is one continous array for both 2G and 5G bands
3404 m is internal starting channel index for each band */
3405
3406 if (i == 0)
3407 m = 0;
3408 else
3409 m = wiphy->bands[i-1]->n_channels + m;
3410
3411 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3412 {
3413 /* k = (m + j) is internal current channel index for 20MHz channel
3414 n is internal channel index for corresponding 40MHz channel */
3415
3416 k = m + j;
3417 n = bw20_ch_index_to_bw40_ch_index(k);
3418
3419 if (n == -1)
3420 return -1;
3421
Kiet Lam5cb90e82013-10-25 19:35:12 +05303422 /* If the regulatory rules for a country do not explicilty
3423 * require a passive scan on a frequency, lift the passive
3424 * scan restriction
3425 */
3426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3427 reg_rule = freq_reg_info(wiphy,
3428 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq));
3429#else
3430 err = freq_reg_info(wiphy,
3431 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq),
3432 0, &reg_rule);
3433#endif
3434
3435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3436 if (!IS_ERR(reg_rule))
3437#else
3438 if (0 == err)
3439#endif
3440 {
Ravi Shankar Upadrasta631d6c52014-06-12 14:46:11 +05303441 if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
3442
3443 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
3444 {
3445 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3446 "%s: Remove passive scan restriction for %u",
3447 __func__, wiphy->bands[i]->channels[j].center_freq);
3448 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3449 }
3450
Ravi Shankar Upadrasta2e528642014-06-12 15:05:03 +05303451 wiphy->bands[i]->channels[j].max_power =
3452 (int) MBM_TO_DBM(reg_rule->power_rule.max_eirp);
Kiet Lam5cb90e82013-10-25 19:35:12 +05303453 }
3454 }
3455
Amar Singhal0d15bd52013-10-12 23:13:13 -07003456 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
3457 {
3458 if (pnvEFSTable == NULL)
3459 {
3460 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003461 "error: pnvEFSTable is NULL, probably not parsed nv.bin yet");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003462 return -1;
3463 }
3464 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3465 NV_CHANNEL_DISABLE;
3466 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3467 NV_CHANNEL_DISABLE;
3468 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303469 /* nv cannot distinguish between DFS and passive channels */
3470 else if (wiphy->bands[i]->channels[j].flags &
3471 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
Amar Singhal0d15bd52013-10-12 23:13:13 -07003472 {
3473 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3474 NV_CHANNEL_DFS;
3475
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303476 // Cap the TX power by the power limits specified in NV for the regdomain
3477 wiphy->bands[i]->channels[j].max_power =
3478 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3479 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)));
3480
Amar Singhal0d15bd52013-10-12 23:13:13 -07003481 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003482 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Abhishek Singh25144bb2014-05-01 16:03:21 +05303483
3484 /* Disable the center channel if neither HT40+ nor HT40- is allowed
3485 */
3486 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) ==
3487 IEEE80211_CHAN_NO_HT40 )
3488 {
3489 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3490 NV_CHANNEL_DISABLE;
3491 }
3492 else
Amar Singhal0d15bd52013-10-12 23:13:13 -07003493 {
3494 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3495 NV_CHANNEL_DFS;
3496
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303497 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3498 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3499 * channels
3500 */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003501 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303502 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
3503 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
3504
Amar Singhal0d15bd52013-10-12 23:13:13 -07003505 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003506 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3507 {
3508 if (NULL == pHddCtx)
3509 {
3510 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3511 ("Invalid pHddCtx pointer") );
3512 }
3513 else
3514 {
3515 pHddCtx->isVHT80Allowed = 1;
3516 }
3517 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003518 }
3519 else /* Enable is only last flag we support */
3520 {
Manjunathappa Prakashde7b2a52014-02-28 16:59:03 -08003521#ifdef FEATURE_WLAN_CH144
3522 if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion()))
3523 {
3524 //Do not enable channel 144 when NV version is not NV3
3525 }
3526 else
3527#endif
3528 {
3529 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].\
3530 channels[k].enabled = NV_CHANNEL_ENABLE;
3531 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003532
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303533 // Cap the TX power by the power limits specified in NV for the regdomain
3534 wiphy->bands[i]->channels[j].max_power =
3535 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3536 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)));
3537
Amar Singhal0d15bd52013-10-12 23:13:13 -07003538 /* max_power is in dBm */
3539 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003540 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Abhishek Singh25144bb2014-05-01 16:03:21 +05303541
3542 /* Disable the center channel if neither HT40+ nor HT40- is allowed
3543 */
3544 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) ==
3545 IEEE80211_CHAN_NO_HT40 )
3546 {
3547 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3548 NV_CHANNEL_DISABLE;
3549 }
3550 else
Amar Singhal0d15bd52013-10-12 23:13:13 -07003551 {
3552 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3553 NV_CHANNEL_ENABLE;
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303554
3555 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3556 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3557 * channels
3558 */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003559 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303560 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
3561 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003562 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003563 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3564 {
3565 if (NULL == pHddCtx)
3566 {
3567 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3568 ("Invalid pHddCtx pointer") );
3569 }
3570 else
3571 {
3572 pHddCtx->isVHT80Allowed = 1;
3573 }
3574 }
3575
Amar Singhal0d15bd52013-10-12 23:13:13 -07003576 }
3577
Kiet Lam5cb90e82013-10-25 19:35:12 +05303578
Amar Singhal0d15bd52013-10-12 23:13:13 -07003579 }
3580 }
3581
3582 if (k == 0)
3583 return -1;
3584
3585 return 0;
3586}
3587
3588
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003589/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07003590 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003591 * This function is called from cfg80211 core to provide regulatory settings
3592 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07003593 * This function is used to create a CRDA regulatory settings entry into internal
3594 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003595 */
Amar Singhala49cbc52013-10-08 18:37:44 -07003596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003597void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07003598 struct regulatory_request *request)
3599#else
Amar Singhala49cbc52013-10-08 18:37:44 -07003600int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003601 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07003602#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003603{
3604 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303605 eCsrBand nBandCapability = eCSR_BAND_ALL;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003606 v_COUNTRYCODE_t country_code;
Agarwal Ashishe3726342014-04-28 17:41:09 +05303607 int i, j;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003608 v_BOOL_t isVHT80Allowed;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003609
Amar Singhala49cbc52013-10-08 18:37:44 -07003610 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003611 "cfg80211 reg notifier callback for country for initiator %d", request->initiator);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003612
Wilson Yang68349dd2014-02-06 17:30:38 -08003613 if (TRUE == isWDresetInProgress())
Arif Hussainec3fbb32013-10-03 11:49:23 -07003614 {
Wilson Yang68349dd2014-02-06 17:30:38 -08003615 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3616 ("SSR is in progress") );
Kiet Lamcffc5862013-10-30 16:28:45 +05303617#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Wilson Yang68349dd2014-02-06 17:30:38 -08003618 return;
Kiet Lamcffc5862013-10-30 16:28:45 +05303619#else
3620 return 0;
3621#endif
3622 }
3623
3624 if (NULL == pHddCtx)
3625 {
3626 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3627 ("Invalid pHddCtx pointer") );
3628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3629 return;
3630#else
3631 return 0;
3632#endif
Arif Hussainec3fbb32013-10-03 11:49:23 -07003633 }
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303634
Mihir Shete18156292014-03-11 15:38:30 +05303635 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
Abhishek Singh3015dad2014-02-28 17:30:13 +05303636 {
3637 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Mihir Shete18156292014-03-11 15:38:30 +05303638 ("%s Unload is in progress"), __func__ );
Abhishek Singh3015dad2014-02-28 17:30:13 +05303639#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3640 return;
3641#else
3642 return 0;
3643#endif
3644 }
3645
Vinay Krishna Eranna22ebc0d2014-05-09 17:20:33 +05303646 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3647 ("%s: Req initiator %d CC=%c%c"), __func__,
3648 request->initiator, request->alpha2[0], request->alpha2[1]);
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303649
3650 sme_GetFreqBand(pHddCtx->hHal, &nBandCapability);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003651 /* first check if this callback is in response to the driver callback */
3652
Amar Singhala49cbc52013-10-08 18:37:44 -07003653 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
3654 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003655
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003656 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303657 if (create_linux_regulatory_entry(wiphy, request, nBandCapability) == 0)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003658 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003659
Amar Singhal0d15bd52013-10-12 23:13:13 -07003660 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07003661 (" regulatory entry created"));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003662 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003663 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3664 {
3665 hdd_checkandupdate_phymode( pHddCtx);
3666 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003667
Amar Singhal0d15bd52013-10-12 23:13:13 -07003668 complete(&pHddCtx->linux_reg_req);
3669 }
3670
Kiet Lamcffc5862013-10-30 16:28:45 +05303671 else if (request->initiator == NL80211_REGDOM_SET_BY_USER ||
3672 request->initiator == NL80211_REGDOM_SET_BY_CORE)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003673 {
3674
3675 /* first lookup the country in the local database */
3676
3677 country_code[0] = request->alpha2[0];
3678 country_code[1] = request->alpha2[1];
3679
3680 temp_reg_domain = REGDOMAIN_COUNT;
3681 for (i = 0; i < countryInfoTable.countryCount &&
3682 REGDOMAIN_COUNT == temp_reg_domain; i++)
3683 {
3684 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3685 VOS_COUNTRY_CODE_LEN) == 0)
3686 {
3687 /* country code is found */
3688 /* record the temporary regulatory_domain as well */
3689 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3690 break;
3691 }
3692 }
3693
3694 if (REGDOMAIN_COUNT == temp_reg_domain)
3695 temp_reg_domain = REGDOMAIN_WORLD;
3696
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003697 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003698 if (create_linux_regulatory_entry(wiphy, request,
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303699 nBandCapability) == 0)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003700 {
3701 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3702 (" regulatory entry created"));
3703
3704 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003705 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3706 {
3707 hdd_checkandupdate_phymode( pHddCtx);
3708 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003709
3710 cur_reg_domain = temp_reg_domain;
3711 linux_reg_cc[0] = country_code[0];
3712 linux_reg_cc[1] = country_code[1];
3713
3714 /* now pass the new country information to sme */
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003715 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
3716 {
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003717 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3718 REGDOMAIN_COUNT);
3719 }
Kiet Lamcffc5862013-10-30 16:28:45 +05303720 else
3721 {
3722 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3723 temp_reg_domain);
3724 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05303725
Kiet Lamcffc5862013-10-30 16:28:45 +05303726 }
Agarwal Ashishe3726342014-04-28 17:41:09 +05303727
3728 /* Mark channels 36-48 as passive for US CC */
3729
3730 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
3731 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
3732 (request->initiator == NL80211_REGDOM_SET_BY_USER))
3733 {
Agarwal Ashish0661dcd2014-05-20 20:16:41 +05303734 if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC &&
3735 wiphy->bands[IEEE80211_BAND_5GHZ])
Agarwal Ashishe3726342014-04-28 17:41:09 +05303736 {
3737 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
3738 {
3739 // UNII-1 band channels are passive when domain is FCC.
3740 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
3741 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
3742 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
3743 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
3744 ((request->alpha2[0]== 'U'&& request->alpha2[1]=='S') &&
3745 pHddCtx->nEnableStrictRegulatoryForFCC))
3746 {
3747 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3748 }
3749 }
3750 }
3751 }
3752
Amar Singhala49cbc52013-10-08 18:37:44 -07003753#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07003754 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07003755#else
3756 return 0;
3757#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003758}
Amar Singhalfddc28c2013-09-05 13:03:40 -07003759
Amar Singhal0d15bd52013-10-12 23:13:13 -07003760
Amar Singhal0a402232013-10-11 20:57:16 -07003761/* initialize wiphy from NV.bin */
3762VOS_STATUS vos_init_wiphy_from_nv_bin(void)
3763{
3764 int i, j, m;
3765 int k = 0;
3766 v_REGDOMAIN_t reg_domain;
3767 v_CONTEXT_t pVosContext = NULL;
3768 hdd_context_t *pHddCtx = NULL;
3769 struct wiphy *wiphy = NULL;
3770
3771 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3772
3773 if (NULL != pVosContext)
3774 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3775 else
3776 return VOS_STATUS_E_EXISTS;
3777
3778 if (NULL == pHddCtx)
3779 {
3780 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3781 ("Invalid pHddCtx pointer") );
3782 return VOS_STATUS_E_FAULT;
3783 }
3784
3785 wiphy = pHddCtx->wiphy;
3786
3787 if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0])
3788 &&
3789 ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]))
3790 {
3791 /* default country is world roaming */
3792
3793 reg_domain = REGDOMAIN_WORLD;
3794 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3795 }
3796 else if (REGDOMAIN_WORLD ==
3797 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) {
3798
3799 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
Amar Singhal0a402232013-10-11 20:57:16 -07003800 }
3801 else {
3802
3803 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3804 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
3805 }
3806
Mihir Shete457834b2014-03-11 21:46:21 +05303807 temp_reg_domain = cur_reg_domain = reg_domain;
3808
Amar Singhala1829502013-11-16 13:57:41 -08003809 m = 0;
Amar Singhal0a402232013-10-11 20:57:16 -07003810 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3811 {
3812
3813 if (wiphy->bands[i] == NULL)
3814 {
3815 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
Amar Singhala1829502013-11-16 13:57:41 -08003816 continue;
Amar Singhal0a402232013-10-11 20:57:16 -07003817 }
3818
3819 /* internal channels[] is one continous array for both 2G and 5G bands
3820 m is internal starting channel index for each band */
Amar Singhal0a402232013-10-11 20:57:16 -07003821
3822 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3823 {
3824 /* k = (m + j) is internal current channel index */
3825 k = m + j;
3826
3827 if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3828 NV_CHANNEL_DISABLE)
3829 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3830
3831 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3832 NV_CHANNEL_DFS) {
3833
3834 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3835
3836 wiphy->bands[i]->channels[j].max_power =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303837 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit);
Amar Singhal0a402232013-10-11 20:57:16 -07003838 }
3839
3840 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3841 NV_CHANNEL_ENABLE) {
3842
3843 wiphy->bands[i]->channels[j].max_power =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303844 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit);
Amar Singhal0a402232013-10-11 20:57:16 -07003845 }
3846 }
Amar Singhala1829502013-11-16 13:57:41 -08003847
3848 m += wiphy->bands[i]->n_channels;
Amar Singhal0a402232013-10-11 20:57:16 -07003849 }
3850
3851 return VOS_STATUS_SUCCESS;
3852}
3853
3854
Amar Singhalfddc28c2013-09-05 13:03:40 -07003855#else
3856
3857/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07003858 \brief vos_nv_setRegDomain -
3859 \param clientCtxt - Client Context, Not used for PRIMA
3860 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303861 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003862 \return status set REG domain operation
3863 \sa
3864 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303865VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3866 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003867{
3868 v_CONTEXT_t pVosContext = NULL;
3869 hdd_context_t *pHddCtx = NULL;
3870 struct wiphy *wiphy = NULL;
3871 /* Client Context Argumant not used for PRIMA */
3872 if (regId >= REGDOMAIN_COUNT)
3873 {
3874 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3875 "VOS set reg domain, invalid REG domain ID %d", regId);
3876 return VOS_STATUS_E_INVAL;
3877 }
3878
3879 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3880 if (NULL != pVosContext)
3881 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3882 else
3883 return VOS_STATUS_E_EXISTS;
3884 /* Set correct channel information based on REG Domain */
3885 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3886
3887 /* when CRDA is not running then we are world roaming.
3888 In this case if 11d is enabled, then country code should
3889 be update on basis of world roaming */
Abhishek Singha306a442013-11-07 18:39:01 +05303890 if (NULL != pHddCtx && sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003891 {
3892 wiphy = pHddCtx->wiphy;
3893 regulatory_hint(wiphy, "00");
3894 }
3895 return VOS_STATUS_SUCCESS;
3896}
3897
3898
3899/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07003900 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3901 a country given its country code
3902 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3903 a country given its country code. This is done from reading a cached
3904 copy of the binary file.
3905 \param pRegDomain - pointer to regulatory domain
3906 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303907 \param source - source of the country code
Amar Singhalfddc28c2013-09-05 13:03:40 -07003908 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3909 VOS_STATUS_E_FAULT - invalid pointer error
3910 VOS_STATUS_E_EMPTY - country code table is empty
3911 VOS_STATUS_E_EXISTS - given country code does not exist in table
3912 \sa
3913 -------------------------------------------------------------------------*/
3914VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303915 const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003916{
Amar Singhala49cbc52013-10-08 18:37:44 -07003917 int i;
3918 v_CONTEXT_t pVosContext = NULL;
3919 hdd_context_t *pHddCtx = NULL;
3920 struct wiphy *wiphy = NULL;
3921 int status;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003922
Amar Singhala49cbc52013-10-08 18:37:44 -07003923 // sanity checks
3924 if (NULL == pRegDomain)
3925 {
3926 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003927 ("Invalid reg domain pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003928 return VOS_STATUS_E_FAULT;
3929 }
3930 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003931
Amar Singhala49cbc52013-10-08 18:37:44 -07003932 if (NULL == countryCode)
3933 {
3934 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003935 ("Country code array is NULL") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003936 return VOS_STATUS_E_FAULT;
3937 }
3938 if (0 == countryInfoTable.countryCount)
3939 {
3940 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003941 ("Reg domain table is empty") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003942 return VOS_STATUS_E_EMPTY;
3943 }
3944 /* If CRDA regulatory settings is valid, i.e. crda is enabled
3945 and reg_notifier is called back.
3946 Intercept here and redirect to the Reg domain table's CRDA
3947 entry if country code is crda's country.
3948 last one NUM_REG_DOMAINS-1 is reserved for crda */
3949 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003950 "vos_nv_getRegDomainFromCountryCode %c%c",
Amar Singhala49cbc52013-10-08 18:37:44 -07003951 countryCode[0], countryCode[1]);
3952
3953 if (crda_regulatory_entry_valid == VOS_TRUE)
3954 {
3955 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
3956 {
3957 *pRegDomain = NUM_REG_DOMAINS-1;
3958 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003959 "vos_nv_getRegDomainFromCountryCode return crda init entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003960 return VOS_STATUS_SUCCESS;
3961 }
3962 if (run_time_alpha2[0]==countryCode[0] &&
3963 run_time_alpha2[1]==countryCode[1] &&
3964 crda_regulatory_run_time_entry_valid == VOS_TRUE)
3965 {
3966 *pRegDomain = NUM_REG_DOMAINS-2;
3967 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003968 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003969 return VOS_STATUS_SUCCESS;
3970 }
3971 else
3972 {
3973 crda_regulatory_run_time_entry_valid = VOS_FALSE;
3974 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3975 if (NULL != pVosContext)
3976 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3977 else
3978 return VOS_STATUS_E_EXISTS;
3979 if (NULL == pHddCtx)
3980 {
3981 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003982 ("Invalid pHddCtx pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003983 return VOS_STATUS_E_FAULT;
3984 }
3985
3986 wiphy = pHddCtx->wiphy;
3987
3988 INIT_COMPLETION(pHddCtx->driver_crda_req);
3989 regulatory_hint(wiphy, countryCode);
3990 status = wait_for_completion_interruptible_timeout(
3991 &pHddCtx->driver_crda_req,
3992 msecs_to_jiffies(CRDA_WAIT_TIME));
3993 if (!status)
3994 {
3995 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3996 "%s: Timeout waiting for CRDA REQ", __func__);
3997 }
3998
3999 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
4000 {
4001 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08004002 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004003 return VOS_STATUS_SUCCESS;
4004 }
4005 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004006 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004007 return VOS_STATUS_E_EXISTS;
4008 }
4009 }
4010
4011 // iterate the country info table until end of table or the country code
4012 // is found
4013 for (i = 0; i < countryInfoTable.countryCount &&
4014 REGDOMAIN_COUNT == *pRegDomain; i++)
4015 {
4016 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
4017 VOS_COUNTRY_CODE_LEN) == 0)
4018 {
4019 // country code is found
4020 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
4021 }
4022 }
4023 if (REGDOMAIN_COUNT != *pRegDomain)
4024 {
4025 return VOS_STATUS_SUCCESS;
4026 }
4027 else
4028 {
4029 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08004030 ("country code is not found"));
Amar Singhala49cbc52013-10-08 18:37:44 -07004031 return VOS_STATUS_E_EXISTS;
4032 }
4033}
Abhishek Singha306a442013-11-07 18:39:01 +05304034/* FUNCTION: vos_nv_change_country_code_cb
4035* to wait for contry code completion
4036*/
4037void* vos_nv_change_country_code_cb(void *pAdapter)
4038{
4039 struct completion *change_code_cng = pAdapter;
4040 complete(change_code_cng);
4041 return NULL;
4042}
Amar Singhala49cbc52013-10-08 18:37:44 -07004043
4044/*
4045 * Function: wlan_hdd_crda_reg_notifier
4046 * This function is called from cfg80211 core to provide regulatory settings
4047 * after new country is requested or intersected (init, user input or 11d)
4048 * This function is used to create a CRDA regulatory settings entry into internal
4049 * regulatory setting table.
4050 */
4051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4052void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
4053 struct regulatory_request *request)
4054#else
4055int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
4056 struct regulatory_request *request)
4057#endif
4058{
4059 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4060 v_REGDOMAIN_t domainIdCurrent;
4061 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
4062 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304063 eCsrBand nBandCapability = eCSR_BAND_ALL;
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304064 int i,j,k,m,n;
4065 int countryIndex = -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07004066
4067 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
4068 " %c%c\n", request->alpha2[0], request->alpha2[1]);
Abhishek Singh3015dad2014-02-28 17:30:13 +05304069
4070 /* During load and SSR, vos_open (which will lead to WDA_SetRegDomain)
4071 * is called before we assign pHddCtx->hHal so we might get it as
4072 * NULL here leading to crash.
4073 */
4074 if (NULL == pHddCtx)
4075 {
4076 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4077 ("%s Invalid pHddCtx pointer"), __func__);
4078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4079 return;
4080#else
4081 return 0;
4082#endif
4083 }
Mihir Shete18156292014-03-11 15:38:30 +05304084 if((WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx)) ||
Abhishek Singh3015dad2014-02-28 17:30:13 +05304085 pHddCtx->isLogpInProgress)
4086 {
4087 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4088 ("%s load/unload or SSR is in progress Ignore"), __func__ );
4089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4090 return;
4091#else
4092 return 0;
4093#endif
4094 }
4095
Amar Singhala49cbc52013-10-08 18:37:44 -07004096 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07004097 {
Abhishek Singha306a442013-11-07 18:39:01 +05304098 int status;
Amar Singhala49cbc52013-10-08 18:37:44 -07004099 wiphy_dbg(wiphy, "info: set by user\n");
Abhishek Singh1c597df2014-03-24 14:00:41 +05304100 memset(ccode, 0, WNI_CFG_COUNTRY_CODE_LEN);
4101 memcpy(ccode, request->alpha2, 2);
Abhishek Singha306a442013-11-07 18:39:01 +05304102 init_completion(&change_country_code);
4103 /* We will process hints by user from nl80211 in driver.
4104 * sme_ChangeCountryCode will set the country to driver
4105 * and update the regdomain.
4106 * when we return back to nl80211 from this callback, the nl80211 will
4107 * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to
4108 * query channel list from nl80211. Thus we need to update the channels
4109 * according to reg domain set by user before returning to nl80211 so
4110 * that hostapd will gets the updated channels.
4111 * The argument sendRegHint in sme_ChangeCountryCode is
4112 * set to eSIR_FALSE (hint is from nl80211 and thus
4113 * no need to notify nl80211 back)*/
4114 status = sme_ChangeCountryCode(pHddCtx->hHal,
4115 (void *)(tSmeChangeCountryCallback)
4116 vos_nv_change_country_code_cb,
Abhishek Singh1c597df2014-03-24 14:00:41 +05304117 ccode,
Abhishek Singha306a442013-11-07 18:39:01 +05304118 &change_country_code,
4119 pHddCtx->pvosContext,
4120 eSIR_FALSE,
4121 eSIR_FALSE);
4122 if (eHAL_STATUS_SUCCESS == status)
4123 {
4124 status = wait_for_completion_interruptible_timeout(
4125 &change_country_code,
4126 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4127 if(status <= 0)
4128 {
4129 wiphy_dbg(wiphy, "info: set country timed out\n");
4130 }
4131 }
4132 else
4133 {
4134 wiphy_dbg(wiphy, "info: unable to set country by user\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07004135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4136 return;
4137#else
4138 return 0;
4139#endif
Abhishek Singha306a442013-11-07 18:39:01 +05304140 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004141 // ToDo
4142 /* Don't change default country code to CRDA country code by user req */
4143 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
4144 regd for new country settings */
4145 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
4146 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147 }
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304148 sme_GetFreqBand(pHddCtx->hHal, &nBandCapability);
Abhishek Singha306a442013-11-07 18:39:01 +05304149 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07004150 {
Amar Singhala49cbc52013-10-08 18:37:44 -07004151 wiphy_dbg(wiphy, "info: set by country IE\n");
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304152 if (create_crda_regulatory_entry(wiphy, request, nBandCapability) != 0)
Amar Singhala49cbc52013-10-08 18:37:44 -07004153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4154 return;
4155#else
4156 return 0;
4157#endif
4158 // ToDo
4159 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004160
Amar Singhala49cbc52013-10-08 18:37:44 -07004161 /* Don't change default country code to CRDA country code by 11d req */
4162 /* for every adapter call sme_ChangeCountryCode to trigger read regd
4163 for intersected new country settings */
4164 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
4165 // &country_code[0], pAdapter, pHddCtx->pvosContext);
4166 }
4167 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
Abhishek Singha306a442013-11-07 18:39:01 +05304168 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
4169 (request->initiator == NL80211_REGDOM_SET_BY_USER))
Amar Singhalfddc28c2013-09-05 13:03:40 -07004170 {
Amar Singhala49cbc52013-10-08 18:37:44 -07004171 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
4172 {
4173 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
4174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4175 return;
4176#else
4177 return 0;
4178#endif
4179 }
4180 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
4181 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
4182 {
4183 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
4184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4185 return;
4186#else
4187 return 0;
4188#endif
4189 }
4190
4191 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304192 for (n = 0; n < MAX_COUNTRY_IGNORE; n++)
4193 {
4194 if (vos_mem_compare(ccode, countryIgnoreList[n].countryCode, VOS_COUNTRY_CODE_LEN))
4195 {
4196 countryIndex = n;
4197 break;
4198 }
4199 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004200 /* if set by driver itself, it means driver can accept the crda
4201 regulatory settings and wiphy->regd should be populated with crda
4202 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
4203 correctly, this may be fixed by later kernel */
4204
Amar Singhala49cbc52013-10-08 18:37:44 -07004205 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
4206 {
4207 if (NULL == wiphy->bands[i])
4208 {
4209 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4210 "error: wiphy->bands[i] is NULL, i = %d", i);
4211 continue;
4212 }
4213
4214 // internal channels[] is one continous array for both 2G and 5G bands
4215 // m is internal starting channel index for each band
4216 if (0 == i)
4217 {
4218 m = 0;
4219 }
4220 else
4221 {
4222 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
4223 }
4224
4225 for (j=0; j<wiphy->bands[i]->n_channels; j++)
4226 {
4227 // k = (m + j) is internal current channel index for 20MHz channel
4228 // n is internal channel index for corresponding 40MHz channel
4229 k = m + j;
4230 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
4231 {
4232 // Enable social channels for P2P
4233 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
4234 2437 == wiphy->bands[i]->channels[j].center_freq ||
4235 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
4236 NV_CHANNEL_ENABLE == regChannels[k].enabled)
4237 {
4238 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4239 }
4240 else
4241 {
4242 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4243 }
4244 continue;
4245 }
4246 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
4247 {
4248 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4249 continue;
4250 }
4251
4252 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
4253 NV_CHANNEL_INVALID == regChannels[k].enabled)
4254 {
4255 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4256 }
4257 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
4258 {
4259 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4260 |IEEE80211_CHAN_RADAR);
4261 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4262 }
4263 else
4264 {
4265 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4266 |IEEE80211_CHAN_PASSIVE_SCAN
4267 |IEEE80211_CHAN_NO_IBSS
4268 |IEEE80211_CHAN_RADAR);
4269 }
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304270
4271 if (countryIndex != -1)
4272 {
4273 for (n = 0; n < MAX_CHANNELS_IGNORE; n++)
4274 {
4275 v_U16_t freq = vos_chan_to_freq(countryIgnoreList[countryIndex].channelList[n]);
4276 if (wiphy->bands[i]->channels[j].center_freq == freq)
4277 {
4278 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4279 |IEEE80211_CHAN_PASSIVE_SCAN
4280 |IEEE80211_CHAN_NO_IBSS
4281 |IEEE80211_CHAN_RADAR);
4282 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4283 }
4284 }
4285 }
4286
Amar Singhala49cbc52013-10-08 18:37:44 -07004287 }
4288 }
4289
4290 /* Haven't seen any condition that will set by driver after init.
4291 If we do, then we should also call sme_ChangeCountryCode */
Kalikinkar dharad73a9bd2014-01-28 22:42:34 -08004292
4293 /* To Disable the strict regulatory FCC rule, need set
4294 gEnableStrictRegulatoryForFCC to zero from INI.
4295 By default regulatory FCC rule enable or set to 1, and
4296 in this case one can control dynamically using IOCTL
4297 (nEnableStrictRegulatoryForFCC).
4298 If gEnableStrictRegulatoryForFCC is set to zero then
4299 IOCTL operation is inactive */
4300
4301 if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC &&
4302 wiphy->bands[IEEE80211_BAND_5GHZ])
Amar Singhala49cbc52013-10-08 18:37:44 -07004303 {
4304 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4305 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304306 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07004307 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
4308 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4309 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4310 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304311 ((domainIdCurrent == REGDOMAIN_FCC) &&
4312 pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004313 {
4314 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4315 }
4316 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
4317 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4318 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4319 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304320 ((domainIdCurrent != REGDOMAIN_FCC) ||
4321 !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004322 {
4323 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
4324 }
Padma, Santhosh Kumare225f142014-04-23 13:02:00 +05304325
4326 //Marking channels 52-144 as Radar channels if they are enabled
4327 k = wiphy->bands[IEEE80211_BAND_2GHZ]->n_channels + j;
4328
4329 if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5260 ||
4330 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5280 ||
4331 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5300 ||
4332 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5320 ||
4333 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5500 ||
4334 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5520) &&
4335 ((regChannels[k].enabled == NV_CHANNEL_ENABLE) ||
4336 (regChannels[k].enabled == NV_CHANNEL_DFS)))
4337 {
4338 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_RADAR;
4339 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004340 }
4341 }
4342
4343 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
4344 {
4345 request->processed = 1;
4346 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07004347 }
4348
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304349 complete(&pHddCtx->wiphy_channel_update_event);
4350
Amar Singhala49cbc52013-10-08 18:37:44 -07004351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4352 return;
4353#else
4354 return 0;
4355#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07004356}
4357
4358#endif