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