blob: 89555c816551f3d98d35bc8a829d855d616e5158 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002* Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
3* All Rights Reserved.
4* Qualcomm Atheros Confidential and Proprietary.
5*/
Jeff Johnson295189b2012-06-20 16:38:30 -07006
7/*============================================================================
8 FILE: vos_nvitem.c
9 OVERVIEW: This source file contains definitions for vOS NV Item APIs
10 DEPENDENCIES: NV, remote API client, WinCE REX
11 Copyright (c) 2008 QUALCOMM Incorporated.
12 All Rights Reserved.
13 Qualcomm Confidential and Proprietary
14============================================================================*/
15/*============================================================================
16 EDIT HISTORY FOR MODULE
17============================================================================*/
18// the following is used to disable warning for having too many labels in
19// the 'nv_items_enum_type'
20
21/*----------------------------------------------------------------------------
22 * Include Files
23 * -------------------------------------------------------------------------*/
24#include "vos_types.h"
25#include "aniGlobal.h"
26#include "vos_nvitem.h"
27#include "vos_trace.h"
28#include "vos_api.h"
29#include "wlan_hdd_misc.h"
30#include "vos_sched.h"
Amar Singhal0d15bd52013-10-12 23:13:13 -070031#include "sme_Api.h"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070032#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070033#include "wlan_hdd_main.h"
34#include <net/cfg80211.h>
Amar Singhalfddc28c2013-09-05 13:03:40 -070035
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -070036#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
37#define IEEE80211_CHAN_NO_80MHZ 1<<7
38#endif
Amar Singhala49cbc52013-10-08 18:37:44 -070039
Amar Singhalfddc28c2013-09-05 13:03:40 -070040#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhala49cbc52013-10-08 18:37:44 -070041
42static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -070043static char linux_reg_cc[2] = {0, 0};
Amar Singhalfddc28c2013-09-05 13:03:40 -070044static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
Amar Singhala49cbc52013-10-08 18:37:44 -070045
Abhishek Singha306a442013-11-07 18:39:01 +053046#else
47
48/* Cant access pAdapter in this file so defining a new variable to wait when changing country*/
49static struct completion change_country_code;
50
Amar Singhalfddc28c2013-09-05 13:03:40 -070051#endif
52
Amar Singhala49cbc52013-10-08 18:37:44 -070053static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
54static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
55static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
56static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
57
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059/*----------------------------------------------------------------------------
60 * Preprocessor Definitions and Constants
61 * -------------------------------------------------------------------------*/
62#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
63#define VALIDITY_BITMAP_SIZE 32
64#define MAX_COUNTRY_COUNT 300
65//To be removed when NV support is fully functional
66#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070067
68#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070069#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070070
Jeff Johnson295189b2012-06-20 16:38:30 -070071/*----------------------------------------------------------------------------
72 * Type Declarations
73 * -------------------------------------------------------------------------*/
74// this wrapper structure is identical to nv_cmd_type except the
75// data_ptr type is changed void* to avoid exceeding the debug information
76// module size as there are too many elements within nv_items_type union
77
78// structure for code and regulatory domain of a single country
79typedef struct
80{
81 v_U8_t regDomain;
82 v_COUNTRYCODE_t countryCode;
83} CountryInfo_t;
84// structure of table to map country code and regulatory domain
85typedef struct
86{
87 v_U16_t countryCount;
88 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
89} CountryInfoTable_t;
90/*----------------------------------------------------------------------------
91 * Global Data Definitions
92 * -------------------------------------------------------------------------*/
93/*----------------------------------------------------------------------------
94 * Static Variable Definitions
95 * -------------------------------------------------------------------------*/
Amar Singhala49cbc52013-10-08 18:37:44 -070096// cache of country info table;
97// this is re-initialized from data on binary file
98// loaded on driver initialization if available
Amar Singhalfddc28c2013-09-05 13:03:40 -070099
100#ifdef CONFIG_ENABLE_LINUX_REG
101
102static CountryInfoTable_t countryInfoTable =
103{
104 /* the first entry in the table is always the world domain */
105 138,
106 {
107 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
108 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
109 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
110 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
111 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
112 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
113 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
114 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
115 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
116 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
117 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
118 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
119 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
120 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
121 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
122 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
123 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
124 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
125 {REGDOMAIN_ETSI, {'B', 'L'}}, //
126 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
127 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
128 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
129 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
130 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
131 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
132 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
133 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
134 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
135 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
136 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
137 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
138 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
139 {REGDOMAIN_ETSI, {'C', 'S'}},
140 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
141 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
142 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
143 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
144 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
145 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
146 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
147 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
148 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
149 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
150 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
151 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
152 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
153 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
154 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
155 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
156 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
157 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
158 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
159 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
160 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
161 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
162 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
163 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
164 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
165 {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
166 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
167 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
168 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
169 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
170 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
171 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
172 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
173 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
174 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
175 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
176 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
177 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
178 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
179 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
180 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
181 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
182 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
183 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
184 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
185 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
186 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
187 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
188 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
189 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
190 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
191 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
192 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
193 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
194 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
195 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
196 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
197 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
198 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
199 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
200 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
201 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
202 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
203 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
204 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
205 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
206 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
207 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
208 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
209 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
210 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
211 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
212 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
213 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
214 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
215 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
216 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
217 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
218 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
219 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
220 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
221 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
222 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
223 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
224 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
225 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
226 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
227 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
228 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
229 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
230 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
231 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
232 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
233 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
234 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
235 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
236 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
237 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
238 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
239 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
240 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
241 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
242 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
243 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
244 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
245 }
246};
247
248#else
249
Jeff Johnson295189b2012-06-20 16:38:30 -0700250// cache of country info table;
251// this is re-initialized from data on binary file
252// loaded on driver initialization if available
253static CountryInfoTable_t countryInfoTable =
254{
255 254,
256 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700257 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
258 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
259 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
260 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
261 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
262 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700263 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700264 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
265 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
266 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
267 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
268 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
269 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
270 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530271 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700272 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
273 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
274 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
275 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
276 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700277 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700278 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
279 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
280 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
281 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
282 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
283 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
284 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
285 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
286 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
287 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
288 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
289 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
290 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
291 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
292 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
293 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
294 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
295 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
296 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
297 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
298 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
299 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
300 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
301 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
302 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
303 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530304 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700305 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
306 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
307 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
308 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
309 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
310 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
311 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
312 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
313 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
314 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
315 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
316 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700317 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700318 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
319 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
320 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
321 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
322 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
323 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
324 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
325 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
326 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
327 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
328 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
329 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
330 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
331 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
332 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
333 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
334 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
335 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
336 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
337 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
338 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
339 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
340 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
341 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
342 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
343 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
344 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
345 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
346 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
347 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700348 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700349 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
350 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
351 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
352 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
353 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
354 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
355 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
356 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
357 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
358 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700359 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700360 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
361 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
362 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
363 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
364 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
365 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
366 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
367 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
368 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
369 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
370 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
371 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
372 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
373 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700374 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700375 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
376 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
377 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
378 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
379 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700380 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700381 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
382 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
383 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
384 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
385 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
386 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
387 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
388 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
389 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700390 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700391 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700392 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700393 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
394 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
395 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
396 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
397 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
398 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
399 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
400 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
401 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700402 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700403 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700404 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
405 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
406 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
407 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
408 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
409 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
410 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700411 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700412 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
413 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
414 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
415 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
416 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
417 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
418 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
419 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
420 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
421 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
422 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
423 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
424 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
425 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
426 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
427 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
428 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
429 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
430 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
431 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700432 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700433 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
434 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
435 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700436 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700437 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700438 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700439 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700440 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
441 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700442 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
443 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
444 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
445 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
446 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
447 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
448 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
449 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
450 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
451 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
452 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
453 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
454 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700455 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
456 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
457 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700458 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
459 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
460 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
461 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
462 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
463 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
464 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
465 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
466 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
467 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
468 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
469 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
470 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
471 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
472 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
473 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
474 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
475 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
476 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
477 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
478 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
479 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
480 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
481 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
482 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
483 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
484 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
485 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
486 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700487 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700488 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
489 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700490 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700491 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700492 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
493 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700494 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
495 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700496 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700497 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
498 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
499 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
500 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
501 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700502 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700503 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
504 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
505 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
506 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
507 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
508 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
509 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700510 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700511 }
512};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700513
514#endif
515
Amar Singhala49cbc52013-10-08 18:37:44 -0700516
Jeff Johnson295189b2012-06-20 16:38:30 -0700517typedef struct nvEFSTable_s
518{
519 v_U32_t nvValidityBitmap;
520 sHalNv halnv;
521} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700522nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700523/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700524static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700525static v_U8_t *pnvEncodedBuf;
526static v_U8_t *pDictFile;
527static v_U8_t *pEncodedBuf;
528static v_SIZE_t nvReadEncodeBufSize;
529static v_SIZE_t nDictionarySize;
530static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700531
Leo Chang80de3c22013-11-26 10:52:12 -0800532/* NV2 specific, No CH 144 support
533 * For NV_FTM operation, NV2 structure should be maintained
534 * This will be used only for the NV_FTM operation */
535typedef struct nvEFSTableV2_s
536{
537 v_U32_t nvValidityBitmap;
538 sHalNvV2 halnvV2;
539} nvEFSTableV2_t;
540nvEFSTableV2_t *gnvEFSTableV2;
541
Jeff Johnson295189b2012-06-20 16:38:30 -0700542const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
543{
544 //RF_SUBBAND_2_4_GHZ
545 //freq, chan#, band
546 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
547 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
548 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
549 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
550 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
551 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
552 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
553 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
554 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
555 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
556 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
557 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
558 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
559 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700560 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
561 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
562 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
563 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
564 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
565 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
566 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700567 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
568 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
569 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
570 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
571 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
572 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
573 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
574 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
575 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
576 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
577 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
578 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
579 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
580 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
581 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
582 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
583 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
584 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
585 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
Leo Chang80de3c22013-11-26 10:52:12 -0800586#ifdef FEATURE_WLAN_CH144
587 { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144,
588#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700589 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
590 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
591 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
592 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
593 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700594 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
595 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
596 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
597 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
598 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
599 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
600 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
601 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
602 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
603 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
604 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
605 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
606 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
607 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
608 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
609 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
610 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
611 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
612 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
613 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
614 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
615 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
616 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
617 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
618 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
619 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
620 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
621 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
622 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
623 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
624 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
Leo Chang80de3c22013-11-26 10:52:12 -0800625#ifdef FEATURE_WLAN_CH144
626 { 5730, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142,
627#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700628 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
629 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
630 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
631 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700632};
633
634extern const sHalNv nvDefaults;
635
636const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
637
638/*----------------------------------------------------------------------------
639 Function Definitions and Documentation
640 * -------------------------------------------------------------------------*/
641VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
642/**------------------------------------------------------------------------
643 \brief vos_nv_init() - initialize the NV module
644 The \a vos_nv_init() initializes the NV module. This read the binary
645 file for country code and regulatory domain information.
646 \return VOS_STATUS_SUCCESS - module is initialized successfully
647 otherwise - module is not initialized
648 \sa
649 -------------------------------------------------------------------------*/
650VOS_STATUS vos_nv_init(void)
651{
652 return VOS_STATUS_SUCCESS;
653}
654
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700655/**------------------------------------------------------------------------
656 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
657 \ tools
658 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
659 otherwise - not successful
660 \sa
661-------------------------------------------------------------------------*/
662VOS_STATUS vos_nv_get_dictionary_data(void)
663{
664 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
665
666 if (MAGIC_NUMBER != magicNumber)
667 {
668 return VOS_STATUS_SUCCESS;
669 }
670
671 nDictionarySize = 0;
672
673 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
674 &nDictionarySize );
675 if (VOS_STATUS_E_NOMEM != vosStatus)
676 {
677 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
678 "Error obtaining binary size" );
679/// NOTE:
680/// We can still work without a dictionary file..
681 return VOS_STATUS_SUCCESS;
682 }
683
684 // malloc a buffer to read in the Configuration binary file.
685 pDictFile = vos_mem_malloc( nDictionarySize );
686 if (NULL == pDictFile)
687 {
688 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
689 "Unable to allocate memory for the CFG binary [size= %d bytes]",
690 nDictionarySize );
691 vosStatus = VOS_STATUS_E_NOMEM;
692 goto fail;
693 }
694
695 /* Get the entire CFG file image... */
696 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
697 &nDictionarySize );
698 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
699 {
700 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
701 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
702 nDictionarySize );
703 return VOS_STATUS_SUCCESS;
704 }
705
706 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
707 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
708
709fail:
710 return vosStatus;
711}
712
Leo Chang80de3c22013-11-26 10:52:12 -0800713/**------------------------------------------------------------------------
714 \brief vos_nv_parseV2bin() - Parse NV2 binary
715 Parse NV2 BIN, and assign contents to common NV structure.
716 \param pnvEncodedBuf
717 NV Bin read buffer
718 \param nvReadBufSize
719 NV Bin read size
720 \param halNv
721 common NV structure storage pointer
722 \return VOS_STATUS_SUCCESS - module is initialized successfully
723 otherwise - module is not initialized
724 \sa
725 -------------------------------------------------------------------------*/
726VOS_STATUS vos_nv_parseV2bin(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
727 sHalNv *halNv)
728{
729 sHalNvV2 *nv2Table;
730 tANI_U16 copyLoop;
731 tANI_U16 channelLoop;
732 void *targetPtr;
733 void *sourcePtr;
734
735 v_U32_t structSize = 0;
736
737 nv2Table = (sHalNvV2 *)pnvEncodedBuf;
738 /* NV Field Default Copy */
739 vos_mem_copy((char *)&halNv->fields,
740 (char *)&nv2Table->fields,
741 sizeof(sNvFields));
742 structSize += sizeof(sNvFields);
743 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
744 "%s: sizeof(sNvFields) %zu, structSize %d",
745 __func__, sizeof(sNvFields), structSize);
746
747 /* NV Table, tRateGroupPwr, NOT depends on channel count */
748 vos_mem_copy((char *)halNv->tables.pwrOptimum,
749 (char *)nv2Table->tables.pwrOptimum,
750 sizeof(halNv->tables.pwrOptimum));
751 structSize += sizeof(halNv->tables.pwrOptimum);
752 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
753 "%s: sizeof(halNv->tables.pwrOptimum) %zu, structSize %d",
754 __func__, sizeof(halNv->tables.pwrOptimum), structSize);
755
756 /* NV Table, regDomains, edepends on channel count */
757 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
758 {
759 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].antennaGain,
760 (char *)nv2Table->tables.regDomains[copyLoop].antennaGain,
761 sizeof(halNv->tables.regDomains[copyLoop].antennaGain));
762 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
763
764 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].bRatePowerOffset,
765 (char *)nv2Table->tables.regDomains[copyLoop].bRatePowerOffset,
766 sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset));
767 structSize += sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset);
768 }
769
770 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
771 {
772 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].channels[0]);
773 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].channels[0]);
774 /* Cannot blindly copy
775 * Each single CH should be assigned */
776 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
777 {
778#ifdef FEATURE_WLAN_CH144
779 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
780 {
781 /* NV2 CH144 is disabled */
782 halNv->tables.regDomains[copyLoop].channels[channelLoop].enabled =
783 NV_CHANNEL_DISABLE;
784 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
785 }
786 else
787#endif /* FEATURE_WLAN_CH144 */
788 {
789
790 vos_mem_copy(targetPtr, sourcePtr, sizeof(sRegulatoryChannel));
791 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
792 sourcePtr = sourcePtr + sizeof(sRegulatoryChannel);
793 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
794 }
795 }
796 }
797 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
798 "%s: sizeof(halNv->tables.regDomains[copyLoop].antennaGain) %zu, structSize %d",
799 __func__, sizeof(halNv->tables.regDomains[copyLoop].antennaGain), structSize);
800
801 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
802 {
803 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
804 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
805 /* Cannot blindly copy
806 * Each single CH should be assigned */
807 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
808 {
809#ifdef FEATURE_WLAN_CH144
810 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
811 {
812 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
813 }
814 else
815#endif /* FEATURE_WLAN_CH144 */
816 {
817 vos_mem_copy(targetPtr, sourcePtr, sizeof(uAbsPwrPrecision));
818 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
819 sourcePtr = sourcePtr + sizeof(uAbsPwrPrecision);
820 structSize += sizeof(sizeof(uAbsPwrPrecision));
821 }
822 }
823 }
824 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
825 "%s: sizeof(uAbsPwrPrecision) %zu, structSize %d",
826 __func__, sizeof(uAbsPwrPrecision), structSize);
827
828 /* nvTable, defaultCountryTable, NOT depends on channel counts */
829 vos_mem_copy((char *)&halNv->tables.defaultCountryTable,
830 (char *)&nv2Table->tables.defaultCountryTable,
831 sizeof(halNv->tables.defaultCountryTable));
832 structSize += sizeof(halNv->tables.defaultCountryTable);
833 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
834 "%s: sizeof(halNv->tables.defaultCountryTable) %zu, structSize %d",
835 __func__, sizeof(halNv->tables.defaultCountryTable), structSize);
836
837 /* NV Table, plutCharacterized, depends on channel count
838 * Cannot blindly copy
839 * Each single CH should be assigned */
840 targetPtr = (char *)&(halNv->tables.plutCharacterized[0]);
841 sourcePtr = (char *)&(nv2Table->tables.plutCharacterized[0]);
842 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
843 {
844#ifdef FEATURE_WLAN_CH144
845 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
846 {
847 targetPtr = targetPtr + sizeof(tTpcPowerTable);
848 }
849 else
850#endif /* FEATURE_WLAN_CH144 */
851 {
852 vos_mem_copy(targetPtr, sourcePtr, sizeof(tTpcPowerTable));
853 targetPtr = targetPtr + sizeof(tTpcPowerTable);
854 sourcePtr = sourcePtr + sizeof(tTpcPowerTable);
855 structSize += sizeof(tTpcPowerTable);
856 }
857 }
858 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
859 "%s: sizeof(tTpcPowerTable) %zu, structSize %d",
860 __func__, sizeof(tTpcPowerTable), structSize);
861
862 /* NV Table, plutPdadcOffset, depends on channel count
863 * Cannot blindly copy
864 * Each single CH should be assigned */
865 targetPtr = (char *)&(halNv->tables.plutPdadcOffset[0]);
866 sourcePtr = (char *)&(nv2Table->tables.plutPdadcOffset[0]);
867 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
868 {
869#ifdef FEATURE_WLAN_CH144
870 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
871 {
872 targetPtr = targetPtr + sizeof(int16);
873 }
874 else
875#endif /* FEATURE_WLAN_CH144 */
876 {
877 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
878 targetPtr = targetPtr + sizeof(int16);
879 sourcePtr = sourcePtr + sizeof(int16);
880 structSize += sizeof(int16);
881 }
882 }
883 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
884 "%s: sizeof(halNv->tables.plutPdadcOffset) %zu, structSize %d",
885 __func__, sizeof(int16), structSize);
886
887 /* NV Table, pwrOptimum_virtualRate, NOT depends on channel count */
888 vos_mem_copy((char *)halNv->tables.pwrOptimum_virtualRate,
889 (char *)nv2Table->tables.pwrOptimum_virtualRate,
890 sizeof(halNv->tables.pwrOptimum_virtualRate));
891 structSize += sizeof(halNv->tables.pwrOptimum_virtualRate);
892 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
893 "%s: sizeof(halNv->tables.pwrOptimum_virtualRate) %zu, structSize %d",
894 __func__, sizeof(halNv->tables.pwrOptimum_virtualRate), structSize);
895
896 /* NV Table, fwConfig, NOT depends on channel count */
897 vos_mem_copy((char *)&halNv->tables.fwConfig,
898 (char *)&nv2Table->tables.fwConfig,
899 sizeof(halNv->tables.fwConfig));
900 structSize += sizeof(halNv->tables.fwConfig);
901 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
902 "%s: sizeof(halNv->tables.fwConfig) %zu, structSize %d",
903 __func__, sizeof(halNv->tables.fwConfig), structSize);
904
905 /* NV Table, rssiChanOffsets, depends on channel count
906 * Cannot blindly copy
907 * Each single CH should be assigned */
908 for (copyLoop = 0; copyLoop < 2; copyLoop++)
909 {
910 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
911 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
912 /* Cannot blindly copy
913 * Each single CH should be assigned */
914 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
915 {
916#ifdef FEATURE_WLAN_CH144
917 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
918 {
919 targetPtr = targetPtr + sizeof(int16);
920 }
921 else
922#endif /* FEATURE_WLAN_CH144 */
923 {
924 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
925 targetPtr = targetPtr + sizeof(int16);
926 sourcePtr = sourcePtr + sizeof(int16);
927 structSize += sizeof(int16);
928 }
929 }
930 }
931 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
932 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
933 __func__, sizeof(int16), structSize);
934
935 for (copyLoop = 0; copyLoop < 2; copyLoop++)
936 {
937 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
938 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
939 /* Cannot blindly copy
940 * Each single CH should be assigned */
941 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
942 {
943#ifdef FEATURE_WLAN_CH144
944 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
945 {
946 targetPtr = targetPtr + sizeof(int16);
947 }
948 else
949#endif /* FEATURE_WLAN_CH144 */
950 {
951 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
952 targetPtr = targetPtr + sizeof(int16);
953 sourcePtr = sourcePtr + sizeof(int16);
954 structSize += sizeof(int16);
955 }
956 }
957 }
958 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
959 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
960 __func__, sizeof(int16), structSize);
961
962 /* NV Table, hwCalValues, NOT depends on channel count */
963 vos_mem_copy((char *)&halNv->tables.hwCalValues,
964 (char *)&nv2Table->tables.hwCalValues,
965 sizeof(halNv->tables.hwCalValues));
966 structSize += sizeof(halNv->tables.fwConfig);
967 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
968 "%s: sizeof(halNv->tables.hwCalValues) %zu, structSize %d",
969 __func__, sizeof(halNv->tables.hwCalValues), structSize);
970
971 /* NV Table, antennaPathLoss, depends on channel count
972 * Cannot blindly copy
973 * Each single CH should be assigned */
974 targetPtr = (char *)&(halNv->tables.antennaPathLoss[0]);
975 sourcePtr = (char *)&(nv2Table->tables.antennaPathLoss[0]);
976 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
977 {
978#ifdef FEATURE_WLAN_CH144
979 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
980 {
981 targetPtr = targetPtr + sizeof(int16);
982 }
983 else
984#endif /* FEATURE_WLAN_CH144 */
985 {
986 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
987 targetPtr = targetPtr + sizeof(int16);
988 sourcePtr = sourcePtr + sizeof(int16);
989 structSize += sizeof(int16);
990 }
991 }
992 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
993 "%s: sizeof(halNv->tables.antennaPathLoss) %zu, structSize %d",
994 __func__, sizeof(int16), structSize);
995
996 /* NV Table, pktTypePwrLimits, depends on channel count
997 * Cannot blindly copy
998 * Each single CH should be assigned */
999 for (copyLoop = 0; copyLoop < NUM_802_11_MODES; copyLoop++)
1000 {
1001 targetPtr = (char *)&(halNv->tables.pktTypePwrLimits[copyLoop][0]);
1002 sourcePtr = (char *)&(nv2Table->tables.pktTypePwrLimits[copyLoop][0]);
1003 /* Cannot blindly copy
1004 * Each single CH should be assigned */
1005 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1006 {
1007#ifdef FEATURE_WLAN_CH144
1008 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1009 {
1010 targetPtr = targetPtr + sizeof(int16);
1011 }
1012 else
1013#endif /* FEATURE_WLAN_CH144 */
1014 {
1015 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1016 targetPtr = targetPtr + sizeof(int16);
1017 sourcePtr = sourcePtr + sizeof(int16);
1018 structSize += sizeof(int16);
1019 }
1020 }
1021 }
1022 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1023 "%s: sizeof(halNv->tables.pktTypePwrLimits) %zu, structSize %d",
1024 __func__, sizeof(int16), structSize);
1025
1026 /* NV Table, ofdmCmdPwrOffset, NOT depends on channel count */
1027 vos_mem_copy((char *)&halNv->tables.ofdmCmdPwrOffset,
1028 (char *)&nv2Table->tables.ofdmCmdPwrOffset,
1029 sizeof(halNv->tables.ofdmCmdPwrOffset));
1030 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1031 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1032 "%s: sizeof(halNv->tables.ofdmCmdPwrOffset) %zu, structSize %d",
1033 __func__, sizeof(halNv->tables.ofdmCmdPwrOffset), structSize);
1034
1035 /* NV Table, txbbFilterMode, NOT depends on channel count */
1036 vos_mem_copy((char *)&halNv->tables.txbbFilterMode,
1037 (char *)&nv2Table->tables.txbbFilterMode,
1038 sizeof(halNv->tables.txbbFilterMode));
1039 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1040 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1041 "%s: sizeof(halNv->tables.txbbFilterMode) %zu, structSize %d",
1042 __func__, sizeof(halNv->tables.txbbFilterMode), structSize);
1043
1044 return VOS_STATUS_SUCCESS;
1045}
1046
1047/**------------------------------------------------------------------------
1048 \brief vos_nv_open() - Open NV operation
1049 Read NV bin file and prepare NV common structure
1050 \return VOS_STATUS_SUCCESS - module is initialized successfully
1051 otherwise - module is not initialized
1052 \sa
1053 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001054VOS_STATUS vos_nv_open(void)
1055{
1056 VOS_STATUS status = VOS_STATUS_SUCCESS;
1057 v_CONTEXT_t pVosContext= NULL;
1058 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001059 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -07001060 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001061 v_U32_t dataOffset;
1062 sHalNv *pnvData = NULL;
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001063 hdd_context_t *pHddCtx = NULL;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001064
Jeff Johnson295189b2012-06-20 16:38:30 -07001065 /*Get the global context */
1066 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001067
1068 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001069 {
1070 return (eHAL_STATUS_FAILURE);
1071 }
1072
Jeff Johnson295189b2012-06-20 16:38:30 -07001073 status = hdd_request_firmware(WLAN_NV_FILE,
1074 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001075 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001076
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001077 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001079 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001081 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001082 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001083 }
1084
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001085 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
1086
1087 /// Allocate buffer with maximum length..
1088 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
1089
1090 if (NULL == pEncodedBuf)
1091 {
1092 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1093 "%s : failed to allocate memory for NV", __func__);
1094 return VOS_STATUS_E_NOMEM;
1095 }
1096
Leo Chang80de3c22013-11-26 10:52:12 -08001097 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1098 "NV Table Size %zu", sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001099
Leo Chang80de3c22013-11-26 10:52:12 -08001100 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
1101 if (NULL == pnvEFSTable)
1102 {
1103 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1104 "%s : failed to allocate memory for NV", __func__);
1105 return VOS_STATUS_E_NOMEM;
1106 }
1107 vos_mem_zero((void *)pnvEFSTable, sizeof(nvEFSTable_t));
1108
1109 // Default NV version, NOT_VALID
1110 ((VosContextType*)(pVosContext))->nvVersion = E_NV_INVALID;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001111 if (MAGIC_NUMBER == magicNumber)
1112 {
Leo Chang80de3c22013-11-26 10:52:12 -08001113 bufSize = sizeof(nvEFSTable_t);
1114 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001115 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
1116
1117 if (NULL == pnvData)
1118 {
1119 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1120 "%s : failed to allocate memory for NV", __func__);
1121 return VOS_STATUS_E_NOMEM;
1122 }
1123
1124 memset(pnvData, 0, sizeof(sHalNv));
1125
1126 /// Data starts from offset of validity bit map + magic number..
1127 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
1128
1129 status = nvParser(&pnvEncodedBuf[dataOffset],
1130 (nvReadBufSize-dataOffset), pnvData);
1131
1132 ///ignore validity bit map
1133 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
1134
1135 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
1136 nvReadEncodeBufSize);
1137
Leo Chang80de3c22013-11-26 10:52:12 -08001138 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001139 "readEncodeBufSize %d",nvReadEncodeBufSize);
1140
1141 if (VOS_STATUS_SUCCESS == status) {
1142 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1143 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
1144 pnvData->fields.productId,
1145 pnvData->fields.couplerType,
1146 pnvData->fields.wlanNvRevId);
1147
1148 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
1149
1150 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
1151 }
1152 else
1153 {
1154 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1155 "nvParser failed %d",status);
1156
1157 nvReadBufSize = 0;
1158
1159 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
1160
1161 nvReadEncodeBufSize = sizeof(sHalNv);
1162 }
Leo Chang80de3c22013-11-26 10:52:12 -08001163 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1164
1165 /* NV verion is NV3 */
1166 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V3;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001167 }
1168 else
1169 {
Leo Chang80de3c22013-11-26 10:52:12 -08001170 bufSize = sizeof(nvEFSTableV2_t);
1171
1172 /*Copying the NV defaults */
1173 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1174 /* NV2 structure should be maintained to support NV_FTM */
1175 gnvEFSTableV2 = (nvEFSTableV2_t * )pnvEncodedBuf;
1176
1177 /* Size mismatch
1178 * NV 1 case, use default NV table */
1179 if (nvReadBufSize != bufSize)
1180 {
1181 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
1182 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1183 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
1184 nvReadBufSize, bufSize);
1185 return VOS_STATUS_SUCCESS;
1186 }
1187
1188 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1189 "NV_2: readBufferSize %zu, EFSV2DefaultSize %zu",
1190 nvReadBufSize, sizeof(nvEFSTableV2_t));
1191
1192 /* From here, NV2 will be stored into NV3 structure */
1193 dataOffset = sizeof(v_U32_t);
1194 nvReadEncodeBufSize = sizeof(sHalNvV2);
1195 vos_mem_copy(pEncodedBuf,
1196 &pnvEncodedBuf[dataOffset],
1197 nvReadBufSize - dataOffset);
1198
1199#ifdef FEATURE_WLAN_CH144
1200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1201 "Default NV2 size %zu", sizeof(nvDefaultsV2));
1202#else
1203 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1204 "Default NV2 size %zu", sizeof(nvDefaults));
1205#endif /* FEATURE_WLAN_CH144 */
1206 /* First assign value with NV default */
1207#ifdef FEATURE_WLAN_CH144
1208 vos_nv_parseV2bin((tANI_U8 *)&nvDefaultsV2,
1209 sizeof(sHalNvV2),
1210 &pnvEFSTable->halnv);
1211#else
1212 vos_nv_parseV2bin((tANI_U8 *)&nvDefaults,
1213 sizeof(sHalNvV2),
1214 &pnvEFSTable->halnv);
1215#endif /* FEATURE_WLAN_CH144 */
1216
1217 /* Actual update from NV.bin */
1218 vos_nv_parseV2bin(pEncodedBuf,
1219 nvReadEncodeBufSize,
1220 &pnvEFSTable->halnv);
1221
1222 vos_mem_copy((void *)&pnvEFSTable->nvValidityBitmap,
1223 pnvEncodedBuf, sizeof(v_U32_t));
1224 gnvEFSTable = pnvEFSTable;
1225
1226 /* NV verion is NV2 */
1227 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V2;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001228 }
1229
1230 if (NULL != pnvData)
1231 {
1232 vos_mem_free(pnvData);
1233 }
1234
1235 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001236 "INFO: NV binary file version=%d Driver default NV version=%d, continue...",
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001237 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
1238
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 /* Copying the read nv data to the globa NV EFS table */
1240 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001241 /* Version mismatch */
1242 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
1243 {
1244 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
1245 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
1246 {
1247 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1248 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
Arif Hussain02882402013-11-17 21:55:29 -08001249 "Make sure that this is intended or may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001250 }
Leo Chang80de3c22013-11-26 10:52:12 -08001251#ifdef FEATURE_WLAN_CH144
1252 else if ((WLAN_NV_VERSION == NV_VERSION_CH144_CONFIG) &&
1253 (((VosContextType*)(pVosContext))->nvVersion == E_NV_V2))
1254 {
1255 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1256 "!!!WARNING: Default NV is NV3 CH144 "
1257 "BIN is NV2, NV2 contents will be used!!!");
1258 }
1259#endif /* FEATURE_WLAN_CH144 */
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001260 else
1261 {
1262 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1263 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
Arif Hussain02882402013-11-17 21:55:29 -08001264 "Driver NV defaults will be used, may impact performance!!!");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001265
1266 return VOS_STATUS_SUCCESS;
1267 }
1268 }
1269
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001270 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001271 /* Copy the valid fields to the NV Global structure */
1272 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001273 VOS_STATUS_SUCCESS)
1274 {
1275 if (itemIsValid == VOS_TRUE) {
1276
1277 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
1278 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001279 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 }
1281 }
1282
Amar Singhalfddc28c2013-09-05 13:03:40 -07001283 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 VOS_STATUS_SUCCESS)
1285 {
1286 if (itemIsValid == VOS_TRUE)
1287 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001288 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001289 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
1290 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001291 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001292 }
1293 }
1294
Amar Singhalfddc28c2013-09-05 13:03:40 -07001295 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001296 VOS_STATUS_SUCCESS)
1297 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001298
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 if (itemIsValid == VOS_TRUE)
1300 {
1301 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
1302 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
1303 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001304 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 }
1306 }
1307
Amar Singhalfddc28c2013-09-05 13:03:40 -07001308 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001309 VOS_STATUS_SUCCESS)
1310 {
1311 if (itemIsValid == VOS_TRUE)
1312 {
1313 if(vos_nv_read( VNV_DEFAULT_LOCATION,
1314 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
1315 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001316 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 }
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001318 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1319 if (NULL != pHddCtx)
1320 {
1321 if (!vos_mem_compare(pHddCtx->cfg_ini->overrideCountryCode,
1322 CFG_OVERRIDE_COUNTRY_CODE_DEFAULT, 3))
1323 {
1324 vos_mem_copy(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode,
1325 pHddCtx->cfg_ini->overrideCountryCode,
1326 3);
1327 }
1328 }
1329 else
1330 {
1331 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1332 ("Invalid pHddCtx pointer") );
1333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001334 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001335
1336 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 VOS_STATUS_SUCCESS)
1338 {
1339 if (itemIsValid == VOS_TRUE)
1340 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001341 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001342 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
1343 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001344 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001345 }
1346 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001347
1348 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001349 VOS_STATUS_SUCCESS)
1350 {
1351 if (itemIsValid == VOS_TRUE)
1352 {
1353 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
1354 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
1355 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001356 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 }
1358 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001359 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 VOS_STATUS_SUCCESS)
1361 {
1362 if (itemIsValid == VOS_TRUE)
1363 {
1364 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
1365 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
1366 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001367 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001368 }
1369 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001370
1371 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001372 VOS_STATUS_SUCCESS)
1373 {
1374 if (itemIsValid == VOS_TRUE)
1375 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001376 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
1377 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
1378 goto error;
1379 }
1380 }
1381
Amar Singhalfddc28c2013-09-05 13:03:40 -07001382 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001383 VOS_STATUS_SUCCESS)
1384 {
1385 if (itemIsValid == VOS_TRUE)
1386 {
1387 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
1388 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001389 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 }
1391 }
1392
Amar Singhalfddc28c2013-09-05 13:03:40 -07001393 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 VOS_STATUS_SUCCESS)
1395 {
1396 if (itemIsValid == VOS_TRUE)
1397 {
1398 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001399 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001400 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001401 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 }
1403 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001404 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 VOS_STATUS_SUCCESS)
1406 {
1407 if (itemIsValid == VOS_TRUE)
1408 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001409 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1410 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001412 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001413 }
1414 }
1415
Amar Singhalfddc28c2013-09-05 13:03:40 -07001416 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 VOS_STATUS_SUCCESS)
1418 {
1419 if (itemIsValid == VOS_TRUE)
1420 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001421 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1422 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001424 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 }
1426 }
1427
Amar Singhalfddc28c2013-09-05 13:03:40 -07001428 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 VOS_STATUS_SUCCESS)
1430 {
1431 if (itemIsValid == VOS_TRUE)
1432 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001433 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1434 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001436 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 }
1438 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001439 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 VOS_STATUS_SUCCESS)
1441 {
1442 if (itemIsValid == VOS_TRUE)
1443 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001444 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1445 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001447 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 }
1449 }
1450 }
1451
1452 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001453error:
1454 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001455 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001456 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001457}
1458
1459VOS_STATUS vos_nv_close(void)
1460{
1461 VOS_STATUS status = VOS_STATUS_SUCCESS;
1462 v_CONTEXT_t pVosContext= NULL;
1463 /*Get the global context */
1464 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1465 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
1466 if ( !VOS_IS_STATUS_SUCCESS( status ))
1467 {
1468 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001469 "%s : vos_open failed",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001470 return VOS_STATUS_E_FAILURE;
1471 }
1472 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001473 vos_mem_free(pEncodedBuf);
1474 vos_mem_free(pDictFile);
1475
Jeff Johnson295189b2012-06-20 16:38:30 -07001476 gnvEFSTable=NULL;
1477 return VOS_STATUS_SUCCESS;
1478}
Jeff Johnson295189b2012-06-20 16:38:30 -07001479
Jeff Johnson295189b2012-06-20 16:38:30 -07001480/**------------------------------------------------------------------------
1481 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1482 country codes
1483 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1484 country codes with paddings in the provided buffer
1485 \param pBuffer - pointer to buffer where supported country codes
1486 and paddings are encoded; this may be set to NULL
1487 if user wishes to query the required buffer size to
1488 get the country code list
1489 \param pBufferSize - this is the provided buffer size on input;
1490 this is the required or consumed buffer size on output
1491 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1492 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1493 the buffer is NULL or buffer size is
1494 sufficient
1495 \sa
1496 -------------------------------------------------------------------------*/
1497VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1498 v_SIZE_t paddingSize )
1499{
1500 v_SIZE_t providedBufferSize = *pBufferSize;
1501 int i;
1502 // pBufferSize now points to the required buffer size
1503 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1504 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1505 {
1506 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08001507 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 return VOS_STATUS_E_NOMEM;
1509 }
1510 for (i = 0; i < countryInfoTable.countryCount; i++)
1511 {
1512 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1513 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1514 }
1515 return VOS_STATUS_SUCCESS;
1516}
1517/**------------------------------------------------------------------------
1518 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1519 \param pTxAntennaCount - antenna count
1520 \return status of the NV read operation
1521 \sa
1522 -------------------------------------------------------------------------*/
1523VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1524{
1525 sNvFields fieldImage;
1526 VOS_STATUS status;
1527 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1528 sizeof(fieldImage) );
1529 if (VOS_STATUS_SUCCESS == status)
1530 {
1531 *pTxAntennaCount = fieldImage.numOfTxChains;
1532 }
1533 return status;
1534}
1535/**------------------------------------------------------------------------
1536 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1537 \param pRxAntennaCount - antenna count
1538 \return status of the NV read operation
1539 \sa
1540 -------------------------------------------------------------------------*/
1541VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1542{
1543 sNvFields fieldImage;
1544 VOS_STATUS status;
1545 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1546 sizeof(fieldImage) );
1547 if (VOS_STATUS_SUCCESS == status)
1548 {
1549 *pRxAntennaCount = fieldImage.numOfRxChains;
1550 }
1551 return status;
1552}
1553
1554/**------------------------------------------------------------------------
1555 \brief vos_nv_readMacAddress() - return the MAC address
1556 \param pMacAddress - MAC address
1557 \return status of the NV read operation
1558 \sa
1559 -------------------------------------------------------------------------*/
1560VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1561{
1562 sNvFields fieldImage;
1563 VOS_STATUS status;
1564 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1565 sizeof(fieldImage) );
1566 if (VOS_STATUS_SUCCESS == status)
1567 {
1568 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1569 }
1570 else
1571 {
1572 //This part of the code can be removed when NV is programmed
1573 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1574 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
Arif Hussaina7c8e412013-11-20 11:06:42 -08001575 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1576 "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR,
1577 MAC_ADDR_ARRAY(macAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001578 status = VOS_STATUS_SUCCESS;
1579 }
1580 return status;
1581}
1582
1583/**------------------------------------------------------------------------
1584
1585 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1586
1587 \param pMacAddress - MAC address
1588 \param macCount - Count of valid MAC addresses to get from NV field
1589
1590 \return status of the NV read operation
1591
1592 \sa
1593
1594 -------------------------------------------------------------------------*/
1595VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1596 v_U8_t macCount )
1597{
1598 sNvFields fieldImage;
1599 VOS_STATUS status;
1600 v_U8_t countLoop;
1601 v_U8_t *pNVMacAddress;
1602
1603 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1604 (NULL == pMacAddress))
1605 {
1606 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301607 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 macCount, pMacAddress);
1609 }
1610
1611 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1612 sizeof(fieldImage) );
1613 if (VOS_STATUS_SUCCESS == status)
1614 {
1615 pNVMacAddress = fieldImage.macAddr;
1616 for(countLoop = 0; countLoop < macCount; countLoop++)
1617 {
1618 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1619 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1620 VOS_MAC_ADDRESS_LEN);
1621 }
1622 }
1623 else
1624 {
1625 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1626 "vos_nv_readMultiMacAddress Get NV Field Fail");
1627 }
1628
1629 return status;
1630}
1631
1632/**------------------------------------------------------------------------
1633 \brief vos_nv_setValidity() - set the validity of an NV item.
1634 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1635 validity information is stored in NV memory.
1636 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1637 An item becomes valid when one has written to it successfully.
1638 \param type - NV item type
1639 \param itemIsValid - boolean value indicating the item's validity
1640 \return VOS_STATUS_SUCCESS - validity is set successfully
1641 VOS_STATUS_E_INVAL - one of the parameters is invalid
1642 VOS_STATUS_E_FAILURE - unknown error
1643 \sa
1644 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001645
1646VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1647{
1648 v_U32_t lastNvValidityBitmap;
1649 v_U32_t newNvValidityBitmap;
1650 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001651
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001653 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001654 {
1655 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001656 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001657 return VOS_STATUS_E_INVAL;
1658 }
1659 // read the validity bitmap
1660 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1661 // modify the validity bitmap
1662 if (itemIsValid)
1663 {
1664 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1665 // commit to NV store if bitmap has been modified
1666 if (newNvValidityBitmap != lastNvValidityBitmap)
1667 {
1668 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1669 }
1670 }
1671 else
1672 {
1673 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1674 if (newNvValidityBitmap != lastNvValidityBitmap)
1675 {
1676 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1677 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1678 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001679 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 status = VOS_STATUS_E_FAULT;
1681 }
1682 }
1683 }
1684
1685 return status;
1686}
Jeff Johnson295189b2012-06-20 16:38:30 -07001687/**------------------------------------------------------------------------
1688 \brief vos_nv_getValidity() - get the validity of an NV item.
1689 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1690 validity information is stored in NV memory.
1691 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1692 An item becomes valid when one has written to it successfully.
1693 \param type - NV item type
1694 \param pItemIsValid- pointer to the boolean value indicating the item's
1695 validity
1696 \return VOS_STATUS_SUCCESS - validity is determined successfully
1697 VOS_STATUS_E_INVAL - one of the parameters is invalid
1698 VOS_STATUS_E_FAILURE - unknown error
1699 \sa
1700 -------------------------------------------------------------------------*/
1701VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1702{
1703 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1704 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001705 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 {
1707 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001708 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001709 return VOS_STATUS_E_INVAL;
1710 }
1711 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1712 return VOS_STATUS_SUCCESS;
1713}
1714/**------------------------------------------------------------------------
1715 \brief vos_nv_read() - read a NV item to an output buffer
1716 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1717 an array, this function would read the entire array. One would get a
1718 VOS_STATUS_E_EXISTS error when reading an invalid item.
1719 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1720 if a default buffer is provided (with a non-NULL value),
1721 the default buffer content is copied to the output buffer.
1722 \param type - NV item type
1723 \param outputBuffer - output buffer
1724 \param defaultBuffer - default buffer
1725 \param bufferSize - output buffer size
1726 \return VOS_STATUS_SUCCESS - NV item is read successfully
1727 VOS_STATUS_E_INVAL - one of the parameters is invalid
1728 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1729 VOS_STATUS_E_EXISTS - NV type is unsupported
1730 VOS_STATUS_E_FAILURE - unknown error
1731 \sa
1732 -------------------------------------------------------------------------*/
1733VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1734 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1735{
1736 VOS_STATUS status = VOS_STATUS_SUCCESS;
1737 v_SIZE_t itemSize;
1738 v_BOOL_t itemIsValid = VOS_TRUE;
1739
Amar Singhala49cbc52013-10-08 18:37:44 -07001740 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001741 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 {
1743 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001744 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 return VOS_STATUS_E_INVAL;
1746 }
1747 if (NULL == outputVoidBuffer)
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001750 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001751 return VOS_STATUS_E_FAULT;
1752 }
1753 if (0 == bufferSize)
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001756 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001757 return VOS_STATUS_E_INVAL;
1758 }
1759 // check if the NV item has valid data
1760 status = vos_nv_getValidity( type, &itemIsValid );
1761 if (!itemIsValid)
1762 {
1763 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08001764 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001765 return VOS_STATUS_E_EMPTY;
1766 }
1767 switch(type)
1768 {
1769 case VNV_FIELD_IMAGE:
1770 itemSize = sizeof(gnvEFSTable->halnv.fields);
1771 if(bufferSize != itemSize) {
1772 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001773 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 itemSize);
1775 status = VOS_STATUS_E_INVAL;
1776 }
1777 else {
1778 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1779 }
1780 break;
1781 case VNV_RATE_TO_POWER_TABLE:
1782 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1783 if(bufferSize != itemSize) {
1784 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001785 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 itemSize);
1787 status = VOS_STATUS_E_INVAL;
1788 }
1789 else {
1790 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1791 }
1792 break;
1793 case VNV_REGULARTORY_DOMAIN_TABLE:
1794 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1795 if(bufferSize != itemSize) {
1796 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001797 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 itemSize);
1799 status = VOS_STATUS_E_INVAL;
1800 }
1801 else {
1802 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1803 }
1804 break;
1805 case VNV_DEFAULT_LOCATION:
1806 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1807 if(bufferSize != itemSize) {
1808 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001809 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 itemSize);
1811 status = VOS_STATUS_E_INVAL;
1812 }
1813 else {
1814 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1815 }
1816 break;
1817 case VNV_TPC_POWER_TABLE:
1818 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1819 if(bufferSize != itemSize) {
1820 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001821 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 itemSize);
1823 status = VOS_STATUS_E_INVAL;
1824 }
1825 else {
1826 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1827 }
1828 break;
1829 case VNV_TPC_PDADC_OFFSETS:
1830 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1831 if(bufferSize != itemSize) {
1832 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001833 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001834 itemSize);
1835 status = VOS_STATUS_E_INVAL;
1836 }
1837 else {
1838 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1839 }
1840 break;
1841 case VNV_RSSI_CHANNEL_OFFSETS:
1842
1843 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1844
1845 if(bufferSize != itemSize) {
1846
1847 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001848 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001849 itemSize);
1850 status = VOS_STATUS_E_INVAL;
1851 }
1852 else {
1853 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1854 }
1855 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001856 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001857
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001858 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001859
1860 if(bufferSize != itemSize) {
1861
1862 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001863 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 itemSize);
1865 status = VOS_STATUS_E_INVAL;
1866 }
1867 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001868 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1869 }
1870 break;
1871 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001872
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001873 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001874
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001875 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001876
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001877 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001878 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001879 itemSize);
1880 status = VOS_STATUS_E_INVAL;
1881 }
1882 else {
1883 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001884 }
1885 break;
1886 case VNV_ANTENNA_PATH_LOSS:
1887 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1888 if(bufferSize != itemSize) {
1889 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001890 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 itemSize);
1892 status = VOS_STATUS_E_INVAL;
1893 }
1894 else {
1895 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1896 }
1897 break;
1898 case VNV_PACKET_TYPE_POWER_LIMITS:
1899 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1900 if(bufferSize != itemSize) {
1901 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001902 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 itemSize);
1904 status = VOS_STATUS_E_INVAL;
1905 }
1906 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001907 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 }
1909 break;
1910 case VNV_OFDM_CMD_PWR_OFFSET:
1911 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1912 if(bufferSize != itemSize) {
1913 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001914 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 itemSize);
1916 status = VOS_STATUS_E_INVAL;
1917 }
1918 else {
1919 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1920 }
1921 break;
1922 case VNV_TX_BB_FILTER_MODE:
1923 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1924 if(bufferSize != itemSize) {
1925 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001926 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 itemSize);
1928 status = VOS_STATUS_E_INVAL;
1929 }
1930 else {
1931 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1932 }
1933 break;
1934
Jeff Johnson295189b2012-06-20 16:38:30 -07001935
1936 case VNV_TABLE_VIRTUAL_RATE:
1937 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1938 if(bufferSize != itemSize) {
1939 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001940 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 itemSize);
1942 status = VOS_STATUS_E_INVAL;
1943 }
1944 else {
1945 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1946 }
1947 break;
1948
1949 default:
1950 break;
1951 }
1952 return status;
1953}
Jeff Johnson295189b2012-06-20 16:38:30 -07001954
1955/**------------------------------------------------------------------------
1956 \brief vos_nv_write() - write to a NV item from an input buffer
1957 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1958 validate the NV item if the write operation is successful.
Leo Chang80de3c22013-11-26 10:52:12 -08001959 NV2 dedicated operation
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 \param type - NV item type
1961 \param inputBuffer - input buffer
1962 \param inputBufferSize - input buffer size
1963 \return VOS_STATUS_SUCCESS - NV item is read successfully
1964 VOS_STATUS_E_INVAL - one of the parameters is invalid
1965 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1966 VOS_STATUS_E_EXISTS - NV type is unsupported
1967 VOS_STATUS_E_FAILURE - unknown error
1968 \sa
1969 -------------------------------------------------------------------------*/
Leo Chang80de3c22013-11-26 10:52:12 -08001970VOS_STATUS vos_nv_write(VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1971 v_SIZE_t bufferSize)
Jeff Johnson295189b2012-06-20 16:38:30 -07001972{
1973 VOS_STATUS status = VOS_STATUS_SUCCESS;
1974 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001975
Amar Singhala49cbc52013-10-08 18:37:44 -07001976 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001977 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 {
Leo Chang80de3c22013-11-26 10:52:12 -08001979 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1980 "%s: invalid type=%d", __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 return VOS_STATUS_E_INVAL;
1982 }
1983 if (NULL == inputVoidBuffer)
1984 {
Leo Chang80de3c22013-11-26 10:52:12 -08001985 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1986 "Buffer provided is NULL");
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 return VOS_STATUS_E_FAULT;
1988 }
1989 if (0 == bufferSize)
1990 {
Leo Chang80de3c22013-11-26 10:52:12 -08001991 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1992 "NV type=%d is invalid", type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001993 return VOS_STATUS_E_INVAL;
1994 }
Leo Chang80de3c22013-11-26 10:52:12 -08001995
1996 switch (type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 {
1998 case VNV_FIELD_IMAGE:
Leo Chang80de3c22013-11-26 10:52:12 -08001999 itemSize = sizeof(gnvEFSTableV2->halnvV2.fields);
2000 if (bufferSize != itemSize)
2001 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002003 "type = %d buffer size=%d is less than data size=%d",
2004 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 status = VOS_STATUS_E_INVAL;
2006 }
Leo Chang80de3c22013-11-26 10:52:12 -08002007 else
2008 {
2009 memcpy(&gnvEFSTableV2->halnvV2.fields,
2010 inputVoidBuffer,
2011 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 }
2013 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002014
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 case VNV_RATE_TO_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002016 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum);
2017 if (bufferSize != itemSize)
2018 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002020 "type = %d buffer size=%d is less than data size=%d",
2021 type, bufferSize,itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 status = VOS_STATUS_E_INVAL;
2023 }
Leo Chang80de3c22013-11-26 10:52:12 -08002024 else
2025 {
2026 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum[0],
2027 inputVoidBuffer,
2028 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002029 }
2030 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002031
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 case VNV_REGULARTORY_DOMAIN_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002033 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.regDomains);
2034 if (bufferSize != itemSize)
2035 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002036 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002037 "type = %d buffer size=%d is less than data size=%d",
2038 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 status = VOS_STATUS_E_INVAL;
2040 }
Leo Chang80de3c22013-11-26 10:52:12 -08002041 else
2042 {
2043 memcpy(&gnvEFSTableV2->halnvV2.tables.regDomains[0],
2044 inputVoidBuffer,
2045 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002046 }
2047 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002048
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 case VNV_DEFAULT_LOCATION:
Leo Chang80de3c22013-11-26 10:52:12 -08002050 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.defaultCountryTable);
2051 if (bufferSize != itemSize)
2052 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002054 "type = %d buffer size=%d is less than data size=%d",
2055 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 status = VOS_STATUS_E_INVAL;
2057 }
Leo Chang80de3c22013-11-26 10:52:12 -08002058 else
2059 {
2060 memcpy(&gnvEFSTableV2->halnvV2.tables.defaultCountryTable,
2061 inputVoidBuffer,
2062 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 }
2064 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002065
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 case VNV_TPC_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002067 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutCharacterized);
2068 if (bufferSize != itemSize)
2069 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002071 "type = %d buffer size=%d is less than data size=%d",
2072 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002073 status = VOS_STATUS_E_INVAL;
2074 }
Leo Chang80de3c22013-11-26 10:52:12 -08002075 else
2076 {
2077 memcpy(&gnvEFSTableV2->halnvV2.tables.plutCharacterized[0],
2078 inputVoidBuffer,
2079 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 }
2081 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002082
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 case VNV_TPC_PDADC_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002084 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutPdadcOffset);
2085 if (bufferSize != itemSize)
2086 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002088 "type = %d buffer size=%d is less than data size=%d",
2089 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 status = VOS_STATUS_E_INVAL;
2091 }
Leo Chang80de3c22013-11-26 10:52:12 -08002092 else
2093 {
2094 memcpy(&gnvEFSTableV2->halnvV2.tables.plutPdadcOffset[0],
2095 inputVoidBuffer,
2096 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 }
2098 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002099
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 case VNV_RSSI_CHANNEL_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002101 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.rssiChanOffsets);
2102 if (bufferSize != itemSize)
2103 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002105 "type = %d buffer size=%d is less than data size=%d",
2106 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 status = VOS_STATUS_E_INVAL;
2108 }
Leo Chang80de3c22013-11-26 10:52:12 -08002109 else
2110 {
2111 memcpy(&gnvEFSTableV2->halnvV2.tables.rssiChanOffsets[0],
2112 inputVoidBuffer,
2113 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 }
2115 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002116
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002117 case VNV_HW_CAL_VALUES:
Leo Chang80de3c22013-11-26 10:52:12 -08002118 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.hwCalValues);
2119 if (bufferSize != itemSize)
2120 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002122 "type = %d buffer size=%d is less than data size=%d",
2123 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 status = VOS_STATUS_E_INVAL;
2125 }
Leo Chang80de3c22013-11-26 10:52:12 -08002126 else
2127 {
2128 memcpy(&gnvEFSTableV2->halnvV2.tables.hwCalValues,
2129 inputVoidBuffer,
2130 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 }
2132 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002133
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002134 case VNV_FW_CONFIG:
Leo Chang80de3c22013-11-26 10:52:12 -08002135 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.fwConfig);
2136 if (bufferSize != itemSize)
2137 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002138 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002139 "type = %d buffer size=%d is less than data size=%d",
2140 type, bufferSize, itemSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002141 status = VOS_STATUS_E_INVAL;
2142 }
Leo Chang80de3c22013-11-26 10:52:12 -08002143 else
2144 {
2145 memcpy(&gnvEFSTableV2->halnvV2.tables.fwConfig,
2146 inputVoidBuffer,
2147 bufferSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002148 }
2149 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002150
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 case VNV_ANTENNA_PATH_LOSS:
Leo Chang80de3c22013-11-26 10:52:12 -08002152 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.antennaPathLoss);
2153 if (bufferSize != itemSize)
2154 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002156 "type = %d buffer size=%d is less than data size=%d",
2157 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 status = VOS_STATUS_E_INVAL;
2159 }
Leo Chang80de3c22013-11-26 10:52:12 -08002160 else
2161 {
2162 memcpy(&gnvEFSTableV2->halnvV2.tables.antennaPathLoss[0],
2163 inputVoidBuffer,
2164 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002165 }
2166 break;
2167
2168 case VNV_PACKET_TYPE_POWER_LIMITS:
Leo Chang80de3c22013-11-26 10:52:12 -08002169 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits);
2170 if (bufferSize != itemSize)
2171 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002173 "type = %d buffer size=%d is less than data size=%d",
2174 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 status = VOS_STATUS_E_INVAL;
2176 }
Leo Chang80de3c22013-11-26 10:52:12 -08002177 else
2178 {
2179 memcpy(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits,
2180 inputVoidBuffer,
2181 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 }
2183 break;
2184
2185 case VNV_OFDM_CMD_PWR_OFFSET:
Leo Chang80de3c22013-11-26 10:52:12 -08002186 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset);
2187 if (bufferSize != itemSize)
2188 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002189 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002190 "type = %d buffer size=%d is less than data size=%d",
2191 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002192 status = VOS_STATUS_E_INVAL;
2193 }
Leo Chang80de3c22013-11-26 10:52:12 -08002194 else
2195 {
2196 memcpy(&gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset,
2197 inputVoidBuffer,
2198 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 }
2200 break;
2201
2202 case VNV_TX_BB_FILTER_MODE:
Leo Chang80de3c22013-11-26 10:52:12 -08002203 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.txbbFilterMode);
2204 if (bufferSize != itemSize)
2205 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002206 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002207 "type = %d buffer size=%d is less than data size=%d",
2208 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 status = VOS_STATUS_E_INVAL;
2210 }
Leo Chang80de3c22013-11-26 10:52:12 -08002211 else
2212 {
2213 memcpy(&gnvEFSTableV2->halnvV2.tables.txbbFilterMode,
2214 inputVoidBuffer,
2215 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 }
2217 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002218
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 case VNV_TABLE_VIRTUAL_RATE:
Leo Chang80de3c22013-11-26 10:52:12 -08002220 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate);
2221 if (bufferSize != itemSize)
2222 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002223 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002224 "type = %d buffer size=%d is less than data size=%d",
2225 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226 status = VOS_STATUS_E_INVAL;
2227 }
Leo Chang80de3c22013-11-26 10:52:12 -08002228 else
2229 {
2230 memcpy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate,
2231 inputVoidBuffer,
2232 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 }
2234 break;
2235
2236 default:
2237 break;
2238 }
Leo Chang80de3c22013-11-26 10:52:12 -08002239
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 if (VOS_STATUS_SUCCESS == status)
2241 {
2242 // set NV item to have valid data
Leo Chang80de3c22013-11-26 10:52:12 -08002243 status = vos_nv_setValidity(type, VOS_TRUE);
2244 if (! VOS_IS_STATUS_SUCCESS(status))
2245 {
2246 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2247 "vos_nv_setValidity failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 status = VOS_STATUS_E_FAULT;
2249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002250
Leo Chang80de3c22013-11-26 10:52:12 -08002251 status = wlan_write_to_efs((v_U8_t*)gnvEFSTableV2, sizeof(nvEFSTable_t));
2252 if (!VOS_IS_STATUS_SUCCESS(status))
2253 {
2254 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2255 "vos_nv_write_to_efs failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 status = VOS_STATUS_E_FAULT;
2257 }
2258 }
Leo Chang80de3c22013-11-26 10:52:12 -08002259
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 return status;
2261}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08002262
Jeff Johnson295189b2012-06-20 16:38:30 -07002263/**------------------------------------------------------------------------
2264 \brief vos_nv_getChannelListWithPower() - function to return the list of
2265 supported channels with the power limit info too.
2266 \param pChannels20MHz - list of 20 Mhz channels
2267 \param pNum20MHzChannelsFound - number of 20 Mhz channels
2268 \param pChannels40MHz - list of 20 Mhz channels
2269 \param pNum40MHzChannelsFound - number of 20 Mhz channels
2270 \return status of the NV read operation
2271 \Note: 40Mhz not currently supported
2272 \sa
2273 -------------------------------------------------------------------------*/
2274VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
2275 tANI_U8 *num20MHzChannelsFound,
2276 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
2277 tANI_U8 *num40MHzChannelsFound
2278 )
2279{
2280 VOS_STATUS status = VOS_STATUS_SUCCESS;
2281 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002282
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
2284 // or pass it as a parameter to NV from SME?
2285
2286 if( channels20MHz && num20MHzChannelsFound )
2287 {
2288 count = 0;
2289 for( i = 0; i <= RF_CHAN_14; i++ )
2290 {
2291 if( regChannels[i].enabled )
2292 {
2293 channels20MHz[count].chanId = rfChannels[i].channelNum;
2294 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2295 }
2296 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002297 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2298 {
2299 if( regChannels[i].enabled )
2300 {
2301 channels20MHz[count].chanId = rfChannels[i].channelNum;
2302 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2303 }
2304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 *num20MHzChannelsFound = (tANI_U8)count;
2306 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002307
2308 if( channels40MHz && num40MHzChannelsFound )
2309 {
2310 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002311 //center channels for 2.4 Ghz 40 MHz channels
2312 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
2313 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002314
Jeff Johnsone7245742012-09-05 17:12:55 -07002315 if( regChannels[i].enabled )
2316 {
2317 channels40MHz[count].chanId = rfChannels[i].channelNum;
2318 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2319 }
2320 }
2321 //center channels for 5 Ghz 40 MHz channels
2322 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
2323 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002324
Jeff Johnsone7245742012-09-05 17:12:55 -07002325 if( regChannels[i].enabled )
2326 {
2327 channels40MHz[count].chanId = rfChannels[i].channelNum;
2328 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2329 }
2330 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002331 *num40MHzChannelsFound = (tANI_U8)count;
2332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002333 return (status);
2334}
2335
2336/**------------------------------------------------------------------------
2337 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
2338 \return default regulatory domain
2339 \sa
2340 -------------------------------------------------------------------------*/
2341
2342v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
2343{
2344 return countryInfoTable.countryInfo[0].regDomain;
2345}
2346
2347/**------------------------------------------------------------------------
2348 \brief vos_nv_getSupportedChannels() - function to return the list of
2349 supported channels
2350 \param p20MhzChannels - list of 20 Mhz channels
2351 \param pNum20MhzChannels - number of 20 Mhz channels
2352 \param p40MhzChannels - list of 40 Mhz channels
2353 \param pNum40MhzChannels - number of 40 Mhz channels
2354 \return status of the NV read operation
2355 \Note: 40Mhz not currently supported
2356 \sa
2357 -------------------------------------------------------------------------*/
2358VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
2359 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
2360{
2361 VOS_STATUS status = VOS_STATUS_E_INVAL;
2362 int i, count = 0;
2363
2364 if( p20MhzChannels && pNum20MhzChannels )
2365 {
2366 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
2367 {
2368 for( i = 0; i <= RF_CHAN_14; i++ )
2369 {
2370 p20MhzChannels[count++] = rfChannels[i].channelNum;
2371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2373 {
2374 p20MhzChannels[count++] = rfChannels[i].channelNum;
2375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002376 status = VOS_STATUS_SUCCESS;
2377 }
2378 *pNum20MhzChannels = count;
2379 }
2380
2381 return (status);
2382}
2383
2384/**------------------------------------------------------------------------
2385 \brief vos_nv_readDefaultCountryTable() - return the default Country table
2386 \param table data - a union to return the default country table data in.
2387 \return status of the NV read operation
2388 \sa
2389 -------------------------------------------------------------------------*/
2390VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
2391{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002392
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002393 VOS_STATUS status = VOS_STATUS_SUCCESS;
2394 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
2395 pr_info("DefaultCountry is %c%c\n",
2396 tableData->defaultCountryTable.countryCode[0],
2397 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002398 return status;
2399}
2400
2401/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002402 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07002403 \param pBuffer - to return the buffer address
2404 pSize - buffer size.
2405 \return status of the NV read operation
2406 \sa
2407 -------------------------------------------------------------------------*/
2408VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2409{
Leo Chang80de3c22013-11-26 10:52:12 -08002410 eNvVersionType nvVersion;
2411
2412 nvVersion = vos_nv_getNvVersion();
2413
2414 if (E_NV_V3 == nvVersion)
2415 {
2416 /* Send the NV V3 structure and size */
2417 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
2418 *pSize = sizeof(sHalNv);
2419 }
2420 else if (E_NV_V2 == nvVersion)
2421 {
2422 /* Send the NV V2 structure and size */
2423 *pNvBuffer = (v_VOID_t *)(&gnvEFSTableV2->halnvV2);
2424 *pSize = sizeof(sHalNvV2);
2425 }
2426 else
2427 {
2428 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2429 "%s : Invalid NV version %d", __func__, nvVersion);
2430 return VOS_STATUS_E_INVAL;
2431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002432
2433 return VOS_STATUS_SUCCESS;
2434}
2435
Jeff Johnson295189b2012-06-20 16:38:30 -07002436/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002437 \brief vos_nv_getBuffer -
2438 \param pBuffer - to return the buffer address
2439 pSize - buffer size.
2440 \return status of the NV read operation
2441 \sa
2442 -------------------------------------------------------------------------*/
2443VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2444{
2445 /* Send the NV structure and size */
Leo Changb1eb8812013-12-30 11:51:44 -08002446 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
2447 *pSize = nvReadEncodeBufSize;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002448 return VOS_STATUS_SUCCESS;
2449}
2450
2451
2452VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2453{
2454 /* Send the NV structure and size */
2455 *pNvBuffer = (v_VOID_t *)(pDictFile);
2456 *pSize = nDictionarySize;
2457
2458 return VOS_STATUS_SUCCESS;
2459}
2460
2461VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
2462{
2463 if (MAGIC_NUMBER == magicNumber)
2464 {
2465 return VOS_STATUS_SUCCESS;
2466 }
2467
2468 return VOS_STATUS_E_FAILURE;
2469}
2470
2471VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
2472{
2473 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2474 (size-sizeof(v_U32_t)));
2475
2476 return VOS_STATUS_SUCCESS;
2477}
2478
2479/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002480 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002481 \param rfChannel - input channel enum to know evabled state
2482 \return eNVChannelEnabledType enabled state for channel
2483 * enabled
2484 * disabled
2485 * DFS
2486 \sa
2487 -------------------------------------------------------------------------*/
2488eNVChannelEnabledType vos_nv_getChannelEnabledState
2489(
2490 v_U32_t rfChannel
2491)
2492{
2493 v_U32_t channelLoop;
2494 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2495
2496 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2497 {
2498 if(rfChannels[channelLoop].channelNum == rfChannel)
2499 {
2500 channelEnum = (eRfChannels)channelLoop;
2501 break;
2502 }
2503 }
2504
2505 if(INVALID_RF_CHANNEL == channelEnum)
2506 {
2507 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002508 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 return NV_CHANNEL_INVALID;
2510 }
2511
2512 return regChannels[channelEnum].enabled;
2513}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002514
Leo Chang80de3c22013-11-26 10:52:12 -08002515/**------------------------------------------------------------------------
2516 \brief vos_nv_getNvVersion -
2517 \param NONE
2518 \return eNvVersionType NV.bin version
2519 * E_NV_V2
2520 * E_NV_V3
2521 * E_NV_INVALID
2522 \sa
2523 -------------------------------------------------------------------------*/
2524eNvVersionType vos_nv_getNvVersion
2525(
2526 void
2527)
2528{
2529 VosContextType *vosCtxt = NULL;
2530
2531 vosCtxt = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2532 if (vosCtxt)
2533 {
2534 return vosCtxt->nvVersion;
2535 }
2536
2537 return E_NV_INVALID;
2538}
2539
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002540/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002541 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002542*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002543
2544static int bw20_ch_index_to_bw40_ch_index(int k)
2545{
2546 int m = -1;
2547 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2548 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002549 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2550 if (m > RF_CHAN_BOND_11)
2551 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002552 }
2553 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2554 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002555 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2556 if (m > RF_CHAN_BOND_214)
2557 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002558 }
2559 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2560 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002561 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2562 if (m > RF_CHAN_BOND_62)
2563 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002564 }
Leo Chang80de3c22013-11-26 10:52:12 -08002565#ifdef FEATURE_WLAN_CH144
2566 else if (k >= RF_CHAN_100 && k <= RF_CHAN_144)
2567#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002568 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
Leo Chang80de3c22013-11-26 10:52:12 -08002569#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002570 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002571 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
Leo Chang80de3c22013-11-26 10:52:12 -08002572#ifdef FEATURE_WLAN_CH144
2573 if (m > RF_CHAN_BOND_142)
2574 m = RF_CHAN_BOND_142;
2575#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002576 if (m > RF_CHAN_BOND_138)
2577 m = RF_CHAN_BOND_138;
Leo Chang80de3c22013-11-26 10:52:12 -08002578#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002579 }
2580 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2581 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002582 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2583 if (m > RF_CHAN_BOND_163)
2584 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002585 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002586return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002587}
2588
Amar Singhala49cbc52013-10-08 18:37:44 -07002589void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002590{
Amar Singhala49cbc52013-10-08 18:37:44 -07002591 int k;
2592 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2593 countryCode[0], countryCode[1], domain_id);
2594 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2595 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2596 NV_CHANNEL_ENABLE;
2597 /* Max Tx Power 20dBm */
2598 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2599 }
2600 /* enable ch 12 to ch 14 passive scan */
2601 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2602 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2603 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2604 NV_CHANNEL_DFS;
2605 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2606 }
2607 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2608 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2609 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2610 NV_CHANNEL_DFS;
2611 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2612 }
2613#ifdef PASSIVE_SCAN_4_9GHZ
2614 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2615 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2616 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2617 NV_CHANNEL_DFS;
2618 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2619 }
2620#endif
2621 if (domain_id == NUM_REG_DOMAINS-1)
2622 { /* init time */
2623 crda_alpha2[0] = countryCode[0];
2624 crda_alpha2[1] = countryCode[1];
2625 crda_regulatory_entry_valid = VOS_TRUE;
2626 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2627 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2628 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2629 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2630 }
2631 if (domain_id == NUM_REG_DOMAINS-2)
2632 { /* none-default country */
2633 run_time_alpha2[0] = countryCode[0];
2634 run_time_alpha2[1] = countryCode[1];
2635 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2636 }
2637}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002638
Amar Singhala49cbc52013-10-08 18:37:44 -07002639static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2640 struct regulatory_request *request,
2641 v_U8_t nBandCapability,
2642 int domain_id)
2643{
2644 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2645 pr_info("Country 00 special handling to enable passive scan.\n");
2646 crda_regulatory_entry_default(request->alpha2, domain_id);
2647 }
2648 return 0;
2649}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002650
Amar Singhala49cbc52013-10-08 18:37:44 -07002651/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2652static int create_crda_regulatory_entry(struct wiphy *wiphy,
2653 struct regulatory_request *request,
2654 v_U8_t nBandCapability)
2655{
2656 int i, j, m;
2657 int k = 0, n = 0;
2658
2659 if (run_time_alpha2[0]==request->alpha2[0] &&
2660 run_time_alpha2[1]==request->alpha2[1] &&
2661 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2662 return 0; /* already created */
2663
2664 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002665 if (nBandCapability == eCSR_BAND_24)
2666 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002667 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002668 {
2669 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2670 continue;
2671 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2672 continue;
2673 if (wiphy->bands[i] == NULL)
2674 {
2675 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2676 return -1;
2677 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002678 // internal channels[] is one continous array for both 2G and 5G bands
2679 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002680 if (i == 0)
2681 m = 0;
2682 else
2683 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002684 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002685 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002686 // k = (m + j) is internal current channel index for 20MHz channel
2687 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002688 k = m + j;
2689 n = bw20_ch_index_to_bw40_ch_index(k);
2690 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002691 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002692 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2693 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002694 if (pnvEFSTable == NULL)
2695 {
2696 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2697 return -1;
2698 }
2699 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2700 NV_CHANNEL_DISABLE;
2701 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2702 NV_CHANNEL_DISABLE;
2703 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2704 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002705 }
2706 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2707 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002708 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2709 NV_CHANNEL_DFS;
2710 // max_power is in mBm = 100 * dBm
2711 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2712 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2713 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2714 {
2715 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2716 NV_CHANNEL_DFS;
2717 // 40MHz channel power is half of 20MHz (-3dB) ??
2718 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2719 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2720 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002721 }
2722 else // Enable is only last flag we support
2723 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002724 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2725 NV_CHANNEL_ENABLE;
2726 // max_power is in dBm
2727 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2728 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2729 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2730 {
2731 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2732 NV_CHANNEL_ENABLE;
2733 // 40MHz channel power is half of 20MHz (-3dB) ??
2734 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2735 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2736 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002737 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002738 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2739 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002740 }
2741 }
2742 if (k == 0)
2743 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002744 run_time_alpha2[0] = request->alpha2[0];
2745 run_time_alpha2[1] = request->alpha2[1];
2746 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2747 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2748return 0;
2749}
Amar Singhal0d15bd52013-10-12 23:13:13 -07002750
2751
Amar Singhala49cbc52013-10-08 18:37:44 -07002752v_BOOL_t is_crda_regulatory_entry_valid(void)
2753{
2754return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002755}
2756
Amar Singhala49cbc52013-10-08 18:37:44 -07002757/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2758start freq + 10000 = center freq of the 20MHz start channel
2759end freq - 10000 = center freq of the 20MHz end channel
2760start freq + 20000 = center freq of the 40MHz start channel
2761end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002762*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002763static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002764{
Leo Chang80de3c22013-11-26 10:52:12 -08002765 int i;
2766 u32 center_freq = freq_khz + 10000;
2767
Amar Singhala49cbc52013-10-08 18:37:44 -07002768 //Has to compare from low freq to high freq
2769 //RF_SUBBAND_2_4_GHZ
2770 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2771 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2772 return i;
2773 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2774 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2775 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2776 return i;
2777 //RF_SUBBAND_5_LOW_GHZ
2778 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2779 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2780 return i;
2781 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002782#ifdef FEATURE_WLAN_CH144
2783 for (i=RF_CHAN_100;i<=RF_CHAN_144;i++)
2784#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002785 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002786#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002787 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2788 return i;
2789 //RF_SUBBAND_5_HIGH_GHZ
2790 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2791 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2792 return i;
2793return -1;
2794}
2795
2796static int bw20_end_freq_to_channel_index(u32 freq_khz)
2797{
Leo Chang80de3c22013-11-26 10:52:12 -08002798 int i;
2799 u32 center_freq = freq_khz - 10000;
2800
Amar Singhala49cbc52013-10-08 18:37:44 -07002801 //Has to compare from high freq to low freq
2802 //RF_SUBBAND_5_HIGH_GHZ
2803 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2804 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2805 return i;
2806 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002807#ifdef FEATURE_WLAN_CH144
2808 for (i=RF_CHAN_144;i>=RF_CHAN_100;i--)
2809#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002810 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002811#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002812 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2813 return i;
2814 //RF_SUBBAND_5_LOW_GHZ
2815 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2816 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2817 return i;
2818 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2819 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2820 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2821 return i;
2822 //RF_SUBBAND_2_4_GHZ
2823 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2824 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2825 return i;
Leo Chang80de3c22013-11-26 10:52:12 -08002826 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002827}
2828
2829static int bw40_start_freq_to_channel_index(u32 freq_khz)
2830{
Leo Chang80de3c22013-11-26 10:52:12 -08002831 int i;
2832 u32 center_freq = freq_khz + 20000;
2833
Amar Singhala49cbc52013-10-08 18:37:44 -07002834 //Has to compare from low freq to high freq
2835 //RF_SUBBAND_2_4_GHZ
2836 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2837 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2838 return i;
2839 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2840 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2841 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2842 return i;
2843 //RF_SUBBAND_5_LOW_GHZ
2844 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2845 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2846 return i;
2847 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002848#ifdef FEATURE_WLAN_CH144
2849 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_142;i++)
2850#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002851 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002852#endif /* RF_CHAN_BOND_142 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002853 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2854 return i;
2855 //RF_SUBBAND_5_HIGH_GHZ
2856 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2857 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2858 return i;
2859return -1;
2860}
2861
2862static int bw40_end_freq_to_channel_index(u32 freq_khz)
2863{
Leo Chang80de3c22013-11-26 10:52:12 -08002864 int i;
2865 u32 center_freq = freq_khz - 20000;
2866
Amar Singhala49cbc52013-10-08 18:37:44 -07002867 //Has to compare from high freq to low freq
2868 //RF_SUBBAND_5_HIGH_GHZ
2869 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2870 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2871 return i;
2872 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002873#ifdef FEATURE_WLAN_CH144
2874 for (i=RF_CHAN_BOND_142;i>=RF_CHAN_BOND_102;i--)
2875#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002876 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002877#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002878 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2879 return i;
2880 //RF_SUBBAND_5_LOW_GHZ
2881 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2882 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2883 return i;
2884 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2885 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2886 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2887 return i;
2888 //RF_SUBBAND_2_4_GHZ
2889 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2890 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2891 return i;
2892return -1;
2893}
2894
2895static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2896{
2897 switch (nBandCapability)
2898 {
2899 case eCSR_BAND_ALL:
2900 return VOS_TRUE;
2901 case eCSR_BAND_24:
2902 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2903 return VOS_TRUE;
2904 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2905 return VOS_TRUE; // 2.4G 40MHz channel
2906 break;
2907 case eCSR_BAND_5G:
2908 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2909 return VOS_TRUE;
2910 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2911 return VOS_TRUE; // 2.4G 40MHz channel
2912 break;
2913 default:
2914 break;
2915 }
2916 return VOS_FALSE;
2917}
2918
2919/* create_crda_regulatory_entry_from_regd should be called during init time */
2920static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2921 struct regulatory_request *request,
2922 v_U8_t nBandCapability)
2923{
2924 int i, j, n, domain_id;
2925 int bw20_start_channel_index, bw20_end_channel_index;
2926 int bw40_start_channel_index, bw40_end_channel_index;
2927
2928 if (wiphy == NULL || wiphy->regd == NULL)
2929 {
2930 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2931 return -1;
2932 }
2933 if (crda_regulatory_entry_valid == VOS_FALSE)
2934 domain_id = NUM_REG_DOMAINS-1; /* init time */
2935 else
2936 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2937 for (n = 0; n < NUM_RF_CHANNELS; n++)
2938 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2939
2940 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2941 {
2942 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2943 bw20_start_channel_index =
2944 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2945 bw20_end_channel_index =
2946 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2947 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2948 {
2949 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2950 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2951 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2952 continue; // skip this rull, but continue to next rule
2953 }
2954 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2955 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2956 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2957 bw20_start_channel_index, bw20_end_channel_index);
2958 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2959 {
2960 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2961 {
2962 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2963 rfChannels[j].channelNum);
2964 continue; // skip this channel, continue to next
2965 }
2966 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2967 {
2968 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2969 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2970 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2971 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05302972 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN)
2973 {
2974 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2975 wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2976 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2977 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002978 else
2979 {
2980 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2981 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2982 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2983 }
2984 /* max_eirp is in mBm (= 100 * dBm) unit */
2985 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2986 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2987 }
2988 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2989 real gain which should be provided by the real design */
2990 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2991 {
2992 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2993 bw40_start_channel_index =
2994 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2995 bw40_end_channel_index =
2996 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2997 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2998 {
2999 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
3000 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3001 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3002 continue; // skip this rull, but continue to next rule
3003 }
3004 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3005 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3006 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3007 bw40_start_channel_index, bw40_end_channel_index);
3008 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
3009 {
3010 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3011 continue; // skip this channel, continue to next
3012 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3013 {
3014 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3015 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
3016 }
3017 else
3018 {
3019 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3020 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
3021 }
3022 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
3023 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3024 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
3025 }
3026 }
3027 }
3028 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
3029 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
3030 these flags and has no implementation yet. */
3031 if (crda_regulatory_entry_valid == VOS_FALSE)
3032 { /* init time */
3033 crda_alpha2[0] = request->alpha2[0];
3034 crda_alpha2[1] = request->alpha2[1];
3035 crda_regulatory_entry_valid = VOS_TRUE;
3036 }
3037 else
3038 { /* none-default country */
3039 run_time_alpha2[0] = request->alpha2[0];
3040 run_time_alpha2[1] = request->alpha2[1];
3041 crda_regulatory_run_time_entry_valid = VOS_TRUE;
3042 }
3043 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
3044 return 0;
3045}
3046
3047#ifdef CONFIG_ENABLE_LINUX_REG
3048
3049/**------------------------------------------------------------------------
3050 \brief vos_nv_setRegDomain -
3051 \param clientCtxt - Client Context, Not used for PRIMA
3052 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303053 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003054 \return status set REG domain operation
3055 \sa
3056 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303057VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3058 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003059{
3060
3061 if (regId >= REGDOMAIN_COUNT)
3062 {
3063 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3064 "VOS set reg domain, invalid REG domain ID %d", regId);
3065 return VOS_STATUS_E_INVAL;
3066 }
3067
3068 /* Set correct channel information based on REG Domain */
3069 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3070
3071 return VOS_STATUS_SUCCESS;
3072}
3073
3074/**------------------------------------------------------------------------
3075 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3076 a country given its country code
3077 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3078 a country given its country code. This is done from reading a cached
3079 copy of the binary file.
3080 \param pRegDomain - pointer to regulatory domain
3081 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303082 \param source - source of the country code
Amar Singhala49cbc52013-10-08 18:37:44 -07003083 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3084 VOS_STATUS_E_FAULT - invalid pointer error
3085 VOS_STATUS_E_EMPTY - country code table is empty
3086 VOS_STATUS_E_EXISTS - given country code does not exist in table
3087 \sa
3088 -------------------------------------------------------------------------*/
3089VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303090 const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source)
Amar Singhala49cbc52013-10-08 18:37:44 -07003091{
3092
Amar Singhalfddc28c2013-09-05 13:03:40 -07003093 v_CONTEXT_t pVosContext = NULL;
3094 hdd_context_t *pHddCtx = NULL;
3095 struct wiphy *wiphy = NULL;
3096 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07003097 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003098
Amar Singhalfddc28c2013-09-05 13:03:40 -07003099 /* sanity checks */
3100 if (NULL == pRegDomain)
3101 {
3102 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3103 ("Invalid reg domain pointer") );
3104 return VOS_STATUS_E_FAULT;
3105 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003106
Amar Singhalfddc28c2013-09-05 13:03:40 -07003107 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003108
Amar Singhala49cbc52013-10-08 18:37:44 -07003109 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003110 {
3111 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3112 ("Country code array is NULL"));
3113 return VOS_STATUS_E_FAULT;
3114 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003115
Amar Singhalfddc28c2013-09-05 13:03:40 -07003116 if (0 == countryInfoTable.countryCount)
3117 {
3118 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3119 ("Reg domain table is empty") );
3120 return VOS_STATUS_E_EMPTY;
3121 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003122
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003123
Amar Singhalfddc28c2013-09-05 13:03:40 -07003124 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003125
Amar Singhalfddc28c2013-09-05 13:03:40 -07003126 if (NULL != pVosContext)
3127 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3128 else
3129 return VOS_STATUS_E_EXISTS;
3130
3131 if (NULL == pHddCtx)
3132 {
3133 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3134 ("Invalid pHddCtx pointer") );
3135 return VOS_STATUS_E_FAULT;
3136 }
3137
Kiet Lam6c583332013-10-14 05:37:09 +05303138 temp_reg_domain = REGDOMAIN_COUNT;
3139 /* lookup the country in the local database */
3140 for (i = 0; i < countryInfoTable.countryCount &&
3141 REGDOMAIN_COUNT == temp_reg_domain; i++)
3142 {
3143 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3144 VOS_COUNTRY_CODE_LEN) == 0)
3145 {
3146 /* country code is found */
3147 /* record the temporary regulatory_domain as well */
3148 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3149 break;
3150 }
3151 }
3152
3153 if (REGDOMAIN_COUNT == temp_reg_domain) {
3154
3155 /* the country was not found in the driver database */
3156 /* so we will return the REGDOMAIN_WORLD to SME/CSR */
3157
3158 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3159 ("Country does not map to any Regulatory domain"));
3160
3161 temp_reg_domain = REGDOMAIN_WORLD;
3162 }
3163
3164 if (COUNTRY_QUERY == source)
3165 {
3166 *pRegDomain = temp_reg_domain;
3167 return VOS_STATUS_SUCCESS;
3168 }
3169
Amar Singhalfddc28c2013-09-05 13:03:40 -07003170 wiphy = pHddCtx->wiphy;
3171
Amar Singhala49cbc52013-10-08 18:37:44 -07003172 if (false == wiphy->registered)
3173 {
3174 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3175 ("wiphy is not yet registered with the kernel") );
3176 return VOS_STATUS_E_FAULT;
3177 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003178
3179 /* We need to query the kernel to get the regulatory information
3180 for this country */
3181
Amar Singhal0d15bd52013-10-12 23:13:13 -07003182
3183 /* First compare the country code with the existing current country code
3184 . If both are same there is no need to query any database */
3185
3186 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3187 ("regdomain request"));
3188
3189 if ((country_code[0] == linux_reg_cc[0]) &&
3190 (country_code[1] == linux_reg_cc[1])) {
3191
3192 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003193
Amar Singhala49cbc52013-10-08 18:37:44 -07003194 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhal0d15bd52013-10-12 23:13:13 -07003195 (" country code already exists"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003196
Amar Singhal0d15bd52013-10-12 23:13:13 -07003197 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003198
Amar Singhal0d15bd52013-10-12 23:13:13 -07003199 return VOS_STATUS_SUCCESS;
3200 }
3201 else {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003202
Amar Singhal0d15bd52013-10-12 23:13:13 -07003203 /* get the regulatory information from the kernel
3204 database */
Amar Singhala49cbc52013-10-08 18:37:44 -07003205
Amar Singhal0d15bd52013-10-12 23:13:13 -07003206 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3207 (" get country information from kernel db"));
3208
Amar Singhal0d15bd52013-10-12 23:13:13 -07003209
Kiet Lam6c583332013-10-14 05:37:09 +05303210 if (COUNTRY_NV == source)
3211 {
3212 INIT_COMPLETION(pHddCtx->linux_reg_req);
3213 regulatory_hint(wiphy, country_code);
3214 wait_result = wait_for_completion_interruptible_timeout(
3215 &pHddCtx->linux_reg_req,
3216 LINUX_REG_WAIT_TIME);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003217
Kiet Lam6c583332013-10-14 05:37:09 +05303218 /* if the country information does not exist with the kernel,
3219 then the driver callback would not be called */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003220
Kiet Lam6c583332013-10-14 05:37:09 +05303221 if (wait_result >= 0) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003222
Kiet Lam6c583332013-10-14 05:37:09 +05303223 /* the driver callback was called. this means the country
3224 regulatory information was found in the kernel database.
3225 The callback would have updated the internal database. Here
3226 update the country and the return value for the regulatory
3227 domain */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003228
Kiet Lam6c583332013-10-14 05:37:09 +05303229 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3230 ("runtime country code is found in kernel db"));
3231
3232 *pRegDomain = temp_reg_domain;
3233 cur_reg_domain = temp_reg_domain;
3234 linux_reg_cc[0] = country_code[0];
3235 linux_reg_cc[1] = country_code[1];
3236
3237 return VOS_STATUS_SUCCESS;
3238 }
3239 else {
3240
3241 /* the country information has not been found in the kernel
3242 database, return failure */
3243
3244 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3245 ("runtime country code is not found in kernel db"));
3246
3247 return VOS_STATUS_E_EXISTS;
3248 }
3249 }
3250 else if (COUNTRY_IE == source || COUNTRY_USER == source)
3251 {
3252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3253 regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER);
3254#else
3255 regulatory_hint_user(country_code);
3256#endif
Amar Singhal0d15bd52013-10-12 23:13:13 -07003257 *pRegDomain = temp_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003258 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003259
Kiet Lam6c583332013-10-14 05:37:09 +05303260 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003261
Kiet Lam6c583332013-10-14 05:37:09 +05303262 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003263}
3264
Amar Singhal0d15bd52013-10-12 23:13:13 -07003265/* create_linux_regulatory_entry to populate internal structures from wiphy */
3266static int create_linux_regulatory_entry(struct wiphy *wiphy,
3267 struct regulatory_request *request,
3268 v_U8_t nBandCapability)
3269{
3270 int i, j, m;
3271 int k = 0, n = 0;
Kiet Lam5cb90e82013-10-25 19:35:12 +05303272#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
3273 int err;
3274#endif
3275 const struct ieee80211_reg_rule *reg_rule;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003276 v_CONTEXT_t pVosContext = NULL;
3277 hdd_context_t *pHddCtx = NULL;
3278
3279 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3280
3281 if (NULL != pVosContext)
3282 {
3283 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3284 if (NULL == pHddCtx)
3285 {
3286 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3287 ("Invalid pHddCtx pointer") );
3288 }
3289 else
3290 {
3291 pHddCtx->isVHT80Allowed = 0;
3292 }
3293 }
3294 else
3295 {
3296 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3297 ("Invalid pVosContext pointer") );
3298 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003299
3300 /* 20MHz channels */
3301 if (nBandCapability == eCSR_BAND_24)
3302 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08003303 "BandCapability is set to 2G only");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003304
3305 for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++)
3306 {
3307 /* 5G only */
3308 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G)
3309 continue;
3310
3311 /* 2G only */
3312 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24)
3313 continue;
3314
3315 if (wiphy->bands[i] == NULL)
3316 {
3317
3318 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003319 "error: wiphy->bands is NULL, i = %d", i);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003320 return -1;
3321 }
3322
3323 /* internal channels[] is one continous array for both 2G and 5G bands
3324 m is internal starting channel index for each band */
3325
3326 if (i == 0)
3327 m = 0;
3328 else
3329 m = wiphy->bands[i-1]->n_channels + m;
3330
3331 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3332 {
3333 /* k = (m + j) is internal current channel index for 20MHz channel
3334 n is internal channel index for corresponding 40MHz channel */
3335
3336 k = m + j;
3337 n = bw20_ch_index_to_bw40_ch_index(k);
3338
3339 if (n == -1)
3340 return -1;
3341
Kiet Lam5cb90e82013-10-25 19:35:12 +05303342 /* If the regulatory rules for a country do not explicilty
3343 * require a passive scan on a frequency, lift the passive
3344 * scan restriction
3345 */
3346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3347 reg_rule = freq_reg_info(wiphy,
3348 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq));
3349#else
3350 err = freq_reg_info(wiphy,
3351 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq),
3352 0, &reg_rule);
3353#endif
3354
3355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3356 if (!IS_ERR(reg_rule))
3357#else
3358 if (0 == err)
3359#endif
3360 {
3361 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
3362 {
3363 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3364 "%s: Remove passive scan restriction for %u",
3365 __func__, wiphy->bands[i]->channels[j].center_freq);
3366 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3367 }
3368 }
3369
Amar Singhal0d15bd52013-10-12 23:13:13 -07003370 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
3371 {
3372 if (pnvEFSTable == NULL)
3373 {
3374 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003375 "error: pnvEFSTable is NULL, probably not parsed nv.bin yet");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003376 return -1;
3377 }
3378 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3379 NV_CHANNEL_DISABLE;
3380 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3381 NV_CHANNEL_DISABLE;
3382 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303383 /* nv cannot distinguish between DFS and passive channels */
3384 else if (wiphy->bands[i]->channels[j].flags &
3385 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
Amar Singhal0d15bd52013-10-12 23:13:13 -07003386 {
3387 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3388 NV_CHANNEL_DFS;
3389
3390 /* max_power is in mBm = 100 * dBm */
3391 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003392 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003393 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
3394 {
3395 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3396 NV_CHANNEL_DFS;
3397
3398 /* 40MHz channel power is half of 20MHz (-3dB) ?? */
3399 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003400 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003401 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003402 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3403 {
3404 if (NULL == pHddCtx)
3405 {
3406 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3407 ("Invalid pHddCtx pointer") );
3408 }
3409 else
3410 {
3411 pHddCtx->isVHT80Allowed = 1;
3412 }
3413 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003414 }
3415 else /* Enable is only last flag we support */
3416 {
3417 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3418 NV_CHANNEL_ENABLE;
3419
3420 /* max_power is in dBm */
3421 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003422 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003423 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
3424 {
3425 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3426 NV_CHANNEL_ENABLE;
3427 /* 40MHz channel power is half of 20MHz (-3dB) */
3428 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003429 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
Amar Singhal0d15bd52013-10-12 23:13:13 -07003430 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003431 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3432 {
3433 if (NULL == pHddCtx)
3434 {
3435 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3436 ("Invalid pHddCtx pointer") );
3437 }
3438 else
3439 {
3440 pHddCtx->isVHT80Allowed = 1;
3441 }
3442 }
3443
Amar Singhal0d15bd52013-10-12 23:13:13 -07003444 }
3445
Kiet Lam5cb90e82013-10-25 19:35:12 +05303446
Amar Singhal0d15bd52013-10-12 23:13:13 -07003447 }
3448 }
3449
3450 if (k == 0)
3451 return -1;
3452
3453 return 0;
3454}
3455
3456
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003457/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07003458 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003459 * This function is called from cfg80211 core to provide regulatory settings
3460 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07003461 * This function is used to create a CRDA regulatory settings entry into internal
3462 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003463 */
Amar Singhala49cbc52013-10-08 18:37:44 -07003464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003465void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07003466 struct regulatory_request *request)
3467#else
Amar Singhala49cbc52013-10-08 18:37:44 -07003468int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003469 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07003470#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003471{
3472 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Amar Singhala49cbc52013-10-08 18:37:44 -07003473 tANI_U8 nBandCapability;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003474 v_COUNTRYCODE_t country_code;
3475 int i;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003476 v_BOOL_t isVHT80Allowed;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003477
Amar Singhala49cbc52013-10-08 18:37:44 -07003478 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003479 "cfg80211 reg notifier callback for country for initiator %d", request->initiator);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003480
Kiet Lamaa8e15a2014-02-11 23:30:06 -08003481 if (pHddCtx->isLoadUnloadInProgress)
Arif Hussainec3fbb32013-10-03 11:49:23 -07003482 {
Kiet Lamaa8e15a2014-02-11 23:30:06 -08003483 wiphy_dbg(wiphy, "info: %s: Unloading/Loading in Progress. Ignore!!!",
3484 __func__);
Kiet Lamcffc5862013-10-30 16:28:45 +05303485#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Kiet Lamaa8e15a2014-02-11 23:30:06 -08003486 return;
Kiet Lamcffc5862013-10-30 16:28:45 +05303487#else
3488 return 0;
3489#endif
3490 }
3491
3492 if (NULL == pHddCtx)
3493 {
3494 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3495 ("Invalid pHddCtx pointer") );
3496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3497 return;
3498#else
3499 return 0;
3500#endif
Arif Hussainec3fbb32013-10-03 11:49:23 -07003501 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003502 /* first check if this callback is in response to the driver callback */
3503
Amar Singhala49cbc52013-10-08 18:37:44 -07003504 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
3505 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003506
Amar Singhal0d15bd52013-10-12 23:13:13 -07003507 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003508 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003509 if (create_linux_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
3510 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003511
Amar Singhal0d15bd52013-10-12 23:13:13 -07003512 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07003513 (" regulatory entry created"));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003514 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003515 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3516 {
3517 hdd_checkandupdate_phymode( pHddCtx);
3518 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003519
Amar Singhal0d15bd52013-10-12 23:13:13 -07003520 complete(&pHddCtx->linux_reg_req);
3521 }
3522
Kiet Lamcffc5862013-10-30 16:28:45 +05303523 else if (request->initiator == NL80211_REGDOM_SET_BY_USER ||
3524 request->initiator == NL80211_REGDOM_SET_BY_CORE)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003525 {
3526
3527 /* first lookup the country in the local database */
3528
3529 country_code[0] = request->alpha2[0];
3530 country_code[1] = request->alpha2[1];
3531
3532 temp_reg_domain = REGDOMAIN_COUNT;
3533 for (i = 0; i < countryInfoTable.countryCount &&
3534 REGDOMAIN_COUNT == temp_reg_domain; i++)
3535 {
3536 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3537 VOS_COUNTRY_CODE_LEN) == 0)
3538 {
3539 /* country code is found */
3540 /* record the temporary regulatory_domain as well */
3541 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3542 break;
3543 }
3544 }
3545
3546 if (REGDOMAIN_COUNT == temp_reg_domain)
3547 temp_reg_domain = REGDOMAIN_WORLD;
3548
3549 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003550 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003551 if (create_linux_regulatory_entry(wiphy, request,
3552 pHddCtx->cfg_ini->nBandCapability) == 0)
3553 {
3554 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3555 (" regulatory entry created"));
3556
3557 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003558 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3559 {
3560 hdd_checkandupdate_phymode( pHddCtx);
3561 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003562
3563 cur_reg_domain = temp_reg_domain;
3564 linux_reg_cc[0] = country_code[0];
3565 linux_reg_cc[1] = country_code[1];
3566
3567 /* now pass the new country information to sme */
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003568 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
3569 {
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003570 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3571 REGDOMAIN_COUNT);
3572 }
Kiet Lamcffc5862013-10-30 16:28:45 +05303573 else
3574 {
3575 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
3576 temp_reg_domain);
3577 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05303578
Kiet Lamcffc5862013-10-30 16:28:45 +05303579 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07003581 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07003582#else
3583 return 0;
3584#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003585}
Amar Singhalfddc28c2013-09-05 13:03:40 -07003586
Amar Singhal0d15bd52013-10-12 23:13:13 -07003587
Amar Singhal0a402232013-10-11 20:57:16 -07003588/* initialize wiphy from NV.bin */
3589VOS_STATUS vos_init_wiphy_from_nv_bin(void)
3590{
3591 int i, j, m;
3592 int k = 0;
3593 v_REGDOMAIN_t reg_domain;
3594 v_CONTEXT_t pVosContext = NULL;
3595 hdd_context_t *pHddCtx = NULL;
3596 struct wiphy *wiphy = NULL;
3597
3598 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3599
3600 if (NULL != pVosContext)
3601 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3602 else
3603 return VOS_STATUS_E_EXISTS;
3604
3605 if (NULL == pHddCtx)
3606 {
3607 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3608 ("Invalid pHddCtx pointer") );
3609 return VOS_STATUS_E_FAULT;
3610 }
3611
3612 wiphy = pHddCtx->wiphy;
3613
3614 if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0])
3615 &&
3616 ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]))
3617 {
3618 /* default country is world roaming */
3619
3620 reg_domain = REGDOMAIN_WORLD;
3621 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3622 }
3623 else if (REGDOMAIN_WORLD ==
3624 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) {
3625
3626 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3627 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3628 }
3629 else {
3630
3631 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
3632 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
3633 }
3634
Amar Singhala1829502013-11-16 13:57:41 -08003635 m = 0;
Amar Singhal0a402232013-10-11 20:57:16 -07003636 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3637 {
3638
3639 if (wiphy->bands[i] == NULL)
3640 {
3641 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
Amar Singhala1829502013-11-16 13:57:41 -08003642 continue;
Amar Singhal0a402232013-10-11 20:57:16 -07003643 }
3644
3645 /* internal channels[] is one continous array for both 2G and 5G bands
3646 m is internal starting channel index for each band */
Amar Singhal0a402232013-10-11 20:57:16 -07003647
3648 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3649 {
3650 /* k = (m + j) is internal current channel index */
3651 k = m + j;
3652
3653 if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3654 NV_CHANNEL_DISABLE)
3655 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3656
3657 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3658 NV_CHANNEL_DFS) {
3659
3660 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
3661
3662 wiphy->bands[i]->channels[j].max_power =
3663 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3664 }
3665
3666 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
3667 NV_CHANNEL_ENABLE) {
3668
3669 wiphy->bands[i]->channels[j].max_power =
3670 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100;
3671 }
3672 }
Amar Singhala1829502013-11-16 13:57:41 -08003673
3674 m += wiphy->bands[i]->n_channels;
Amar Singhal0a402232013-10-11 20:57:16 -07003675 }
3676
3677 return VOS_STATUS_SUCCESS;
3678}
3679
3680
Amar Singhalfddc28c2013-09-05 13:03:40 -07003681#else
3682
3683/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07003684 \brief vos_nv_setRegDomain -
3685 \param clientCtxt - Client Context, Not used for PRIMA
3686 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303687 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003688 \return status set REG domain operation
3689 \sa
3690 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303691VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3692 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003693{
3694 v_CONTEXT_t pVosContext = NULL;
3695 hdd_context_t *pHddCtx = NULL;
3696 struct wiphy *wiphy = NULL;
3697 /* Client Context Argumant not used for PRIMA */
3698 if (regId >= REGDOMAIN_COUNT)
3699 {
3700 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3701 "VOS set reg domain, invalid REG domain ID %d", regId);
3702 return VOS_STATUS_E_INVAL;
3703 }
3704
3705 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3706 if (NULL != pVosContext)
3707 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3708 else
3709 return VOS_STATUS_E_EXISTS;
3710 /* Set correct channel information based on REG Domain */
3711 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3712
3713 /* when CRDA is not running then we are world roaming.
3714 In this case if 11d is enabled, then country code should
3715 be update on basis of world roaming */
Abhishek Singha306a442013-11-07 18:39:01 +05303716 if (NULL != pHddCtx && sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003717 {
3718 wiphy = pHddCtx->wiphy;
3719 regulatory_hint(wiphy, "00");
3720 }
3721 return VOS_STATUS_SUCCESS;
3722}
3723
3724
3725/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07003726 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3727 a country given its country code
3728 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3729 a country given its country code. This is done from reading a cached
3730 copy of the binary file.
3731 \param pRegDomain - pointer to regulatory domain
3732 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303733 \param source - source of the country code
Amar Singhalfddc28c2013-09-05 13:03:40 -07003734 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3735 VOS_STATUS_E_FAULT - invalid pointer error
3736 VOS_STATUS_E_EMPTY - country code table is empty
3737 VOS_STATUS_E_EXISTS - given country code does not exist in table
3738 \sa
3739 -------------------------------------------------------------------------*/
3740VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303741 const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003742{
Amar Singhala49cbc52013-10-08 18:37:44 -07003743 int i;
3744 v_CONTEXT_t pVosContext = NULL;
3745 hdd_context_t *pHddCtx = NULL;
3746 struct wiphy *wiphy = NULL;
3747 int status;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003748
Amar Singhala49cbc52013-10-08 18:37:44 -07003749 // sanity checks
3750 if (NULL == pRegDomain)
3751 {
3752 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003753 ("Invalid reg domain pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003754 return VOS_STATUS_E_FAULT;
3755 }
3756 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003757
Amar Singhala49cbc52013-10-08 18:37:44 -07003758 if (NULL == countryCode)
3759 {
3760 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003761 ("Country code array is NULL") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003762 return VOS_STATUS_E_FAULT;
3763 }
3764 if (0 == countryInfoTable.countryCount)
3765 {
3766 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003767 ("Reg domain table is empty") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003768 return VOS_STATUS_E_EMPTY;
3769 }
3770 /* If CRDA regulatory settings is valid, i.e. crda is enabled
3771 and reg_notifier is called back.
3772 Intercept here and redirect to the Reg domain table's CRDA
3773 entry if country code is crda's country.
3774 last one NUM_REG_DOMAINS-1 is reserved for crda */
3775 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003776 "vos_nv_getRegDomainFromCountryCode %c%c",
Amar Singhala49cbc52013-10-08 18:37:44 -07003777 countryCode[0], countryCode[1]);
3778
3779 if (crda_regulatory_entry_valid == VOS_TRUE)
3780 {
3781 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
3782 {
3783 *pRegDomain = NUM_REG_DOMAINS-1;
3784 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003785 "vos_nv_getRegDomainFromCountryCode return crda init entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003786 return VOS_STATUS_SUCCESS;
3787 }
3788 if (run_time_alpha2[0]==countryCode[0] &&
3789 run_time_alpha2[1]==countryCode[1] &&
3790 crda_regulatory_run_time_entry_valid == VOS_TRUE)
3791 {
3792 *pRegDomain = NUM_REG_DOMAINS-2;
3793 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003794 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003795 return VOS_STATUS_SUCCESS;
3796 }
3797 else
3798 {
3799 crda_regulatory_run_time_entry_valid = VOS_FALSE;
3800 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3801 if (NULL != pVosContext)
3802 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3803 else
3804 return VOS_STATUS_E_EXISTS;
3805 if (NULL == pHddCtx)
3806 {
3807 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003808 ("Invalid pHddCtx pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07003809 return VOS_STATUS_E_FAULT;
3810 }
3811
3812 wiphy = pHddCtx->wiphy;
3813
3814 INIT_COMPLETION(pHddCtx->driver_crda_req);
3815 regulatory_hint(wiphy, countryCode);
3816 status = wait_for_completion_interruptible_timeout(
3817 &pHddCtx->driver_crda_req,
3818 msecs_to_jiffies(CRDA_WAIT_TIME));
3819 if (!status)
3820 {
3821 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3822 "%s: Timeout waiting for CRDA REQ", __func__);
3823 }
3824
3825 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
3826 {
3827 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08003828 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003829 return VOS_STATUS_SUCCESS;
3830 }
3831 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003832 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07003833 return VOS_STATUS_E_EXISTS;
3834 }
3835 }
3836
3837 // iterate the country info table until end of table or the country code
3838 // is found
3839 for (i = 0; i < countryInfoTable.countryCount &&
3840 REGDOMAIN_COUNT == *pRegDomain; i++)
3841 {
3842 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
3843 VOS_COUNTRY_CODE_LEN) == 0)
3844 {
3845 // country code is found
3846 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
3847 }
3848 }
3849 if (REGDOMAIN_COUNT != *pRegDomain)
3850 {
3851 return VOS_STATUS_SUCCESS;
3852 }
3853 else
3854 {
3855 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08003856 ("country code is not found"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003857 return VOS_STATUS_E_EXISTS;
3858 }
3859}
Abhishek Singha306a442013-11-07 18:39:01 +05303860/* FUNCTION: vos_nv_change_country_code_cb
3861* to wait for contry code completion
3862*/
3863void* vos_nv_change_country_code_cb(void *pAdapter)
3864{
3865 struct completion *change_code_cng = pAdapter;
3866 complete(change_code_cng);
3867 return NULL;
3868}
Amar Singhala49cbc52013-10-08 18:37:44 -07003869
3870/*
3871 * Function: wlan_hdd_crda_reg_notifier
3872 * This function is called from cfg80211 core to provide regulatory settings
3873 * after new country is requested or intersected (init, user input or 11d)
3874 * This function is used to create a CRDA regulatory settings entry into internal
3875 * regulatory setting table.
3876 */
3877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3878void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3879 struct regulatory_request *request)
3880#else
3881int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
3882 struct regulatory_request *request)
3883#endif
3884{
3885 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3886 v_REGDOMAIN_t domainIdCurrent;
3887 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
3888 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
3889 tANI_U8 nBandCapability;
3890 int i,j,k,m;
3891
3892 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
3893 " %c%c\n", request->alpha2[0], request->alpha2[1]);
3894 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003895 {
Abhishek Singha306a442013-11-07 18:39:01 +05303896 int status;
Amar Singhala49cbc52013-10-08 18:37:44 -07003897 wiphy_dbg(wiphy, "info: set by user\n");
Abhishek Singha306a442013-11-07 18:39:01 +05303898 init_completion(&change_country_code);
3899 /* We will process hints by user from nl80211 in driver.
3900 * sme_ChangeCountryCode will set the country to driver
3901 * and update the regdomain.
3902 * when we return back to nl80211 from this callback, the nl80211 will
3903 * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to
3904 * query channel list from nl80211. Thus we need to update the channels
3905 * according to reg domain set by user before returning to nl80211 so
3906 * that hostapd will gets the updated channels.
3907 * The argument sendRegHint in sme_ChangeCountryCode is
3908 * set to eSIR_FALSE (hint is from nl80211 and thus
3909 * no need to notify nl80211 back)*/
3910 status = sme_ChangeCountryCode(pHddCtx->hHal,
3911 (void *)(tSmeChangeCountryCallback)
3912 vos_nv_change_country_code_cb,
3913 request->alpha2,
3914 &change_country_code,
3915 pHddCtx->pvosContext,
3916 eSIR_FALSE,
3917 eSIR_FALSE);
3918 if (eHAL_STATUS_SUCCESS == status)
3919 {
3920 status = wait_for_completion_interruptible_timeout(
3921 &change_country_code,
3922 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3923 if(status <= 0)
3924 {
3925 wiphy_dbg(wiphy, "info: set country timed out\n");
3926 }
3927 }
3928 else
3929 {
3930 wiphy_dbg(wiphy, "info: unable to set country by user\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07003931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3932 return;
3933#else
3934 return 0;
3935#endif
Abhishek Singha306a442013-11-07 18:39:01 +05303936 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003937 // ToDo
3938 /* Don't change default country code to CRDA country code by user req */
3939 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
3940 regd for new country settings */
3941 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3942 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003943 }
Abhishek Singha306a442013-11-07 18:39:01 +05303944
3945 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003946 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003947 wiphy_dbg(wiphy, "info: set by country IE\n");
3948 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
3949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3950 return;
3951#else
3952 return 0;
3953#endif
3954 // ToDo
3955 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003956
Amar Singhala49cbc52013-10-08 18:37:44 -07003957 /* Don't change default country code to CRDA country code by 11d req */
3958 /* for every adapter call sme_ChangeCountryCode to trigger read regd
3959 for intersected new country settings */
3960 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
3961 // &country_code[0], pAdapter, pHddCtx->pvosContext);
3962 }
3963 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
Abhishek Singha306a442013-11-07 18:39:01 +05303964 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
3965 (request->initiator == NL80211_REGDOM_SET_BY_USER))
Amar Singhalfddc28c2013-09-05 13:03:40 -07003966 {
Amar Singhala49cbc52013-10-08 18:37:44 -07003967 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
3968 {
3969 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
3970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3971 return;
3972#else
3973 return 0;
3974#endif
3975 }
3976 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
3977 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
3978 {
3979 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
3980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3981 return;
3982#else
3983 return 0;
3984#endif
3985 }
3986
3987 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
3988 /* if set by driver itself, it means driver can accept the crda
3989 regulatory settings and wiphy->regd should be populated with crda
3990 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
3991 correctly, this may be fixed by later kernel */
3992
3993 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
3994 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
3995 {
3996 if (NULL == wiphy->bands[i])
3997 {
3998 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3999 "error: wiphy->bands[i] is NULL, i = %d", i);
4000 continue;
4001 }
4002
4003 // internal channels[] is one continous array for both 2G and 5G bands
4004 // m is internal starting channel index for each band
4005 if (0 == i)
4006 {
4007 m = 0;
4008 }
4009 else
4010 {
4011 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
4012 }
4013
4014 for (j=0; j<wiphy->bands[i]->n_channels; j++)
4015 {
4016 // k = (m + j) is internal current channel index for 20MHz channel
4017 // n is internal channel index for corresponding 40MHz channel
4018 k = m + j;
4019 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
4020 {
4021 // Enable social channels for P2P
4022 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
4023 2437 == wiphy->bands[i]->channels[j].center_freq ||
4024 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
4025 NV_CHANNEL_ENABLE == regChannels[k].enabled)
4026 {
4027 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4028 }
4029 else
4030 {
4031 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4032 }
4033 continue;
4034 }
4035 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
4036 {
4037 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4038 continue;
4039 }
4040
4041 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
4042 NV_CHANNEL_INVALID == regChannels[k].enabled)
4043 {
4044 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4045 }
4046 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
4047 {
4048 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4049 |IEEE80211_CHAN_RADAR);
4050 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4051 }
4052 else
4053 {
4054 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4055 |IEEE80211_CHAN_PASSIVE_SCAN
4056 |IEEE80211_CHAN_NO_IBSS
4057 |IEEE80211_CHAN_RADAR);
4058 }
4059 }
4060 }
4061
4062 /* Haven't seen any condition that will set by driver after init.
4063 If we do, then we should also call sme_ChangeCountryCode */
Kalikinkar dharad73a9bd2014-01-28 22:42:34 -08004064
4065 /* To Disable the strict regulatory FCC rule, need set
4066 gEnableStrictRegulatoryForFCC to zero from INI.
4067 By default regulatory FCC rule enable or set to 1, and
4068 in this case one can control dynamically using IOCTL
4069 (nEnableStrictRegulatoryForFCC).
4070 If gEnableStrictRegulatoryForFCC is set to zero then
4071 IOCTL operation is inactive */
4072
4073 if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC &&
4074 wiphy->bands[IEEE80211_BAND_5GHZ])
Amar Singhala49cbc52013-10-08 18:37:44 -07004075 {
4076 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4077 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304078 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07004079 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
4080 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4081 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4082 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304083 ((domainIdCurrent == REGDOMAIN_FCC) &&
4084 pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004085 {
4086 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4087 }
4088 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
4089 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4090 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4091 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304092 ((domainIdCurrent != REGDOMAIN_FCC) ||
4093 !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004094 {
4095 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
4096 }
4097 }
4098 }
4099
4100 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
4101 {
4102 request->processed = 1;
4103 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07004104 }
4105
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304106 complete(&pHddCtx->wiphy_channel_update_event);
4107
Amar Singhala49cbc52013-10-08 18:37:44 -07004108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4109 return;
4110#else
4111 return 0;
4112#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07004113}
4114
4115#endif