blob: 89a3d466d27a1f31c54c0c6b80c943f3a457f0ff [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam1ed83fc2014-02-19 01:15:45 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lam1ed83fc2014-02-19 01:15:45 -080026 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*============================================================================
32 FILE: vos_nvitem.c
33 OVERVIEW: This source file contains definitions for vOS NV Item APIs
34 DEPENDENCIES: NV, remote API client, WinCE REX
Jeff Johnson295189b2012-06-20 16:38:30 -070035============================================================================*/
36/*============================================================================
37 EDIT HISTORY FOR MODULE
38============================================================================*/
39// the following is used to disable warning for having too many labels in
40// the 'nv_items_enum_type'
41
42/*----------------------------------------------------------------------------
43 * Include Files
44 * -------------------------------------------------------------------------*/
45#include "vos_types.h"
46#include "aniGlobal.h"
47#include "vos_nvitem.h"
48#include "vos_trace.h"
49#include "vos_api.h"
50#include "wlan_hdd_misc.h"
51#include "vos_sched.h"
Amar Singhal0d15bd52013-10-12 23:13:13 -070052#include "sme_Api.h"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070053#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070054#include "wlan_hdd_main.h"
55#include <net/cfg80211.h>
Anand N Sunkada92e4db2015-02-05 12:00:56 +053056#include <linux/firmware.h>
57#include <linux/vmalloc.h>
Amar Singhalfddc28c2013-09-05 13:03:40 -070058
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -070059#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
60#define IEEE80211_CHAN_NO_80MHZ 1<<7
61#endif
Amar Singhala49cbc52013-10-08 18:37:44 -070062
Amar Singhalfddc28c2013-09-05 13:03:40 -070063#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhala49cbc52013-10-08 18:37:44 -070064
65static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
Agarwal Ashish6db9d532014-09-30 18:19:10 +053066static char linux_reg_cc[2] = {0, 0};
Amar Singhalfddc28c2013-09-05 13:03:40 -070067static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
Amar Singhala49cbc52013-10-08 18:37:44 -070068
Abhishek Singha306a442013-11-07 18:39:01 +053069#else
70
71/* Cant access pAdapter in this file so defining a new variable to wait when changing country*/
72static struct completion change_country_code;
73
Amar Singhalfddc28c2013-09-05 13:03:40 -070074#endif
75
Amar Singhala49cbc52013-10-08 18:37:44 -070076static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
77static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
78static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
79static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
80
Jeff Johnson295189b2012-06-20 16:38:30 -070081/*----------------------------------------------------------------------------
82 * Preprocessor Definitions and Constants
83 * -------------------------------------------------------------------------*/
84#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
85#define VALIDITY_BITMAP_SIZE 32
86#define MAX_COUNTRY_COUNT 300
87//To be removed when NV support is fully functional
88#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070089
90#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070091#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070092
Mihir Shete7f3fe0e2014-07-04 12:56:33 +053093#define MIN(a, b) (a > b ? b : a)
Sushant Kaushikece4b562015-04-09 18:27:33 +053094#define MAX(a, b) (a > b ? a : b)
95
Jeff Johnson295189b2012-06-20 16:38:30 -070096/*----------------------------------------------------------------------------
97 * Type Declarations
98 * -------------------------------------------------------------------------*/
99// this wrapper structure is identical to nv_cmd_type except the
100// data_ptr type is changed void* to avoid exceeding the debug information
101// module size as there are too many elements within nv_items_type union
102
103// structure for code and regulatory domain of a single country
104typedef struct
105{
106 v_U8_t regDomain;
107 v_COUNTRYCODE_t countryCode;
108} CountryInfo_t;
109// structure of table to map country code and regulatory domain
110typedef struct
111{
112 v_U16_t countryCount;
113 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
114} CountryInfoTable_t;
115/*----------------------------------------------------------------------------
116 * Global Data Definitions
117 * -------------------------------------------------------------------------*/
118/*----------------------------------------------------------------------------
119 * Static Variable Definitions
120 * -------------------------------------------------------------------------*/
Amar Singhala49cbc52013-10-08 18:37:44 -0700121// cache of country info table;
122// this is re-initialized from data on binary file
123// loaded on driver initialization if available
Amar Singhalfddc28c2013-09-05 13:03:40 -0700124
125#ifdef CONFIG_ENABLE_LINUX_REG
126
127static CountryInfoTable_t countryInfoTable =
128{
129 /* the first entry in the table is always the world domain */
130 138,
131 {
132 {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
133 {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
134 {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
135 {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
136 {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
137 {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
138 {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
139 {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
140 {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
141 {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
142 {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
143 {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
144 {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
145 {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
146 {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
147 {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
148 {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
149 {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
150 {REGDOMAIN_ETSI, {'B', 'L'}}, //
151 {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
152 {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
153 {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
154 {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
155 {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
156 {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
157 {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
158 {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
159 {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
160 {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
161 {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
162 {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
163 {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
164 {REGDOMAIN_ETSI, {'C', 'S'}},
165 {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
166 {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
167 {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
168 {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
169 {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
170 {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
171 {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
172 {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
173 {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
174 {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
175 {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
176 {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
177 {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
178 {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
179 {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
180 {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
181 {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
182 {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
183 {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
184 {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
185 {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
186 {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
187 {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
188 {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
189 {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
Sachin Ahuja2d15ff62015-06-30 12:46:44 +0530190 {REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
Amar Singhalfddc28c2013-09-05 13:03:40 -0700191 {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
192 {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
193 {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
194 {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
195 {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
196 {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
197 {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
198 {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
199 {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
200 {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
201 {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
202 {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
203 {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
204 {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
205 {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
206 {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
207 {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
208 {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
209 {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
210 {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
211 {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
212 {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
213 {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
214 {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
215 {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
216 {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
217 {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
218 {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
219 {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
220 {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
221 {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
222 {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
223 {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
224 {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
225 {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
226 {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
227 {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
228 {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
229 {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
230 {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
231 {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
232 {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
233 {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
234 {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
235 {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
236 {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
237 {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
238 {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
239 {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
240 {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
241 {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
242 {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
243 {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
244 {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
245 {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
246 {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
247 {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
248 {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
249 {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
250 {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
251 {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
252 {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
253 {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
254 {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
255 {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
256 {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
257 {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
258 {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
259 {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
260 {REGDOMAIN_FCC, {'U', 'S'}}, //USA
261 {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
262 {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
263 {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
264 {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
265 {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
266 {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
267 {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
268 {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
269 {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
270 }
271};
272
273#else
274
Jeff Johnson295189b2012-06-20 16:38:30 -0700275// cache of country info table;
276// this is re-initialized from data on binary file
277// loaded on driver initialization if available
278static CountryInfoTable_t countryInfoTable =
279{
280 254,
281 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700282 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
283 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
284 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
285 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
286 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
287 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700288 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700289 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
290 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
291 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
292 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
293 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
294 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
295 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530296 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700297 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
298 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
299 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
300 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
301 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700302 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700303 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
304 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
305 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
306 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
307 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
308 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
309 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
310 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
311 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
312 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
313 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
314 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
315 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
316 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
317 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
318 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
319 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
320 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
321 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
322 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
323 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
324 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
325 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
326 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
327 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
328 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530329 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700330 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
331 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
332 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
333 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
334 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
335 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
336 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
337 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
338 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
339 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
340 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
341 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700342 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700343 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
344 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
345 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
346 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
347 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
348 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
349 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
350 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
351 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
352 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
353 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
354 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
355 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
356 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
357 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
358 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
359 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
360 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
361 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
362 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
363 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
364 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
365 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
366 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
367 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
368 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
369 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
370 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
371 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
372 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700373 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700374 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
375 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
376 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
377 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
378 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
379 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
380 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
381 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
382 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
383 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700384 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700385 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
386 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
387 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
388 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
389 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
390 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
391 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
392 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
393 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
394 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
395 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
396 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
397 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
398 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700399 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700400 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
401 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
402 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
403 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
404 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700405 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700406 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
407 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
408 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
409 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
410 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
411 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
412 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
413 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
414 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700415 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700416 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700417 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700418 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
419 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
420 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
421 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
422 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
423 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
424 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
425 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
426 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700427 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700428 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700429 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
430 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
431 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
432 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
433 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
434 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
435 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700436 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700437 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
438 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
439 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
440 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
441 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
442 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
443 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
444 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
445 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
446 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
447 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
448 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
449 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
450 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
451 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
452 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
453 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
454 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
455 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
456 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700457 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700458 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
459 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
460 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700461 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700462 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700463 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700464 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700465 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
466 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700467 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
468 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
469 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
470 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
471 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
472 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
473 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
474 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
475 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
476 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
477 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
478 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
479 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700480 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
481 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
482 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700483 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
484 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
485 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
486 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
487 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
488 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
489 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
490 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
491 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
492 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
493 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
494 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
495 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
496 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
497 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
498 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
499 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
500 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
501 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
502 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
503 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
504 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
505 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
506 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
507 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
508 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
509 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
510 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
511 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700512 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700513 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
514 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700515 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700516 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700517 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
518 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700519 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
520 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700521 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700522 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
523 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
524 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
525 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
526 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700527 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700528 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
529 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
530 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
531 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
532 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
533 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
534 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700535 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 }
537};
Amar Singhalfddc28c2013-09-05 13:03:40 -0700538
539#endif
540
Amar Singhala49cbc52013-10-08 18:37:44 -0700541
Jeff Johnson295189b2012-06-20 16:38:30 -0700542typedef struct nvEFSTable_s
543{
544 v_U32_t nvValidityBitmap;
545 sHalNv halnv;
546} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700547nvEFSTable_t *gnvEFSTable;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700548/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700549static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700550static v_U8_t *pnvEncodedBuf;
Anand N Sunkada92e4db2015-02-05 12:00:56 +0530551static v_U8_t *pnvtmpBuf;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700552static v_U8_t *pDictFile;
553static v_U8_t *pEncodedBuf;
554static v_SIZE_t nvReadEncodeBufSize;
555static v_SIZE_t nDictionarySize;
556static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700557
Leo Chang80de3c22013-11-26 10:52:12 -0800558/* NV2 specific, No CH 144 support
559 * For NV_FTM operation, NV2 structure should be maintained
560 * This will be used only for the NV_FTM operation */
561typedef struct nvEFSTableV2_s
562{
563 v_U32_t nvValidityBitmap;
564 sHalNvV2 halnvV2;
565} nvEFSTableV2_t;
566nvEFSTableV2_t *gnvEFSTableV2;
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
569{
570 //RF_SUBBAND_2_4_GHZ
571 //freq, chan#, band
572 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
573 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
574 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
575 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
576 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
577 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
578 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
579 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
580 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
581 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
582 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
583 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
584 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
585 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700586 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
587 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
588 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
589 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
590 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
591 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
592 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700593 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
594 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
595 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
596 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
597 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
598 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
599 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
600 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
601 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
602 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
603 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
604 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
605 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
606 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
607 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
608 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
609 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
610 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
611 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
Leo Chang80de3c22013-11-26 10:52:12 -0800612#ifdef FEATURE_WLAN_CH144
613 { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144,
614#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
616 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
617 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
618 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
619 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700620 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
621 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
622 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
623 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
624 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
625 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
626 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
627 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
628 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
629 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
630 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
631 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
632 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
633 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
634 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
635 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
636 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
637 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
638 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
639 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
640 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
641 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
642 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
643 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
644 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
645 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
646 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
647 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
648 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
649 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
650 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
Leo Chang80de3c22013-11-26 10:52:12 -0800651#ifdef FEATURE_WLAN_CH144
652 { 5730, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142,
653#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700654 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
655 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
656 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
657 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700658};
659
660extern const sHalNv nvDefaults;
661
662const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
663
Mihir Shete7f3fe0e2014-07-04 12:56:33 +0530664
Jeff Johnson295189b2012-06-20 16:38:30 -0700665/*----------------------------------------------------------------------------
666 Function Definitions and Documentation
667 * -------------------------------------------------------------------------*/
668VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
Sushant Kaushike0d2cce2014-04-10 14:36:07 +0530669const char * voss_DomainIdtoString(v_U8_t domainIdCurrent)
670{
671 switch (domainIdCurrent)
672 {
673 CASE_RETURN_STRING( REGDOMAIN_FCC );
674 CASE_RETURN_STRING( REGDOMAIN_ETSI );
675 CASE_RETURN_STRING( REGDOMAIN_JAPAN );
676 CASE_RETURN_STRING( REGDOMAIN_WORLD );
677 CASE_RETURN_STRING( REGDOMAIN_N_AMER_EXC_FCC );
678 CASE_RETURN_STRING( REGDOMAIN_APAC );
679 CASE_RETURN_STRING( REGDOMAIN_KOREA );
680 CASE_RETURN_STRING( REGDOMAIN_HI_5GHZ );
681 CASE_RETURN_STRING( REGDOMAIN_NO_5GHZ );
682 CASE_RETURN_STRING( REGDOMAIN_COUNT );
683 default:
684 return "Regulation Domain Unknown";
685 }
686}
Jeff Johnson295189b2012-06-20 16:38:30 -0700687/**------------------------------------------------------------------------
688 \brief vos_nv_init() - initialize the NV module
689 The \a vos_nv_init() initializes the NV module. This read the binary
690 file for country code and regulatory domain information.
691 \return VOS_STATUS_SUCCESS - module is initialized successfully
692 otherwise - module is not initialized
693 \sa
694 -------------------------------------------------------------------------*/
695VOS_STATUS vos_nv_init(void)
696{
697 return VOS_STATUS_SUCCESS;
698}
699
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700700/**------------------------------------------------------------------------
701 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
702 \ tools
703 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
704 otherwise - not successful
705 \sa
706-------------------------------------------------------------------------*/
707VOS_STATUS vos_nv_get_dictionary_data(void)
708{
709 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
710
711 if (MAGIC_NUMBER != magicNumber)
712 {
713 return VOS_STATUS_SUCCESS;
714 }
715
716 nDictionarySize = 0;
717
718 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
719 &nDictionarySize );
720 if (VOS_STATUS_E_NOMEM != vosStatus)
721 {
722 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
723 "Error obtaining binary size" );
724/// NOTE:
725/// We can still work without a dictionary file..
726 return VOS_STATUS_SUCCESS;
727 }
728
729 // malloc a buffer to read in the Configuration binary file.
730 pDictFile = vos_mem_malloc( nDictionarySize );
731 if (NULL == pDictFile)
732 {
733 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
734 "Unable to allocate memory for the CFG binary [size= %d bytes]",
735 nDictionarySize );
736 vosStatus = VOS_STATUS_E_NOMEM;
737 goto fail;
738 }
739
740 /* Get the entire CFG file image... */
741 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
742 &nDictionarySize );
743 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
744 {
745 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
746 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
747 nDictionarySize );
748 return VOS_STATUS_SUCCESS;
749 }
750
751 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
752 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
753
754fail:
755 return vosStatus;
756}
757
Leo Chang80de3c22013-11-26 10:52:12 -0800758/**------------------------------------------------------------------------
759 \brief vos_nv_parseV2bin() - Parse NV2 binary
760 Parse NV2 BIN, and assign contents to common NV structure.
761 \param pnvEncodedBuf
762 NV Bin read buffer
763 \param nvReadBufSize
764 NV Bin read size
765 \param halNv
766 common NV structure storage pointer
767 \return VOS_STATUS_SUCCESS - module is initialized successfully
768 otherwise - module is not initialized
769 \sa
770 -------------------------------------------------------------------------*/
771VOS_STATUS vos_nv_parseV2bin(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
772 sHalNv *halNv)
773{
774 sHalNvV2 *nv2Table;
775 tANI_U16 copyLoop;
776 tANI_U16 channelLoop;
777 void *targetPtr;
778 void *sourcePtr;
779
780 v_U32_t structSize = 0;
781
782 nv2Table = (sHalNvV2 *)pnvEncodedBuf;
783 /* NV Field Default Copy */
784 vos_mem_copy((char *)&halNv->fields,
785 (char *)&nv2Table->fields,
786 sizeof(sNvFields));
787 structSize += sizeof(sNvFields);
788 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
789 "%s: sizeof(sNvFields) %zu, structSize %d",
790 __func__, sizeof(sNvFields), structSize);
791
792 /* NV Table, tRateGroupPwr, NOT depends on channel count */
793 vos_mem_copy((char *)halNv->tables.pwrOptimum,
794 (char *)nv2Table->tables.pwrOptimum,
795 sizeof(halNv->tables.pwrOptimum));
796 structSize += sizeof(halNv->tables.pwrOptimum);
797 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
798 "%s: sizeof(halNv->tables.pwrOptimum) %zu, structSize %d",
799 __func__, sizeof(halNv->tables.pwrOptimum), structSize);
800
801 /* NV Table, regDomains, edepends on channel count */
802 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
803 {
804 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].antennaGain,
805 (char *)nv2Table->tables.regDomains[copyLoop].antennaGain,
806 sizeof(halNv->tables.regDomains[copyLoop].antennaGain));
807 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
808
809 vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].bRatePowerOffset,
810 (char *)nv2Table->tables.regDomains[copyLoop].bRatePowerOffset,
811 sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset));
812 structSize += sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset);
813 }
814
815 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
816 {
817 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].channels[0]);
818 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].channels[0]);
819 /* Cannot blindly copy
820 * Each single CH should be assigned */
821 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
822 {
823#ifdef FEATURE_WLAN_CH144
824 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
825 {
826 /* NV2 CH144 is disabled */
827 halNv->tables.regDomains[copyLoop].channels[channelLoop].enabled =
828 NV_CHANNEL_DISABLE;
829 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
830 }
831 else
832#endif /* FEATURE_WLAN_CH144 */
833 {
834
835 vos_mem_copy(targetPtr, sourcePtr, sizeof(sRegulatoryChannel));
836 targetPtr = targetPtr + sizeof(sRegulatoryChannel);
837 sourcePtr = sourcePtr + sizeof(sRegulatoryChannel);
838 structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain);
839 }
840 }
841 }
842 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
843 "%s: sizeof(halNv->tables.regDomains[copyLoop].antennaGain) %zu, structSize %d",
844 __func__, sizeof(halNv->tables.regDomains[copyLoop].antennaGain), structSize);
845
846 for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++)
847 {
848 targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
849 sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].gnRatePowerOffset[0]);
850 /* Cannot blindly copy
851 * Each single CH should be assigned */
852 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
853 {
854#ifdef FEATURE_WLAN_CH144
855 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
856 {
857 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
858 }
859 else
860#endif /* FEATURE_WLAN_CH144 */
861 {
862 vos_mem_copy(targetPtr, sourcePtr, sizeof(uAbsPwrPrecision));
863 targetPtr = targetPtr + sizeof(uAbsPwrPrecision);
864 sourcePtr = sourcePtr + sizeof(uAbsPwrPrecision);
865 structSize += sizeof(sizeof(uAbsPwrPrecision));
866 }
867 }
868 }
869 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
870 "%s: sizeof(uAbsPwrPrecision) %zu, structSize %d",
871 __func__, sizeof(uAbsPwrPrecision), structSize);
872
873 /* nvTable, defaultCountryTable, NOT depends on channel counts */
874 vos_mem_copy((char *)&halNv->tables.defaultCountryTable,
875 (char *)&nv2Table->tables.defaultCountryTable,
876 sizeof(halNv->tables.defaultCountryTable));
877 structSize += sizeof(halNv->tables.defaultCountryTable);
878 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
879 "%s: sizeof(halNv->tables.defaultCountryTable) %zu, structSize %d",
880 __func__, sizeof(halNv->tables.defaultCountryTable), structSize);
881
882 /* NV Table, plutCharacterized, depends on channel count
883 * Cannot blindly copy
884 * Each single CH should be assigned */
885 targetPtr = (char *)&(halNv->tables.plutCharacterized[0]);
886 sourcePtr = (char *)&(nv2Table->tables.plutCharacterized[0]);
887 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
888 {
889#ifdef FEATURE_WLAN_CH144
890 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
891 {
892 targetPtr = targetPtr + sizeof(tTpcPowerTable);
893 }
894 else
895#endif /* FEATURE_WLAN_CH144 */
896 {
897 vos_mem_copy(targetPtr, sourcePtr, sizeof(tTpcPowerTable));
898 targetPtr = targetPtr + sizeof(tTpcPowerTable);
899 sourcePtr = sourcePtr + sizeof(tTpcPowerTable);
900 structSize += sizeof(tTpcPowerTable);
901 }
902 }
903 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
904 "%s: sizeof(tTpcPowerTable) %zu, structSize %d",
905 __func__, sizeof(tTpcPowerTable), structSize);
906
907 /* NV Table, plutPdadcOffset, depends on channel count
908 * Cannot blindly copy
909 * Each single CH should be assigned */
910 targetPtr = (char *)&(halNv->tables.plutPdadcOffset[0]);
911 sourcePtr = (char *)&(nv2Table->tables.plutPdadcOffset[0]);
912 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
913 {
914#ifdef FEATURE_WLAN_CH144
915 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
916 {
917 targetPtr = targetPtr + sizeof(int16);
918 }
919 else
920#endif /* FEATURE_WLAN_CH144 */
921 {
922 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
923 targetPtr = targetPtr + sizeof(int16);
924 sourcePtr = sourcePtr + sizeof(int16);
925 structSize += sizeof(int16);
926 }
927 }
928 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
929 "%s: sizeof(halNv->tables.plutPdadcOffset) %zu, structSize %d",
930 __func__, sizeof(int16), structSize);
931
932 /* NV Table, pwrOptimum_virtualRate, NOT depends on channel count */
933 vos_mem_copy((char *)halNv->tables.pwrOptimum_virtualRate,
934 (char *)nv2Table->tables.pwrOptimum_virtualRate,
935 sizeof(halNv->tables.pwrOptimum_virtualRate));
936 structSize += sizeof(halNv->tables.pwrOptimum_virtualRate);
937 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
938 "%s: sizeof(halNv->tables.pwrOptimum_virtualRate) %zu, structSize %d",
939 __func__, sizeof(halNv->tables.pwrOptimum_virtualRate), structSize);
940
941 /* NV Table, fwConfig, NOT depends on channel count */
942 vos_mem_copy((char *)&halNv->tables.fwConfig,
943 (char *)&nv2Table->tables.fwConfig,
944 sizeof(halNv->tables.fwConfig));
945 structSize += sizeof(halNv->tables.fwConfig);
946 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
947 "%s: sizeof(halNv->tables.fwConfig) %zu, structSize %d",
948 __func__, sizeof(halNv->tables.fwConfig), structSize);
949
950 /* NV Table, rssiChanOffsets, depends on channel count
951 * Cannot blindly copy
952 * Each single CH should be assigned */
953 for (copyLoop = 0; copyLoop < 2; copyLoop++)
954 {
955 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
956 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]);
957 /* Cannot blindly copy
958 * Each single CH should be assigned */
959 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
960 {
961#ifdef FEATURE_WLAN_CH144
962 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
963 {
964 targetPtr = targetPtr + sizeof(int16);
965 }
966 else
967#endif /* FEATURE_WLAN_CH144 */
968 {
969 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
970 targetPtr = targetPtr + sizeof(int16);
971 sourcePtr = sourcePtr + sizeof(int16);
972 structSize += sizeof(int16);
973 }
974 }
975 }
976 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
977 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
978 __func__, sizeof(int16), structSize);
979
980 for (copyLoop = 0; copyLoop < 2; copyLoop++)
981 {
982 targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
983 sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]);
984 /* Cannot blindly copy
985 * Each single CH should be assigned */
986 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
987 {
988#ifdef FEATURE_WLAN_CH144
989 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
990 {
991 targetPtr = targetPtr + sizeof(int16);
992 }
993 else
994#endif /* FEATURE_WLAN_CH144 */
995 {
996 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
997 targetPtr = targetPtr + sizeof(int16);
998 sourcePtr = sourcePtr + sizeof(int16);
999 structSize += sizeof(int16);
1000 }
1001 }
1002 }
1003 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1004 "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d",
1005 __func__, sizeof(int16), structSize);
1006
1007 /* NV Table, hwCalValues, NOT depends on channel count */
1008 vos_mem_copy((char *)&halNv->tables.hwCalValues,
1009 (char *)&nv2Table->tables.hwCalValues,
1010 sizeof(halNv->tables.hwCalValues));
1011 structSize += sizeof(halNv->tables.fwConfig);
1012 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1013 "%s: sizeof(halNv->tables.hwCalValues) %zu, structSize %d",
1014 __func__, sizeof(halNv->tables.hwCalValues), structSize);
1015
1016 /* NV Table, antennaPathLoss, depends on channel count
1017 * Cannot blindly copy
1018 * Each single CH should be assigned */
1019 targetPtr = (char *)&(halNv->tables.antennaPathLoss[0]);
1020 sourcePtr = (char *)&(nv2Table->tables.antennaPathLoss[0]);
1021 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1022 {
1023#ifdef FEATURE_WLAN_CH144
1024 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1025 {
1026 targetPtr = targetPtr + sizeof(int16);
1027 }
1028 else
1029#endif /* FEATURE_WLAN_CH144 */
1030 {
1031 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1032 targetPtr = targetPtr + sizeof(int16);
1033 sourcePtr = sourcePtr + sizeof(int16);
1034 structSize += sizeof(int16);
1035 }
1036 }
1037 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1038 "%s: sizeof(halNv->tables.antennaPathLoss) %zu, structSize %d",
1039 __func__, sizeof(int16), structSize);
1040
1041 /* NV Table, pktTypePwrLimits, depends on channel count
1042 * Cannot blindly copy
1043 * Each single CH should be assigned */
1044 for (copyLoop = 0; copyLoop < NUM_802_11_MODES; copyLoop++)
1045 {
1046 targetPtr = (char *)&(halNv->tables.pktTypePwrLimits[copyLoop][0]);
1047 sourcePtr = (char *)&(nv2Table->tables.pktTypePwrLimits[copyLoop][0]);
1048 /* Cannot blindly copy
1049 * Each single CH should be assigned */
1050 for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++)
1051 {
1052#ifdef FEATURE_WLAN_CH144
1053 if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop))
1054 {
1055 targetPtr = targetPtr + sizeof(int16);
1056 }
1057 else
1058#endif /* FEATURE_WLAN_CH144 */
1059 {
1060 vos_mem_copy(targetPtr, sourcePtr, sizeof(int16));
1061 targetPtr = targetPtr + sizeof(int16);
1062 sourcePtr = sourcePtr + sizeof(int16);
1063 structSize += sizeof(int16);
1064 }
1065 }
1066 }
1067 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1068 "%s: sizeof(halNv->tables.pktTypePwrLimits) %zu, structSize %d",
1069 __func__, sizeof(int16), structSize);
1070
1071 /* NV Table, ofdmCmdPwrOffset, NOT depends on channel count */
1072 vos_mem_copy((char *)&halNv->tables.ofdmCmdPwrOffset,
1073 (char *)&nv2Table->tables.ofdmCmdPwrOffset,
1074 sizeof(halNv->tables.ofdmCmdPwrOffset));
1075 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1076 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1077 "%s: sizeof(halNv->tables.ofdmCmdPwrOffset) %zu, structSize %d",
1078 __func__, sizeof(halNv->tables.ofdmCmdPwrOffset), structSize);
1079
1080 /* NV Table, txbbFilterMode, NOT depends on channel count */
1081 vos_mem_copy((char *)&halNv->tables.txbbFilterMode,
1082 (char *)&nv2Table->tables.txbbFilterMode,
1083 sizeof(halNv->tables.txbbFilterMode));
1084 structSize += sizeof(halNv->tables.ofdmCmdPwrOffset);
1085 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1086 "%s: sizeof(halNv->tables.txbbFilterMode) %zu, structSize %d",
1087 __func__, sizeof(halNv->tables.txbbFilterMode), structSize);
1088
1089 return VOS_STATUS_SUCCESS;
1090}
1091
1092/**------------------------------------------------------------------------
1093 \brief vos_nv_open() - Open NV operation
1094 Read NV bin file and prepare NV common structure
1095 \return VOS_STATUS_SUCCESS - module is initialized successfully
1096 otherwise - module is not initialized
1097 \sa
1098 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001099VOS_STATUS vos_nv_open(void)
1100{
1101 VOS_STATUS status = VOS_STATUS_SUCCESS;
1102 v_CONTEXT_t pVosContext= NULL;
1103 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001104 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001106 v_U32_t dataOffset;
1107 sHalNv *pnvData = NULL;
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001108 hdd_context_t *pHddCtx = NULL;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001109
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 /*Get the global context */
1111 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001112
1113 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001114 {
1115 return (eHAL_STATUS_FAILURE);
1116 }
1117
Jeff Johnson295189b2012-06-20 16:38:30 -07001118 status = hdd_request_firmware(WLAN_NV_FILE,
1119 ((VosContextType*)(pVosContext))->pHDDContext,
Anand N Sunkada92e4db2015-02-05 12:00:56 +05301120 (v_VOID_t**)&pnvtmpBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
Anand N Sunkada92e4db2015-02-05 12:00:56 +05301122 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvtmpBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001124 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001125 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001126 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001127 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001128 }
1129
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301130 pnvEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadBufSize);
Anand N Sunkada92e4db2015-02-05 12:00:56 +05301131
1132 if (NULL == pnvEncodedBuf) {
1133 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1134 "%s : failed to allocate memory for NV", __func__);
1135 return VOS_STATUS_E_NOMEM;
1136 }
1137 vos_mem_copy(pnvEncodedBuf, pnvtmpBuf, nvReadBufSize);
1138 release_firmware(((hdd_context_t*)((VosContextType*)
1139 (pVosContext))->pHDDContext)->nv);
1140
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301141 vos_mem_copy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001142
1143 /// Allocate buffer with maximum length..
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301144 pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadBufSize);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001145
1146 if (NULL == pEncodedBuf)
1147 {
1148 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1149 "%s : failed to allocate memory for NV", __func__);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301150 vos_mem_vfree(pnvEncodedBuf);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001151 return VOS_STATUS_E_NOMEM;
1152 }
1153
Leo Chang80de3c22013-11-26 10:52:12 -08001154 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1155 "NV Table Size %zu", sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001156
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301157 pnvEFSTable = (nvEFSTable_t *)vos_mem_vmalloc(sizeof(nvEFSTable_t));
Leo Chang80de3c22013-11-26 10:52:12 -08001158 if (NULL == pnvEFSTable)
1159 {
1160 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1161 "%s : failed to allocate memory for NV", __func__);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301162 vos_mem_vfree(pnvEncodedBuf);
1163 vos_mem_vfree(pEncodedBuf);
Leo Chang80de3c22013-11-26 10:52:12 -08001164 return VOS_STATUS_E_NOMEM;
1165 }
1166 vos_mem_zero((void *)pnvEFSTable, sizeof(nvEFSTable_t));
1167
1168 // Default NV version, NOT_VALID
1169 ((VosContextType*)(pVosContext))->nvVersion = E_NV_INVALID;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001170 if (MAGIC_NUMBER == magicNumber)
1171 {
Leo Chang80de3c22013-11-26 10:52:12 -08001172 bufSize = sizeof(nvEFSTable_t);
1173 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001174 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
1175
1176 if (NULL == pnvData)
1177 {
1178 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1179 "%s : failed to allocate memory for NV", __func__);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301180 vos_mem_vfree(pnvEncodedBuf);
1181 vos_mem_vfree(pEncodedBuf);
1182 vos_mem_vfree(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001183 return VOS_STATUS_E_NOMEM;
1184 }
1185
1186 memset(pnvData, 0, sizeof(sHalNv));
1187
1188 /// Data starts from offset of validity bit map + magic number..
1189 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
1190
1191 status = nvParser(&pnvEncodedBuf[dataOffset],
1192 (nvReadBufSize-dataOffset), pnvData);
1193
1194 ///ignore validity bit map
1195 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
1196
1197 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
1198 nvReadEncodeBufSize);
1199
Leo Chang80de3c22013-11-26 10:52:12 -08001200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001201 "readEncodeBufSize %d",nvReadEncodeBufSize);
1202
1203 if (VOS_STATUS_SUCCESS == status) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301204 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001205 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
1206 pnvData->fields.productId,
1207 pnvData->fields.couplerType,
1208 pnvData->fields.wlanNvRevId);
1209
1210 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
1211
1212 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
1213 }
1214 else
1215 {
1216 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1217 "nvParser failed %d",status);
1218
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301219 if (nvReadBufSize != sizeof(sHalNv)) {
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301220 vos_mem_vfree(pEncodedBuf);
1221 pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(sizeof(sHalNv));
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301222
1223 if (!pEncodedBuf) {
1224 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1225 "%s : failed to allocate memory for NV", __func__);
1226 vos_mem_free(pnvData);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301227 vos_mem_vfree(pnvEncodedBuf);
1228 vos_mem_vfree(pnvEFSTable);
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301229 return VOS_STATUS_E_NOMEM;
1230 }
1231 }
1232
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001233 nvReadBufSize = 0;
1234
1235 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
1236
1237 nvReadEncodeBufSize = sizeof(sHalNv);
1238 }
Leo Chang80de3c22013-11-26 10:52:12 -08001239 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1240
1241 /* NV verion is NV3 */
1242 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V3;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001243 }
1244 else
1245 {
Leo Chang80de3c22013-11-26 10:52:12 -08001246 bufSize = sizeof(nvEFSTableV2_t);
1247
1248 /*Copying the NV defaults */
1249 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
1250 /* NV2 structure should be maintained to support NV_FTM */
1251 gnvEFSTableV2 = (nvEFSTableV2_t * )pnvEncodedBuf;
1252
1253 /* Size mismatch
1254 * NV 1 case, use default NV table */
1255 if (nvReadBufSize != bufSize)
1256 {
1257 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
1258 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Mahesh A Saptasagar3f6cf342014-07-24 22:16:25 +05301259 "Size mismatch INVALID NV FILE %d %d!!!",
Leo Chang80de3c22013-11-26 10:52:12 -08001260 nvReadBufSize, bufSize);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301261 vos_mem_vfree(pnvEncodedBuf);
1262 vos_mem_vfree(pEncodedBuf);
1263 vos_mem_vfree(pnvEFSTable);
Mahesh A Saptasagar3f6cf342014-07-24 22:16:25 +05301264 return VOS_STATUS_E_FAILURE;
Leo Chang80de3c22013-11-26 10:52:12 -08001265 }
1266
1267 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallif5c12a02014-02-25 16:50:40 +05301268 "NV_2: readBufferSize %u, EFSV2DefaultSize %zu",
Leo Chang80de3c22013-11-26 10:52:12 -08001269 nvReadBufSize, sizeof(nvEFSTableV2_t));
1270
1271 /* From here, NV2 will be stored into NV3 structure */
1272 dataOffset = sizeof(v_U32_t);
1273 nvReadEncodeBufSize = sizeof(sHalNvV2);
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301274 if (nvReadBufSize != nvReadEncodeBufSize)
1275 {
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301276 vos_mem_vfree(pEncodedBuf);
1277 pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadEncodeBufSize);
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301278 if (!pEncodedBuf)
1279 {
1280 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1281 "%s : failed to allocate memory for NV", __func__);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301282 vos_mem_vfree(pnvEncodedBuf);
1283 vos_mem_vfree(pnvEFSTable);
Hanumantha Reddy Pothula70f70d92015-04-07 10:23:02 +05301284 return VOS_STATUS_E_NOMEM;
1285 }
1286 }
Leo Chang80de3c22013-11-26 10:52:12 -08001287 vos_mem_copy(pEncodedBuf,
1288 &pnvEncodedBuf[dataOffset],
1289 nvReadBufSize - dataOffset);
1290
1291#ifdef FEATURE_WLAN_CH144
1292 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1293 "Default NV2 size %zu", sizeof(nvDefaultsV2));
1294#else
1295 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1296 "Default NV2 size %zu", sizeof(nvDefaults));
1297#endif /* FEATURE_WLAN_CH144 */
1298 /* First assign value with NV default */
1299#ifdef FEATURE_WLAN_CH144
1300 vos_nv_parseV2bin((tANI_U8 *)&nvDefaultsV2,
1301 sizeof(sHalNvV2),
1302 &pnvEFSTable->halnv);
1303#else
1304 vos_nv_parseV2bin((tANI_U8 *)&nvDefaults,
1305 sizeof(sHalNvV2),
1306 &pnvEFSTable->halnv);
1307#endif /* FEATURE_WLAN_CH144 */
1308
1309 /* Actual update from NV.bin */
1310 vos_nv_parseV2bin(pEncodedBuf,
1311 nvReadEncodeBufSize,
1312 &pnvEFSTable->halnv);
1313
1314 vos_mem_copy((void *)&pnvEFSTable->nvValidityBitmap,
1315 pnvEncodedBuf, sizeof(v_U32_t));
1316 gnvEFSTable = pnvEFSTable;
1317
1318 /* NV verion is NV2 */
1319 ((VosContextType*)(pVosContext))->nvVersion = E_NV_V2;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001320 }
1321
1322 if (NULL != pnvData)
1323 {
1324 vos_mem_free(pnvData);
1325 }
1326
1327 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001328 "INFO: NV version = %d is loaded, driver supports NV version = %d",
1329 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001330
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 /* Copying the read nv data to the globa NV EFS table */
1332 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001333 /* Version mismatch */
1334 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
1335 {
1336 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
1337 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
1338 {
1339 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001340 "INFO: Using Coupler Type field instead of FW Config table, "
1341 "make sure that this is intended or may impact performance.");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001342 }
Leo Chang80de3c22013-11-26 10:52:12 -08001343#ifdef FEATURE_WLAN_CH144
1344 else if ((WLAN_NV_VERSION == NV_VERSION_CH144_CONFIG) &&
1345 (((VosContextType*)(pVosContext))->nvVersion == E_NV_V2))
1346 {
1347 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001348 "INFO: Driver supports NV3 CH144 by default, "
1349 "NV2 is currently loaded, NV2 will be used.");
Leo Chang80de3c22013-11-26 10:52:12 -08001350 }
1351#endif /* FEATURE_WLAN_CH144 */
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001352 else
1353 {
1354 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Yue Mae8f68342014-04-08 14:20:38 -07001355 "INFO: NV loaded doesn't match with driver default NV, "
1356 "driver default NV will be used, may impact performance.");
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001357
1358 return VOS_STATUS_SUCCESS;
1359 }
1360 }
1361
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -07001362 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Amar Singhalfddc28c2013-09-05 13:03:40 -07001363 /* Copy the valid fields to the NV Global structure */
1364 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001365 VOS_STATUS_SUCCESS)
1366 {
1367 if (itemIsValid == VOS_TRUE) {
1368
1369 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
1370 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001371 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001372 }
1373 }
1374
Amar Singhalfddc28c2013-09-05 13:03:40 -07001375 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001376 VOS_STATUS_SUCCESS)
1377 {
1378 if (itemIsValid == VOS_TRUE)
1379 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001380 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001381 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
1382 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001383 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 }
1385 }
1386
Amar Singhalfddc28c2013-09-05 13:03:40 -07001387 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 VOS_STATUS_SUCCESS)
1389 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001390
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 if (itemIsValid == VOS_TRUE)
1392 {
1393 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
1394 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
1395 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001396 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001397 }
1398 }
1399
Amar Singhalfddc28c2013-09-05 13:03:40 -07001400 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 VOS_STATUS_SUCCESS)
1402 {
1403 if (itemIsValid == VOS_TRUE)
1404 {
1405 if(vos_nv_read( VNV_DEFAULT_LOCATION,
1406 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
1407 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001408 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 }
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001410 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1411 if (NULL != pHddCtx)
1412 {
1413 if (!vos_mem_compare(pHddCtx->cfg_ini->overrideCountryCode,
1414 CFG_OVERRIDE_COUNTRY_CODE_DEFAULT, 3))
1415 {
Vinay Krishna Eranna22ebc0d2014-05-09 17:20:33 +05301416 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1417 ("Overriding NV Country(%c%c) from INI (%c%c)"),
1418 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
1419 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
1420 pHddCtx->cfg_ini->overrideCountryCode[0],
1421 pHddCtx->cfg_ini->overrideCountryCode[1]);
Tushnim Bhattacharyya9889e792013-12-19 18:18:36 -08001422 vos_mem_copy(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode,
1423 pHddCtx->cfg_ini->overrideCountryCode,
1424 3);
1425 }
1426 }
1427 else
1428 {
1429 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1430 ("Invalid pHddCtx pointer") );
1431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001432 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001433
1434 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 VOS_STATUS_SUCCESS)
1436 {
1437 if (itemIsValid == VOS_TRUE)
1438 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001439 if(vos_nv_read( VNV_TPC_POWER_TABLE,
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
1441 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001442 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 }
1444 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001445
1446 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 VOS_STATUS_SUCCESS)
1448 {
1449 if (itemIsValid == VOS_TRUE)
1450 {
1451 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
1452 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
1453 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001454 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001455 }
1456 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001457 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 VOS_STATUS_SUCCESS)
1459 {
1460 if (itemIsValid == VOS_TRUE)
1461 {
1462 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
1463 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
1464 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001465 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 }
1467 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001468
1469 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001470 VOS_STATUS_SUCCESS)
1471 {
1472 if (itemIsValid == VOS_TRUE)
1473 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001474 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
1475 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
1476 goto error;
1477 }
1478 }
1479
Amar Singhalfddc28c2013-09-05 13:03:40 -07001480 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001481 VOS_STATUS_SUCCESS)
1482 {
1483 if (itemIsValid == VOS_TRUE)
1484 {
1485 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
1486 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001487 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 }
1489 }
1490
Amar Singhalfddc28c2013-09-05 13:03:40 -07001491 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 VOS_STATUS_SUCCESS)
1493 {
1494 if (itemIsValid == VOS_TRUE)
1495 {
1496 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
Amar Singhalfddc28c2013-09-05 13:03:40 -07001497 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001498 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001499 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001500 }
1501 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001502 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001503 VOS_STATUS_SUCCESS)
1504 {
1505 if (itemIsValid == VOS_TRUE)
1506 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001507 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
1508 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001509 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001510 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 }
1512 }
1513
Amar Singhalfddc28c2013-09-05 13:03:40 -07001514 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 VOS_STATUS_SUCCESS)
1516 {
1517 if (itemIsValid == VOS_TRUE)
1518 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001519 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
1520 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001521 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001522 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 }
1524 }
1525
Amar Singhalfddc28c2013-09-05 13:03:40 -07001526 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 VOS_STATUS_SUCCESS)
1528 {
1529 if (itemIsValid == VOS_TRUE)
1530 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001531 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
1532 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001534 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 }
1536 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07001537 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001538 VOS_STATUS_SUCCESS)
1539 {
1540 if (itemIsValid == VOS_TRUE)
1541 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001542 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
1543 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07001544 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001545 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 }
1547 }
1548 }
1549
1550 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001551error:
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301552 vos_mem_vfree(pnvEFSTable);
1553 vos_mem_vfree(pEncodedBuf);
1554 vos_mem_vfree(pnvEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08001555 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001556}
1557
1558VOS_STATUS vos_nv_close(void)
1559{
Jeff Johnson295189b2012-06-20 16:38:30 -07001560 v_CONTEXT_t pVosContext= NULL;
1561 /*Get the global context */
1562 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Anand N Sunkada92e4db2015-02-05 12:00:56 +05301563
1564 ((hdd_context_t*)((VosContextType*)(pVosContext))->pHDDContext)->nv = NULL;
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301565 vos_mem_vfree(pnvEFSTable);
1566 vos_mem_vfree(pEncodedBuf);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001567 vos_mem_free(pDictFile);
Sushant Kaushikf4a27972015-04-16 16:48:00 +05301568 vos_mem_vfree(pnvEncodedBuf);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001569
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 gnvEFSTable=NULL;
1571 return VOS_STATUS_SUCCESS;
1572}
Jeff Johnson295189b2012-06-20 16:38:30 -07001573
Jeff Johnson295189b2012-06-20 16:38:30 -07001574/**------------------------------------------------------------------------
1575 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1576 country codes
1577 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1578 country codes with paddings in the provided buffer
1579 \param pBuffer - pointer to buffer where supported country codes
1580 and paddings are encoded; this may be set to NULL
1581 if user wishes to query the required buffer size to
1582 get the country code list
1583 \param pBufferSize - this is the provided buffer size on input;
1584 this is the required or consumed buffer size on output
1585 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1586 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1587 the buffer is NULL or buffer size is
1588 sufficient
1589 \sa
1590 -------------------------------------------------------------------------*/
1591VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1592 v_SIZE_t paddingSize )
1593{
1594 v_SIZE_t providedBufferSize = *pBufferSize;
1595 int i;
1596 // pBufferSize now points to the required buffer size
1597 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1598 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1599 {
1600 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08001601 ("Insufficient memory for country code list"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 return VOS_STATUS_E_NOMEM;
1603 }
1604 for (i = 0; i < countryInfoTable.countryCount; i++)
1605 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301606 vos_mem_copy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1608 }
1609 return VOS_STATUS_SUCCESS;
1610}
1611/**------------------------------------------------------------------------
1612 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1613 \param pTxAntennaCount - antenna count
1614 \return status of the NV read operation
1615 \sa
1616 -------------------------------------------------------------------------*/
1617VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1618{
1619 sNvFields fieldImage;
1620 VOS_STATUS status;
1621 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1622 sizeof(fieldImage) );
1623 if (VOS_STATUS_SUCCESS == status)
1624 {
1625 *pTxAntennaCount = fieldImage.numOfTxChains;
1626 }
1627 return status;
1628}
1629/**------------------------------------------------------------------------
1630 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1631 \param pRxAntennaCount - antenna count
1632 \return status of the NV read operation
1633 \sa
1634 -------------------------------------------------------------------------*/
1635VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1636{
1637 sNvFields fieldImage;
1638 VOS_STATUS status;
1639 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1640 sizeof(fieldImage) );
1641 if (VOS_STATUS_SUCCESS == status)
1642 {
1643 *pRxAntennaCount = fieldImage.numOfRxChains;
1644 }
1645 return status;
1646}
1647
1648/**------------------------------------------------------------------------
1649 \brief vos_nv_readMacAddress() - return the MAC address
1650 \param pMacAddress - MAC address
1651 \return status of the NV read operation
1652 \sa
1653 -------------------------------------------------------------------------*/
1654VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1655{
1656 sNvFields fieldImage;
1657 VOS_STATUS status;
1658 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1659 sizeof(fieldImage) );
1660 if (VOS_STATUS_SUCCESS == status)
1661 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301662 vos_mem_copy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 }
1664 else
1665 {
1666 //This part of the code can be removed when NV is programmed
1667 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301668 vos_mem_copy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
Arif Hussaina7c8e412013-11-20 11:06:42 -08001669 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1670 "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR,
1671 MAC_ADDR_ARRAY(macAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 status = VOS_STATUS_SUCCESS;
1673 }
1674 return status;
1675}
1676
1677/**------------------------------------------------------------------------
1678
1679 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1680
1681 \param pMacAddress - MAC address
1682 \param macCount - Count of valid MAC addresses to get from NV field
1683
1684 \return status of the NV read operation
1685
1686 \sa
1687
1688 -------------------------------------------------------------------------*/
1689VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1690 v_U8_t macCount )
1691{
1692 sNvFields fieldImage;
1693 VOS_STATUS status;
1694 v_U8_t countLoop;
1695 v_U8_t *pNVMacAddress;
1696
1697 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1698 (NULL == pMacAddress))
1699 {
1700 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301701 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 macCount, pMacAddress);
1703 }
1704
1705 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1706 sizeof(fieldImage) );
1707 if (VOS_STATUS_SUCCESS == status)
1708 {
1709 pNVMacAddress = fieldImage.macAddr;
1710 for(countLoop = 0; countLoop < macCount; countLoop++)
1711 {
1712 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1713 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1714 VOS_MAC_ADDRESS_LEN);
1715 }
1716 }
1717 else
1718 {
1719 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1720 "vos_nv_readMultiMacAddress Get NV Field Fail");
1721 }
1722
1723 return status;
1724}
1725
1726/**------------------------------------------------------------------------
1727 \brief vos_nv_setValidity() - set the validity of an NV item.
1728 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1729 validity information is stored in NV memory.
1730 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1731 An item becomes valid when one has written to it successfully.
1732 \param type - NV item type
1733 \param itemIsValid - boolean value indicating the item's validity
1734 \return VOS_STATUS_SUCCESS - validity is set successfully
1735 VOS_STATUS_E_INVAL - one of the parameters is invalid
1736 VOS_STATUS_E_FAILURE - unknown error
1737 \sa
1738 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001739
1740VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1741{
1742 v_U32_t lastNvValidityBitmap;
1743 v_U32_t newNvValidityBitmap;
1744 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001745
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001747 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 {
1749 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001750 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001751 return VOS_STATUS_E_INVAL;
1752 }
1753 // read the validity bitmap
1754 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1755 // modify the validity bitmap
1756 if (itemIsValid)
1757 {
1758 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1759 // commit to NV store if bitmap has been modified
1760 if (newNvValidityBitmap != lastNvValidityBitmap)
1761 {
1762 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1763 }
1764 }
1765 else
1766 {
1767 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1768 if (newNvValidityBitmap != lastNvValidityBitmap)
1769 {
1770 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1771 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1772 if (! VOS_IS_STATUS_SUCCESS(status)) {
Arif Hussain02882402013-11-17 21:55:29 -08001773 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 status = VOS_STATUS_E_FAULT;
1775 }
1776 }
1777 }
1778
1779 return status;
1780}
Jeff Johnson295189b2012-06-20 16:38:30 -07001781/**------------------------------------------------------------------------
1782 \brief vos_nv_getValidity() - get the validity of an NV item.
1783 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1784 validity information is stored in NV memory.
1785 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1786 An item becomes valid when one has written to it successfully.
1787 \param type - NV item type
1788 \param pItemIsValid- pointer to the boolean value indicating the item's
1789 validity
1790 \return VOS_STATUS_SUCCESS - validity is determined successfully
1791 VOS_STATUS_E_INVAL - one of the parameters is invalid
1792 VOS_STATUS_E_FAILURE - unknown error
1793 \sa
1794 -------------------------------------------------------------------------*/
1795VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1796{
1797 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1798 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001799 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 {
1801 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001802 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 return VOS_STATUS_E_INVAL;
1804 }
1805 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1806 return VOS_STATUS_SUCCESS;
1807}
1808/**------------------------------------------------------------------------
1809 \brief vos_nv_read() - read a NV item to an output buffer
1810 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1811 an array, this function would read the entire array. One would get a
1812 VOS_STATUS_E_EXISTS error when reading an invalid item.
1813 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1814 if a default buffer is provided (with a non-NULL value),
1815 the default buffer content is copied to the output buffer.
1816 \param type - NV item type
1817 \param outputBuffer - output buffer
1818 \param defaultBuffer - default buffer
1819 \param bufferSize - output buffer size
1820 \return VOS_STATUS_SUCCESS - NV item is read successfully
1821 VOS_STATUS_E_INVAL - one of the parameters is invalid
1822 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1823 VOS_STATUS_E_EXISTS - NV type is unsupported
1824 VOS_STATUS_E_FAILURE - unknown error
1825 \sa
1826 -------------------------------------------------------------------------*/
1827VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1828 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1829{
1830 VOS_STATUS status = VOS_STATUS_SUCCESS;
1831 v_SIZE_t itemSize;
1832 v_BOOL_t itemIsValid = VOS_TRUE;
1833
Amar Singhala49cbc52013-10-08 18:37:44 -07001834 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001835 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 {
1837 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001838 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 return VOS_STATUS_E_INVAL;
1840 }
1841 if (NULL == outputVoidBuffer)
1842 {
1843 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001844 ("Buffer provided is NULL") );
Jeff Johnson295189b2012-06-20 16:38:30 -07001845 return VOS_STATUS_E_FAULT;
1846 }
1847 if (0 == bufferSize)
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001850 ("NV type=%d is invalid"), type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001851 return VOS_STATUS_E_INVAL;
1852 }
1853 // check if the NV item has valid data
1854 status = vos_nv_getValidity( type, &itemIsValid );
1855 if (!itemIsValid)
1856 {
1857 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08001858 "NV type=%d does not have valid data", type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 return VOS_STATUS_E_EMPTY;
1860 }
1861 switch(type)
1862 {
1863 case VNV_FIELD_IMAGE:
1864 itemSize = sizeof(gnvEFSTable->halnv.fields);
1865 if(bufferSize != itemSize) {
1866 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001867 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001868 itemSize);
1869 status = VOS_STATUS_E_INVAL;
1870 }
1871 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301872 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 }
1874 break;
1875 case VNV_RATE_TO_POWER_TABLE:
1876 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1877 if(bufferSize != itemSize) {
1878 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001879 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001880 itemSize);
1881 status = VOS_STATUS_E_INVAL;
1882 }
1883 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301884 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 }
1886 break;
1887 case VNV_REGULARTORY_DOMAIN_TABLE:
1888 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1889 if(bufferSize != itemSize) {
1890 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001891 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 itemSize);
1893 status = VOS_STATUS_E_INVAL;
1894 }
1895 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301896 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 }
1898 break;
1899 case VNV_DEFAULT_LOCATION:
1900 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1901 if(bufferSize != itemSize) {
1902 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001903 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 itemSize);
1905 status = VOS_STATUS_E_INVAL;
1906 }
1907 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301908 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001909 }
1910 break;
1911 case VNV_TPC_POWER_TABLE:
1912 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1913 if(bufferSize != itemSize) {
1914 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001915 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001916 itemSize);
1917 status = VOS_STATUS_E_INVAL;
1918 }
1919 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301920 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 }
1922 break;
1923 case VNV_TPC_PDADC_OFFSETS:
1924 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1925 if(bufferSize != itemSize) {
1926 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001927 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 itemSize);
1929 status = VOS_STATUS_E_INVAL;
1930 }
1931 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301932 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001933 }
1934 break;
1935 case VNV_RSSI_CHANNEL_OFFSETS:
1936
1937 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1938
1939 if(bufferSize != itemSize) {
1940
1941 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001942 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 itemSize);
1944 status = VOS_STATUS_E_INVAL;
1945 }
1946 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301947 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 }
1949 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001950 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001951
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001952 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953
1954 if(bufferSize != itemSize) {
1955
1956 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001957 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 itemSize);
1959 status = VOS_STATUS_E_INVAL;
1960 }
1961 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301962 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001963 }
1964 break;
1965 case VNV_FW_CONFIG:
Amar Singhalfddc28c2013-09-05 13:03:40 -07001966
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001967 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
Amar Singhalfddc28c2013-09-05 13:03:40 -07001968
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001969 if(bufferSize != itemSize) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07001970
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001971 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001972 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001973 itemSize);
1974 status = VOS_STATUS_E_INVAL;
1975 }
1976 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301977 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 }
1979 break;
1980 case VNV_ANTENNA_PATH_LOSS:
1981 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1982 if(bufferSize != itemSize) {
1983 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001984 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001985 itemSize);
1986 status = VOS_STATUS_E_INVAL;
1987 }
1988 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301989 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 }
1991 break;
1992 case VNV_PACKET_TYPE_POWER_LIMITS:
1993 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1994 if(bufferSize != itemSize) {
1995 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08001996 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 itemSize);
1998 status = VOS_STATUS_E_INVAL;
1999 }
2000 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302001 vos_mem_copy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 }
2003 break;
2004 case VNV_OFDM_CMD_PWR_OFFSET:
2005 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
2006 if(bufferSize != itemSize) {
2007 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08002008 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 itemSize);
2010 status = VOS_STATUS_E_INVAL;
2011 }
2012 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302013 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 }
2015 break;
2016 case VNV_TX_BB_FILTER_MODE:
2017 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
2018 if(bufferSize != itemSize) {
2019 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08002020 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 itemSize);
2022 status = VOS_STATUS_E_INVAL;
2023 }
2024 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302025 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 }
2027 break;
2028
Jeff Johnson295189b2012-06-20 16:38:30 -07002029
2030 case VNV_TABLE_VIRTUAL_RATE:
2031 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
2032 if(bufferSize != itemSize) {
2033 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08002034 ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 itemSize);
2036 status = VOS_STATUS_E_INVAL;
2037 }
2038 else {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302039 vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002040 }
2041 break;
2042
2043 default:
2044 break;
2045 }
2046 return status;
2047}
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
2049/**------------------------------------------------------------------------
2050 \brief vos_nv_write() - write to a NV item from an input buffer
2051 The \a vos_nv_write() writes to a NV item from an input buffer. This would
2052 validate the NV item if the write operation is successful.
Leo Chang80de3c22013-11-26 10:52:12 -08002053 NV2 dedicated operation
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 \param type - NV item type
2055 \param inputBuffer - input buffer
2056 \param inputBufferSize - input buffer size
2057 \return VOS_STATUS_SUCCESS - NV item is read successfully
2058 VOS_STATUS_E_INVAL - one of the parameters is invalid
2059 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
2060 VOS_STATUS_E_EXISTS - NV type is unsupported
2061 VOS_STATUS_E_FAILURE - unknown error
2062 \sa
2063 -------------------------------------------------------------------------*/
Leo Chang80de3c22013-11-26 10:52:12 -08002064VOS_STATUS vos_nv_write(VNV_TYPE type, v_VOID_t *inputVoidBuffer,
2065 v_SIZE_t bufferSize)
Jeff Johnson295189b2012-06-20 16:38:30 -07002066{
2067 VOS_STATUS status = VOS_STATUS_SUCCESS;
2068 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07002069
Amar Singhala49cbc52013-10-08 18:37:44 -07002070 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07002071 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 {
Leo Chang80de3c22013-11-26 10:52:12 -08002073 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2074 "%s: invalid type=%d", __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07002075 return VOS_STATUS_E_INVAL;
2076 }
2077 if (NULL == inputVoidBuffer)
2078 {
Leo Chang80de3c22013-11-26 10:52:12 -08002079 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2080 "Buffer provided is NULL");
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 return VOS_STATUS_E_FAULT;
2082 }
2083 if (0 == bufferSize)
2084 {
Leo Chang80de3c22013-11-26 10:52:12 -08002085 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2086 "NV type=%d is invalid", type);
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 return VOS_STATUS_E_INVAL;
2088 }
Leo Chang80de3c22013-11-26 10:52:12 -08002089
2090 switch (type)
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 {
2092 case VNV_FIELD_IMAGE:
Leo Chang80de3c22013-11-26 10:52:12 -08002093 itemSize = sizeof(gnvEFSTableV2->halnvV2.fields);
2094 if (bufferSize != itemSize)
2095 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002097 "type = %d buffer size=%d is less than data size=%d",
2098 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 status = VOS_STATUS_E_INVAL;
2100 }
Leo Chang80de3c22013-11-26 10:52:12 -08002101 else
2102 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302103 vos_mem_copy(&gnvEFSTableV2->halnvV2.fields,
Leo Chang80de3c22013-11-26 10:52:12 -08002104 inputVoidBuffer,
2105 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 }
2107 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 case VNV_RATE_TO_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002110 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum);
2111 if (bufferSize != itemSize)
2112 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002114 "type = %d buffer size=%d is less than data size=%d",
2115 type, bufferSize,itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 status = VOS_STATUS_E_INVAL;
2117 }
Leo Chang80de3c22013-11-26 10:52:12 -08002118 else
2119 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302120 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002121 inputVoidBuffer,
2122 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 }
2124 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002125
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 case VNV_REGULARTORY_DOMAIN_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002127 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.regDomains);
2128 if (bufferSize != itemSize)
2129 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002131 "type = %d buffer size=%d is less than data size=%d",
2132 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002133 status = VOS_STATUS_E_INVAL;
2134 }
Leo Chang80de3c22013-11-26 10:52:12 -08002135 else
2136 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302137 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.regDomains[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002138 inputVoidBuffer,
2139 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 }
2141 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002142
Jeff Johnson295189b2012-06-20 16:38:30 -07002143 case VNV_DEFAULT_LOCATION:
Leo Chang80de3c22013-11-26 10:52:12 -08002144 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.defaultCountryTable);
2145 if (bufferSize != itemSize)
2146 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002148 "type = %d buffer size=%d is less than data size=%d",
2149 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 status = VOS_STATUS_E_INVAL;
2151 }
Leo Chang80de3c22013-11-26 10:52:12 -08002152 else
2153 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302154 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.defaultCountryTable,
Leo Chang80de3c22013-11-26 10:52:12 -08002155 inputVoidBuffer,
2156 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 }
2158 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002159
Jeff Johnson295189b2012-06-20 16:38:30 -07002160 case VNV_TPC_POWER_TABLE:
Leo Chang80de3c22013-11-26 10:52:12 -08002161 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutCharacterized);
2162 if (bufferSize != itemSize)
2163 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002165 "type = %d buffer size=%d is less than data size=%d",
2166 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 status = VOS_STATUS_E_INVAL;
2168 }
Leo Chang80de3c22013-11-26 10:52:12 -08002169 else
2170 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302171 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.plutCharacterized[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002172 inputVoidBuffer,
2173 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002174 }
2175 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002176
Jeff Johnson295189b2012-06-20 16:38:30 -07002177 case VNV_TPC_PDADC_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002178 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutPdadcOffset);
2179 if (bufferSize != itemSize)
2180 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002182 "type = %d buffer size=%d is less than data size=%d",
2183 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 status = VOS_STATUS_E_INVAL;
2185 }
Leo Chang80de3c22013-11-26 10:52:12 -08002186 else
2187 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302188 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.plutPdadcOffset[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002189 inputVoidBuffer,
2190 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 }
2192 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002193
Jeff Johnson295189b2012-06-20 16:38:30 -07002194 case VNV_RSSI_CHANNEL_OFFSETS:
Leo Chang80de3c22013-11-26 10:52:12 -08002195 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.rssiChanOffsets);
2196 if (bufferSize != itemSize)
2197 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002199 "type = %d buffer size=%d is less than data size=%d",
2200 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 status = VOS_STATUS_E_INVAL;
2202 }
Leo Chang80de3c22013-11-26 10:52:12 -08002203 else
2204 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302205 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.rssiChanOffsets[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002206 inputVoidBuffer,
2207 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002208 }
2209 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002210
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002211 case VNV_HW_CAL_VALUES:
Leo Chang80de3c22013-11-26 10:52:12 -08002212 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.hwCalValues);
2213 if (bufferSize != itemSize)
2214 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002216 "type = %d buffer size=%d is less than data size=%d",
2217 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 status = VOS_STATUS_E_INVAL;
2219 }
Leo Chang80de3c22013-11-26 10:52:12 -08002220 else
2221 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302222 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.hwCalValues,
Leo Chang80de3c22013-11-26 10:52:12 -08002223 inputVoidBuffer,
2224 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 }
2226 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002227
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002228 case VNV_FW_CONFIG:
Leo Chang80de3c22013-11-26 10:52:12 -08002229 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.fwConfig);
2230 if (bufferSize != itemSize)
2231 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002232 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002233 "type = %d buffer size=%d is less than data size=%d",
2234 type, bufferSize, itemSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002235 status = VOS_STATUS_E_INVAL;
2236 }
Leo Chang80de3c22013-11-26 10:52:12 -08002237 else
2238 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302239 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.fwConfig,
Leo Chang80de3c22013-11-26 10:52:12 -08002240 inputVoidBuffer,
2241 bufferSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08002242 }
2243 break;
Leo Chang80de3c22013-11-26 10:52:12 -08002244
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 case VNV_ANTENNA_PATH_LOSS:
Leo Chang80de3c22013-11-26 10:52:12 -08002246 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.antennaPathLoss);
2247 if (bufferSize != itemSize)
2248 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002250 "type = %d buffer size=%d is less than data size=%d",
2251 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 status = VOS_STATUS_E_INVAL;
2253 }
Leo Chang80de3c22013-11-26 10:52:12 -08002254 else
2255 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302256 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.antennaPathLoss[0],
Leo Chang80de3c22013-11-26 10:52:12 -08002257 inputVoidBuffer,
2258 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 }
2260 break;
2261
2262 case VNV_PACKET_TYPE_POWER_LIMITS:
Leo Chang80de3c22013-11-26 10:52:12 -08002263 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits);
2264 if (bufferSize != itemSize)
2265 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002267 "type = %d buffer size=%d is less than data size=%d",
2268 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002269 status = VOS_STATUS_E_INVAL;
2270 }
Leo Chang80de3c22013-11-26 10:52:12 -08002271 else
2272 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302273 vos_mem_copy(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits,
Leo Chang80de3c22013-11-26 10:52:12 -08002274 inputVoidBuffer,
2275 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 }
2277 break;
2278
2279 case VNV_OFDM_CMD_PWR_OFFSET:
Leo Chang80de3c22013-11-26 10:52:12 -08002280 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset);
2281 if (bufferSize != itemSize)
2282 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002284 "type = %d buffer size=%d is less than data size=%d",
2285 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 status = VOS_STATUS_E_INVAL;
2287 }
Leo Chang80de3c22013-11-26 10:52:12 -08002288 else
2289 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302290 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset,
Leo Chang80de3c22013-11-26 10:52:12 -08002291 inputVoidBuffer,
2292 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002293 }
2294 break;
2295
2296 case VNV_TX_BB_FILTER_MODE:
Leo Chang80de3c22013-11-26 10:52:12 -08002297 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.txbbFilterMode);
2298 if (bufferSize != itemSize)
2299 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002301 "type = %d buffer size=%d is less than data size=%d",
2302 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 status = VOS_STATUS_E_INVAL;
2304 }
Leo Chang80de3c22013-11-26 10:52:12 -08002305 else
2306 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302307 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.txbbFilterMode,
Leo Chang80de3c22013-11-26 10:52:12 -08002308 inputVoidBuffer,
2309 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 }
2311 break;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002312
Jeff Johnson295189b2012-06-20 16:38:30 -07002313 case VNV_TABLE_VIRTUAL_RATE:
Leo Chang80de3c22013-11-26 10:52:12 -08002314 itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate);
2315 if (bufferSize != itemSize)
2316 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Leo Chang80de3c22013-11-26 10:52:12 -08002318 "type = %d buffer size=%d is less than data size=%d",
2319 type, bufferSize, itemSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 status = VOS_STATUS_E_INVAL;
2321 }
Leo Chang80de3c22013-11-26 10:52:12 -08002322 else
2323 {
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302324 vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate,
Leo Chang80de3c22013-11-26 10:52:12 -08002325 inputVoidBuffer,
2326 bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002327 }
2328 break;
2329
2330 default:
2331 break;
2332 }
Leo Chang80de3c22013-11-26 10:52:12 -08002333
Jeff Johnson295189b2012-06-20 16:38:30 -07002334 if (VOS_STATUS_SUCCESS == status)
2335 {
2336 // set NV item to have valid data
Leo Chang80de3c22013-11-26 10:52:12 -08002337 status = vos_nv_setValidity(type, VOS_TRUE);
2338 if (! VOS_IS_STATUS_SUCCESS(status))
2339 {
2340 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2341 "vos_nv_setValidity failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002342 status = VOS_STATUS_E_FAULT;
2343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002344
Arif Hussaine46afe12014-02-14 11:55:42 -08002345 status = wlan_write_to_efs((v_U8_t*)gnvEFSTableV2, sizeof(*gnvEFSTableV2));
Leo Chang80de3c22013-11-26 10:52:12 -08002346 if (!VOS_IS_STATUS_SUCCESS(status))
2347 {
2348 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2349 "vos_nv_write_to_efs failed!!!");
Jeff Johnson295189b2012-06-20 16:38:30 -07002350 status = VOS_STATUS_E_FAULT;
2351 }
2352 }
Leo Chang80de3c22013-11-26 10:52:12 -08002353
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 return status;
2355}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08002356
Jeff Johnson295189b2012-06-20 16:38:30 -07002357/**------------------------------------------------------------------------
2358 \brief vos_nv_getChannelListWithPower() - function to return the list of
2359 supported channels with the power limit info too.
2360 \param pChannels20MHz - list of 20 Mhz channels
2361 \param pNum20MHzChannelsFound - number of 20 Mhz channels
2362 \param pChannels40MHz - list of 20 Mhz channels
2363 \param pNum40MHzChannelsFound - number of 20 Mhz channels
2364 \return status of the NV read operation
2365 \Note: 40Mhz not currently supported
2366 \sa
2367 -------------------------------------------------------------------------*/
2368VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
2369 tANI_U8 *num20MHzChannelsFound,
2370 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
2371 tANI_U8 *num40MHzChannelsFound
2372 )
2373{
2374 VOS_STATUS status = VOS_STATUS_SUCCESS;
2375 int i, count;
Amar Singhalfddc28c2013-09-05 13:03:40 -07002376
Jeff Johnson295189b2012-06-20 16:38:30 -07002377 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
2378 // or pass it as a parameter to NV from SME?
2379
2380 if( channels20MHz && num20MHzChannelsFound )
2381 {
2382 count = 0;
2383 for( i = 0; i <= RF_CHAN_14; i++ )
2384 {
2385 if( regChannels[i].enabled )
2386 {
2387 channels20MHz[count].chanId = rfChannels[i].channelNum;
2388 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2389 }
2390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002391 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2392 {
2393 if( regChannels[i].enabled )
2394 {
2395 channels20MHz[count].chanId = rfChannels[i].channelNum;
2396 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
2397 }
2398 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002399 *num20MHzChannelsFound = (tANI_U8)count;
2400 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002401
2402 if( channels40MHz && num40MHzChannelsFound )
2403 {
2404 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002405 //center channels for 2.4 Ghz 40 MHz channels
2406 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
2407 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002408
Jeff Johnsone7245742012-09-05 17:12:55 -07002409 if( regChannels[i].enabled )
2410 {
2411 channels40MHz[count].chanId = rfChannels[i].channelNum;
2412 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2413 }
2414 }
2415 //center channels for 5 Ghz 40 MHz channels
2416 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
2417 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07002418
Jeff Johnsone7245742012-09-05 17:12:55 -07002419 if( regChannels[i].enabled )
2420 {
2421 channels40MHz[count].chanId = rfChannels[i].channelNum;
2422 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
2423 }
2424 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002425 *num40MHzChannelsFound = (tANI_U8)count;
2426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 return (status);
2428}
2429
2430/**------------------------------------------------------------------------
2431 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
2432 \return default regulatory domain
2433 \sa
2434 -------------------------------------------------------------------------*/
2435
2436v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
2437{
2438 return countryInfoTable.countryInfo[0].regDomain;
2439}
2440
2441/**------------------------------------------------------------------------
2442 \brief vos_nv_getSupportedChannels() - function to return the list of
2443 supported channels
2444 \param p20MhzChannels - list of 20 Mhz channels
2445 \param pNum20MhzChannels - number of 20 Mhz channels
2446 \param p40MhzChannels - list of 40 Mhz channels
2447 \param pNum40MhzChannels - number of 40 Mhz channels
2448 \return status of the NV read operation
2449 \Note: 40Mhz not currently supported
2450 \sa
2451 -------------------------------------------------------------------------*/
2452VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
2453 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
2454{
2455 VOS_STATUS status = VOS_STATUS_E_INVAL;
2456 int i, count = 0;
2457
2458 if( p20MhzChannels && pNum20MhzChannels )
2459 {
2460 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
2461 {
2462 for( i = 0; i <= RF_CHAN_14; i++ )
2463 {
2464 p20MhzChannels[count++] = rfChannels[i].channelNum;
2465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002466 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
2467 {
2468 p20MhzChannels[count++] = rfChannels[i].channelNum;
2469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002470 status = VOS_STATUS_SUCCESS;
2471 }
2472 *pNum20MhzChannels = count;
2473 }
2474
2475 return (status);
2476}
2477
2478/**------------------------------------------------------------------------
2479 \brief vos_nv_readDefaultCountryTable() - return the default Country table
2480 \param table data - a union to return the default country table data in.
2481 \return status of the NV read operation
2482 \sa
2483 -------------------------------------------------------------------------*/
2484VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
2485{
Amar Singhalfddc28c2013-09-05 13:03:40 -07002486
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002487 VOS_STATUS status = VOS_STATUS_SUCCESS;
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302488 vos_mem_copy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002489 pr_info("DefaultCountry is %c%c\n",
2490 tableData->defaultCountryTable.countryCode[0],
2491 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002492 return status;
2493}
2494
2495/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002496 \brief vos_nv_getBuffer -
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 \param pBuffer - to return the buffer address
2498 pSize - buffer size.
2499 \return status of the NV read operation
2500 \sa
2501 -------------------------------------------------------------------------*/
2502VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2503{
Leo Chang80de3c22013-11-26 10:52:12 -08002504 eNvVersionType nvVersion;
2505
2506 nvVersion = vos_nv_getNvVersion();
2507
2508 if (E_NV_V3 == nvVersion)
2509 {
2510 /* Send the NV V3 structure and size */
2511 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
2512 *pSize = sizeof(sHalNv);
2513 }
2514 else if (E_NV_V2 == nvVersion)
2515 {
2516 /* Send the NV V2 structure and size */
2517 *pNvBuffer = (v_VOID_t *)(&gnvEFSTableV2->halnvV2);
2518 *pSize = sizeof(sHalNvV2);
2519 }
2520 else
2521 {
2522 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2523 "%s : Invalid NV version %d", __func__, nvVersion);
2524 return VOS_STATUS_E_INVAL;
2525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002526
2527 return VOS_STATUS_SUCCESS;
2528}
2529
Jeff Johnson295189b2012-06-20 16:38:30 -07002530/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002531 \brief vos_nv_getBuffer -
2532 \param pBuffer - to return the buffer address
2533 pSize - buffer size.
2534 \return status of the NV read operation
2535 \sa
2536 -------------------------------------------------------------------------*/
2537VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2538{
2539 /* Send the NV structure and size */
Leo Changb1eb8812013-12-30 11:51:44 -08002540 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
2541 *pSize = nvReadEncodeBufSize;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07002542 return VOS_STATUS_SUCCESS;
2543}
2544
2545
2546VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
2547{
2548 /* Send the NV structure and size */
2549 *pNvBuffer = (v_VOID_t *)(pDictFile);
2550 *pSize = nDictionarySize;
2551
2552 return VOS_STATUS_SUCCESS;
2553}
2554
2555VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
2556{
2557 if (MAGIC_NUMBER == magicNumber)
2558 {
2559 return VOS_STATUS_SUCCESS;
2560 }
2561
2562 return VOS_STATUS_E_FAILURE;
2563}
2564
2565VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
2566{
2567 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
2568 (size-sizeof(v_U32_t)));
2569
2570 return VOS_STATUS_SUCCESS;
2571}
2572
2573/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07002574 \brief vos_nv_getChannelEnabledState -
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 \param rfChannel - input channel enum to know evabled state
2576 \return eNVChannelEnabledType enabled state for channel
2577 * enabled
2578 * disabled
2579 * DFS
2580 \sa
2581 -------------------------------------------------------------------------*/
2582eNVChannelEnabledType vos_nv_getChannelEnabledState
2583(
2584 v_U32_t rfChannel
2585)
2586{
2587 v_U32_t channelLoop;
2588 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2589
2590 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2591 {
2592 if(rfChannels[channelLoop].channelNum == rfChannel)
2593 {
2594 channelEnum = (eRfChannels)channelLoop;
2595 break;
2596 }
2597 }
2598
2599 if(INVALID_RF_CHANNEL == channelEnum)
2600 {
2601 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002602 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 return NV_CHANNEL_INVALID;
2604 }
2605
2606 return regChannels[channelEnum].enabled;
2607}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002608
Leo Chang80de3c22013-11-26 10:52:12 -08002609/**------------------------------------------------------------------------
2610 \brief vos_nv_getNvVersion -
2611 \param NONE
2612 \return eNvVersionType NV.bin version
2613 * E_NV_V2
2614 * E_NV_V3
2615 * E_NV_INVALID
2616 \sa
2617 -------------------------------------------------------------------------*/
2618eNvVersionType vos_nv_getNvVersion
2619(
2620 void
2621)
2622{
2623 VosContextType *vosCtxt = NULL;
2624
2625 vosCtxt = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2626 if (vosCtxt)
2627 {
2628 return vosCtxt->nvVersion;
2629 }
2630
2631 return E_NV_INVALID;
2632}
2633
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002634/******************************************************************
Amar Singhala49cbc52013-10-08 18:37:44 -07002635 Add CRDA regulatory support
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002636*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002637
2638static int bw20_ch_index_to_bw40_ch_index(int k)
2639{
2640 int m = -1;
2641 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2642 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002643 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2644 if (m > RF_CHAN_BOND_11)
2645 m = RF_CHAN_BOND_11;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002646 }
2647 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2648 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002649 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2650 if (m > RF_CHAN_BOND_214)
2651 m = RF_CHAN_BOND_214;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002652 }
2653 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2654 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002655 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2656 if (m > RF_CHAN_BOND_62)
2657 m = RF_CHAN_BOND_62;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002658 }
Leo Chang80de3c22013-11-26 10:52:12 -08002659#ifdef FEATURE_WLAN_CH144
2660 else if (k >= RF_CHAN_100 && k <= RF_CHAN_144)
2661#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002662 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
Leo Chang80de3c22013-11-26 10:52:12 -08002663#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002664 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002665 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
Leo Chang80de3c22013-11-26 10:52:12 -08002666#ifdef FEATURE_WLAN_CH144
2667 if (m > RF_CHAN_BOND_142)
2668 m = RF_CHAN_BOND_142;
2669#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002670 if (m > RF_CHAN_BOND_138)
2671 m = RF_CHAN_BOND_138;
Leo Chang80de3c22013-11-26 10:52:12 -08002672#endif /* FEATURE_WLAN_CH144 */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002673 }
2674 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2675 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002676 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2677 if (m > RF_CHAN_BOND_163)
2678 m = RF_CHAN_BOND_163;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002679 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002680return m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002681}
2682
Amar Singhala49cbc52013-10-08 18:37:44 -07002683void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002684{
Amar Singhala49cbc52013-10-08 18:37:44 -07002685 int k;
2686 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2687 countryCode[0], countryCode[1], domain_id);
2688 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2689 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2690 NV_CHANNEL_ENABLE;
2691 /* Max Tx Power 20dBm */
2692 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2693 }
2694 /* enable ch 12 to ch 14 passive scan */
2695 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2696 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2697 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2698 NV_CHANNEL_DFS;
2699 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2700 }
2701 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2702 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2703 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2704 NV_CHANNEL_DFS;
2705 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2706 }
2707#ifdef PASSIVE_SCAN_4_9GHZ
2708 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2709 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2710 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2711 NV_CHANNEL_DFS;
2712 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2713 }
2714#endif
2715 if (domain_id == NUM_REG_DOMAINS-1)
2716 { /* init time */
2717 crda_alpha2[0] = countryCode[0];
2718 crda_alpha2[1] = countryCode[1];
2719 crda_regulatory_entry_valid = VOS_TRUE;
2720 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2721 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2722 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2723 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2724 }
2725 if (domain_id == NUM_REG_DOMAINS-2)
2726 { /* none-default country */
2727 run_time_alpha2[0] = countryCode[0];
2728 run_time_alpha2[1] = countryCode[1];
2729 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2730 }
2731}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002732
Amar Singhala49cbc52013-10-08 18:37:44 -07002733static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2734 struct regulatory_request *request,
2735 v_U8_t nBandCapability,
2736 int domain_id)
2737{
2738 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2739 pr_info("Country 00 special handling to enable passive scan.\n");
2740 crda_regulatory_entry_default(request->alpha2, domain_id);
2741 }
2742 return 0;
2743}
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002744
Amar Singhala49cbc52013-10-08 18:37:44 -07002745/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2746static int create_crda_regulatory_entry(struct wiphy *wiphy,
2747 struct regulatory_request *request,
2748 v_U8_t nBandCapability)
2749{
2750 int i, j, m;
2751 int k = 0, n = 0;
2752
2753 if (run_time_alpha2[0]==request->alpha2[0] &&
2754 run_time_alpha2[1]==request->alpha2[1] &&
2755 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2756 return 0; /* already created */
2757
2758 /* 20MHz channels */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002759 if (nBandCapability == eCSR_BAND_24)
2760 pr_info("BandCapability is set to 2G only.\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07002761 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002762 {
2763 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2764 continue;
2765 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2766 continue;
2767 if (wiphy->bands[i] == NULL)
2768 {
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002769 return -1;
2770 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002771 // internal channels[] is one continous array for both 2G and 5G bands
2772 // m is internal starting channel index for each band
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002773 if (i == 0)
2774 m = 0;
2775 else
2776 m = wiphy->bands[i-1]->n_channels + m;
Amar Singhala49cbc52013-10-08 18:37:44 -07002777 for (j=0;j<wiphy->bands[i]->n_channels;j++)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002778 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002779 // k = (m + j) is internal current channel index for 20MHz channel
2780 // n is internal channel index for corresponding 40MHz channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002781 k = m + j;
2782 n = bw20_ch_index_to_bw40_ch_index(k);
2783 if (n == -1)
Amar Singhala49cbc52013-10-08 18:37:44 -07002784 return -1;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002785 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2786 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002787 if (pnvEFSTable == NULL)
2788 {
2789 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2790 return -1;
2791 }
2792 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2793 NV_CHANNEL_DISABLE;
2794 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2795 NV_CHANNEL_DISABLE;
2796 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2797 // rfChannels[n].channelNum);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002798 }
2799 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2800 {
Amar Singhala49cbc52013-10-08 18:37:44 -07002801 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2802 NV_CHANNEL_DFS;
2803 // max_power is in mBm = 100 * dBm
2804 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2805 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2806 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2807 {
2808 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2809 NV_CHANNEL_DFS;
2810 // 40MHz channel power is half of 20MHz (-3dB) ??
2811 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2812 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2813 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002814 }
2815 else // Enable is only last flag we support
2816 {
Manjunathappa Prakashde7b2a52014-02-28 16:59:03 -08002817#ifdef FEATURE_WLAN_CH144
2818 if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion()))
2819 {
2820 //Do not enable channel 144 when NV version is not NV3
2821 }
2822 else
2823#endif
2824 {
2825 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].\
2826 channels[k].enabled = NV_CHANNEL_ENABLE;
2827 }
2828
Amar Singhala49cbc52013-10-08 18:37:44 -07002829 // max_power is in dBm
2830 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
2831 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
2832 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2833 {
2834 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2835 NV_CHANNEL_ENABLE;
2836 // 40MHz channel power is half of 20MHz (-3dB) ??
2837 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
2838 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
2839 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002840 }
Amar Singhala49cbc52013-10-08 18:37:44 -07002841 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2842 real gain which should be provided by the real design */
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002843 }
2844 }
2845 if (k == 0)
2846 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002847 run_time_alpha2[0] = request->alpha2[0];
2848 run_time_alpha2[1] = request->alpha2[1];
2849 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2850 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
2851return 0;
2852}
Amar Singhal0d15bd52013-10-12 23:13:13 -07002853
2854
Amar Singhala49cbc52013-10-08 18:37:44 -07002855v_BOOL_t is_crda_regulatory_entry_valid(void)
2856{
2857return crda_regulatory_entry_valid;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002858}
2859
Amar Singhala49cbc52013-10-08 18:37:44 -07002860/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2861start freq + 10000 = center freq of the 20MHz start channel
2862end freq - 10000 = center freq of the 20MHz end channel
2863start freq + 20000 = center freq of the 40MHz start channel
2864end freq - 20000 = center freq of the 40MHz end channel
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002865*/
Amar Singhala49cbc52013-10-08 18:37:44 -07002866static int bw20_start_freq_to_channel_index(u32 freq_khz)
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002867{
Leo Chang80de3c22013-11-26 10:52:12 -08002868 int i;
2869 u32 center_freq = freq_khz + 10000;
2870
Amar Singhala49cbc52013-10-08 18:37:44 -07002871 //Has to compare from low freq to high freq
2872 //RF_SUBBAND_2_4_GHZ
2873 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2874 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2875 return i;
2876 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2877 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2878 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2879 return i;
2880 //RF_SUBBAND_5_LOW_GHZ
2881 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2882 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2883 return i;
2884 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002885#ifdef FEATURE_WLAN_CH144
2886 for (i=RF_CHAN_100;i<=RF_CHAN_144;i++)
2887#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002888 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002889#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002890 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2891 return i;
2892 //RF_SUBBAND_5_HIGH_GHZ
2893 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2894 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2895 return i;
2896return -1;
2897}
2898
2899static int bw20_end_freq_to_channel_index(u32 freq_khz)
2900{
Leo Chang80de3c22013-11-26 10:52:12 -08002901 int i;
2902 u32 center_freq = freq_khz - 10000;
2903
Amar Singhala49cbc52013-10-08 18:37:44 -07002904 //Has to compare from high freq to low freq
2905 //RF_SUBBAND_5_HIGH_GHZ
2906 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2907 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2908 return i;
2909 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002910#ifdef FEATURE_WLAN_CH144
2911 for (i=RF_CHAN_144;i>=RF_CHAN_100;i--)
2912#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002913 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002914#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002915 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2916 return i;
2917 //RF_SUBBAND_5_LOW_GHZ
2918 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2919 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2920 return i;
2921 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2922 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2923 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2924 return i;
2925 //RF_SUBBAND_2_4_GHZ
2926 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2927 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2928 return i;
Leo Chang80de3c22013-11-26 10:52:12 -08002929 return -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07002930}
2931
2932static int bw40_start_freq_to_channel_index(u32 freq_khz)
2933{
Leo Chang80de3c22013-11-26 10:52:12 -08002934 int i;
2935 u32 center_freq = freq_khz + 20000;
2936
Amar Singhala49cbc52013-10-08 18:37:44 -07002937 //Has to compare from low freq to high freq
2938 //RF_SUBBAND_2_4_GHZ
2939 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2940 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2941 return i;
2942 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2943 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2944 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2945 return i;
2946 //RF_SUBBAND_5_LOW_GHZ
2947 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2948 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2949 return i;
2950 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002951#ifdef FEATURE_WLAN_CH144
2952 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_142;i++)
2953#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002954 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
Leo Chang80de3c22013-11-26 10:52:12 -08002955#endif /* RF_CHAN_BOND_142 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002956 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2957 return i;
2958 //RF_SUBBAND_5_HIGH_GHZ
2959 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2960 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2961 return i;
2962return -1;
2963}
2964
2965static int bw40_end_freq_to_channel_index(u32 freq_khz)
2966{
Leo Chang80de3c22013-11-26 10:52:12 -08002967 int i;
2968 u32 center_freq = freq_khz - 20000;
2969
Amar Singhala49cbc52013-10-08 18:37:44 -07002970 //Has to compare from high freq to low freq
2971 //RF_SUBBAND_5_HIGH_GHZ
2972 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2973 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2974 return i;
2975 //RF_SUBBAND_5_MID_GHZ
Leo Chang80de3c22013-11-26 10:52:12 -08002976#ifdef FEATURE_WLAN_CH144
2977 for (i=RF_CHAN_BOND_142;i>=RF_CHAN_BOND_102;i--)
2978#else
Amar Singhala49cbc52013-10-08 18:37:44 -07002979 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
Leo Chang80de3c22013-11-26 10:52:12 -08002980#endif /* FEATURE_WLAN_CH144 */
Amar Singhala49cbc52013-10-08 18:37:44 -07002981 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2982 return i;
2983 //RF_SUBBAND_5_LOW_GHZ
2984 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2985 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2986 return i;
2987 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2988 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2989 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2990 return i;
2991 //RF_SUBBAND_2_4_GHZ
2992 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2993 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2994 return i;
2995return -1;
2996}
2997
2998static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2999{
3000 switch (nBandCapability)
3001 {
3002 case eCSR_BAND_ALL:
3003 return VOS_TRUE;
3004 case eCSR_BAND_24:
3005 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
3006 return VOS_TRUE;
3007 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
3008 return VOS_TRUE; // 2.4G 40MHz channel
3009 break;
3010 case eCSR_BAND_5G:
3011 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
3012 return VOS_TRUE;
3013 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
3014 return VOS_TRUE; // 2.4G 40MHz channel
3015 break;
3016 default:
3017 break;
3018 }
3019 return VOS_FALSE;
3020}
3021
3022/* create_crda_regulatory_entry_from_regd should be called during init time */
3023static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
3024 struct regulatory_request *request,
3025 v_U8_t nBandCapability)
3026{
3027 int i, j, n, domain_id;
3028 int bw20_start_channel_index, bw20_end_channel_index;
3029 int bw40_start_channel_index, bw40_end_channel_index;
3030
3031 if (wiphy == NULL || wiphy->regd == NULL)
3032 {
3033 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
3034 return -1;
3035 }
3036 if (crda_regulatory_entry_valid == VOS_FALSE)
3037 domain_id = NUM_REG_DOMAINS-1; /* init time */
3038 else
3039 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
3040 for (n = 0; n < NUM_RF_CHANNELS; n++)
3041 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
3042
3043 for (i=0;i<wiphy->regd->n_reg_rules;i++)
3044 {
3045 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
3046 bw20_start_channel_index =
3047 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
3048 bw20_end_channel_index =
3049 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3050 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
3051 {
3052 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
3053 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3054 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3055 continue; // skip this rull, but continue to next rule
3056 }
3057 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3058 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3059 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3060 bw20_start_channel_index, bw20_end_channel_index);
3061 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
3062 {
3063 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3064 {
3065 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
3066 rfChannels[j].channelNum);
3067 continue; // skip this channel, continue to next
3068 }
3069 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3070 {
3071 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3072 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3073 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3074 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303075 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN)
3076 {
3077 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3078 wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3079 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3080 }
Amar Singhala49cbc52013-10-08 18:37:44 -07003081 else
3082 {
3083 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3084 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
3085 wiphy->regd->reg_rules[i].power_rule.max_eirp);
3086 }
3087 /* max_eirp is in mBm (= 100 * dBm) unit */
3088 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3089 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
3090 }
3091 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
3092 real gain which should be provided by the real design */
3093 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
3094 {
3095 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
3096 bw40_start_channel_index =
3097 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
3098 bw40_end_channel_index =
3099 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3100 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
3101 {
3102 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
3103 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3104 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
3105 continue; // skip this rull, but continue to next rule
3106 }
3107 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
3108 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
3109 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
3110 bw40_start_channel_index, bw40_end_channel_index);
3111 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
3112 {
3113 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
3114 continue; // skip this channel, continue to next
3115 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
3116 {
3117 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
3118 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
3119 }
3120 else
3121 {
3122 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
3123 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
3124 }
3125 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
3126 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
3127 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
3128 }
3129 }
3130 }
3131 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
3132 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
3133 these flags and has no implementation yet. */
3134 if (crda_regulatory_entry_valid == VOS_FALSE)
3135 { /* init time */
3136 crda_alpha2[0] = request->alpha2[0];
3137 crda_alpha2[1] = request->alpha2[1];
3138 crda_regulatory_entry_valid = VOS_TRUE;
3139 }
3140 else
3141 { /* none-default country */
3142 run_time_alpha2[0] = request->alpha2[0];
3143 run_time_alpha2[1] = request->alpha2[1];
3144 crda_regulatory_run_time_entry_valid = VOS_TRUE;
3145 }
3146 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
3147 return 0;
3148}
3149
Manjunathappa Prakash73fc1982014-02-03 13:14:11 -08003150/**------------------------------------------------------------------------
3151 \brief vos_chan_to_freq -
3152 \param - input channel number to know channel frequency
3153 \return Channel frequency
3154 \sa
3155 -------------------------------------------------------------------------*/
3156v_U16_t vos_chan_to_freq(v_U8_t chanNum)
3157{
3158 int i;
3159
3160 for (i = 0; i < NUM_RF_CHANNELS; i++)
3161 {
3162 if (rfChannels[i].channelNum == chanNum)
3163 {
3164 return rfChannels[i].targetFreq;
3165 }
3166 }
3167
3168 return (0);
3169}
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05303170
3171/**------------------------------------------------------------------------
3172 \brief vos_freq_to_chan -
3173 \param - input frequency to know channel number
3174 \return Channel frequency
3175 \sa
3176 -------------------------------------------------------------------------*/
3177v_U8_t vos_freq_to_chan(v_U32_t freq)
3178{
3179 int i;
3180
3181 for (i = 0; i < NUM_RF_CHANNELS; i++)
3182 {
3183 if (rfChannels[i].targetFreq == freq)
3184 {
3185 return rfChannels[i].channelNum;
3186 }
3187 }
3188
3189 return (0);
3190}
3191
Abhishek Singh678227a2014-11-04 10:52:38 +05303192/* function to tell about if Default country is Non-Zero */
3193v_BOOL_t vos_is_nv_country_non_zero()
3194{
3195 v_BOOL_t status = VOS_FALSE;
3196 if (!(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] == '0' &&
3197 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] == '0'))
3198 {
3199 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3200 "Default Country is Non-Zero\n");
3201 return VOS_TRUE;
3202 }
3203
3204 return status ;
3205}
Manjunathappa Prakash73fc1982014-02-03 13:14:11 -08003206
Amar Singhala49cbc52013-10-08 18:37:44 -07003207#ifdef CONFIG_ENABLE_LINUX_REG
3208
Abhishek Singh28a41a72014-12-24 15:41:10 +05303209static int bw20_ch_index_to_bw40_plus_minus_ch_index(int k,
3210 eChannnelBondingTypes cbflag )
3211{
3212 int m = INVALID_RF_CHANNEL;
3213 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
3214 {
3215 if(RF_CHAN_BOND_HT40_PLUS == cbflag)
3216 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
3217 else
3218 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 - HT_40MINUS_INDEX ;
3219
3220 if (m > RF_CHAN_BOND_11)
3221 m = INVALID_RF_CHANNEL;
3222 if (m < RF_CHAN_BOND_3)
3223 m = INVALID_RF_CHANNEL;
3224 }
3225 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
3226 {
3227 if(RF_CHAN_BOND_HT40_PLUS == cbflag)
3228 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
3229 else
3230 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 - HT_40MINUS_INDEX;
3231
3232 if (m > RF_CHAN_BOND_214)
3233 m = INVALID_RF_CHANNEL;
3234 if (m < RF_CHAN_BOND_242)
3235 m = INVALID_RF_CHANNEL;
3236 }
3237 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
3238 {
3239 if(RF_CHAN_BOND_HT40_PLUS == cbflag)
3240 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
3241 else
3242 m = k - RF_CHAN_36 + RF_CHAN_BOND_38 - HT_40MINUS_INDEX;
3243
3244 if (m > RF_CHAN_BOND_62)
3245 m = INVALID_RF_CHANNEL;
3246 if (m < RF_CHAN_BOND_38)
3247 m = INVALID_RF_CHANNEL;
3248 }
3249#ifdef FEATURE_WLAN_CH144
3250 else if (k >= RF_CHAN_100 && k <= RF_CHAN_144)
3251#else
3252 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
3253#endif /* FEATURE_WLAN_CH144 */
3254 {
3255 if(RF_CHAN_BOND_HT40_PLUS == cbflag)
3256 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
3257 else
3258 m = k - RF_CHAN_100 + RF_CHAN_BOND_102 - HT_40MINUS_INDEX;
3259#ifdef FEATURE_WLAN_CH144
3260 if (m > RF_CHAN_BOND_142)
3261 m = INVALID_RF_CHANNEL;
3262 if (m < RF_CHAN_BOND_102)
3263 m = INVALID_RF_CHANNEL;
3264#else
3265 if (m > RF_CHAN_BOND_138)
3266 m = INVALID_RF_CHANNEL;
3267 if (m < RF_CHAN_BOND_102)
3268 m = INVALID_RF_CHANNEL;
3269#endif /* FEATURE_WLAN_CH144 */
3270 }
3271 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
3272 {
3273 if(RF_CHAN_BOND_HT40_PLUS == cbflag)
3274 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
3275 else
3276 m = k - RF_CHAN_149 + RF_CHAN_BOND_151 - HT_40MINUS_INDEX;
3277
3278 if (m > RF_CHAN_BOND_163)
3279 m = INVALID_RF_CHANNEL;
3280 if (m < RF_CHAN_BOND_151)
3281 m = INVALID_RF_CHANNEL;
3282 }
3283 return m;
3284}
Amar Singhala49cbc52013-10-08 18:37:44 -07003285/**------------------------------------------------------------------------
3286 \brief vos_nv_setRegDomain -
3287 \param clientCtxt - Client Context, Not used for PRIMA
3288 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05303289 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07003290 \return status set REG domain operation
3291 \sa
3292 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05303293VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
3294 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07003295{
3296
3297 if (regId >= REGDOMAIN_COUNT)
3298 {
3299 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3300 "VOS set reg domain, invalid REG domain ID %d", regId);
3301 return VOS_STATUS_E_INVAL;
3302 }
3303
3304 /* Set correct channel information based on REG Domain */
3305 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
3306
3307 return VOS_STATUS_SUCCESS;
3308}
3309
3310/**------------------------------------------------------------------------
3311 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
3312 a country given its country code
3313 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
3314 a country given its country code. This is done from reading a cached
3315 copy of the binary file.
3316 \param pRegDomain - pointer to regulatory domain
3317 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05303318 \param source - source of the country code
Amar Singhala49cbc52013-10-08 18:37:44 -07003319 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
3320 VOS_STATUS_E_FAULT - invalid pointer error
3321 VOS_STATUS_E_EMPTY - country code table is empty
3322 VOS_STATUS_E_EXISTS - given country code does not exist in table
3323 \sa
3324 -------------------------------------------------------------------------*/
3325VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05303326 const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source)
Amar Singhala49cbc52013-10-08 18:37:44 -07003327{
3328
Amar Singhalfddc28c2013-09-05 13:03:40 -07003329 v_CONTEXT_t pVosContext = NULL;
3330 hdd_context_t *pHddCtx = NULL;
3331 struct wiphy *wiphy = NULL;
3332 int i;
Amar Singhala49cbc52013-10-08 18:37:44 -07003333 int wait_result;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003334
Amar Singhalfddc28c2013-09-05 13:03:40 -07003335 /* sanity checks */
3336 if (NULL == pRegDomain)
3337 {
3338 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3339 ("Invalid reg domain pointer") );
3340 return VOS_STATUS_E_FAULT;
3341 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003342
Amar Singhalfddc28c2013-09-05 13:03:40 -07003343 *pRegDomain = REGDOMAIN_COUNT;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003344
Amar Singhala49cbc52013-10-08 18:37:44 -07003345 if (NULL == country_code)
Amar Singhalfddc28c2013-09-05 13:03:40 -07003346 {
3347 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3348 ("Country code array is NULL"));
3349 return VOS_STATUS_E_FAULT;
3350 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003351
Amar Singhalfddc28c2013-09-05 13:03:40 -07003352 if (0 == countryInfoTable.countryCount)
3353 {
3354 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3355 ("Reg domain table is empty") );
3356 return VOS_STATUS_E_EMPTY;
3357 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003358
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003359
Amar Singhalfddc28c2013-09-05 13:03:40 -07003360 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003361
Amar Singhalfddc28c2013-09-05 13:03:40 -07003362 if (NULL != pVosContext)
3363 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3364 else
3365 return VOS_STATUS_E_EXISTS;
3366
3367 if (NULL == pHddCtx)
3368 {
3369 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3370 ("Invalid pHddCtx pointer") );
3371 return VOS_STATUS_E_FAULT;
3372 }
3373
Kiet Lam6c583332013-10-14 05:37:09 +05303374 temp_reg_domain = REGDOMAIN_COUNT;
3375 /* lookup the country in the local database */
3376 for (i = 0; i < countryInfoTable.countryCount &&
3377 REGDOMAIN_COUNT == temp_reg_domain; i++)
3378 {
3379 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
3380 VOS_COUNTRY_CODE_LEN) == 0)
3381 {
3382 /* country code is found */
3383 /* record the temporary regulatory_domain as well */
3384 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
3385 break;
3386 }
3387 }
3388
3389 if (REGDOMAIN_COUNT == temp_reg_domain) {
3390
3391 /* the country was not found in the driver database */
3392 /* so we will return the REGDOMAIN_WORLD to SME/CSR */
3393
3394 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3395 ("Country does not map to any Regulatory domain"));
3396
3397 temp_reg_domain = REGDOMAIN_WORLD;
3398 }
3399
3400 if (COUNTRY_QUERY == source)
3401 {
3402 *pRegDomain = temp_reg_domain;
3403 return VOS_STATUS_SUCCESS;
3404 }
3405
Amar Singhalfddc28c2013-09-05 13:03:40 -07003406 wiphy = pHddCtx->wiphy;
3407
Amar Singhala49cbc52013-10-08 18:37:44 -07003408 if (false == wiphy->registered)
3409 {
3410 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3411 ("wiphy is not yet registered with the kernel") );
3412 return VOS_STATUS_E_FAULT;
3413 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003414
3415 /* We need to query the kernel to get the regulatory information
3416 for this country */
3417
Amar Singhal0d15bd52013-10-12 23:13:13 -07003418
3419 /* First compare the country code with the existing current country code
3420 . If both are same there is no need to query any database */
3421
3422 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3423 ("regdomain request"));
3424
3425 if ((country_code[0] == linux_reg_cc[0]) &&
3426 (country_code[1] == linux_reg_cc[1])) {
3427
3428 /* country code already exists */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003429
Amar Singhala49cbc52013-10-08 18:37:44 -07003430 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhal0d15bd52013-10-12 23:13:13 -07003431 (" country code already exists"));
Amar Singhala49cbc52013-10-08 18:37:44 -07003432
Amar Singhal0d15bd52013-10-12 23:13:13 -07003433 *pRegDomain = cur_reg_domain;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003434
Amar Singhal0d15bd52013-10-12 23:13:13 -07003435 return VOS_STATUS_SUCCESS;
3436 }
3437 else {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003438
Amar Singhal0d15bd52013-10-12 23:13:13 -07003439 /* get the regulatory information from the kernel
3440 database */
Amar Singhala49cbc52013-10-08 18:37:44 -07003441
Amar Singhal0d15bd52013-10-12 23:13:13 -07003442 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3443 (" get country information from kernel db"));
3444
Amar Singhal0d15bd52013-10-12 23:13:13 -07003445
Kiet Lam6c583332013-10-14 05:37:09 +05303446 if (COUNTRY_NV == source)
3447 {
3448 INIT_COMPLETION(pHddCtx->linux_reg_req);
3449 regulatory_hint(wiphy, country_code);
Abhishek Singh2a705962014-10-30 14:47:28 +05303450 /* Wait for 300ms*/
Kiet Lam6c583332013-10-14 05:37:09 +05303451 wait_result = wait_for_completion_interruptible_timeout(
3452 &pHddCtx->linux_reg_req,
Abhishek Singh2a705962014-10-30 14:47:28 +05303453 msecs_to_jiffies(LINUX_REG_WAIT_TIME));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003454
Kiet Lam6c583332013-10-14 05:37:09 +05303455 /* if the country information does not exist with the kernel,
3456 then the driver callback would not be called */
Amar Singhal0d15bd52013-10-12 23:13:13 -07003457
Kiet Lam6c583332013-10-14 05:37:09 +05303458 if (wait_result >= 0) {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003459
Kiet Lam6c583332013-10-14 05:37:09 +05303460 /* the driver callback was called. this means the country
3461 regulatory information was found in the kernel database.
3462 The callback would have updated the internal database. Here
3463 update the country and the return value for the regulatory
3464 domain */
Amar Singhalfddc28c2013-09-05 13:03:40 -07003465
Kiet Lam6c583332013-10-14 05:37:09 +05303466 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3467 ("runtime country code is found in kernel db"));
3468
3469 *pRegDomain = temp_reg_domain;
3470 cur_reg_domain = temp_reg_domain;
3471 linux_reg_cc[0] = country_code[0];
3472 linux_reg_cc[1] = country_code[1];
3473
3474 return VOS_STATUS_SUCCESS;
3475 }
3476 else {
3477
3478 /* the country information has not been found in the kernel
3479 database, return failure */
3480
3481 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3482 ("runtime country code is not found in kernel db"));
3483
3484 return VOS_STATUS_E_EXISTS;
3485 }
3486 }
3487 else if (COUNTRY_IE == source || COUNTRY_USER == source)
3488 {
Sachin Ahuja70e37512015-01-19 14:44:45 +05303489 INIT_COMPLETION(pHddCtx->linux_reg_req);
Kiet Lam6c583332013-10-14 05:37:09 +05303490#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3491 regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER);
3492#else
3493 regulatory_hint_user(country_code);
3494#endif
Sachin Ahuja70e37512015-01-19 14:44:45 +05303495 wait_result = wait_for_completion_interruptible_timeout(
3496 &pHddCtx->linux_reg_req,
3497 msecs_to_jiffies(LINUX_REG_WAIT_TIME));
3498
3499 /* if the country information does not exist with the kernel,
3500 then the driver callback would not be called */
3501
3502 if (wait_result >= 0)
3503 {
3504 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3505 "runtime country code : %c%c is found in kernel db",
3506 country_code[0], country_code[1]);
3507 *pRegDomain = temp_reg_domain;
3508 }
3509
3510 else
3511 {
3512 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
3513 "runtime country code : %c%c is not found"
3514 " in kernel db",
3515 country_code[0], country_code[1]);
3516
3517 return VOS_STATUS_E_EXISTS;
3518 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003519 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003520
Kiet Lam6c583332013-10-14 05:37:09 +05303521 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07003522
Kiet Lam6c583332013-10-14 05:37:09 +05303523 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003524}
3525
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303526int vos_update_nv_table_from_wiphy_band(void *hdd_ctx,
3527 void *pwiphy,v_U8_t nBandCapability)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003528{
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303529 int i, j, m;
3530 int k = 0, n = 0;
3531 const struct ieee80211_reg_rule *reg_rule;
Kiet Lam5cb90e82013-10-25 19:35:12 +05303532#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303533 int err;
Kiet Lam5cb90e82013-10-25 19:35:12 +05303534#endif
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303535 hdd_context_t *pHddCtx = (hdd_context_t *)hdd_ctx;
3536 struct wiphy *wiphy = (struct wiphy *)pwiphy;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003537
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303538 for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++)
3539 {
Amar Singhal0d15bd52013-10-12 23:13:13 -07003540
3541 if (wiphy->bands[i] == NULL)
3542 {
3543
Ratheesh S P36dbc932015-08-07 14:28:57 +05303544 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Arif Hussain02882402013-11-17 21:55:29 -08003545 "error: wiphy->bands is NULL, i = %d", i);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303546 continue;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003547 }
3548
3549 /* internal channels[] is one continous array for both 2G and 5G bands
3550 m is internal starting channel index for each band */
3551
3552 if (i == 0)
3553 m = 0;
3554 else
3555 m = wiphy->bands[i-1]->n_channels + m;
3556
3557 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
3558 {
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303559 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability)
3560 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3561 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability)
3562 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
3563
Amar Singhal0d15bd52013-10-12 23:13:13 -07003564 /* k = (m + j) is internal current channel index for 20MHz channel
3565 n is internal channel index for corresponding 40MHz channel */
3566
3567 k = m + j;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003568
Kiet Lam5cb90e82013-10-25 19:35:12 +05303569 /* If the regulatory rules for a country do not explicilty
3570 * require a passive scan on a frequency, lift the passive
3571 * scan restriction
3572 */
3573#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3574 reg_rule = freq_reg_info(wiphy,
3575 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq));
3576#else
3577 err = freq_reg_info(wiphy,
3578 MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq),
3579 0, &reg_rule);
3580#endif
3581
3582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3583 if (!IS_ERR(reg_rule))
3584#else
3585 if (0 == err)
3586#endif
3587 {
Agarwal Ashish6cc761c2014-08-25 19:14:46 +05303588 /* When Country code in nv.bin file is Non Zero and Reg Domain
3589 * is world; it's neither CUSTOM nor STRICT. In this Case
3590 * if country code is Non-Zero and domain is world; driver
3591 * will not change channel to active.
3592 */
Ravi Shankar Upadrasta631d6c52014-06-12 14:46:11 +05303593
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3595 if (!(wiphy->regulatory_flags & REGULATORY_STRICT_REG))
3596#else
Agarwal Ashish6cc761c2014-08-25 19:14:46 +05303597 if (!(wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY ))
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303598#endif
Agarwal Ashish6cc761c2014-08-25 19:14:46 +05303599 {
Ravi Shankar Upadrasta631d6c52014-06-12 14:46:11 +05303600 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
3601 {
3602 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3603 "%s: Remove passive scan restriction for %u",
3604 __func__, wiphy->bands[i]->channels[j].center_freq);
3605 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
3606 }
3607
Ravi Shankar Upadrasta2e528642014-06-12 15:05:03 +05303608 wiphy->bands[i]->channels[j].max_power =
3609 (int) MBM_TO_DBM(reg_rule->power_rule.max_eirp);
Kiet Lam5cb90e82013-10-25 19:35:12 +05303610 }
3611 }
3612
Amar Singhal0d15bd52013-10-12 23:13:13 -07003613 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
3614 {
3615 if (pnvEFSTable == NULL)
3616 {
3617 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08003618 "error: pnvEFSTable is NULL, probably not parsed nv.bin yet");
Amar Singhal0d15bd52013-10-12 23:13:13 -07003619 return -1;
3620 }
3621 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
3622 NV_CHANNEL_DISABLE;
Abhishek Singh28a41a72014-12-24 15:41:10 +05303623 if (INVALID_RF_CHANNEL !=
3624 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k , RF_CHAN_BOND_HT40_MINUS)))
3625 {
3626 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3627 NV_CHANNEL_DISABLE;
3628 }
3629 if (INVALID_RF_CHANNEL !=
3630 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k , RF_CHAN_BOND_HT40_PLUS)))
3631 {
3632 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3633 NV_CHANNEL_DISABLE;
3634 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003635 }
Kiet Lam5cb90e82013-10-25 19:35:12 +05303636 /* nv cannot distinguish between DFS and passive channels */
3637 else if (wiphy->bands[i]->channels[j].flags &
3638 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
Amar Singhal0d15bd52013-10-12 23:13:13 -07003639 {
Sachin Ahuja1f21df82014-10-15 18:00:48 +05303640#ifdef FEATURE_WLAN_CH144
3641 if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion()))
3642 {
3643 //Do not enable channel 144 when NV version is not NV3
3644 }
3645 else
3646#endif
3647 {
3648 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].\
3649 channels[k].enabled = NV_CHANNEL_DFS;
3650 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003651
Sushant Kaushikece4b562015-04-09 18:27:33 +05303652 if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3653 && !wiphy->bands[i]->channels[j].max_power)
3654 {
3655 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3656 FL("Both NV and DB.txt power limit is zero."
3657 "Setting default value %d"),TX_POWER_DEFAULT);
3658 wiphy->bands[i]->channels[j].max_power = TX_POWER_DEFAULT;
3659 }
3660
3661 else if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3662 || !wiphy->bands[i]->channels[j].max_power)
3663 {
3664 wiphy->bands[i]->channels[j].max_power =
3665 MAX(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3666 ((wiphy->bands[i]->channels[j].max_power)));
3667 }
3668
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303669 // Cap the TX power by the power limits specified in NV for the regdomain
Sushant Kaushikece4b562015-04-09 18:27:33 +05303670 if (gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3671 && wiphy->bands[i]->channels[j].max_power)
Kaushik, Sushant88c9f872014-10-29 18:44:04 +05303672 {
3673 wiphy->bands[i]->channels[j].max_power =
3674 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3675 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)));
3676 }
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303677
Amar Singhal0d15bd52013-10-12 23:13:13 -07003678 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003679 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Abhishek Singh25144bb2014-05-01 16:03:21 +05303680
3681 /* Disable the center channel if neither HT40+ nor HT40- is allowed
3682 */
3683 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) ==
3684 IEEE80211_CHAN_NO_HT40 )
3685 {
Abhishek Singh28a41a72014-12-24 15:41:10 +05303686 if ( INVALID_RF_CHANNEL !=
3687 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS)))
3688 {
3689 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
Abhishek Singh25144bb2014-05-01 16:03:21 +05303690 NV_CHANNEL_DISABLE;
Abhishek Singh28a41a72014-12-24 15:41:10 +05303691 }
3692 if ( INVALID_RF_CHANNEL !=
3693 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS)))
3694 {
3695 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3696 NV_CHANNEL_DISABLE;
3697 }
Abhishek Singh25144bb2014-05-01 16:03:21 +05303698 }
3699 else
Amar Singhal0d15bd52013-10-12 23:13:13 -07003700 {
Abhishek Singh28a41a72014-12-24 15:41:10 +05303701 if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40PLUS))
3702 {
3703 if (INVALID_RF_CHANNEL !=
3704 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS)))
3705 {
3706 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3707 NV_CHANNEL_DFS;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003708
Abhishek Singh28a41a72014-12-24 15:41:10 +05303709 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3710 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3711 * channels
3712 */
3713 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
3714 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303715 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
Abhishek Singh28a41a72014-12-24 15:41:10 +05303716 }
3717 }
3718 if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40MINUS))
3719 {
3720 if (INVALID_RF_CHANNEL !=
3721 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS)))
3722 {
3723 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3724 NV_CHANNEL_DFS;
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303725
Abhishek Singh28a41a72014-12-24 15:41:10 +05303726 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3727 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3728 * channels
3729 */
3730 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
3731 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
3732 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
3733 }
3734 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003735 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003736 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3737 {
3738 if (NULL == pHddCtx)
3739 {
3740 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3741 ("Invalid pHddCtx pointer") );
3742 }
3743 else
3744 {
3745 pHddCtx->isVHT80Allowed = 1;
3746 }
3747 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003748 }
3749 else /* Enable is only last flag we support */
3750 {
Manjunathappa Prakashde7b2a52014-02-28 16:59:03 -08003751#ifdef FEATURE_WLAN_CH144
3752 if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion()))
3753 {
3754 //Do not enable channel 144 when NV version is not NV3
3755 }
3756 else
3757#endif
3758 {
3759 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].\
3760 channels[k].enabled = NV_CHANNEL_ENABLE;
3761 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003762
Sushant Kaushikece4b562015-04-09 18:27:33 +05303763 if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3764 && !wiphy->bands[i]->channels[j].max_power)
3765 {
3766 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3767 FL("Both NV and DB.txt power limit is zero."
3768 "Setting default value %d"),TX_POWER_DEFAULT);
3769 wiphy->bands[i]->channels[j].max_power = TX_POWER_DEFAULT;
3770 }
3771
3772 else if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3773 || !wiphy->bands[i]->channels[j].max_power)
3774 {
3775 wiphy->bands[i]->channels[j].max_power =
3776 MAX(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3777 ((wiphy->bands[i]->channels[j].max_power)));
3778 }
3779
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303780 // Cap the TX power by the power limits specified in NV for the regdomain
Sushant Kaushikece4b562015-04-09 18:27:33 +05303781 if (gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit
3782 && wiphy->bands[i]->channels[j].max_power)
Kaushik, Sushant88c9f872014-10-29 18:44:04 +05303783 {
3784 wiphy->bands[i]->channels[j].max_power =
3785 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit,
3786 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)));
3787 }
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303788
Amar Singhal0d15bd52013-10-12 23:13:13 -07003789 /* max_power is in dBm */
3790 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
Amar Singhal19523302013-12-06 10:15:13 -08003791 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
Abhishek Singh25144bb2014-05-01 16:03:21 +05303792
3793 /* Disable the center channel if neither HT40+ nor HT40- is allowed
3794 */
3795 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) ==
3796 IEEE80211_CHAN_NO_HT40 )
3797 {
Abhishek Singh28a41a72014-12-24 15:41:10 +05303798 if ( INVALID_RF_CHANNEL !=
3799 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS)))
3800 {
3801 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
Abhishek Singh25144bb2014-05-01 16:03:21 +05303802 NV_CHANNEL_DISABLE;
Abhishek Singh28a41a72014-12-24 15:41:10 +05303803 }
3804 if ( INVALID_RF_CHANNEL !=
3805 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS)))
3806 {
3807 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3808 NV_CHANNEL_DISABLE;
3809 }
Abhishek Singh25144bb2014-05-01 16:03:21 +05303810 }
3811 else
Amar Singhal0d15bd52013-10-12 23:13:13 -07003812 {
Abhishek Singh28a41a72014-12-24 15:41:10 +05303813 if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40PLUS))
3814 {
3815 if (INVALID_RF_CHANNEL !=
3816 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS)))
3817 {
3818 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3819 NV_CHANNEL_ENABLE;
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303820
Abhishek Singh28a41a72014-12-24 15:41:10 +05303821 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3822 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3823 * channels
3824 */
3825 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
3826 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05303827 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
Abhishek Singh28a41a72014-12-24 15:41:10 +05303828 }
3829 }
3830 if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40MINUS))
3831 {
3832 if (INVALID_RF_CHANNEL !=
3833 (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS)))
3834 {
3835 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
3836 NV_CHANNEL_ENABLE;
3837
3838 /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from
3839 * wiphy limits, since wiphy has same limits for 20MHz and 40MHz
3840 * channels
3841 */
3842 pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
3843 MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit,
3844 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3)));
3845 }
3846 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07003847 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003848 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
3849 {
3850 if (NULL == pHddCtx)
3851 {
3852 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3853 ("Invalid pHddCtx pointer") );
3854 }
3855 else
3856 {
3857 pHddCtx->isVHT80Allowed = 1;
3858 }
3859 }
3860
Amar Singhal0d15bd52013-10-12 23:13:13 -07003861 }
3862
Kiet Lam5cb90e82013-10-25 19:35:12 +05303863
Amar Singhal0d15bd52013-10-12 23:13:13 -07003864 }
3865 }
3866
3867 if (k == 0)
3868 return -1;
3869
3870 return 0;
3871}
3872
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05303873/* create_linux_regulatory_entry to populate internal structures from wiphy */
3874static int create_linux_regulatory_entry(struct wiphy *wiphy,
3875 struct regulatory_request *request,
3876 v_U8_t nBandCapability)
3877{
3878 v_CONTEXT_t pVosContext = NULL;
3879 hdd_context_t *pHddCtx = NULL;
3880
3881 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
3882
3883 if (NULL != pVosContext)
3884 {
3885 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
3886 if (NULL == pHddCtx)
3887 {
3888 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3889 ("Invalid pHddCtx pointer") );
3890 }
3891 else
3892 {
3893 pHddCtx->isVHT80Allowed = 0;
3894 }
3895 }
3896 else
3897 {
3898 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3899 ("Invalid pVosContext pointer") );
3900 }
3901
3902 /* 20MHz channels */
3903 if (nBandCapability == eCSR_BAND_24)
3904 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3905 "BandCapability is set to 2G only");
3906 return vos_update_nv_table_from_wiphy_band(pHddCtx, wiphy, nBandCapability);
3907
3908
3909}
3910
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003911/*
Amar Singhalfddc28c2013-09-05 13:03:40 -07003912 * Function: wlan_hdd_linux_reg_notifier
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003913 * This function is called from cfg80211 core to provide regulatory settings
3914 * after new country is requested or intersected (init, user input or 11d)
Amar Singhala49cbc52013-10-08 18:37:44 -07003915 * This function is used to create a CRDA regulatory settings entry into internal
3916 * regulatory setting table.
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003917 */
Amar Singhala49cbc52013-10-08 18:37:44 -07003918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05303919void __wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07003920 struct regulatory_request *request)
3921#else
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05303922int __wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003923 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07003924#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07003925{
3926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303927 eCsrBand nBandCapability = eCSR_BAND_ALL;
Amar Singhal0d15bd52013-10-12 23:13:13 -07003928 v_COUNTRYCODE_t country_code;
Agarwal Ashishe3726342014-04-28 17:41:09 +05303929 int i, j;
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003930 v_BOOL_t isVHT80Allowed;
Amar Singhalfddc28c2013-09-05 13:03:40 -07003931
Amar Singhala49cbc52013-10-08 18:37:44 -07003932 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07003933 "cfg80211 reg notifier callback for country for initiator %d", request->initiator);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003934
Kiet Lamcffc5862013-10-30 16:28:45 +05303935 if (NULL == pHddCtx)
3936 {
3937 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3938 ("Invalid pHddCtx pointer") );
3939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
3940 return;
3941#else
3942 return 0;
3943#endif
Arif Hussainec3fbb32013-10-03 11:49:23 -07003944 }
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303945
Hanumantha Reddy Pothulae215adc2015-04-23 11:40:26 +05303946 if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL))
3947 {
3948 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3949 ("SSR is in progress") );
3950 goto do_comp;
3951 }
3952
Mihir Shete18156292014-03-11 15:38:30 +05303953 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
Abhishek Singh3015dad2014-02-28 17:30:13 +05303954 {
3955 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Mihir Shete18156292014-03-11 15:38:30 +05303956 ("%s Unload is in progress"), __func__ );
Hanumantha Reddy Pothulae215adc2015-04-23 11:40:26 +05303957 goto do_comp;
Abhishek Singh3015dad2014-02-28 17:30:13 +05303958 }
3959
Vinay Krishna Eranna22ebc0d2014-05-09 17:20:33 +05303960 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
3961 ("%s: Req initiator %d CC=%c%c"), __func__,
3962 request->initiator, request->alpha2[0], request->alpha2[1]);
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303963
3964 sme_GetFreqBand(pHddCtx->hHal, &nBandCapability);
Amar Singhalfddc28c2013-09-05 13:03:40 -07003965 /* first check if this callback is in response to the driver callback */
3966
Amar Singhala49cbc52013-10-08 18:37:44 -07003967 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
3968 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003969
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003970 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05303971 if (create_linux_regulatory_entry(wiphy, request, nBandCapability) == 0)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003972 {
Amar Singhalfddc28c2013-09-05 13:03:40 -07003973
Amar Singhal0d15bd52013-10-12 23:13:13 -07003974 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07003975 (" regulatory entry created"));
Amar Singhal0d15bd52013-10-12 23:13:13 -07003976 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003977 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
3978 {
3979 hdd_checkandupdate_phymode( pHddCtx);
3980 }
Vinay Krishna Eranna853725f2014-07-25 21:31:21 +05303981 linux_reg_cc[0] = request->alpha2[0];
3982 linux_reg_cc[1] = request->alpha2[1];
Amar Singhalfddc28c2013-09-05 13:03:40 -07003983
Amar Singhal0d15bd52013-10-12 23:13:13 -07003984 }
3985
Kiet Lamcffc5862013-10-30 16:28:45 +05303986 else if (request->initiator == NL80211_REGDOM_SET_BY_USER ||
3987 request->initiator == NL80211_REGDOM_SET_BY_CORE)
Amar Singhal0d15bd52013-10-12 23:13:13 -07003988 {
Abhishek Singh2a705962014-10-30 14:47:28 +05303989 /* Copy the country of kernel, so that we will not send the reg hint
3990 * if kernel country and driver country are same during load.
3991 */
3992 linux_reg_cc[0] = request->alpha2[0];
3993 linux_reg_cc[1] = request->alpha2[1];
Amar Singhal0d15bd52013-10-12 23:13:13 -07003994 /* first lookup the country in the local database */
3995
Agarwal Ashishf3298ac2014-07-26 19:34:17 +05303996 if (!(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] == '0' &&
3997 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] == '0') &&
3998 (vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)))
3999 {
4000 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
4001 (" Default Country in nv is non Zero and Driver load/unload"
4002 "is in progress; avoid updating country from kernel\n"));
4003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4004 return;
4005#else
4006 return 0;
4007#endif
4008 }
4009
Amar Singhal0d15bd52013-10-12 23:13:13 -07004010 country_code[0] = request->alpha2[0];
4011 country_code[1] = request->alpha2[1];
4012
4013 temp_reg_domain = REGDOMAIN_COUNT;
4014 for (i = 0; i < countryInfoTable.countryCount &&
4015 REGDOMAIN_COUNT == temp_reg_domain; i++)
4016 {
4017 if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode,
4018 VOS_COUNTRY_CODE_LEN) == 0)
4019 {
4020 /* country code is found */
4021 /* record the temporary regulatory_domain as well */
4022 temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
4023 break;
4024 }
4025 }
4026
4027 if (REGDOMAIN_COUNT == temp_reg_domain)
4028 temp_reg_domain = REGDOMAIN_WORLD;
4029
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004030 isVHT80Allowed = pHddCtx->isVHT80Allowed;
Amar Singhal0d15bd52013-10-12 23:13:13 -07004031 if (create_linux_regulatory_entry(wiphy, request,
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304032 nBandCapability) == 0)
Amar Singhal0d15bd52013-10-12 23:13:13 -07004033 {
4034 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
4035 (" regulatory entry created"));
4036
4037 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004038 if (pHddCtx->isVHT80Allowed != isVHT80Allowed)
4039 {
4040 hdd_checkandupdate_phymode( pHddCtx);
4041 }
Amar Singhal0d15bd52013-10-12 23:13:13 -07004042
4043 cur_reg_domain = temp_reg_domain;
Amar Singhal0d15bd52013-10-12 23:13:13 -07004044
4045 /* now pass the new country information to sme */
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07004046 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
4047 {
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07004048 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
Agarwal Ashishf3298ac2014-07-26 19:34:17 +05304049 REGDOMAIN_COUNT);
Tushnim Bhattacharyyac3c1e8e2013-10-29 17:27:43 -07004050 }
Kiet Lamcffc5862013-10-30 16:28:45 +05304051 else
4052 {
4053 sme_GenericChangeCountryCode(pHddCtx->hHal, country_code,
4054 temp_reg_domain);
4055 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05304056
Kiet Lamcffc5862013-10-30 16:28:45 +05304057 }
Agarwal Ashishe3726342014-04-28 17:41:09 +05304058
4059 /* Mark channels 36-48 as passive for US CC */
4060
4061 if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
4062 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
4063 (request->initiator == NL80211_REGDOM_SET_BY_USER))
4064 {
Agarwal Ashish0661dcd2014-05-20 20:16:41 +05304065 if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC &&
4066 wiphy->bands[IEEE80211_BAND_5GHZ])
Agarwal Ashishe3726342014-04-28 17:41:09 +05304067 {
4068 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4069 {
4070 // UNII-1 band channels are passive when domain is FCC.
4071 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
4072 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4073 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4074 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
4075 ((request->alpha2[0]== 'U'&& request->alpha2[1]=='S') &&
4076 pHddCtx->nEnableStrictRegulatoryForFCC))
4077 {
4078 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4079 }
4080 }
4081 }
4082 }
Hanumantha Reddy Pothulae215adc2015-04-23 11:40:26 +05304083do_comp:
Sachin Ahuja70e37512015-01-19 14:44:45 +05304084 if ((request->initiator == NL80211_REGDOM_SET_BY_DRIVER) ||
4085 (request->initiator == NL80211_REGDOM_SET_BY_USER))
4086 {
4087 complete(&pHddCtx->linux_reg_req);
4088 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Yue Maf49ba872013-08-19 12:04:25 -07004090 return;
Amar Singhala49cbc52013-10-08 18:37:44 -07004091#else
4092 return 0;
4093#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004094}
Amar Singhalfddc28c2013-09-05 13:03:40 -07004095
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05304096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4097void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
4098 struct regulatory_request *request)
4099{
4100 vos_ssr_protect(__func__);
4101 __wlan_hdd_linux_reg_notifier(wiphy, request);
4102 vos_ssr_unprotect(__func__);
4103 return;
4104}
4105#else
4106int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
4107 struct regulatory_request *request)
4108{
4109 int ret;
4110 vos_ssr_protect(__func__);
4111 ret = __wlan_hdd_linux_reg_notifier(wiphy, request);
4112 vos_ssr_unprotect(__func__);
4113 return ret;
4114}
4115#endif
Amar Singhal0d15bd52013-10-12 23:13:13 -07004116
Amar Singhal0a402232013-10-11 20:57:16 -07004117/* initialize wiphy from NV.bin */
4118VOS_STATUS vos_init_wiphy_from_nv_bin(void)
4119{
4120 int i, j, m;
4121 int k = 0;
4122 v_REGDOMAIN_t reg_domain;
4123 v_CONTEXT_t pVosContext = NULL;
4124 hdd_context_t *pHddCtx = NULL;
4125 struct wiphy *wiphy = NULL;
4126
4127 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4128
4129 if (NULL != pVosContext)
4130 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
4131 else
4132 return VOS_STATUS_E_EXISTS;
4133
4134 if (NULL == pHddCtx)
4135 {
4136 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4137 ("Invalid pHddCtx pointer") );
4138 return VOS_STATUS_E_FAULT;
4139 }
4140
4141 wiphy = pHddCtx->wiphy;
4142
4143 if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0])
4144 &&
4145 ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]))
4146 {
4147 /* default country is world roaming */
4148
4149 reg_domain = REGDOMAIN_WORLD;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4151 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4152#else
Amar Singhal0a402232013-10-11 20:57:16 -07004153 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304154#endif
Amar Singhal0a402232013-10-11 20:57:16 -07004155 }
4156 else if (REGDOMAIN_WORLD ==
4157 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) {
4158
4159 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
Amar Singhal0a402232013-10-11 20:57:16 -07004160 }
4161 else {
4162
4163 reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4165 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
4166#else
Amar Singhal0a402232013-10-11 20:57:16 -07004167 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304168#endif
Amar Singhal0a402232013-10-11 20:57:16 -07004169 }
4170
Mihir Shete457834b2014-03-11 21:46:21 +05304171 temp_reg_domain = cur_reg_domain = reg_domain;
4172
Amar Singhala1829502013-11-16 13:57:41 -08004173 m = 0;
Amar Singhal0a402232013-10-11 20:57:16 -07004174 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4175 {
4176
4177 if (wiphy->bands[i] == NULL)
4178 {
Amar Singhala1829502013-11-16 13:57:41 -08004179 continue;
Amar Singhal0a402232013-10-11 20:57:16 -07004180 }
4181
4182 /* internal channels[] is one continous array for both 2G and 5G bands
4183 m is internal starting channel index for each band */
Amar Singhal0a402232013-10-11 20:57:16 -07004184
4185 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4186 {
4187 /* k = (m + j) is internal current channel index */
4188 k = m + j;
4189
4190 if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
4191 NV_CHANNEL_DISABLE)
4192 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4193
4194 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
4195 NV_CHANNEL_DFS) {
4196
4197 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4198
4199 wiphy->bands[i]->channels[j].max_power =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05304200 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit);
Amar Singhal0a402232013-10-11 20:57:16 -07004201 }
4202
4203 else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled ==
4204 NV_CHANNEL_ENABLE) {
4205
4206 wiphy->bands[i]->channels[j].max_power =
Mihir Shete7f3fe0e2014-07-04 12:56:33 +05304207 (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit);
Amar Singhal0a402232013-10-11 20:57:16 -07004208 }
4209 }
Amar Singhala1829502013-11-16 13:57:41 -08004210
4211 m += wiphy->bands[i]->n_channels;
Amar Singhal0a402232013-10-11 20:57:16 -07004212 }
4213
4214 return VOS_STATUS_SUCCESS;
4215}
4216
4217
Agarwal Ashish6db9d532014-09-30 18:19:10 +05304218/**------------------------------------------------------------------------
4219 \brief vos_getCurrentCountryCode -
4220 \param CC - country code
4221 \return None
4222 \sa
4223 -------------------------------------------------------------------------*/
4224
4225void vos_getCurrentCountryCode( tANI_U8 *cc)
4226{
4227 vos_mem_copy(cc, linux_reg_cc, 2);
4228}
4229
Amar Singhalfddc28c2013-09-05 13:03:40 -07004230#else
4231
4232/**------------------------------------------------------------------------
Amar Singhala49cbc52013-10-08 18:37:44 -07004233 \brief vos_nv_setRegDomain -
4234 \param clientCtxt - Client Context, Not used for PRIMA
4235 regId - Regulatory Domain ID
Abhishek Singha306a442013-11-07 18:39:01 +05304236 sendRegHint - send hint to nl80211
Amar Singhala49cbc52013-10-08 18:37:44 -07004237 \return status set REG domain operation
4238 \sa
4239 -------------------------------------------------------------------------*/
Abhishek Singha306a442013-11-07 18:39:01 +05304240VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
4241 v_BOOL_t sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07004242{
4243 v_CONTEXT_t pVosContext = NULL;
4244 hdd_context_t *pHddCtx = NULL;
4245 struct wiphy *wiphy = NULL;
4246 /* Client Context Argumant not used for PRIMA */
4247 if (regId >= REGDOMAIN_COUNT)
4248 {
4249 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4250 "VOS set reg domain, invalid REG domain ID %d", regId);
4251 return VOS_STATUS_E_INVAL;
4252 }
4253
4254 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4255 if (NULL != pVosContext)
4256 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
4257 else
4258 return VOS_STATUS_E_EXISTS;
4259 /* Set correct channel information based on REG Domain */
4260 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
4261
4262 /* when CRDA is not running then we are world roaming.
4263 In this case if 11d is enabled, then country code should
4264 be update on basis of world roaming */
Abhishek Singha306a442013-11-07 18:39:01 +05304265 if (NULL != pHddCtx && sendRegHint)
Amar Singhala49cbc52013-10-08 18:37:44 -07004266 {
4267 wiphy = pHddCtx->wiphy;
4268 regulatory_hint(wiphy, "00");
4269 }
4270 return VOS_STATUS_SUCCESS;
4271}
4272
4273
4274/**------------------------------------------------------------------------
Amar Singhalfddc28c2013-09-05 13:03:40 -07004275 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
4276 a country given its country code
4277 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
4278 a country given its country code. This is done from reading a cached
4279 copy of the binary file.
4280 \param pRegDomain - pointer to regulatory domain
4281 \param countryCode - country code
Kiet Lam6c583332013-10-14 05:37:09 +05304282 \param source - source of the country code
Amar Singhalfddc28c2013-09-05 13:03:40 -07004283 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
4284 VOS_STATUS_E_FAULT - invalid pointer error
4285 VOS_STATUS_E_EMPTY - country code table is empty
4286 VOS_STATUS_E_EXISTS - given country code does not exist in table
4287 \sa
4288 -------------------------------------------------------------------------*/
4289VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
Kiet Lam6c583332013-10-14 05:37:09 +05304290 const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source)
Amar Singhalfddc28c2013-09-05 13:03:40 -07004291{
Amar Singhala49cbc52013-10-08 18:37:44 -07004292 int i;
4293 v_CONTEXT_t pVosContext = NULL;
4294 hdd_context_t *pHddCtx = NULL;
4295 struct wiphy *wiphy = NULL;
4296 int status;
Amar Singhal0d15bd52013-10-12 23:13:13 -07004297
Amar Singhala49cbc52013-10-08 18:37:44 -07004298 // sanity checks
4299 if (NULL == pRegDomain)
4300 {
4301 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004302 ("Invalid reg domain pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07004303 return VOS_STATUS_E_FAULT;
4304 }
4305 *pRegDomain = REGDOMAIN_COUNT;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004306
Amar Singhala49cbc52013-10-08 18:37:44 -07004307 if (NULL == countryCode)
4308 {
4309 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004310 ("Country code array is NULL") );
Amar Singhala49cbc52013-10-08 18:37:44 -07004311 return VOS_STATUS_E_FAULT;
4312 }
4313 if (0 == countryInfoTable.countryCount)
4314 {
4315 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004316 ("Reg domain table is empty") );
Amar Singhala49cbc52013-10-08 18:37:44 -07004317 return VOS_STATUS_E_EMPTY;
4318 }
4319 /* If CRDA regulatory settings is valid, i.e. crda is enabled
4320 and reg_notifier is called back.
4321 Intercept here and redirect to the Reg domain table's CRDA
4322 entry if country code is crda's country.
4323 last one NUM_REG_DOMAINS-1 is reserved for crda */
4324 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08004325 "vos_nv_getRegDomainFromCountryCode %c%c",
Amar Singhala49cbc52013-10-08 18:37:44 -07004326 countryCode[0], countryCode[1]);
4327
4328 if (crda_regulatory_entry_valid == VOS_TRUE)
4329 {
4330 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
4331 {
4332 *pRegDomain = NUM_REG_DOMAINS-1;
4333 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08004334 "vos_nv_getRegDomainFromCountryCode return crda init entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004335 return VOS_STATUS_SUCCESS;
4336 }
4337 if (run_time_alpha2[0]==countryCode[0] &&
4338 run_time_alpha2[1]==countryCode[1] &&
4339 crda_regulatory_run_time_entry_valid == VOS_TRUE)
4340 {
4341 *pRegDomain = NUM_REG_DOMAINS-2;
4342 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08004343 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004344 return VOS_STATUS_SUCCESS;
4345 }
4346 else
4347 {
4348 crda_regulatory_run_time_entry_valid = VOS_FALSE;
4349 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
4350 if (NULL != pVosContext)
4351 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
4352 else
4353 return VOS_STATUS_E_EXISTS;
4354 if (NULL == pHddCtx)
4355 {
4356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004357 ("Invalid pHddCtx pointer") );
Amar Singhala49cbc52013-10-08 18:37:44 -07004358 return VOS_STATUS_E_FAULT;
4359 }
4360
4361 wiphy = pHddCtx->wiphy;
4362
4363 INIT_COMPLETION(pHddCtx->driver_crda_req);
4364 regulatory_hint(wiphy, countryCode);
4365 status = wait_for_completion_interruptible_timeout(
4366 &pHddCtx->driver_crda_req,
4367 msecs_to_jiffies(CRDA_WAIT_TIME));
4368 if (!status)
4369 {
4370 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4371 "%s: Timeout waiting for CRDA REQ", __func__);
4372 }
4373
4374 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
4375 {
4376 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussain02882402013-11-17 21:55:29 -08004377 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004378 return VOS_STATUS_SUCCESS;
4379 }
4380 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -08004381 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry");
Amar Singhala49cbc52013-10-08 18:37:44 -07004382 return VOS_STATUS_E_EXISTS;
4383 }
4384 }
4385
4386 // iterate the country info table until end of table or the country code
4387 // is found
4388 for (i = 0; i < countryInfoTable.countryCount &&
4389 REGDOMAIN_COUNT == *pRegDomain; i++)
4390 {
4391 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
4392 VOS_COUNTRY_CODE_LEN) == 0)
4393 {
4394 // country code is found
4395 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
4396 }
4397 }
4398 if (REGDOMAIN_COUNT != *pRegDomain)
4399 {
4400 return VOS_STATUS_SUCCESS;
4401 }
4402 else
4403 {
4404 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Arif Hussain02882402013-11-17 21:55:29 -08004405 ("country code is not found"));
Amar Singhala49cbc52013-10-08 18:37:44 -07004406 return VOS_STATUS_E_EXISTS;
4407 }
4408}
Abhishek Singha306a442013-11-07 18:39:01 +05304409/* FUNCTION: vos_nv_change_country_code_cb
4410* to wait for contry code completion
4411*/
4412void* vos_nv_change_country_code_cb(void *pAdapter)
4413{
4414 struct completion *change_code_cng = pAdapter;
4415 complete(change_code_cng);
4416 return NULL;
4417}
Amar Singhala49cbc52013-10-08 18:37:44 -07004418
4419/*
4420 * Function: wlan_hdd_crda_reg_notifier
4421 * This function is called from cfg80211 core to provide regulatory settings
4422 * after new country is requested or intersected (init, user input or 11d)
4423 * This function is used to create a CRDA regulatory settings entry into internal
4424 * regulatory setting table.
4425 */
4426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05304427void __wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
Amar Singhala49cbc52013-10-08 18:37:44 -07004428 struct regulatory_request *request)
4429#else
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05304430int __wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
Amar Singhala49cbc52013-10-08 18:37:44 -07004431 struct regulatory_request *request)
4432#endif
4433{
4434 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4435 v_REGDOMAIN_t domainIdCurrent;
4436 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
4437 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304438 eCsrBand nBandCapability = eCSR_BAND_ALL;
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304439 int i,j,k,m,n;
4440 int countryIndex = -1;
Amar Singhala49cbc52013-10-08 18:37:44 -07004441
4442 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
4443 " %c%c\n", request->alpha2[0], request->alpha2[1]);
Abhishek Singh3015dad2014-02-28 17:30:13 +05304444
4445 /* During load and SSR, vos_open (which will lead to WDA_SetRegDomain)
4446 * is called before we assign pHddCtx->hHal so we might get it as
4447 * NULL here leading to crash.
4448 */
4449 if (NULL == pHddCtx)
4450 {
4451 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4452 ("%s Invalid pHddCtx pointer"), __func__);
4453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4454 return;
4455#else
4456 return 0;
4457#endif
4458 }
Mihir Shete18156292014-03-11 15:38:30 +05304459 if((WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx)) ||
Abhishek Singh3015dad2014-02-28 17:30:13 +05304460 pHddCtx->isLogpInProgress)
4461 {
4462 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
4463 ("%s load/unload or SSR is in progress Ignore"), __func__ );
4464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4465 return;
4466#else
4467 return 0;
4468#endif
4469 }
4470
Amar Singhala49cbc52013-10-08 18:37:44 -07004471 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
Amar Singhalfddc28c2013-09-05 13:03:40 -07004472 {
Abhishek Singha306a442013-11-07 18:39:01 +05304473 int status;
Amar Singhala49cbc52013-10-08 18:37:44 -07004474 wiphy_dbg(wiphy, "info: set by user\n");
Abhishek Singh1c597df2014-03-24 14:00:41 +05304475 memset(ccode, 0, WNI_CFG_COUNTRY_CODE_LEN);
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05304476 vos_mem_copy(ccode, request->alpha2, 2);
Abhishek Singha306a442013-11-07 18:39:01 +05304477 init_completion(&change_country_code);
4478 /* We will process hints by user from nl80211 in driver.
4479 * sme_ChangeCountryCode will set the country to driver
4480 * and update the regdomain.
4481 * when we return back to nl80211 from this callback, the nl80211 will
4482 * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to
4483 * query channel list from nl80211. Thus we need to update the channels
4484 * according to reg domain set by user before returning to nl80211 so
4485 * that hostapd will gets the updated channels.
4486 * The argument sendRegHint in sme_ChangeCountryCode is
4487 * set to eSIR_FALSE (hint is from nl80211 and thus
4488 * no need to notify nl80211 back)*/
4489 status = sme_ChangeCountryCode(pHddCtx->hHal,
4490 (void *)(tSmeChangeCountryCallback)
4491 vos_nv_change_country_code_cb,
Abhishek Singh1c597df2014-03-24 14:00:41 +05304492 ccode,
Abhishek Singha306a442013-11-07 18:39:01 +05304493 &change_country_code,
4494 pHddCtx->pvosContext,
4495 eSIR_FALSE,
4496 eSIR_FALSE);
4497 if (eHAL_STATUS_SUCCESS == status)
4498 {
4499 status = wait_for_completion_interruptible_timeout(
4500 &change_country_code,
4501 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4502 if(status <= 0)
4503 {
4504 wiphy_dbg(wiphy, "info: set country timed out\n");
4505 }
4506 }
4507 else
4508 {
4509 wiphy_dbg(wiphy, "info: unable to set country by user\n");
Amar Singhala49cbc52013-10-08 18:37:44 -07004510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4511 return;
4512#else
4513 return 0;
4514#endif
Abhishek Singha306a442013-11-07 18:39:01 +05304515 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004516 // ToDo
4517 /* Don't change default country code to CRDA country code by user req */
4518 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
4519 regd for new country settings */
4520 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
4521 // &country_code[0], pAdapter, pHddCtx->pvosContext);
Amar Singhalfddc28c2013-09-05 13:03:40 -07004522 }
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304523 sme_GetFreqBand(pHddCtx->hHal, &nBandCapability);
Abhishek Singha306a442013-11-07 18:39:01 +05304524 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
Amar Singhalfddc28c2013-09-05 13:03:40 -07004525 {
Amar Singhala49cbc52013-10-08 18:37:44 -07004526 wiphy_dbg(wiphy, "info: set by country IE\n");
Deepthi Gowri7fd19db2014-02-10 20:49:54 +05304527 if (create_crda_regulatory_entry(wiphy, request, nBandCapability) != 0)
Amar Singhala49cbc52013-10-08 18:37:44 -07004528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4529 return;
4530#else
4531 return 0;
4532#endif
4533 // ToDo
4534 /* Intersect of 11d and crda settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004535
Amar Singhala49cbc52013-10-08 18:37:44 -07004536 /* Don't change default country code to CRDA country code by 11d req */
4537 /* for every adapter call sme_ChangeCountryCode to trigger read regd
4538 for intersected new country settings */
4539 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
4540 // &country_code[0], pAdapter, pHddCtx->pvosContext);
4541 }
4542 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
Abhishek Singha306a442013-11-07 18:39:01 +05304543 (request->initiator == NL80211_REGDOM_SET_BY_CORE)||
4544 (request->initiator == NL80211_REGDOM_SET_BY_USER))
Amar Singhalfddc28c2013-09-05 13:03:40 -07004545 {
Amar Singhala49cbc52013-10-08 18:37:44 -07004546 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
4547 {
4548 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
4549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4550 return;
4551#else
4552 return 0;
4553#endif
4554 }
4555 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
4556 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
4557 {
4558 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
4559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4560 return;
4561#else
4562 return 0;
4563#endif
4564 }
4565
4566 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304567 for (n = 0; n < MAX_COUNTRY_IGNORE; n++)
4568 {
4569 if (vos_mem_compare(ccode, countryIgnoreList[n].countryCode, VOS_COUNTRY_CODE_LEN))
4570 {
4571 countryIndex = n;
4572 break;
4573 }
4574 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004575 /* if set by driver itself, it means driver can accept the crda
4576 regulatory settings and wiphy->regd should be populated with crda
4577 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
4578 correctly, this may be fixed by later kernel */
4579
Amar Singhala49cbc52013-10-08 18:37:44 -07004580 for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++)
4581 {
4582 if (NULL == wiphy->bands[i])
4583 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304584 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Amar Singhala49cbc52013-10-08 18:37:44 -07004585 "error: wiphy->bands[i] is NULL, i = %d", i);
4586 continue;
4587 }
4588
4589 // internal channels[] is one continous array for both 2G and 5G bands
4590 // m is internal starting channel index for each band
4591 if (0 == i)
4592 {
4593 m = 0;
4594 }
4595 else
4596 {
4597 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
4598 }
4599
4600 for (j=0; j<wiphy->bands[i]->n_channels; j++)
4601 {
4602 // k = (m + j) is internal current channel index for 20MHz channel
4603 // n is internal channel index for corresponding 40MHz channel
4604 k = m + j;
4605 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
4606 {
4607 // Enable social channels for P2P
4608 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
4609 2437 == wiphy->bands[i]->channels[j].center_freq ||
4610 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
4611 NV_CHANNEL_ENABLE == regChannels[k].enabled)
4612 {
4613 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4614 }
4615 else
4616 {
4617 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4618 }
4619 continue;
4620 }
4621 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
4622 {
4623 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4624 continue;
4625 }
4626
4627 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
4628 NV_CHANNEL_INVALID == regChannels[k].enabled)
4629 {
4630 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4631 }
4632 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
4633 {
4634 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4635 |IEEE80211_CHAN_RADAR);
4636 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4637 }
4638 else
4639 {
4640 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4641 |IEEE80211_CHAN_PASSIVE_SCAN
4642 |IEEE80211_CHAN_NO_IBSS
4643 |IEEE80211_CHAN_RADAR);
4644 }
Sushant Kaushikf4e085e2014-06-17 16:07:33 +05304645
4646 if (countryIndex != -1)
4647 {
4648 for (n = 0; n < MAX_CHANNELS_IGNORE; n++)
4649 {
4650 v_U16_t freq = vos_chan_to_freq(countryIgnoreList[countryIndex].channelList[n]);
4651 if (wiphy->bands[i]->channels[j].center_freq == freq)
4652 {
4653 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4654 |IEEE80211_CHAN_PASSIVE_SCAN
4655 |IEEE80211_CHAN_NO_IBSS
4656 |IEEE80211_CHAN_RADAR);
4657 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4658 }
4659 }
4660 }
4661
Amar Singhala49cbc52013-10-08 18:37:44 -07004662 }
4663 }
4664
4665 /* Haven't seen any condition that will set by driver after init.
4666 If we do, then we should also call sme_ChangeCountryCode */
Kalikinkar dharad73a9bd2014-01-28 22:42:34 -08004667
4668 /* To Disable the strict regulatory FCC rule, need set
4669 gEnableStrictRegulatoryForFCC to zero from INI.
4670 By default regulatory FCC rule enable or set to 1, and
4671 in this case one can control dynamically using IOCTL
4672 (nEnableStrictRegulatoryForFCC).
4673 If gEnableStrictRegulatoryForFCC is set to zero then
4674 IOCTL operation is inactive */
4675
4676 if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC &&
4677 wiphy->bands[IEEE80211_BAND_5GHZ])
Amar Singhala49cbc52013-10-08 18:37:44 -07004678 {
4679 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4680 {
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304681 // UNII-1 band channels are passive when domain is FCC.
Amar Singhala49cbc52013-10-08 18:37:44 -07004682 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
4683 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4684 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4685 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304686 ((domainIdCurrent == REGDOMAIN_FCC) &&
4687 pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004688 {
4689 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4690 }
4691 else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
4692 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
4693 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
4694 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
Swaroop Golti6c68ceb2014-01-19 17:28:04 +05304695 ((domainIdCurrent != REGDOMAIN_FCC) ||
4696 !pHddCtx->nEnableStrictRegulatoryForFCC))
Amar Singhala49cbc52013-10-08 18:37:44 -07004697 {
4698 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
4699 }
Padma, Santhosh Kumare225f142014-04-23 13:02:00 +05304700
4701 //Marking channels 52-144 as Radar channels if they are enabled
4702 k = wiphy->bands[IEEE80211_BAND_2GHZ]->n_channels + j;
4703
4704 if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5260 ||
4705 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5280 ||
4706 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5300 ||
4707 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5320 ||
4708 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5500 ||
4709 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5520) &&
4710 ((regChannels[k].enabled == NV_CHANNEL_ENABLE) ||
4711 (regChannels[k].enabled == NV_CHANNEL_DFS)))
4712 {
4713 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_RADAR;
4714 }
Amar Singhala49cbc52013-10-08 18:37:44 -07004715 }
4716 }
4717
4718 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
4719 {
4720 request->processed = 1;
4721 }
Amar Singhalfddc28c2013-09-05 13:03:40 -07004722 }
4723
Kiet Lam46b8e4e2013-11-06 21:49:53 +05304724 complete(&pHddCtx->wiphy_channel_update_event);
4725
Amar Singhala49cbc52013-10-08 18:37:44 -07004726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4727 return;
4728#else
4729 return 0;
4730#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07004731}
4732
Mukul Sharmae5ea4e02015-02-23 16:31:15 +05304733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4734void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
4735 struct regulatory_request *request)
4736{
4737 vos_ssr_protect(__func__);
4738 __wlan_hdd_crda_reg_notifier(wiphy, request);
4739 vos_ssr_unprotect(__func__);
4740 return;
4741}
4742#else
4743int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
4744 struct regulatory_request *request)
4745{
4746 int ret;
4747 vos_ssr_protect(__func__);
4748 ret = __wlan_hdd_crda_reg_notifier(wiphy, request);
4749 vos_ssr_unprotect(__func__);
4750 return ret;
4751}
4752#endif
4753
Amar Singhalfddc28c2013-09-05 13:03:40 -07004754#endif