blob: 1c68a9928249925c2138afdc15e8b6e506e58dfc [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*============================================================================
43 FILE: vos_nvitem.c
44 OVERVIEW: This source file contains definitions for vOS NV Item APIs
45 DEPENDENCIES: NV, remote API client, WinCE REX
46 Copyright (c) 2008 QUALCOMM Incorporated.
47 All Rights Reserved.
48 Qualcomm Confidential and Proprietary
49============================================================================*/
50/*============================================================================
51 EDIT HISTORY FOR MODULE
52============================================================================*/
53// the following is used to disable warning for having too many labels in
54// the 'nv_items_enum_type'
55
56/*----------------------------------------------------------------------------
57 * Include Files
58 * -------------------------------------------------------------------------*/
59#include "vos_types.h"
60#include "aniGlobal.h"
61#include "vos_nvitem.h"
62#include "vos_trace.h"
63#include "vos_api.h"
64#include "wlan_hdd_misc.h"
65#include "vos_sched.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070066#ifdef CONFIG_CFG80211
67#include "wlan_hdd_main.h"
68#include <net/cfg80211.h>
69static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
70static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
71static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
72static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
73#endif
74
Jeff Johnson295189b2012-06-20 16:38:30 -070075/*----------------------------------------------------------------------------
76 * Preprocessor Definitions and Constants
77 * -------------------------------------------------------------------------*/
78#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
79#define VALIDITY_BITMAP_SIZE 32
80#define MAX_COUNTRY_COUNT 300
81//To be removed when NV support is fully functional
82#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070083
84#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
85
Jeff Johnson295189b2012-06-20 16:38:30 -070086/*----------------------------------------------------------------------------
87 * Type Declarations
88 * -------------------------------------------------------------------------*/
89// this wrapper structure is identical to nv_cmd_type except the
90// data_ptr type is changed void* to avoid exceeding the debug information
91// module size as there are too many elements within nv_items_type union
92
93// structure for code and regulatory domain of a single country
94typedef struct
95{
96 v_U8_t regDomain;
97 v_COUNTRYCODE_t countryCode;
98} CountryInfo_t;
99// structure of table to map country code and regulatory domain
100typedef struct
101{
102 v_U16_t countryCount;
103 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
104} CountryInfoTable_t;
105/*----------------------------------------------------------------------------
106 * Global Data Definitions
107 * -------------------------------------------------------------------------*/
108/*----------------------------------------------------------------------------
109 * Static Variable Definitions
110 * -------------------------------------------------------------------------*/
111// cache of country info table;
112// this is re-initialized from data on binary file
113// loaded on driver initialization if available
114static CountryInfoTable_t countryInfoTable =
115{
116 254,
117 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700118 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
119 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
120 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
121 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
122 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
123 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
124 { REGDOMAIN_NO_5GHZ, {'A', 'L'}}, //ALBANIA
125 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
126 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
127 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
128 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
129 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
130 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
131 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
132 { REGDOMAIN_APAC, {'A', 'U'}}, //AUSTRALIA
133 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
134 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
135 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
136 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
137 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
138 { REGDOMAIN_NO_5GHZ, {'B', 'D'}}, //BANGLADESH
139 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
140 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
141 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
142 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
143 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
144 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
145 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
146 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
147 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
148 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
149 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
150 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
151 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
152 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
153 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
154 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
155 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
156 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
157 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
158 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
159 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
160 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
161 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
162 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
163 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
164 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
165 { REGDOMAIN_HI_5GHZ, {'C', 'N'}}, //CHINA
166 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
167 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
168 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
169 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
170 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
171 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
172 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
173 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
174 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
175 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
176 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
177 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
178 { REGDOMAIN_NO_5GHZ, {'D', 'Z'}}, //ALGERIA
179 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
180 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
181 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
182 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
183 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
184 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
185 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
186 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
187 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
188 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
189 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
190 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
191 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
192 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
193 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
194 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
195 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
196 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
197 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
198 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
199 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
200 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
201 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
202 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
203 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
204 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
205 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
206 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
207 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
208 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
209 { REGDOMAIN_APAC, {'G', 'U'}}, //GUAM
210 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
211 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
212 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
213 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
214 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
215 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
216 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
217 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
218 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
219 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
220 { REGDOMAIN_NO_5GHZ, {'I', 'L'}}, //ISRAEL
221 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
222 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
223 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
224 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
225 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
226 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
227 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
228 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
229 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
230 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
231 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
232 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
233 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
234 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
235 { REGDOMAIN_WORLD, {'J', 'O'}}, //JORDAN
236 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
237 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
238 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
239 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
240 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
241 { REGDOMAIN_HI_5GHZ, {'K', 'E'}}, //KENYA
242 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
243 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
244 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
245 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
246 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
247 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
248 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
249 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
250 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
251 { REGDOMAIN_NO_5GHZ, {'K', 'Z'}}, //KAZAKHSTAN
252 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
253 { REGDOMAIN_HI_5GHZ, {'L', 'B'}}, //LEBANON
254 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
255 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
256 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
257 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
258 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
259 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
260 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
261 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
262 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
263 { REGDOMAIN_NO_5GHZ, {'M', 'A'}}, //MOROCCO
264 { REGDOMAIN_N_AMER_EXC_FCC, {'M', 'C'}}, //MONACO
265 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
266 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
267 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
268 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
269 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
270 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
271 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
272 { REGDOMAIN_NO_5GHZ, {'M', 'N'}}, //MONGOLIA
273 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
274 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
275 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
276 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
277 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
278 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
279 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
280 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
281 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
282 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
283 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
284 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
285 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
286 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
287 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
288 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
289 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
290 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
291 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
292 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
293 { REGDOMAIN_HI_5GHZ, {'N', 'P'}}, //NEPAL
294 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
295 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
296 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
297 { REGDOMAIN_WORLD, {'O', 'M'}}, //OMAN
298 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
299 { REGDOMAIN_HI_5GHZ, {'P', 'E'}}, //PERU
300 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
301 { REGDOMAIN_APAC, {'P', 'G'}}, //PAPUA NEW GUINEA
302 { REGDOMAIN_HI_5GHZ, {'P', 'H'}}, //PHILIPPINES
303 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
304 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
305 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
306 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
307 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
308 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
309 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
310 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
311 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
312 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
313 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
314 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
315 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
316 { REGDOMAIN_HI_5GHZ, {'R', 'U'}}, //RUSSIA
317 { REGDOMAIN_HI_5GHZ, {'R', 'W'}}, //RWANDA
318 { REGDOMAIN_APAC, {'S', 'A'}}, //SAUDI ARABIA
319 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
320 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
321 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
322 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
323 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
324 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
325 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
326 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
327 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
328 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
329 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
330 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
331 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
332 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
333 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
334 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
335 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
336 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
337 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
338 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
339 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
340 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
341 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
342 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
343 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
344 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
345 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
346 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
347 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
348 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'R'}}, //TURKEY
349 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
350 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
351 { REGDOMAIN_WORLD, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
352 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
353 { REGDOMAIN_NO_5GHZ, {'U', 'A'}}, //UKRAINE
354 { REGDOMAIN_WORLD, {'U', 'G'}}, //UGANDA
355 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
356 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
357 { REGDOMAIN_WORLD, {'U', 'Z'}}, //UZBEKISTAN
358 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
359 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
360 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
361 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
362 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
363 { REGDOMAIN_N_AMER_EXC_FCC, {'V', 'N'}}, //VIET NAM
364 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
365 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
366 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
367 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
368 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
369 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
370 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
371 { REGDOMAIN_NO_5GHZ, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373};
374typedef struct nvEFSTable_s
375{
376 v_U32_t nvValidityBitmap;
377 sHalNv halnv;
378} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700379nvEFSTable_t *gnvEFSTable;
Jeff Johnson295189b2012-06-20 16:38:30 -0700380/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700381static nvEFSTable_t *pnvEFSTable;
Jeff Johnson295189b2012-06-20 16:38:30 -0700382
383const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
384{
385 //RF_SUBBAND_2_4_GHZ
386 //freq, chan#, band
387 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
388 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
389 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
390 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
391 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
392 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
393 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
394 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
395 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
396 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
397 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
398 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
399 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
400 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
401#ifdef FEATURE_WLAN_INTEGRATED_SOC
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700402 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
403 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
404 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
405 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
406 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
407 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
408 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700409 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
410 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
411 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
412 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
413 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
414 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
415 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
416 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
417 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
418 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
419 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
420 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
421 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
422 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
423 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
424 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
425 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
426 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
427 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
428 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
429 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
430 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
431 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
432 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700433 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
434 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
435 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
436 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
437 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
438 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
439 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
440 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
441 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
442 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
443 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
444 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
445 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
446 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
447 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
448 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
449 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
450 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
451 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
452 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
453 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
454 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
455 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
456 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
457 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
458 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
459 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
460 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
461 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
462 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
463 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
464 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
465 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
466 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
467 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700468#endif
469};
470
471extern const sHalNv nvDefaults;
472
473const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
474
475/*----------------------------------------------------------------------------
476 Function Definitions and Documentation
477 * -------------------------------------------------------------------------*/
478VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
479/**------------------------------------------------------------------------
480 \brief vos_nv_init() - initialize the NV module
481 The \a vos_nv_init() initializes the NV module. This read the binary
482 file for country code and regulatory domain information.
483 \return VOS_STATUS_SUCCESS - module is initialized successfully
484 otherwise - module is not initialized
485 \sa
486 -------------------------------------------------------------------------*/
487VOS_STATUS vos_nv_init(void)
488{
489 return VOS_STATUS_SUCCESS;
490}
491
492VOS_STATUS vos_nv_open(void)
493{
494 VOS_STATUS status = VOS_STATUS_SUCCESS;
495 v_CONTEXT_t pVosContext= NULL;
496 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700497 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700498 v_BOOL_t itemIsValid = VOS_FALSE;
499
500 /*Get the global context */
501 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800502
503 if(pVosContext == NULL)
504 {
505 return (eHAL_STATUS_FAILURE);
506 }
507
Jeff Johnson295189b2012-06-20 16:38:30 -0700508 bufSize = sizeof(nvEFSTable_t);
509 status = hdd_request_firmware(WLAN_NV_FILE,
510 ((VosContextType*)(pVosContext))->pHDDContext,
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700511 (v_VOID_t**)&gnvEFSTable, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700512
513 if ( (!VOS_IS_STATUS_SUCCESS( status )) || !gnvEFSTable)
514 {
515 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
516 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700517 __func__, WLAN_NV_FILE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 return VOS_STATUS_E_RESOURCES;
519 }
520
521 /* Copying the read nv data to the globa NV EFS table */
522 {
523 /* Allocate memory to global NV table */
524 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
525 if (NULL == pnvEFSTable)
526 {
527 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700528 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 return VOS_STATUS_E_NOMEM;
530 }
531
532 /*Copying the NV defaults */
533 vos_mem_copy(&(pnvEFSTable->halnv),&nvDefaults,sizeof(sHalNv));
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700534
535 if ( nvReadBufSize != bufSize)
536 {
537 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
538 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
539 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
540 nvReadBufSize, bufSize);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800541 goto error;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700542 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700543
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700544 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Jeff Johnson295189b2012-06-20 16:38:30 -0700545 /* Copy the valid fields to the NV Global structure */
546 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
547 VOS_STATUS_SUCCESS)
548 {
549 if (itemIsValid == VOS_TRUE) {
550
551 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
552 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800553 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700554 }
555 }
556
557 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
558 VOS_STATUS_SUCCESS)
559 {
560 if (itemIsValid == VOS_TRUE)
561 {
562 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
563 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
564 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800565 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700566 }
567 }
568
569 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
570 VOS_STATUS_SUCCESS)
571 {
572
573 if (itemIsValid == VOS_TRUE)
574 {
575 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
576 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
577 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800578 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700579 }
580 }
581
582 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
583 VOS_STATUS_SUCCESS)
584 {
585 if (itemIsValid == VOS_TRUE)
586 {
587 if(vos_nv_read( VNV_DEFAULT_LOCATION,
588 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
589 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800590 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 }
592 }
593
594 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
595 VOS_STATUS_SUCCESS)
596 {
597 if (itemIsValid == VOS_TRUE)
598 {
599 if(vos_nv_read( VNV_TPC_POWER_TABLE,
600 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
601 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800602 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700603 }
604 }
605
606 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
607 VOS_STATUS_SUCCESS)
608 {
609 if (itemIsValid == VOS_TRUE)
610 {
611 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
612 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
613 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800614 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 }
616 }
617 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
618 VOS_STATUS_SUCCESS)
619 {
620 if (itemIsValid == VOS_TRUE)
621 {
622 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
623 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
624 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800625 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700626 }
627 }
628
629 if (vos_nv_getValidity(VNV_RF_CAL_VALUES, &itemIsValid) ==
630 VOS_STATUS_SUCCESS)
631 {
632 if (itemIsValid == VOS_TRUE)
633 {
634 if(vos_nv_read( VNV_RF_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
635 .tables.rFCalValues, NULL, sizeof(sRFCalValues) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800636 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700637 }
638 }
639
640 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
641 VOS_STATUS_SUCCESS)
642 {
643 if (itemIsValid == VOS_TRUE)
644 {
645 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
646 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
647 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800648 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700649 }
650 }
651 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
652 VOS_STATUS_SUCCESS)
653 {
654 if (itemIsValid == VOS_TRUE)
655 {
656 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
657 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
658 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800659 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700660 }
661 }
662
663 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
664 VOS_STATUS_SUCCESS)
665 {
666 if (itemIsValid == VOS_TRUE)
667 {
668 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
669 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
670 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800671 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700672 }
673 }
674
675 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
676 VOS_STATUS_SUCCESS)
677 {
678 if (itemIsValid == VOS_TRUE)
679 {
680 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
681 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
682 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800683 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700684 }
685 }
686 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
687 VOS_STATUS_SUCCESS)
688 {
689 if (itemIsValid == VOS_TRUE)
690 {
691 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
692 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
693 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800694 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700695 }
696 }
697 }
698
699 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800700error:
701 vos_mem_free(pnvEFSTable);
702 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700703}
704
705VOS_STATUS vos_nv_close(void)
706{
707 VOS_STATUS status = VOS_STATUS_SUCCESS;
708 v_CONTEXT_t pVosContext= NULL;
709 /*Get the global context */
710 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
711 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
712 if ( !VOS_IS_STATUS_SUCCESS( status ))
713 {
714 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
715 "%s : vos_open failed\n",__func__);
716 return VOS_STATUS_E_FAILURE;
717 }
718 vos_mem_free(pnvEFSTable);
719 gnvEFSTable=NULL;
720 return VOS_STATUS_SUCCESS;
721}
722/**------------------------------------------------------------------------
723 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
724 a country given its country code
725 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
726 a country given its country code. This is done from reading a cached
727 copy of the binary file.
728 \param pRegDomain - pointer to regulatory domain
729 \param countryCode - country code
730 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
731 VOS_STATUS_E_FAULT - invalid pointer error
732 VOS_STATUS_E_EMPTY - country code table is empty
733 VOS_STATUS_E_EXISTS - given country code does not exist in table
734 \sa
735 -------------------------------------------------------------------------*/
736VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
737 const v_COUNTRYCODE_t countryCode )
738{
739 int i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700740 v_CONTEXT_t pVosContext = NULL;
741 hdd_context_t *pHddCtx = NULL;
742 struct wiphy *wiphy = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700743 // sanity checks
744 if (NULL == pRegDomain)
745 {
746 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
747 ("Invalid reg domain pointer\r\n") );
748 return VOS_STATUS_E_FAULT;
749 }
750 *pRegDomain = REGDOMAIN_COUNT;
751
752 if (NULL == countryCode)
753 {
754 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
755 ("Country code array is NULL\r\n") );
756 return VOS_STATUS_E_FAULT;
757 }
758 if (0 == countryInfoTable.countryCount)
759 {
760 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
761 ("Reg domain table is empty\r\n") );
762 return VOS_STATUS_E_EMPTY;
763 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764#ifdef CONFIG_CFG80211
765 /* If CRDA regulatory settings is valid, i.e. crda is enabled
766 and reg_notifier is called back.
767 Intercept here and redirect to the Reg domain table's CRDA
768 entry if country code is crda's country.
769 last one NUM_REG_DOMAINS-1 is reserved for crda */
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800770 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700771 "vos_nv_getRegDomainFromCountryCode %c%c\n",
772 countryCode[0], countryCode[1]);
773
774 if (crda_regulatory_entry_valid == VOS_TRUE)
775 {
776 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
777 {
778 *pRegDomain = NUM_REG_DOMAINS-1;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800779 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700780 "vos_nv_getRegDomainFromCountryCode return crda init entry\n");
781 return VOS_STATUS_SUCCESS;
782 }
783 if (run_time_alpha2[0]==countryCode[0] &&
784 run_time_alpha2[1]==countryCode[1] &&
785 crda_regulatory_run_time_entry_valid == VOS_TRUE)
786 {
787 *pRegDomain = NUM_REG_DOMAINS-2;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800788 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700789 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry\n");
790 return VOS_STATUS_SUCCESS;
791 }
792 else
793 {
794 crda_regulatory_run_time_entry_valid = VOS_FALSE;
795 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
796 if (NULL != pVosContext)
797 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
798 else
799 return VOS_STATUS_E_EXISTS;
800 wiphy = pHddCtx->wiphy;
801 init_completion(&pHddCtx->driver_crda_req);
802 regulatory_hint(wiphy, countryCode);
803 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
804 CRDA_WAIT_TIME);
805 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
806 {
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800807 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700808 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry\n");
809 return VOS_STATUS_SUCCESS;
810 }
811 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
812 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry\n");
813 return VOS_STATUS_E_EXISTS;
814 }
815 }
816#endif
817
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 // iterate the country info table until end of table or the country code
819 // is found
820 for (i = 0; i < countryInfoTable.countryCount &&
821 REGDOMAIN_COUNT == *pRegDomain; i++)
822 {
823 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
824 VOS_COUNTRY_CODE_LEN) == 0)
825 {
826 // country code is found
827 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
828 }
829 }
830 if (REGDOMAIN_COUNT != *pRegDomain)
831 {
832 return VOS_STATUS_SUCCESS;
833 }
834 else
835 {
836 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
837 ("country code is not found\r\n"));
838 return VOS_STATUS_E_EXISTS;
839 }
840}
841/**------------------------------------------------------------------------
842 \brief vos_nv_getSupportedCountryCode() - get the list of supported
843 country codes
844 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
845 country codes with paddings in the provided buffer
846 \param pBuffer - pointer to buffer where supported country codes
847 and paddings are encoded; this may be set to NULL
848 if user wishes to query the required buffer size to
849 get the country code list
850 \param pBufferSize - this is the provided buffer size on input;
851 this is the required or consumed buffer size on output
852 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
853 VOS_STATUS_E_NOMEM - country codes are not encoded because either
854 the buffer is NULL or buffer size is
855 sufficient
856 \sa
857 -------------------------------------------------------------------------*/
858VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
859 v_SIZE_t paddingSize )
860{
861 v_SIZE_t providedBufferSize = *pBufferSize;
862 int i;
863 // pBufferSize now points to the required buffer size
864 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
865 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
866 {
867 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
868 ("Insufficient memory for country code list\r\n"));
869 return VOS_STATUS_E_NOMEM;
870 }
871 for (i = 0; i < countryInfoTable.countryCount; i++)
872 {
873 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
874 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
875 }
876 return VOS_STATUS_SUCCESS;
877}
878/**------------------------------------------------------------------------
879 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
880 \param pTxAntennaCount - antenna count
881 \return status of the NV read operation
882 \sa
883 -------------------------------------------------------------------------*/
884VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
885{
886 sNvFields fieldImage;
887 VOS_STATUS status;
888 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
889 sizeof(fieldImage) );
890 if (VOS_STATUS_SUCCESS == status)
891 {
892 *pTxAntennaCount = fieldImage.numOfTxChains;
893 }
894 return status;
895}
896/**------------------------------------------------------------------------
897 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
898 \param pRxAntennaCount - antenna count
899 \return status of the NV read operation
900 \sa
901 -------------------------------------------------------------------------*/
902VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
903{
904 sNvFields fieldImage;
905 VOS_STATUS status;
906 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
907 sizeof(fieldImage) );
908 if (VOS_STATUS_SUCCESS == status)
909 {
910 *pRxAntennaCount = fieldImage.numOfRxChains;
911 }
912 return status;
913}
914
915/**------------------------------------------------------------------------
916 \brief vos_nv_readMacAddress() - return the MAC address
917 \param pMacAddress - MAC address
918 \return status of the NV read operation
919 \sa
920 -------------------------------------------------------------------------*/
921VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
922{
923 sNvFields fieldImage;
924 VOS_STATUS status;
925 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
926 sizeof(fieldImage) );
927 if (VOS_STATUS_SUCCESS == status)
928 {
929 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
930 }
931 else
932 {
933 //This part of the code can be removed when NV is programmed
934 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
935 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
936 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
937 " fail to get MAC address from NV, hardcoded to %02X-%02X-%02X-%02X-%02X%02X",
938 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
939 status = VOS_STATUS_SUCCESS;
940 }
941 return status;
942}
943
944/**------------------------------------------------------------------------
945
946 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
947
948 \param pMacAddress - MAC address
949 \param macCount - Count of valid MAC addresses to get from NV field
950
951 \return status of the NV read operation
952
953 \sa
954
955 -------------------------------------------------------------------------*/
956VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
957 v_U8_t macCount )
958{
959 sNvFields fieldImage;
960 VOS_STATUS status;
961 v_U8_t countLoop;
962 v_U8_t *pNVMacAddress;
963
964 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
965 (NULL == pMacAddress))
966 {
967 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
968 " Invalid Parameter from NV Client macCount %d, pMacAddress 0x%x",
969 macCount, pMacAddress);
970 }
971
972 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
973 sizeof(fieldImage) );
974 if (VOS_STATUS_SUCCESS == status)
975 {
976 pNVMacAddress = fieldImage.macAddr;
977 for(countLoop = 0; countLoop < macCount; countLoop++)
978 {
979 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
980 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
981 VOS_MAC_ADDRESS_LEN);
982 }
983 }
984 else
985 {
986 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
987 "vos_nv_readMultiMacAddress Get NV Field Fail");
988 }
989
990 return status;
991}
992
993/**------------------------------------------------------------------------
994 \brief vos_nv_setValidity() - set the validity of an NV item.
995 The \a vos_nv_setValidity() validates and invalidates an NV item. The
996 validity information is stored in NV memory.
997 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
998 An item becomes valid when one has written to it successfully.
999 \param type - NV item type
1000 \param itemIsValid - boolean value indicating the item's validity
1001 \return VOS_STATUS_SUCCESS - validity is set successfully
1002 VOS_STATUS_E_INVAL - one of the parameters is invalid
1003 VOS_STATUS_E_FAILURE - unknown error
1004 \sa
1005 -------------------------------------------------------------------------*/
1006#ifndef WLAN_FTM_STUB
1007
1008VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1009{
1010 v_U32_t lastNvValidityBitmap;
1011 v_U32_t newNvValidityBitmap;
1012 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001013
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001015 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001016 {
1017 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001018 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001019 return VOS_STATUS_E_INVAL;
1020 }
1021 // read the validity bitmap
1022 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1023 // modify the validity bitmap
1024 if (itemIsValid)
1025 {
1026 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1027 // commit to NV store if bitmap has been modified
1028 if (newNvValidityBitmap != lastNvValidityBitmap)
1029 {
1030 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1031 }
1032 }
1033 else
1034 {
1035 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1036 if (newNvValidityBitmap != lastNvValidityBitmap)
1037 {
1038 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1039 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1040 if (! VOS_IS_STATUS_SUCCESS(status)) {
1041 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1042 status = VOS_STATUS_E_FAULT;
1043 }
1044 }
1045 }
1046
1047 return status;
1048}
1049#endif
1050/**------------------------------------------------------------------------
1051 \brief vos_nv_getValidity() - get the validity of an NV item.
1052 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1053 validity information is stored in NV memory.
1054 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1055 An item becomes valid when one has written to it successfully.
1056 \param type - NV item type
1057 \param pItemIsValid- pointer to the boolean value indicating the item's
1058 validity
1059 \return VOS_STATUS_SUCCESS - validity is determined successfully
1060 VOS_STATUS_E_INVAL - one of the parameters is invalid
1061 VOS_STATUS_E_FAILURE - unknown error
1062 \sa
1063 -------------------------------------------------------------------------*/
1064VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1065{
1066 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1067 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001068 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001069 {
1070 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001071 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 return VOS_STATUS_E_INVAL;
1073 }
1074 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1075 return VOS_STATUS_SUCCESS;
1076}
1077/**------------------------------------------------------------------------
1078 \brief vos_nv_read() - read a NV item to an output buffer
1079 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1080 an array, this function would read the entire array. One would get a
1081 VOS_STATUS_E_EXISTS error when reading an invalid item.
1082 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1083 if a default buffer is provided (with a non-NULL value),
1084 the default buffer content is copied to the output buffer.
1085 \param type - NV item type
1086 \param outputBuffer - output buffer
1087 \param defaultBuffer - default buffer
1088 \param bufferSize - output buffer size
1089 \return VOS_STATUS_SUCCESS - NV item is read successfully
1090 VOS_STATUS_E_INVAL - one of the parameters is invalid
1091 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1092 VOS_STATUS_E_EXISTS - NV type is unsupported
1093 VOS_STATUS_E_FAILURE - unknown error
1094 \sa
1095 -------------------------------------------------------------------------*/
1096VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1097 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1098{
1099 VOS_STATUS status = VOS_STATUS_SUCCESS;
1100 v_SIZE_t itemSize;
1101 v_BOOL_t itemIsValid = VOS_TRUE;
1102
1103 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001104 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 {
1106 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001107 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 return VOS_STATUS_E_INVAL;
1109 }
1110 if (NULL == outputVoidBuffer)
1111 {
1112 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1113 ("Buffer provided is NULL\r\n") );
1114 return VOS_STATUS_E_FAULT;
1115 }
1116 if (0 == bufferSize)
1117 {
1118 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1119 ("NV type=%d is invalid\r\n"), type );
1120 return VOS_STATUS_E_INVAL;
1121 }
1122 // check if the NV item has valid data
1123 status = vos_nv_getValidity( type, &itemIsValid );
1124 if (!itemIsValid)
1125 {
1126 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1127 "NV type=%d does not have valid data\r\n", type );
1128 return VOS_STATUS_E_EMPTY;
1129 }
1130 switch(type)
1131 {
1132 case VNV_FIELD_IMAGE:
1133 itemSize = sizeof(gnvEFSTable->halnv.fields);
1134 if(bufferSize != itemSize) {
1135 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1136 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1137 itemSize);
1138 status = VOS_STATUS_E_INVAL;
1139 }
1140 else {
1141 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1142 }
1143 break;
1144 case VNV_RATE_TO_POWER_TABLE:
1145 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1146 if(bufferSize != itemSize) {
1147 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1148 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1149 itemSize);
1150 status = VOS_STATUS_E_INVAL;
1151 }
1152 else {
1153 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1154 }
1155 break;
1156 case VNV_REGULARTORY_DOMAIN_TABLE:
1157 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1158 if(bufferSize != itemSize) {
1159 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1160 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1161 itemSize);
1162 status = VOS_STATUS_E_INVAL;
1163 }
1164 else {
1165 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1166 }
1167 break;
1168 case VNV_DEFAULT_LOCATION:
1169 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1170 if(bufferSize != itemSize) {
1171 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1172 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1173 itemSize);
1174 status = VOS_STATUS_E_INVAL;
1175 }
1176 else {
1177 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1178 }
1179 break;
1180 case VNV_TPC_POWER_TABLE:
1181 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1182 if(bufferSize != itemSize) {
1183 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1184 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1185 itemSize);
1186 status = VOS_STATUS_E_INVAL;
1187 }
1188 else {
1189 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1190 }
1191 break;
1192 case VNV_TPC_PDADC_OFFSETS:
1193 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1194 if(bufferSize != itemSize) {
1195 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1196 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1197 itemSize);
1198 status = VOS_STATUS_E_INVAL;
1199 }
1200 else {
1201 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1202 }
1203 break;
1204 case VNV_RSSI_CHANNEL_OFFSETS:
1205
1206 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1207
1208 if(bufferSize != itemSize) {
1209
1210 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1211 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1212 itemSize);
1213 status = VOS_STATUS_E_INVAL;
1214 }
1215 else {
1216 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1217 }
1218 break;
1219 case VNV_RF_CAL_VALUES:
1220
1221 itemSize = sizeof(gnvEFSTable->halnv.tables.rFCalValues);
1222
1223 if(bufferSize != itemSize) {
1224
1225 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1226 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1227 itemSize);
1228 status = VOS_STATUS_E_INVAL;
1229 }
1230 else {
1231 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rFCalValues,bufferSize);
1232 }
1233 break;
1234 case VNV_ANTENNA_PATH_LOSS:
1235 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1236 if(bufferSize != itemSize) {
1237 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1238 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1239 itemSize);
1240 status = VOS_STATUS_E_INVAL;
1241 }
1242 else {
1243 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1244 }
1245 break;
1246 case VNV_PACKET_TYPE_POWER_LIMITS:
1247 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1248 if(bufferSize != itemSize) {
1249 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1250 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1251 itemSize);
1252 status = VOS_STATUS_E_INVAL;
1253 }
1254 else {
1255 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pktTypePwrLimits[0][0],bufferSize);
1256 }
1257 break;
1258 case VNV_OFDM_CMD_PWR_OFFSET:
1259 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1260 if(bufferSize != itemSize) {
1261 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1262 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1263 itemSize);
1264 status = VOS_STATUS_E_INVAL;
1265 }
1266 else {
1267 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1268 }
1269 break;
1270 case VNV_TX_BB_FILTER_MODE:
1271 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1272 if(bufferSize != itemSize) {
1273 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1274 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1275 itemSize);
1276 status = VOS_STATUS_E_INVAL;
1277 }
1278 else {
1279 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1280 }
1281 break;
1282
1283#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
1284 case VNV_FREQUENCY_FOR_1_3V_SUPPLY:
1285 itemSize = sizeof(gnvEFSTable->halnv.tables.freqFor1p3VSupply);
1286 if(bufferSize != itemSize) {
1287 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1288 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1289 itemSize);
1290 status = VOS_STATUS_E_INVAL;
1291 }
1292 else {
1293 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.freqFor1p3VSupply,bufferSize);
1294 }
1295 break;
1296#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
1297
1298 case VNV_TABLE_VIRTUAL_RATE:
1299 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1300 if(bufferSize != itemSize) {
1301 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1302 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1303 itemSize);
1304 status = VOS_STATUS_E_INVAL;
1305 }
1306 else {
1307 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1308 }
1309 break;
1310
1311 default:
1312 break;
1313 }
1314 return status;
1315}
1316#ifndef WLAN_FTM_STUB
1317
1318/**------------------------------------------------------------------------
1319 \brief vos_nv_write() - write to a NV item from an input buffer
1320 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1321 validate the NV item if the write operation is successful.
1322 \param type - NV item type
1323 \param inputBuffer - input buffer
1324 \param inputBufferSize - input buffer size
1325 \return VOS_STATUS_SUCCESS - NV item is read successfully
1326 VOS_STATUS_E_INVAL - one of the parameters is invalid
1327 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1328 VOS_STATUS_E_EXISTS - NV type is unsupported
1329 VOS_STATUS_E_FAILURE - unknown error
1330 \sa
1331 -------------------------------------------------------------------------*/
1332VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1333 v_SIZE_t bufferSize )
1334{
1335 VOS_STATUS status = VOS_STATUS_SUCCESS;
1336 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001337
1338 // sanity check
1339 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001340 {
1341 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001342 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001343 return VOS_STATUS_E_INVAL;
1344 }
1345 if (NULL == inputVoidBuffer)
1346 {
1347 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1348 ("Buffer provided is NULL\r\n") );
1349 return VOS_STATUS_E_FAULT;
1350 }
1351 if (0 == bufferSize)
1352 {
1353 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1354 ("NV type=%d is invalid\r\n"), type );
1355 return VOS_STATUS_E_INVAL;
1356 }
1357 switch(type)
1358 {
1359 case VNV_FIELD_IMAGE:
1360 itemSize = sizeof(gnvEFSTable->halnv.fields);
1361 if(bufferSize != itemSize) {
1362 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1363 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1364 itemSize);
1365 status = VOS_STATUS_E_INVAL;
1366 }
1367 else {
1368 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1369 }
1370 break;
1371 case VNV_RATE_TO_POWER_TABLE:
1372 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1373 if(bufferSize != itemSize) {
1374 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1375 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1376 itemSize);
1377 status = VOS_STATUS_E_INVAL;
1378 }
1379 else {
1380 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1381 }
1382 break;
1383 case VNV_REGULARTORY_DOMAIN_TABLE:
1384 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1385 if(bufferSize != itemSize) {
1386 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1387 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1388 itemSize);
1389 status = VOS_STATUS_E_INVAL;
1390 }
1391 else {
1392 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1393 }
1394 break;
1395 case VNV_DEFAULT_LOCATION:
1396 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1397 if(bufferSize != itemSize) {
1398 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1399 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1400 itemSize);
1401 status = VOS_STATUS_E_INVAL;
1402 }
1403 else {
1404 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1405 }
1406 break;
1407 case VNV_TPC_POWER_TABLE:
1408 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1409 if(bufferSize != itemSize) {
1410 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1411 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1412 itemSize);
1413 status = VOS_STATUS_E_INVAL;
1414 }
1415 else {
1416 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1417 }
1418 break;
1419 case VNV_TPC_PDADC_OFFSETS:
1420 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1421 if(bufferSize != itemSize) {
1422 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1423 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1424 itemSize);
1425 status = VOS_STATUS_E_INVAL;
1426 }
1427 else {
1428 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1429 }
1430 break;
1431 case VNV_RSSI_CHANNEL_OFFSETS:
1432
1433 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1434
1435 if(bufferSize != itemSize) {
1436
1437 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1438 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1439 itemSize);
1440 status = VOS_STATUS_E_INVAL;
1441 }
1442 else {
1443 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1444 }
1445 break;
1446 case VNV_RF_CAL_VALUES:
1447
1448 itemSize = sizeof(gnvEFSTable->halnv.tables.rFCalValues);
1449
1450 if(bufferSize != itemSize) {
1451
1452 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1453 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1454 itemSize);
1455 status = VOS_STATUS_E_INVAL;
1456 }
1457 else {
1458 memcpy(&gnvEFSTable->halnv.tables.rFCalValues,inputVoidBuffer,bufferSize);
1459 }
1460 break;
1461 case VNV_ANTENNA_PATH_LOSS:
1462 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1463 if(bufferSize != itemSize) {
1464 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1465 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1466 itemSize);
1467 status = VOS_STATUS_E_INVAL;
1468 }
1469 else {
1470 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1471 }
1472 break;
1473
1474 case VNV_PACKET_TYPE_POWER_LIMITS:
1475 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1476 if(bufferSize != itemSize) {
1477 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1478 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1479 itemSize);
1480 status = VOS_STATUS_E_INVAL;
1481 }
1482 else {
1483 memcpy(&gnvEFSTable->halnv.tables.pktTypePwrLimits[0][0],inputVoidBuffer,bufferSize);
1484 }
1485 break;
1486
1487 case VNV_OFDM_CMD_PWR_OFFSET:
1488 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1489 if(bufferSize != itemSize) {
1490 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1491 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1492 itemSize);
1493 status = VOS_STATUS_E_INVAL;
1494 }
1495 else {
1496 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1497 }
1498 break;
1499
1500 case VNV_TX_BB_FILTER_MODE:
1501 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1502 if(bufferSize != itemSize) {
1503 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1504 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1505 itemSize);
1506 status = VOS_STATUS_E_INVAL;
1507 }
1508 else {
1509 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1510 }
1511 break;
1512
1513#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
1514 case VNV_FREQUENCY_FOR_1_3V_SUPPLY:
1515 itemSize = sizeof(gnvEFSTable->halnv.tables.freqFor1p3VSupply);
1516 if(bufferSize != itemSize) {
1517 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1518 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1519 itemSize);
1520 status = VOS_STATUS_E_INVAL;
1521 }
1522 else {
1523 memcpy(&gnvEFSTable->halnv.tables.freqFor1p3VSupply,inputVoidBuffer,bufferSize);
1524 }
1525 break;
1526#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
1527
1528 case VNV_TABLE_VIRTUAL_RATE:
1529 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1530 if(bufferSize != itemSize) {
1531 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1532 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1533 itemSize);
1534 status = VOS_STATUS_E_INVAL;
1535 }
1536 else {
1537 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1538 }
1539 break;
1540
1541 default:
1542 break;
1543 }
1544 if (VOS_STATUS_SUCCESS == status)
1545 {
1546 // set NV item to have valid data
1547 status = vos_nv_setValidity( type, VOS_TRUE );
1548 if (! VOS_IS_STATUS_SUCCESS(status)) {
1549 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!\r\n"));
1550 status = VOS_STATUS_E_FAULT;
1551 }
1552 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1553
1554 if (! VOS_IS_STATUS_SUCCESS(status)) {
1555 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1556 status = VOS_STATUS_E_FAULT;
1557 }
1558 }
1559 return status;
1560}
1561#endif
1562
1563/**------------------------------------------------------------------------
1564 \brief vos_nv_getChannelListWithPower() - function to return the list of
1565 supported channels with the power limit info too.
1566 \param pChannels20MHz - list of 20 Mhz channels
1567 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1568 \param pChannels40MHz - list of 20 Mhz channels
1569 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1570 \return status of the NV read operation
1571 \Note: 40Mhz not currently supported
1572 \sa
1573 -------------------------------------------------------------------------*/
1574VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1575 tANI_U8 *num20MHzChannelsFound,
1576 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1577 tANI_U8 *num40MHzChannelsFound
1578 )
1579{
1580 VOS_STATUS status = VOS_STATUS_SUCCESS;
1581 int i, count;
1582
1583 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1584 // or pass it as a parameter to NV from SME?
1585
1586 if( channels20MHz && num20MHzChannelsFound )
1587 {
1588 count = 0;
1589 for( i = 0; i <= RF_CHAN_14; i++ )
1590 {
1591 if( regChannels[i].enabled )
1592 {
1593 channels20MHz[count].chanId = rfChannels[i].channelNum;
1594 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1595 }
1596 }
1597#ifdef FEATURE_WLAN_INTEGRATED_SOC
1598 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1599 {
1600 if( regChannels[i].enabled )
1601 {
1602 channels20MHz[count].chanId = rfChannels[i].channelNum;
1603 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1604 }
1605 }
1606#endif
1607 *num20MHzChannelsFound = (tANI_U8)count;
1608 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001609
1610 if( channels40MHz && num40MHzChannelsFound )
1611 {
1612 count = 0;
1613#ifdef FEATURE_WLAN_INTEGRATED_SOC
1614 //center channels for 2.4 Ghz 40 MHz channels
1615 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1616 {
1617
1618 if( regChannels[i].enabled )
1619 {
1620 channels40MHz[count].chanId = rfChannels[i].channelNum;
1621 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1622 }
1623 }
1624 //center channels for 5 Ghz 40 MHz channels
1625 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1626 {
1627
1628 if( regChannels[i].enabled )
1629 {
1630 channels40MHz[count].chanId = rfChannels[i].channelNum;
1631 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1632 }
1633 }
1634#endif
1635 *num40MHzChannelsFound = (tANI_U8)count;
1636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 return (status);
1638}
1639
1640/**------------------------------------------------------------------------
1641 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1642 \return default regulatory domain
1643 \sa
1644 -------------------------------------------------------------------------*/
1645
1646v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1647{
1648 return countryInfoTable.countryInfo[0].regDomain;
1649}
1650
1651/**------------------------------------------------------------------------
1652 \brief vos_nv_getSupportedChannels() - function to return the list of
1653 supported channels
1654 \param p20MhzChannels - list of 20 Mhz channels
1655 \param pNum20MhzChannels - number of 20 Mhz channels
1656 \param p40MhzChannels - list of 40 Mhz channels
1657 \param pNum40MhzChannels - number of 40 Mhz channels
1658 \return status of the NV read operation
1659 \Note: 40Mhz not currently supported
1660 \sa
1661 -------------------------------------------------------------------------*/
1662VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1663 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1664{
1665 VOS_STATUS status = VOS_STATUS_E_INVAL;
1666 int i, count = 0;
1667
1668 if( p20MhzChannels && pNum20MhzChannels )
1669 {
1670 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1671 {
1672 for( i = 0; i <= RF_CHAN_14; i++ )
1673 {
1674 p20MhzChannels[count++] = rfChannels[i].channelNum;
1675 }
1676#ifdef FEATURE_WLAN_INTEGRATED_SOC
1677 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1678 {
1679 p20MhzChannels[count++] = rfChannels[i].channelNum;
1680 }
1681#endif
1682 status = VOS_STATUS_SUCCESS;
1683 }
1684 *pNum20MhzChannels = count;
1685 }
1686
1687 return (status);
1688}
1689
1690/**------------------------------------------------------------------------
1691 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1692 \param table data - a union to return the default country table data in.
1693 \return status of the NV read operation
1694 \sa
1695 -------------------------------------------------------------------------*/
1696VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1697{
1698
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001699 VOS_STATUS status = VOS_STATUS_SUCCESS;
1700 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1701 pr_info("DefaultCountry is %c%c\n",
1702 tableData->defaultCountryTable.countryCode[0],
1703 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 return status;
1705}
1706
1707/**------------------------------------------------------------------------
1708 \brief vos_nv_getBuffer -
1709 \param pBuffer - to return the buffer address
1710 pSize - buffer size.
1711 \return status of the NV read operation
1712 \sa
1713 -------------------------------------------------------------------------*/
1714VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1715{
1716
1717 /* Send the NV structure and size */
1718 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1719 *pSize = sizeof(sHalNv);
1720
1721 return VOS_STATUS_SUCCESS;
1722}
1723
1724#ifdef FEATURE_WLAN_INTEGRATED_SOC
1725/**------------------------------------------------------------------------
1726 \brief vos_nv_setRegDomain -
1727 \param clientCtxt - Client Context, Not used for PRIMA
1728 regId - Regulatory Domain ID
1729 \return status set REG domain operation
1730 \sa
1731 -------------------------------------------------------------------------*/
1732VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
1733{
1734 /* Client Context Argumant not used for PRIMA */
1735 if(regId >= REGDOMAIN_COUNT)
1736 {
1737 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1738 "VOS set reg domain, invalid REG domain ID %d", regId);
1739 return VOS_STATUS_E_INVAL;
1740 }
1741
1742 /* Set correct channel information based on REG Domain */
1743 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
1744
1745 return VOS_STATUS_SUCCESS;
1746}
1747
1748/**------------------------------------------------------------------------
1749 \brief vos_nv_getChannelEnabledState -
1750 \param rfChannel - input channel enum to know evabled state
1751 \return eNVChannelEnabledType enabled state for channel
1752 * enabled
1753 * disabled
1754 * DFS
1755 \sa
1756 -------------------------------------------------------------------------*/
1757eNVChannelEnabledType vos_nv_getChannelEnabledState
1758(
1759 v_U32_t rfChannel
1760)
1761{
1762 v_U32_t channelLoop;
1763 eRfChannels channelEnum = INVALID_RF_CHANNEL;
1764
1765 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
1766 {
1767 if(rfChannels[channelLoop].channelNum == rfChannel)
1768 {
1769 channelEnum = (eRfChannels)channelLoop;
1770 break;
1771 }
1772 }
1773
1774 if(INVALID_RF_CHANNEL == channelEnum)
1775 {
1776 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08001777 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001778 return NV_CHANNEL_INVALID;
1779 }
1780
1781 return regChannels[channelEnum].enabled;
1782}
1783#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001784
1785/******************************************************************
1786 Add CRDA regulatory support
1787*******************************************************************/
1788#ifdef CONFIG_CFG80211
1789
1790static int bw20_ch_index_to_bw40_ch_index(int k)
1791{
1792 int m = -1;
1793 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
1794 {
1795 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
1796 if (m > RF_CHAN_BOND_11)
1797 m = RF_CHAN_BOND_11;
1798 }
1799 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
1800 {
1801 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
1802 if (m > RF_CHAN_BOND_214)
1803 m = RF_CHAN_BOND_214;
1804 }
1805 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
1806 {
1807 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
1808 if (m > RF_CHAN_BOND_62)
1809 m = RF_CHAN_BOND_62;
1810 }
1811 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
1812 {
1813 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
1814 if (m > RF_CHAN_BOND_138)
1815 m = RF_CHAN_BOND_138;
1816 }
1817 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
1818 {
1819 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
1820 if (m > RF_CHAN_BOND_163)
1821 m = RF_CHAN_BOND_163;
1822 }
1823return m;
1824}
1825
1826/* create_crda_regulatory_entry should be called from user command or 11d country IE */
1827static int create_crda_regulatory_entry(struct wiphy *wiphy,
1828 struct regulatory_request *request,
1829 v_U8_t nBandCapability)
1830{
1831 int i, j, m;
1832 int k = 0, n = 0;
1833
1834 if (run_time_alpha2[0]==request->alpha2[0] &&
1835 run_time_alpha2[1]==request->alpha2[1] &&
1836 crda_regulatory_run_time_entry_valid == VOS_TRUE)
1837 return 0; /* already created */
1838
1839 /* 20MHz channels */
1840 if (nBandCapability == eCSR_BAND_24)
1841 pr_info("BandCapability is set to 2G only.\n");
1842 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
1843 {
1844 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
1845 continue;
1846 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
1847 continue;
1848 if (wiphy->bands[i] == NULL)
1849 {
1850 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
1851 return -1;
1852 }
1853 // internal channels[] is one continous array for both 2G and 5G bands
1854 // m is internal starting channel index for each band
1855 if (i == 0)
1856 m = 0;
1857 else
1858 m = wiphy->bands[i-1]->n_channels + m;
1859 for (j=0;j<wiphy->bands[i]->n_channels;j++)
1860 {
1861 // k = (m + j) is internal current channel index for 20MHz channel
1862 // n is internal channel index for corresponding 40MHz channel
1863 k = m + j;
1864 n = bw20_ch_index_to_bw40_ch_index(k);
1865 if (n == -1)
1866 return -1;
1867 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
1868 {
1869 if (pnvEFSTable == NULL)
1870 {
1871 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
1872 return -1;
1873 }
1874 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
1875 NV_CHANNEL_DISABLE;
1876 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
1877 NV_CHANNEL_DISABLE;
1878 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
1879 // rfChannels[n].channelNum);
1880 }
1881 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
1882 {
1883 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
1884 NV_CHANNEL_DFS;
1885 // max_power is in mBm = 100 * d
1886 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
1887 (tANI_S8) (wiphy->bands[i]->channels[j].max_power);
1888 pr_info("CH %d is enabled and DFS, max power %d dBm.\n", rfChannels[k].channelNum,
1889 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit);
1890 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
1891 {
1892 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
1893 NV_CHANNEL_DFS;
1894 // 40MHz channel power is half of 20MHz (-3dB) ??
1895 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
1896 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)-3);
1897 pr_info(" CH %d is enabled for 40MHz and DFS, max power %d dBm.\n", rfChannels[n].channelNum,
1898 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit);
1899 }
1900 }
1901 else // Enable is only last flag we support
1902 {
1903 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
1904 NV_CHANNEL_ENABLE;
1905 // max_power is in dBm
1906 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
1907 (tANI_S8) (wiphy->bands[i]->channels[j].max_power);
1908 pr_info("CH %d is enabled and no DFS, max power %d dBm.\n", rfChannels[k].channelNum,
1909 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit);
1910 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
1911 {
1912 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
1913 NV_CHANNEL_ENABLE;
1914 // 40MHz channel power is half of 20MHz (-3dB) ??
1915 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
1916 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)-3);
1917 pr_info(" CH %d is enabled for 40MHz and no DFS, max power %d dBm.\n", rfChannels[n].channelNum,
1918 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit);
1919 }
1920 }
1921 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
1922 real gain which should be provided by the real design */
1923 }
1924 }
1925 if (k == 0)
1926 return -1;
1927 run_time_alpha2[0] = request->alpha2[0];
1928 run_time_alpha2[1] = request->alpha2[1];
1929 crda_regulatory_run_time_entry_valid = VOS_TRUE;
1930return 0;
1931}
1932v_BOOL_t is_crda_regulatory_entry_valid(void)
1933{
1934return crda_regulatory_entry_valid;
1935}
1936
1937/* Handling routines for the conversion from regd rules (start/end freq) to channel index
1938start freq + 10000 = center freq of the 20MHz start channel
1939end freq - 10000 = center freq of the 20MHz end channel
1940start freq + 20000 = center freq of the 40MHz start channel
1941end freq - 20000 = center freq of the 40MHz end channel
1942*/
1943static int bw20_start_freq_to_channel_index(u32 freq_khz)
1944{
1945int i;
1946u32 center_freq = freq_khz + 10000;
1947 //Has to compare from low freq to high freq
1948 //RF_SUBBAND_2_4_GHZ
1949 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
1950 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
1951 return i;
1952#ifdef FEATURE_WLAN_INTEGRATED_SOC
1953 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
1954 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
1955 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
1956 return i;
1957 //RF_SUBBAND_5_LOW_GHZ
1958 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
1959 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
1960 return i;
1961 //RF_SUBBAND_5_MID_GHZ
1962 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
1963 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
1964 return i;
1965 //RF_SUBBAND_5_HIGH_GHZ
1966 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
1967 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
1968 return i;
1969#endif
1970return -1;
1971}
1972
1973static int bw20_end_freq_to_channel_index(u32 freq_khz)
1974{
1975int i;
1976u32 center_freq = freq_khz - 10000;
1977 //Has to compare from high freq to low freq
1978#ifdef FEATURE_WLAN_INTEGRATED_SOC
1979 //RF_SUBBAND_5_HIGH_GHZ
1980 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
1981 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
1982 return i;
1983 //RF_SUBBAND_5_MID_GHZ
1984 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
1985 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
1986 return i;
1987 //RF_SUBBAND_5_LOW_GHZ
1988 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
1989 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
1990 return i;
1991 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
1992 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
1993 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
1994 return i;
1995#endif
1996 //RF_SUBBAND_2_4_GHZ
1997 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
1998 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
1999 return i;
2000return -1;
2001}
2002
2003static int bw40_start_freq_to_channel_index(u32 freq_khz)
2004{
2005int i;
2006u32 center_freq = freq_khz + 20000;
2007 //Has to compare from low freq to high freq
2008 //RF_SUBBAND_2_4_GHZ
2009 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2010 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2011 return i;
2012#ifdef FEATURE_WLAN_INTEGRATED_SOC
2013 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2014 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2015 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2016 return i;
2017 //RF_SUBBAND_5_LOW_GHZ
2018 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2019 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2020 return i;
2021 //RF_SUBBAND_5_MID_GHZ
2022 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
2023 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2024 return i;
2025 //RF_SUBBAND_5_HIGH_GHZ
2026 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2027 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2028 return i;
2029#endif
2030return -1;
2031}
2032
2033static int bw40_end_freq_to_channel_index(u32 freq_khz)
2034{
2035int i;
2036u32 center_freq = freq_khz - 20000;
2037 //Has to compare from high freq to low freq
2038#ifdef FEATURE_WLAN_INTEGRATED_SOC
2039 //RF_SUBBAND_5_HIGH_GHZ
2040 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2041 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2042 return i;
2043 //RF_SUBBAND_5_MID_GHZ
2044 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
2045 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2046 return i;
2047 //RF_SUBBAND_5_LOW_GHZ
2048 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2049 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2050 return i;
2051 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2052 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2053 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2054 return i;
2055#endif
2056 //RF_SUBBAND_2_4_GHZ
2057 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2058 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2059 return i;
2060return -1;
2061}
2062
2063static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2064{
2065 switch (nBandCapability)
2066 {
2067 case eCSR_BAND_ALL:
2068 return VOS_TRUE;
2069 case eCSR_BAND_24:
2070 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2071 return VOS_TRUE;
2072 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2073 return VOS_TRUE; // 2.4G 40MHz channel
2074 break;
2075 case eCSR_BAND_5G:
2076 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2077 return VOS_TRUE;
2078 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2079 return VOS_TRUE; // 2.4G 40MHz channel
2080 break;
2081 default:
2082 break;
2083 }
2084 return VOS_FALSE;
2085}
2086
2087/* create_crda_regulatory_entry_from_regd should be called during init time */
2088static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2089 struct regulatory_request *request,
2090 v_U8_t nBandCapability)
2091{
2092 int i, j, n, domain_id;
2093 int bw20_start_channel_index, bw20_end_channel_index;
2094 int bw40_start_channel_index, bw40_end_channel_index;
2095
2096 if (wiphy == NULL || wiphy->regd == NULL)
2097 {
2098 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2099 return -1;
2100 }
2101 if (crda_regulatory_entry_valid == VOS_FALSE)
2102 domain_id = NUM_REG_DOMAINS-1; /* init time */
2103 else
2104 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2105 for (n = 0; n < NUM_RF_CHANNELS; n++)
2106 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2107
2108 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2109 {
2110 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2111 bw20_start_channel_index =
2112 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2113 bw20_end_channel_index =
2114 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2115 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2116 {
2117 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2118 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2119 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2120 continue; // skip this rull, but continue to next rule
2121 }
2122 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2123 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2124 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2125 bw20_start_channel_index, bw20_end_channel_index);
2126 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2127 {
2128 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2129 {
2130 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2131 rfChannels[j].channelNum);
2132 continue; // skip this channel, continue to next
2133 }
2134 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2135 {
2136 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2137 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2138 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2139 }
2140 else
2141 {
2142 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2143 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2144 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2145 }
2146 /* max_eirp is in mBm (= 100 * dBm) unit */
2147 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2148 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2149 }
2150 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2151 real gain which should be provided by the real design */
2152 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2153 {
2154 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2155 bw40_start_channel_index =
2156 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2157 bw40_end_channel_index =
2158 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2159 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2160 {
2161 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2162 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2163 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2164 continue; // skip this rull, but continue to next rule
2165 }
2166 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2167 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2168 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2169 bw40_start_channel_index, bw40_end_channel_index);
2170 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2171 {
2172 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2173 continue; // skip this channel, continue to next
2174 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2175 {
2176 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2177 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2178 }
2179 else
2180 {
2181 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2182 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2183 }
2184 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2185 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2186 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2187 }
2188 }
2189 }
2190 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
2191 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
2192 these flags and has no implementation yet. */
2193 if (crda_regulatory_entry_valid == VOS_FALSE)
2194 { /* init time */
2195 crda_alpha2[0] = request->alpha2[0];
2196 crda_alpha2[1] = request->alpha2[1];
2197 crda_regulatory_entry_valid = VOS_TRUE;
2198 }
2199 else
2200 { /* none-default country */
2201 run_time_alpha2[0] = request->alpha2[0];
2202 run_time_alpha2[1] = request->alpha2[1];
2203 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2204 }
2205 return 0;
2206}
2207
2208/*
2209 * Function: wlan_hdd_crda_reg_notifier
2210 * This function is called from cfg80211 core to provide regulatory settings
2211 * after new country is requested or intersected (init, user input or 11d)
2212 * This function is used to create a CRDA regulatory settings entry into internal
2213 * regulatory setting table.
2214 */
2215int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
2216 struct regulatory_request *request)
2217{
2218 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2219 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
2220 " %c%c\n", request->alpha2[0], request->alpha2[1]);
2221 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
2222 {
2223 wiphy_dbg(wiphy, "info: set by user\n");
2224 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
2225 return 0;
2226 // ToDo
2227 /* Don't change default country code to CRDA country code by user req */
2228 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
2229 regd for new country settings */
2230 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2231 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2232 }
2233 else if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
2234 {
2235 wiphy_dbg(wiphy, "info: set by country IE\n");
2236 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
2237 return 0;
2238 // ToDo
2239 /* Intersect of 11d and crda settings */
2240
2241 /* Don't change default country code to CRDA country code by 11d req */
2242 /* for every adapter call sme_ChangeCountryCode to trigger read regd
2243 for intersected new country settings */
2244 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2245 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2246 }
2247 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
2248 {
2249 wiphy_dbg(wiphy, "info: set by driver\n");
2250 /* if set by driver itself, it means driver can accept the crda
2251 regulatory settings and wiphy->regd should be populated with crda
2252 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
2253 correctly, this may be fixed by later kernel */
2254 if (create_crda_regulatory_entry_from_regd(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
2255 {
2256 pr_info("crda entry created.\n");
2257 if (crda_alpha2[0] == request->alpha2[0] && crda_alpha2[1] == request->alpha2[1])
2258 { /* first CRDA request should be from init time */
2259 /* Change default country code to CRDA country code, assume indoor */
2260 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = request->alpha2[0];
2261 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = request->alpha2[1];
2262 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2263 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2264 wiphy_dbg(wiphy, "info: init time default country code is %c%c%c\n",
2265 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
2266 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
2267 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2]);
2268 }
2269 else /* second or later CRDA request after init time */
2270 {
2271 wiphy_dbg(wiphy, "info: crda none-default country code is %c%c\n",
2272 request->alpha2[0], request->alpha2[1]);
2273 }
2274 // hdd will read regd for this country after complete
2275 }
2276 complete(&pHddCtx->driver_crda_req);
2277
2278 /* Haven't seen any condition that will set by driver after init.
2279 If we do, then we should also call sme_ChangeCountryCode */
2280 }
2281return 0;
2282}
2283#endif