blob: 0c9721dee611a78348e62410a272ab195fe7ca55 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*============================================================================
43 FILE: vos_nvitem.c
44 OVERVIEW: This source file contains definitions for vOS NV Item APIs
45 DEPENDENCIES: NV, remote API client, WinCE REX
46 Copyright (c) 2008 QUALCOMM Incorporated.
47 All Rights Reserved.
48 Qualcomm Confidential and Proprietary
49============================================================================*/
50/*============================================================================
51 EDIT HISTORY FOR MODULE
52============================================================================*/
53// the following is used to disable warning for having too many labels in
54// the 'nv_items_enum_type'
55
56/*----------------------------------------------------------------------------
57 * Include Files
58 * -------------------------------------------------------------------------*/
59#include "vos_types.h"
60#include "aniGlobal.h"
61#include "vos_nvitem.h"
62#include "vos_trace.h"
63#include "vos_api.h"
64#include "wlan_hdd_misc.h"
65#include "vos_sched.h"
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070066#include "wlan_nv_parser.h"
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070067#include "wlan_hdd_main.h"
68#include <net/cfg80211.h>
69static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
70static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
71static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
72static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -070073
Jeff Johnson295189b2012-06-20 16:38:30 -070074/*----------------------------------------------------------------------------
75 * Preprocessor Definitions and Constants
76 * -------------------------------------------------------------------------*/
77#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I
78#define VALIDITY_BITMAP_SIZE 32
79#define MAX_COUNTRY_COUNT 300
80//To be removed when NV support is fully functional
81#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6}
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070082
83#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -070084#define MAGIC_NUMBER 0xCAFEBABE
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -070085
Jeff Johnson295189b2012-06-20 16:38:30 -070086/*----------------------------------------------------------------------------
87 * Type Declarations
88 * -------------------------------------------------------------------------*/
89// this wrapper structure is identical to nv_cmd_type except the
90// data_ptr type is changed void* to avoid exceeding the debug information
91// module size as there are too many elements within nv_items_type union
92
93// structure for code and regulatory domain of a single country
94typedef struct
95{
96 v_U8_t regDomain;
97 v_COUNTRYCODE_t countryCode;
98} CountryInfo_t;
99// structure of table to map country code and regulatory domain
100typedef struct
101{
102 v_U16_t countryCount;
103 CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
104} CountryInfoTable_t;
105/*----------------------------------------------------------------------------
106 * Global Data Definitions
107 * -------------------------------------------------------------------------*/
108/*----------------------------------------------------------------------------
109 * Static Variable Definitions
110 * -------------------------------------------------------------------------*/
111// cache of country info table;
112// this is re-initialized from data on binary file
113// loaded on driver initialization if available
114static CountryInfoTable_t countryInfoTable =
115{
116 254,
117 {
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700118 { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code
119 { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA
120 { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
121 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN
122 { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA
123 { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA
Yue Ma4f433fd2013-06-10 10:52:22 -0700124 { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700125 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA
126 { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
127 { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA
128 { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA
129 { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA
130 { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
131 { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
Madan Mohan Koyyalamudi04f638b2013-07-16 20:19:08 +0530132 { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700133 { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA
134 { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS
135 { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN
136 { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
137 { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS
Yue Ma4a9d1232013-07-10 11:18:57 -0700138 { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700139 { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM
140 { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO
141 { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
142 { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN
143 { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI
144 { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN
145 { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
146 { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM
147 { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA
148 { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL
149 { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS
150 { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN
151 { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND
152 { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA
153 { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
154 { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE
155 { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
156 { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS
157 { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE
158 { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC
159 { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO
160 { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
161 { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE
162 { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS
163 { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE
164 { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON
Gopichand Nakkalad2e1f292013-04-23 18:36:17 +0530165 { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700166 { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA
167 { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA
168 { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA
169 { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE
170 { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND
171 { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
172 { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
173 { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
174 { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI
175 { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
176 { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA
177 { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC
Yue Ma4f433fd2013-06-10 10:52:22 -0700178 { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700179 { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR
180 { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
181 { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT
182 { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA
183 { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA
184 { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
185 { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA
186 { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI)
187 { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
188 { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI
189 { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS)
190 { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF
191 { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS
192 { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
193 { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON
194 { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
195 { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA
196 { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
197 { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
198 { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY
199 { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA
200 { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR
201 { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
202 { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA
203 { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA
204 { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
205 { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA
206 { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
207 { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
208 { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA
Yue Ma4f433fd2013-06-10 10:52:22 -0700209 { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700210 { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU
211 { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA
212 { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG
213 { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS
214 { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS
215 { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA
216 { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI
217 { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
218 { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA
219 { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
Yue Ma4f433fd2013-06-10 10:52:22 -0700220 { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700221 { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN
222 { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA
223 { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY
224 { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ
225 { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
226 { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND
227 { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
228 { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1
229 { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2
230 { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3
231 { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4
232 { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5
233 { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY
234 { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA
Yue Ma4f433fd2013-06-10 10:52:22 -0700235 { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700236 { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
237 { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1
238 { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2
239 { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3
240 { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4
Yue Ma4a9d1232013-07-10 11:18:57 -0700241 { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700242 { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN
243 { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
244 { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI
245 { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS
246 { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS
247 { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF
248 { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF
249 { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT
250 { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS
Yue Ma4f433fd2013-06-10 10:52:22 -0700251 { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700252 { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC
Yue Ma4a9d1232013-07-10 11:18:57 -0700253 { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700254 { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA
255 { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
256 { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA
257 { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA
258 { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO
259 { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
260 { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
261 { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA
262 { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA
Yue Ma4f433fd2013-06-10 10:52:22 -0700263 { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO
Yue Ma4a9d1232013-07-10 11:18:57 -0700264 { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700265 { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF
266 { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO
267 { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR
268 { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS
269 { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
270 { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI
271 { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR
Yue Ma37b074b2013-06-19 10:36:42 -0700272 { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700273 { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO
274 { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
275 { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
276 { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA
277 { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT
278 { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA
279 { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
280 { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES
281 { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI
282 { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO
283 { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA
284 { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE
285 { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA
286 { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA
287 { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER
288 { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND
289 { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA
290 { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA
291 { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
292 { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700293 { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700294 { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU
295 { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE
296 { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND
Yue Ma4a9d1232013-07-10 11:18:57 -0700297 { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700298 { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA
Yue Ma4f433fd2013-06-10 10:52:22 -0700299 { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700300 { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
Yue Ma4a9d1232013-07-10 11:18:57 -0700301 { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA
302 { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700303 { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN
304 { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
305 { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON
306 { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN
307 { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
308 { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
309 { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
310 { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU
311 { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY
312 { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR
313 { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
314 { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA
315 { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700316 { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA
317 { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA
318 { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700319 { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS
320 { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES
321 { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN
322 { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
323 { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE
324 { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA
325 { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
326 { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN
327 { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
328 { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE
329 { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO
330 { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL
331 { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA
332 { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME
333 { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE
334 { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR
335 { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
336 { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND
337 { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS
338 { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD
339 { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES
340 { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO
341 { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND
342 { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN
343 { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU
344 { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE
345 { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN
346 { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA
347 { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA
Yue Ma4a9d1232013-07-10 11:18:57 -0700348 { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700349 { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO
350 { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU
Yue Ma4f433fd2013-06-10 10:52:22 -0700351 { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700352 { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
Yue Ma4f433fd2013-06-10 10:52:22 -0700353 { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE
354 { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700355 { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS
356 { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY
Yue Ma4f433fd2013-06-10 10:52:22 -0700357 { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700358 { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE)
359 { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES
360 { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA
361 { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH
362 { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
Yue Ma4a9d1232013-07-10 11:18:57 -0700363 { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM
Madan Mohan Koyyalamudi00ff26d2012-11-02 13:33:26 -0700364 { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU
365 { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA
366 { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA
367 { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN
368 { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
369 { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA
370 { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA
Yue Ma4f433fd2013-06-10 10:52:22 -0700371 { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373};
374typedef struct nvEFSTable_s
375{
376 v_U32_t nvValidityBitmap;
377 sHalNv halnv;
378} nvEFSTable_t;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700379nvEFSTable_t *gnvEFSTable;
Jeff Johnson295189b2012-06-20 16:38:30 -0700380/* EFS Table to send the NV structure to HAL*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700381static nvEFSTable_t *pnvEFSTable;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700382static v_U8_t *pnvEncodedBuf;
383static v_U8_t *pDictFile;
384static v_U8_t *pEncodedBuf;
385static v_SIZE_t nvReadEncodeBufSize;
386static v_SIZE_t nDictionarySize;
387static v_U32_t magicNumber;
Jeff Johnson295189b2012-06-20 16:38:30 -0700388
389const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
390{
391 //RF_SUBBAND_2_4_GHZ
392 //freq, chan#, band
393 { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1,
394 { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2,
395 { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3,
396 { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4,
397 { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5,
398 { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6,
399 { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7,
400 { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8,
401 { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9,
402 { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10,
403 { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11,
404 { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12,
405 { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
406 { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700407 { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
408 { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
409 { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
410 { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
411 { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
412 { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
413 { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
415 { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
416 { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
417 { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48,
418 { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52,
419 { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56,
420 { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60,
421 { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64,
422 { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100,
423 { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104,
424 { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108,
425 { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112,
426 { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116,
427 { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120,
428 { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124,
429 { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128,
430 { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132,
431 { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136,
432 { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140,
433 { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149,
434 { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153,
435 { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
436 { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
437 { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700438 { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
439 { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
440 { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
441 { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
442 { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
443 { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
444 { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
445 { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
446 { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
447 { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
448 { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
449 { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
450 { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
451 { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
452 { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
453 { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
454 { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
455 { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
456 { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
457 { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
458 { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
459 { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
460 { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
461 { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
462 { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
463 { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
464 { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
465 { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
466 { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
467 { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
468 { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
469 { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
470 { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
471 { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
472 { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
Jeff Johnson295189b2012-06-20 16:38:30 -0700473};
474
475extern const sHalNv nvDefaults;
476
477const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
478
479/*----------------------------------------------------------------------------
480 Function Definitions and Documentation
481 * -------------------------------------------------------------------------*/
482VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
483/**------------------------------------------------------------------------
484 \brief vos_nv_init() - initialize the NV module
485 The \a vos_nv_init() initializes the NV module. This read the binary
486 file for country code and regulatory domain information.
487 \return VOS_STATUS_SUCCESS - module is initialized successfully
488 otherwise - module is not initialized
489 \sa
490 -------------------------------------------------------------------------*/
491VOS_STATUS vos_nv_init(void)
492{
493 return VOS_STATUS_SUCCESS;
494}
495
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700496/**------------------------------------------------------------------------
497 \brief vos_nv_get_dictionary_data() - get the dictionary data required for
498 \ tools
499 \return VOS_STATUS_SUCCESS - dictionary data is read successfully
500 otherwise - not successful
501 \sa
502-------------------------------------------------------------------------*/
503VOS_STATUS vos_nv_get_dictionary_data(void)
504{
505 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
506
507 if (MAGIC_NUMBER != magicNumber)
508 {
509 return VOS_STATUS_SUCCESS;
510 }
511
512 nDictionarySize = 0;
513
514 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
515 &nDictionarySize );
516 if (VOS_STATUS_E_NOMEM != vosStatus)
517 {
518 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
519 "Error obtaining binary size" );
520/// NOTE:
521/// We can still work without a dictionary file..
522 return VOS_STATUS_SUCCESS;
523 }
524
525 // malloc a buffer to read in the Configuration binary file.
526 pDictFile = vos_mem_malloc( nDictionarySize );
527 if (NULL == pDictFile)
528 {
529 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
530 "Unable to allocate memory for the CFG binary [size= %d bytes]",
531 nDictionarySize );
532 vosStatus = VOS_STATUS_E_NOMEM;
533 goto fail;
534 }
535
536 /* Get the entire CFG file image... */
537 vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
538 &nDictionarySize );
539 if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
540 {
541 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
542 "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
543 nDictionarySize );
544 return VOS_STATUS_SUCCESS;
545 }
546
547 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
548 "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
549
550fail:
551 return vosStatus;
552}
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554VOS_STATUS vos_nv_open(void)
555{
556 VOS_STATUS status = VOS_STATUS_SUCCESS;
557 v_CONTEXT_t pVosContext= NULL;
558 v_SIZE_t bufSize;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700559 v_SIZE_t nvReadBufSize;
Jeff Johnson295189b2012-06-20 16:38:30 -0700560 v_BOOL_t itemIsValid = VOS_FALSE;
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700561 v_U32_t dataOffset;
562 sHalNv *pnvData = NULL;
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564 /*Get the global context */
565 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700566
567 if (NULL == pVosContext)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800568 {
569 return (eHAL_STATUS_FAILURE);
570 }
571
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 bufSize = sizeof(nvEFSTable_t);
573 status = hdd_request_firmware(WLAN_NV_FILE,
574 ((VosContextType*)(pVosContext))->pHDDContext,
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700575 (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700576
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700577 if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
Jeff Johnson295189b2012-06-20 16:38:30 -0700578 {
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700579 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700580 "%s: unable to download NV file %s",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700581 __func__, WLAN_NV_FILE);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700582 return VOS_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 }
584
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700585 memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
586
587 /// Allocate buffer with maximum length..
588 pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
589
590 if (NULL == pEncodedBuf)
591 {
592 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
593 "%s : failed to allocate memory for NV", __func__);
594 return VOS_STATUS_E_NOMEM;
595 }
596
597 gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
598
599 if (MAGIC_NUMBER == magicNumber)
600 {
601 pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
602
603 if (NULL == pnvData)
604 {
605 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
606 "%s : failed to allocate memory for NV", __func__);
607 return VOS_STATUS_E_NOMEM;
608 }
609
610 memset(pnvData, 0, sizeof(sHalNv));
611
612 /// Data starts from offset of validity bit map + magic number..
613 dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
614
615 status = nvParser(&pnvEncodedBuf[dataOffset],
616 (nvReadBufSize-dataOffset), pnvData);
617
618 ///ignore validity bit map
619 nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
620
621 vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
622 nvReadEncodeBufSize);
623
624 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
625 "readEncodeBufSize %d",nvReadEncodeBufSize);
626
627 if (VOS_STATUS_SUCCESS == status) {
628 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
629 "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
630 pnvData->fields.productId,
631 pnvData->fields.couplerType,
632 pnvData->fields.wlanNvRevId);
633
634 vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
635
636 nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
637 }
638 else
639 {
640 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
641 "nvParser failed %d",status);
642
643 nvReadBufSize = 0;
644
645 vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
646
647 nvReadEncodeBufSize = sizeof(sHalNv);
648 }
649 }
650 else
651 {
652 dataOffset = sizeof(v_U32_t);
653 nvReadEncodeBufSize = sizeof(sHalNv);
654 memcpy(pEncodedBuf, &pnvEncodedBuf[dataOffset], nvReadEncodeBufSize);
655 }
656
657 if (NULL != pnvData)
658 {
659 vos_mem_free(pnvData);
660 }
661
662 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800663 "INFO: NV binary file version=%d Driver default NV version=%d, continue...\n",
664 gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
665
Jeff Johnson295189b2012-06-20 16:38:30 -0700666 /* Copying the read nv data to the globa NV EFS table */
667 {
668 /* Allocate memory to global NV table */
669 pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700670 if ( NULL == pnvEFSTable )
Jeff Johnson295189b2012-06-20 16:38:30 -0700671 {
672 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700673 "%s : failed to allocate memory for NV", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 return VOS_STATUS_E_NOMEM;
675 }
676
677 /*Copying the NV defaults */
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700678 vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800679
680 /* Size mismatch */
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700681 if ( nvReadBufSize != bufSize)
682 {
683 pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP;
684 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
685 "!!!WARNING: INVALID NV FILE, DRIVER IS USING DEFAULT CAL VALUES %d %d!!!",
686 nvReadBufSize, bufSize);
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800687 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700688 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700689
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800690 /* Version mismatch */
691 if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION)
692 {
693 if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) &&
694 (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE))
695 {
696 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
697 "!!!WARNING: Using Coupler Type field instead of Fw Config table,\n"
698 "Make sure that this is intented or may impact performance!!!\n");
699 }
700 else
701 {
702 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
703 "!!!WARNING: NV binary file version doesn't match with Driver default NV version\n"
704 "Driver NV defaults will be used, may impact performance!!!\n");
705
706 return VOS_STATUS_SUCCESS;
707 }
708 }
709
Madan Mohan Koyyalamudi1dd5c882012-09-24 13:31:39 -0700710 pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Copy the valid fields to the NV Global structure */
712 if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
713 VOS_STATUS_SUCCESS)
714 {
715 if (itemIsValid == VOS_TRUE) {
716
717 if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields,
718 NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800719 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700720 }
721 }
722
723 if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
724 VOS_STATUS_SUCCESS)
725 {
726 if (itemIsValid == VOS_TRUE)
727 {
728 if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
729 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
730 NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800731 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700732 }
733 }
734
735 if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
736 VOS_STATUS_SUCCESS)
737 {
738
739 if (itemIsValid == VOS_TRUE)
740 {
741 if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
742 (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0],
743 NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800744 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700745 }
746 }
747
748 if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
749 VOS_STATUS_SUCCESS)
750 {
751 if (itemIsValid == VOS_TRUE)
752 {
753 if(vos_nv_read( VNV_DEFAULT_LOCATION,
754 (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable,
755 NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800756 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 }
758 }
759
760 if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
761 VOS_STATUS_SUCCESS)
762 {
763 if (itemIsValid == VOS_TRUE)
764 {
765 if(vos_nv_read( VNV_TPC_POWER_TABLE,
766 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
767 NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800768 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700769 }
770 }
771
772 if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
773 VOS_STATUS_SUCCESS)
774 {
775 if (itemIsValid == VOS_TRUE)
776 {
777 if(vos_nv_read( VNV_TPC_PDADC_OFFSETS,
778 (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0],
779 NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800780 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 }
782 }
783 if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
784 VOS_STATUS_SUCCESS)
785 {
786 if (itemIsValid == VOS_TRUE)
787 {
788 if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS,
789 (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0],
790 NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800791 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 }
793 }
794
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800795 if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 VOS_STATUS_SUCCESS)
797 {
798 if (itemIsValid == VOS_TRUE)
799 {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -0800800 if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv
801 .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS)
802 goto error;
803 }
804 }
805
806 if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
807 VOS_STATUS_SUCCESS)
808 {
809 if (itemIsValid == VOS_TRUE)
810 {
811 if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv
812 .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800813 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700814 }
815 }
816
817 if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
818 VOS_STATUS_SUCCESS)
819 {
820 if (itemIsValid == VOS_TRUE)
821 {
822 if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
823 (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
824 sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800825 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 }
827 }
828 if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
829 VOS_STATUS_SUCCESS)
830 {
831 if (itemIsValid == VOS_TRUE)
832 {
833 if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
834 (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
835 sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800836 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 }
838 }
839
840 if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
841 VOS_STATUS_SUCCESS)
842 {
843 if (itemIsValid == VOS_TRUE)
844 {
845 if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
846 (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
847 sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800848 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700849 }
850 }
851
852 if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
853 VOS_STATUS_SUCCESS)
854 {
855 if (itemIsValid == VOS_TRUE)
856 {
857 if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
858 (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
859 sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800860 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 }
862 }
863 if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
864 VOS_STATUS_SUCCESS)
865 {
866 if (itemIsValid == VOS_TRUE)
867 {
868 if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
869 (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
870 sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800871 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 }
873 }
874 }
875
876 return VOS_STATUS_SUCCESS;
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800877error:
878 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700879 vos_mem_free(pEncodedBuf);
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -0800880 return eHAL_STATUS_FAILURE ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700881}
882
883VOS_STATUS vos_nv_close(void)
884{
885 VOS_STATUS status = VOS_STATUS_SUCCESS;
886 v_CONTEXT_t pVosContext= NULL;
887 /*Get the global context */
888 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
889 status = hdd_release_firmware(WLAN_NV_FILE, ((VosContextType*)(pVosContext))->pHDDContext);
890 if ( !VOS_IS_STATUS_SUCCESS( status ))
891 {
892 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
893 "%s : vos_open failed\n",__func__);
894 return VOS_STATUS_E_FAILURE;
895 }
896 vos_mem_free(pnvEFSTable);
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -0700897 vos_mem_free(pEncodedBuf);
898 vos_mem_free(pDictFile);
899
Jeff Johnson295189b2012-06-20 16:38:30 -0700900 gnvEFSTable=NULL;
901 return VOS_STATUS_SUCCESS;
902}
903/**------------------------------------------------------------------------
904 \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
905 a country given its country code
906 The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
907 a country given its country code. This is done from reading a cached
908 copy of the binary file.
909 \param pRegDomain - pointer to regulatory domain
910 \param countryCode - country code
911 \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
912 VOS_STATUS_E_FAULT - invalid pointer error
913 VOS_STATUS_E_EMPTY - country code table is empty
914 VOS_STATUS_E_EXISTS - given country code does not exist in table
915 \sa
916 -------------------------------------------------------------------------*/
917VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
918 const v_COUNTRYCODE_t countryCode )
919{
920 int i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700921 v_CONTEXT_t pVosContext = NULL;
922 hdd_context_t *pHddCtx = NULL;
923 struct wiphy *wiphy = NULL;
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530924 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700925 // sanity checks
926 if (NULL == pRegDomain)
927 {
928 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
929 ("Invalid reg domain pointer\r\n") );
930 return VOS_STATUS_E_FAULT;
931 }
932 *pRegDomain = REGDOMAIN_COUNT;
933
934 if (NULL == countryCode)
935 {
936 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
937 ("Country code array is NULL\r\n") );
938 return VOS_STATUS_E_FAULT;
939 }
940 if (0 == countryInfoTable.countryCount)
941 {
942 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
943 ("Reg domain table is empty\r\n") );
944 return VOS_STATUS_E_EMPTY;
945 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700946 /* If CRDA regulatory settings is valid, i.e. crda is enabled
947 and reg_notifier is called back.
948 Intercept here and redirect to the Reg domain table's CRDA
949 entry if country code is crda's country.
950 last one NUM_REG_DOMAINS-1 is reserved for crda */
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800951 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700952 "vos_nv_getRegDomainFromCountryCode %c%c\n",
953 countryCode[0], countryCode[1]);
954
955 if (crda_regulatory_entry_valid == VOS_TRUE)
956 {
957 if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
958 {
959 *pRegDomain = NUM_REG_DOMAINS-1;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800960 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700961 "vos_nv_getRegDomainFromCountryCode return crda init entry\n");
962 return VOS_STATUS_SUCCESS;
963 }
964 if (run_time_alpha2[0]==countryCode[0] &&
965 run_time_alpha2[1]==countryCode[1] &&
966 crda_regulatory_run_time_entry_valid == VOS_TRUE)
967 {
968 *pRegDomain = NUM_REG_DOMAINS-2;
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -0800969 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700970 "vos_nv_getRegDomainFromCountryCode return crda none-default country entry\n");
971 return VOS_STATUS_SUCCESS;
972 }
973 else
974 {
975 crda_regulatory_run_time_entry_valid = VOS_FALSE;
976 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
977 if (NULL != pVosContext)
978 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
979 else
980 return VOS_STATUS_E_EXISTS;
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700981 if (NULL == pHddCtx)
982 {
983 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
984 ("Invalid pHddCtx pointer\r\n") );
985 return VOS_STATUS_E_FAULT;
986 }
987
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700988 wiphy = pHddCtx->wiphy;
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530989 INIT_COMPLETION(pHddCtx->driver_crda_req);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700990 regulatory_hint(wiphy, countryCode);
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530991 status = wait_for_completion_interruptible_timeout(
992 &pHddCtx->driver_crda_req,
993 msecs_to_jiffies(CRDA_WAIT_TIME));
994 if (!status)
995 {
996 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
997 "%s: Timeout waiting for CRDA REQ", __func__);
998 }
999
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001000 if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
1001 {
Madan Mohan Koyyalamudi2502e682012-12-06 13:02:53 -08001002 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001003 "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry\n");
1004 return VOS_STATUS_SUCCESS;
1005 }
1006 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1007 "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry\n");
1008 return VOS_STATUS_E_EXISTS;
1009 }
1010 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001011
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 // iterate the country info table until end of table or the country code
1013 // is found
1014 for (i = 0; i < countryInfoTable.countryCount &&
1015 REGDOMAIN_COUNT == *pRegDomain; i++)
1016 {
1017 if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
1018 VOS_COUNTRY_CODE_LEN) == 0)
1019 {
1020 // country code is found
1021 *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
1022 }
1023 }
1024 if (REGDOMAIN_COUNT != *pRegDomain)
1025 {
1026 return VOS_STATUS_SUCCESS;
1027 }
1028 else
1029 {
1030 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1031 ("country code is not found\r\n"));
1032 return VOS_STATUS_E_EXISTS;
1033 }
1034}
1035/**------------------------------------------------------------------------
1036 \brief vos_nv_getSupportedCountryCode() - get the list of supported
1037 country codes
1038 The \a vos_nv_getSupportedCountryCode() encodes the list of supported
1039 country codes with paddings in the provided buffer
1040 \param pBuffer - pointer to buffer where supported country codes
1041 and paddings are encoded; this may be set to NULL
1042 if user wishes to query the required buffer size to
1043 get the country code list
1044 \param pBufferSize - this is the provided buffer size on input;
1045 this is the required or consumed buffer size on output
1046 \return VOS_STATUS_SUCCESS - country codes are successfully encoded
1047 VOS_STATUS_E_NOMEM - country codes are not encoded because either
1048 the buffer is NULL or buffer size is
1049 sufficient
1050 \sa
1051 -------------------------------------------------------------------------*/
1052VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
1053 v_SIZE_t paddingSize )
1054{
1055 v_SIZE_t providedBufferSize = *pBufferSize;
1056 int i;
1057 // pBufferSize now points to the required buffer size
1058 *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize );
1059 if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
1060 {
1061 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1062 ("Insufficient memory for country code list\r\n"));
1063 return VOS_STATUS_E_NOMEM;
1064 }
1065 for (i = 0; i < countryInfoTable.countryCount; i++)
1066 {
1067 memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN );
1068 pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize );
1069 }
1070 return VOS_STATUS_SUCCESS;
1071}
1072/**------------------------------------------------------------------------
1073 \brief vos_nv_readTxAntennaCount() - return number of TX antenna
1074 \param pTxAntennaCount - antenna count
1075 \return status of the NV read operation
1076 \sa
1077 -------------------------------------------------------------------------*/
1078VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount )
1079{
1080 sNvFields fieldImage;
1081 VOS_STATUS status;
1082 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1083 sizeof(fieldImage) );
1084 if (VOS_STATUS_SUCCESS == status)
1085 {
1086 *pTxAntennaCount = fieldImage.numOfTxChains;
1087 }
1088 return status;
1089}
1090/**------------------------------------------------------------------------
1091 \brief vos_nv_readRxAntennaCount() - return number of RX antenna
1092 \param pRxAntennaCount - antenna count
1093 \return status of the NV read operation
1094 \sa
1095 -------------------------------------------------------------------------*/
1096VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount )
1097{
1098 sNvFields fieldImage;
1099 VOS_STATUS status;
1100 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1101 sizeof(fieldImage) );
1102 if (VOS_STATUS_SUCCESS == status)
1103 {
1104 *pRxAntennaCount = fieldImage.numOfRxChains;
1105 }
1106 return status;
1107}
1108
1109/**------------------------------------------------------------------------
1110 \brief vos_nv_readMacAddress() - return the MAC address
1111 \param pMacAddress - MAC address
1112 \return status of the NV read operation
1113 \sa
1114 -------------------------------------------------------------------------*/
1115VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress )
1116{
1117 sNvFields fieldImage;
1118 VOS_STATUS status;
1119 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1120 sizeof(fieldImage) );
1121 if (VOS_STATUS_SUCCESS == status)
1122 {
1123 memcpy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN );
1124 }
1125 else
1126 {
1127 //This part of the code can be removed when NV is programmed
1128 const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC;
1129 memcpy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN );
1130 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1131 " fail to get MAC address from NV, hardcoded to %02X-%02X-%02X-%02X-%02X%02X",
1132 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
1133 status = VOS_STATUS_SUCCESS;
1134 }
1135 return status;
1136}
1137
1138/**------------------------------------------------------------------------
1139
1140 \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses
1141
1142 \param pMacAddress - MAC address
1143 \param macCount - Count of valid MAC addresses to get from NV field
1144
1145 \return status of the NV read operation
1146
1147 \sa
1148
1149 -------------------------------------------------------------------------*/
1150VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress,
1151 v_U8_t macCount )
1152{
1153 sNvFields fieldImage;
1154 VOS_STATUS status;
1155 v_U8_t countLoop;
1156 v_U8_t *pNVMacAddress;
1157
1158 if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) ||
1159 (NULL == pMacAddress))
1160 {
1161 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301162 " Invalid Parameter from NV Client macCount %d, pMacAddress %p",
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 macCount, pMacAddress);
1164 }
1165
1166 status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL,
1167 sizeof(fieldImage) );
1168 if (VOS_STATUS_SUCCESS == status)
1169 {
1170 pNVMacAddress = fieldImage.macAddr;
1171 for(countLoop = 0; countLoop < macCount; countLoop++)
1172 {
1173 vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1174 pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN),
1175 VOS_MAC_ADDRESS_LEN);
1176 }
1177 }
1178 else
1179 {
1180 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1181 "vos_nv_readMultiMacAddress Get NV Field Fail");
1182 }
1183
1184 return status;
1185}
1186
1187/**------------------------------------------------------------------------
1188 \brief vos_nv_setValidity() - set the validity of an NV item.
1189 The \a vos_nv_setValidity() validates and invalidates an NV item. The
1190 validity information is stored in NV memory.
1191 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1192 An item becomes valid when one has written to it successfully.
1193 \param type - NV item type
1194 \param itemIsValid - boolean value indicating the item's validity
1195 \return VOS_STATUS_SUCCESS - validity is set successfully
1196 VOS_STATUS_E_INVAL - one of the parameters is invalid
1197 VOS_STATUS_E_FAILURE - unknown error
1198 \sa
1199 -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001200
1201VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid )
1202{
1203 v_U32_t lastNvValidityBitmap;
1204 v_U32_t newNvValidityBitmap;
1205 VOS_STATUS status = VOS_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07001206
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001208 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 {
1210 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001211 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 return VOS_STATUS_E_INVAL;
1213 }
1214 // read the validity bitmap
1215 lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1216 // modify the validity bitmap
1217 if (itemIsValid)
1218 {
1219 newNvValidityBitmap = lastNvValidityBitmap | (1 << type);
1220 // commit to NV store if bitmap has been modified
1221 if (newNvValidityBitmap != lastNvValidityBitmap)
1222 {
1223 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1224 }
1225 }
1226 else
1227 {
1228 newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type));
1229 if (newNvValidityBitmap != lastNvValidityBitmap)
1230 {
1231 gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
1232 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1233 if (! VOS_IS_STATUS_SUCCESS(status)) {
1234 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1235 status = VOS_STATUS_E_FAULT;
1236 }
1237 }
1238 }
1239
1240 return status;
1241}
Jeff Johnson295189b2012-06-20 16:38:30 -07001242/**------------------------------------------------------------------------
1243 \brief vos_nv_getValidity() - get the validity of an NV item.
1244 The \a vos_nv_getValidity() indicates if an NV item is valid. The
1245 validity information is stored in NV memory.
1246 One would get the VOS_STATUS_E_EXISTS error when reading an invalid item.
1247 An item becomes valid when one has written to it successfully.
1248 \param type - NV item type
1249 \param pItemIsValid- pointer to the boolean value indicating the item's
1250 validity
1251 \return VOS_STATUS_SUCCESS - validity is determined successfully
1252 VOS_STATUS_E_INVAL - one of the parameters is invalid
1253 VOS_STATUS_E_FAILURE - unknown error
1254 \sa
1255 -------------------------------------------------------------------------*/
1256VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid )
1257{
1258 v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
1259 // check if the current NV type is valid
Jeff Johnson43971f52012-07-17 12:26:56 -07001260 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001261 {
1262 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001263 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001264 return VOS_STATUS_E_INVAL;
1265 }
1266 *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1);
1267 return VOS_STATUS_SUCCESS;
1268}
1269/**------------------------------------------------------------------------
1270 \brief vos_nv_read() - read a NV item to an output buffer
1271 The \a vos_nv_read() reads a NV item to an output buffer. If the item is
1272 an array, this function would read the entire array. One would get a
1273 VOS_STATUS_E_EXISTS error when reading an invalid item.
1274 For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE,
1275 if a default buffer is provided (with a non-NULL value),
1276 the default buffer content is copied to the output buffer.
1277 \param type - NV item type
1278 \param outputBuffer - output buffer
1279 \param defaultBuffer - default buffer
1280 \param bufferSize - output buffer size
1281 \return VOS_STATUS_SUCCESS - NV item is read successfully
1282 VOS_STATUS_E_INVAL - one of the parameters is invalid
1283 VOS_STATUS_E_FAULT - defaultBuffer point is NULL
1284 VOS_STATUS_E_EXISTS - NV type is unsupported
1285 VOS_STATUS_E_FAILURE - unknown error
1286 \sa
1287 -------------------------------------------------------------------------*/
1288VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer,
1289 v_VOID_t *defaultBuffer, v_SIZE_t bufferSize )
1290{
1291 VOS_STATUS status = VOS_STATUS_SUCCESS;
1292 v_SIZE_t itemSize;
1293 v_BOOL_t itemIsValid = VOS_TRUE;
1294
1295 // sanity check
Jeff Johnson43971f52012-07-17 12:26:56 -07001296 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 {
1298 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001299 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 return VOS_STATUS_E_INVAL;
1301 }
1302 if (NULL == outputVoidBuffer)
1303 {
1304 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1305 ("Buffer provided is NULL\r\n") );
1306 return VOS_STATUS_E_FAULT;
1307 }
1308 if (0 == bufferSize)
1309 {
1310 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1311 ("NV type=%d is invalid\r\n"), type );
1312 return VOS_STATUS_E_INVAL;
1313 }
1314 // check if the NV item has valid data
1315 status = vos_nv_getValidity( type, &itemIsValid );
1316 if (!itemIsValid)
1317 {
1318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1319 "NV type=%d does not have valid data\r\n", type );
1320 return VOS_STATUS_E_EMPTY;
1321 }
1322 switch(type)
1323 {
1324 case VNV_FIELD_IMAGE:
1325 itemSize = sizeof(gnvEFSTable->halnv.fields);
1326 if(bufferSize != itemSize) {
1327 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1328 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1329 itemSize);
1330 status = VOS_STATUS_E_INVAL;
1331 }
1332 else {
1333 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize);
1334 }
1335 break;
1336 case VNV_RATE_TO_POWER_TABLE:
1337 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1338 if(bufferSize != itemSize) {
1339 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1340 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1341 itemSize);
1342 status = VOS_STATUS_E_INVAL;
1343 }
1344 else {
1345 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize);
1346 }
1347 break;
1348 case VNV_REGULARTORY_DOMAIN_TABLE:
1349 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1350 if(bufferSize != itemSize) {
1351 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1352 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1353 itemSize);
1354 status = VOS_STATUS_E_INVAL;
1355 }
1356 else {
1357 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize);
1358 }
1359 break;
1360 case VNV_DEFAULT_LOCATION:
1361 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1362 if(bufferSize != itemSize) {
1363 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1364 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1365 itemSize);
1366 status = VOS_STATUS_E_INVAL;
1367 }
1368 else {
1369 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize);
1370 }
1371 break;
1372 case VNV_TPC_POWER_TABLE:
1373 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1374 if(bufferSize != itemSize) {
1375 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1376 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1377 itemSize);
1378 status = VOS_STATUS_E_INVAL;
1379 }
1380 else {
1381 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize);
1382 }
1383 break;
1384 case VNV_TPC_PDADC_OFFSETS:
1385 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1386 if(bufferSize != itemSize) {
1387 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1388 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1389 itemSize);
1390 status = VOS_STATUS_E_INVAL;
1391 }
1392 else {
1393 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize);
1394 }
1395 break;
1396 case VNV_RSSI_CHANNEL_OFFSETS:
1397
1398 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1399
1400 if(bufferSize != itemSize) {
1401
1402 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1403 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1404 itemSize);
1405 status = VOS_STATUS_E_INVAL;
1406 }
1407 else {
1408 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize);
1409 }
1410 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001411 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001412
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001413 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001414
1415 if(bufferSize != itemSize) {
1416
1417 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1418 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1419 itemSize);
1420 status = VOS_STATUS_E_INVAL;
1421 }
1422 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001423 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize);
1424 }
1425 break;
1426 case VNV_FW_CONFIG:
1427
1428 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
1429
1430 if(bufferSize != itemSize) {
1431
1432 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1433 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1434 itemSize);
1435 status = VOS_STATUS_E_INVAL;
1436 }
1437 else {
1438 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 }
1440 break;
1441 case VNV_ANTENNA_PATH_LOSS:
1442 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1443 if(bufferSize != itemSize) {
1444 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1445 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1446 itemSize);
1447 status = VOS_STATUS_E_INVAL;
1448 }
1449 else {
1450 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize);
1451 }
1452 break;
1453 case VNV_PACKET_TYPE_POWER_LIMITS:
1454 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1455 if(bufferSize != itemSize) {
1456 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1457 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1458 itemSize);
1459 status = VOS_STATUS_E_INVAL;
1460 }
1461 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001462 memcpy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 }
1464 break;
1465 case VNV_OFDM_CMD_PWR_OFFSET:
1466 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1467 if(bufferSize != itemSize) {
1468 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1469 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1470 itemSize);
1471 status = VOS_STATUS_E_INVAL;
1472 }
1473 else {
1474 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize);
1475 }
1476 break;
1477 case VNV_TX_BB_FILTER_MODE:
1478 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1479 if(bufferSize != itemSize) {
1480 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1481 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1482 itemSize);
1483 status = VOS_STATUS_E_INVAL;
1484 }
1485 else {
1486 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize);
1487 }
1488 break;
1489
Jeff Johnson295189b2012-06-20 16:38:30 -07001490
1491 case VNV_TABLE_VIRTUAL_RATE:
1492 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1493 if(bufferSize != itemSize) {
1494 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1495 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1496 itemSize);
1497 status = VOS_STATUS_E_INVAL;
1498 }
1499 else {
1500 memcpy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize);
1501 }
1502 break;
1503
1504 default:
1505 break;
1506 }
1507 return status;
1508}
Jeff Johnson295189b2012-06-20 16:38:30 -07001509
1510/**------------------------------------------------------------------------
1511 \brief vos_nv_write() - write to a NV item from an input buffer
1512 The \a vos_nv_write() writes to a NV item from an input buffer. This would
1513 validate the NV item if the write operation is successful.
1514 \param type - NV item type
1515 \param inputBuffer - input buffer
1516 \param inputBufferSize - input buffer size
1517 \return VOS_STATUS_SUCCESS - NV item is read successfully
1518 VOS_STATUS_E_INVAL - one of the parameters is invalid
1519 VOS_STATUS_E_FAULT - outputBuffer pointer is NULL
1520 VOS_STATUS_E_EXISTS - NV type is unsupported
1521 VOS_STATUS_E_FAILURE - unknown error
1522 \sa
1523 -------------------------------------------------------------------------*/
1524VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputVoidBuffer,
1525 v_SIZE_t bufferSize )
1526{
1527 VOS_STATUS status = VOS_STATUS_SUCCESS;
1528 v_SIZE_t itemSize;
Jeff Johnson43971f52012-07-17 12:26:56 -07001529
1530 // sanity check
1531 if (VNV_TYPE_COUNT <= type)
Jeff Johnson295189b2012-06-20 16:38:30 -07001532 {
1533 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001534 ("%s: invalid type=%d"), __func__, type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 return VOS_STATUS_E_INVAL;
1536 }
1537 if (NULL == inputVoidBuffer)
1538 {
1539 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1540 ("Buffer provided is NULL\r\n") );
1541 return VOS_STATUS_E_FAULT;
1542 }
1543 if (0 == bufferSize)
1544 {
1545 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1546 ("NV type=%d is invalid\r\n"), type );
1547 return VOS_STATUS_E_INVAL;
1548 }
1549 switch(type)
1550 {
1551 case VNV_FIELD_IMAGE:
1552 itemSize = sizeof(gnvEFSTable->halnv.fields);
1553 if(bufferSize != itemSize) {
1554 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1555 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1556 itemSize);
1557 status = VOS_STATUS_E_INVAL;
1558 }
1559 else {
1560 memcpy(&gnvEFSTable->halnv.fields,inputVoidBuffer,bufferSize);
1561 }
1562 break;
1563 case VNV_RATE_TO_POWER_TABLE:
1564 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
1565 if(bufferSize != itemSize) {
1566 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1567 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1568 itemSize);
1569 status = VOS_STATUS_E_INVAL;
1570 }
1571 else {
1572 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum[0],inputVoidBuffer,bufferSize);
1573 }
1574 break;
1575 case VNV_REGULARTORY_DOMAIN_TABLE:
1576 itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
1577 if(bufferSize != itemSize) {
1578 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1579 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1580 itemSize);
1581 status = VOS_STATUS_E_INVAL;
1582 }
1583 else {
1584 memcpy(&gnvEFSTable->halnv.tables.regDomains[0],inputVoidBuffer,bufferSize);
1585 }
1586 break;
1587 case VNV_DEFAULT_LOCATION:
1588 itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
1589 if(bufferSize != itemSize) {
1590 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1591 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1592 itemSize);
1593 status = VOS_STATUS_E_INVAL;
1594 }
1595 else {
1596 memcpy(&gnvEFSTable->halnv.tables.defaultCountryTable,inputVoidBuffer,bufferSize);
1597 }
1598 break;
1599 case VNV_TPC_POWER_TABLE:
1600 itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
1601 if(bufferSize != itemSize) {
1602 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1603 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1604 itemSize);
1605 status = VOS_STATUS_E_INVAL;
1606 }
1607 else {
1608 memcpy(&gnvEFSTable->halnv.tables.plutCharacterized[0],inputVoidBuffer,bufferSize);
1609 }
1610 break;
1611 case VNV_TPC_PDADC_OFFSETS:
1612 itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
1613 if(bufferSize != itemSize) {
1614 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1615 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1616 itemSize);
1617 status = VOS_STATUS_E_INVAL;
1618 }
1619 else {
1620 memcpy(&gnvEFSTable->halnv.tables.plutPdadcOffset[0],inputVoidBuffer,bufferSize);
1621 }
1622 break;
1623 case VNV_RSSI_CHANNEL_OFFSETS:
1624
1625 itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets);
1626
1627 if(bufferSize != itemSize) {
1628
1629 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1630 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1631 itemSize);
1632 status = VOS_STATUS_E_INVAL;
1633 }
1634 else {
1635 memcpy(&gnvEFSTable->halnv.tables.rssiChanOffsets[0],inputVoidBuffer,bufferSize);
1636 }
1637 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001638 case VNV_HW_CAL_VALUES:
Jeff Johnson295189b2012-06-20 16:38:30 -07001639
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001640 itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues);
Jeff Johnson295189b2012-06-20 16:38:30 -07001641
1642 if(bufferSize != itemSize) {
1643
1644 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1645 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1646 itemSize);
1647 status = VOS_STATUS_E_INVAL;
1648 }
1649 else {
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001650 memcpy(&gnvEFSTable->halnv.tables.hwCalValues,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 }
1652 break;
Gopichand Nakkala90bcf7a2013-01-04 11:45:31 -08001653 case VNV_FW_CONFIG:
1654
1655 itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
1656
1657 if(bufferSize != itemSize) {
1658
1659 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1660 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1661 itemSize);
1662 status = VOS_STATUS_E_INVAL;
1663 }
1664 else {
1665 memcpy(&gnvEFSTable->halnv.tables.fwConfig,inputVoidBuffer,bufferSize);
1666 }
1667 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 case VNV_ANTENNA_PATH_LOSS:
1669 itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
1670 if(bufferSize != itemSize) {
1671 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1672 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1673 itemSize);
1674 status = VOS_STATUS_E_INVAL;
1675 }
1676 else {
1677 memcpy(&gnvEFSTable->halnv.tables.antennaPathLoss[0],inputVoidBuffer,bufferSize);
1678 }
1679 break;
1680
1681 case VNV_PACKET_TYPE_POWER_LIMITS:
1682 itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
1683 if(bufferSize != itemSize) {
1684 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1685 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1686 itemSize);
1687 status = VOS_STATUS_E_INVAL;
1688 }
1689 else {
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -07001690 memcpy(gnvEFSTable->halnv.tables.pktTypePwrLimits,inputVoidBuffer,bufferSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07001691 }
1692 break;
1693
1694 case VNV_OFDM_CMD_PWR_OFFSET:
1695 itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
1696 if(bufferSize != itemSize) {
1697 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1698 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1699 itemSize);
1700 status = VOS_STATUS_E_INVAL;
1701 }
1702 else {
1703 memcpy(&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,inputVoidBuffer,bufferSize);
1704 }
1705 break;
1706
1707 case VNV_TX_BB_FILTER_MODE:
1708 itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
1709 if(bufferSize != itemSize) {
1710 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1711 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1712 itemSize);
1713 status = VOS_STATUS_E_INVAL;
1714 }
1715 else {
1716 memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
1717 }
1718 break;
1719
Jeff Johnson295189b2012-06-20 16:38:30 -07001720
1721 case VNV_TABLE_VIRTUAL_RATE:
1722 itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
1723 if(bufferSize != itemSize) {
1724 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1725 ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
1726 itemSize);
1727 status = VOS_STATUS_E_INVAL;
1728 }
1729 else {
1730 memcpy(&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,inputVoidBuffer,bufferSize);
1731 }
1732 break;
1733
1734 default:
1735 break;
1736 }
1737 if (VOS_STATUS_SUCCESS == status)
1738 {
1739 // set NV item to have valid data
1740 status = vos_nv_setValidity( type, VOS_TRUE );
1741 if (! VOS_IS_STATUS_SUCCESS(status)) {
1742 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!\r\n"));
1743 status = VOS_STATUS_E_FAULT;
1744 }
1745 status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
1746
1747 if (! VOS_IS_STATUS_SUCCESS(status)) {
1748 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
1749 status = VOS_STATUS_E_FAULT;
1750 }
1751 }
1752 return status;
1753}
Venkata Prathyusha Kuntupalli9778fb32013-02-26 22:16:52 -08001754
Jeff Johnson295189b2012-06-20 16:38:30 -07001755/**------------------------------------------------------------------------
1756 \brief vos_nv_getChannelListWithPower() - function to return the list of
1757 supported channels with the power limit info too.
1758 \param pChannels20MHz - list of 20 Mhz channels
1759 \param pNum20MHzChannelsFound - number of 20 Mhz channels
1760 \param pChannels40MHz - list of 20 Mhz channels
1761 \param pNum40MHzChannelsFound - number of 20 Mhz channels
1762 \return status of the NV read operation
1763 \Note: 40Mhz not currently supported
1764 \sa
1765 -------------------------------------------------------------------------*/
1766VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */,
1767 tANI_U8 *num20MHzChannelsFound,
1768 tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */,
1769 tANI_U8 *num40MHzChannelsFound
1770 )
1771{
1772 VOS_STATUS status = VOS_STATUS_SUCCESS;
1773 int i, count;
1774
1775 //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
1776 // or pass it as a parameter to NV from SME?
1777
1778 if( channels20MHz && num20MHzChannelsFound )
1779 {
1780 count = 0;
1781 for( i = 0; i <= RF_CHAN_14; i++ )
1782 {
1783 if( regChannels[i].enabled )
1784 {
1785 channels20MHz[count].chanId = rfChannels[i].channelNum;
1786 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1787 }
1788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1790 {
1791 if( regChannels[i].enabled )
1792 {
1793 channels20MHz[count].chanId = rfChannels[i].channelNum;
1794 channels20MHz[count++].pwr = regChannels[i].pwrLimit;
1795 }
1796 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 *num20MHzChannelsFound = (tANI_U8)count;
1798 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001799
1800 if( channels40MHz && num40MHzChannelsFound )
1801 {
1802 count = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07001803 //center channels for 2.4 Ghz 40 MHz channels
1804 for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
1805 {
1806
1807 if( regChannels[i].enabled )
1808 {
1809 channels40MHz[count].chanId = rfChannels[i].channelNum;
1810 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1811 }
1812 }
1813 //center channels for 5 Ghz 40 MHz channels
1814 for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
1815 {
1816
1817 if( regChannels[i].enabled )
1818 {
1819 channels40MHz[count].chanId = rfChannels[i].channelNum;
1820 channels40MHz[count++].pwr = regChannels[i].pwrLimit;
1821 }
1822 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001823 *num40MHzChannelsFound = (tANI_U8)count;
1824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 return (status);
1826}
1827
1828/**------------------------------------------------------------------------
1829 \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain
1830 \return default regulatory domain
1831 \sa
1832 -------------------------------------------------------------------------*/
1833
1834v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void )
1835{
1836 return countryInfoTable.countryInfo[0].regDomain;
1837}
1838
1839/**------------------------------------------------------------------------
1840 \brief vos_nv_getSupportedChannels() - function to return the list of
1841 supported channels
1842 \param p20MhzChannels - list of 20 Mhz channels
1843 \param pNum20MhzChannels - number of 20 Mhz channels
1844 \param p40MhzChannels - list of 40 Mhz channels
1845 \param pNum40MhzChannels - number of 40 Mhz channels
1846 \return status of the NV read operation
1847 \Note: 40Mhz not currently supported
1848 \sa
1849 -------------------------------------------------------------------------*/
1850VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels,
1851 v_U8_t *p40MhzChannels, int *pNum40MhzChannels)
1852{
1853 VOS_STATUS status = VOS_STATUS_E_INVAL;
1854 int i, count = 0;
1855
1856 if( p20MhzChannels && pNum20MhzChannels )
1857 {
1858 if( *pNum20MhzChannels >= NUM_RF_CHANNELS )
1859 {
1860 for( i = 0; i <= RF_CHAN_14; i++ )
1861 {
1862 p20MhzChannels[count++] = rfChannels[i].channelNum;
1863 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
1865 {
1866 p20MhzChannels[count++] = rfChannels[i].channelNum;
1867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001868 status = VOS_STATUS_SUCCESS;
1869 }
1870 *pNum20MhzChannels = count;
1871 }
1872
1873 return (status);
1874}
1875
1876/**------------------------------------------------------------------------
1877 \brief vos_nv_readDefaultCountryTable() - return the default Country table
1878 \param table data - a union to return the default country table data in.
1879 \return status of the NV read operation
1880 \sa
1881 -------------------------------------------------------------------------*/
1882VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
1883{
1884
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07001885 VOS_STATUS status = VOS_STATUS_SUCCESS;
1886 memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
1887 pr_info("DefaultCountry is %c%c\n",
1888 tableData->defaultCountryTable.countryCode[0],
1889 tableData->defaultCountryTable.countryCode[1]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 return status;
1891}
1892
1893/**------------------------------------------------------------------------
1894 \brief vos_nv_getBuffer -
1895 \param pBuffer - to return the buffer address
1896 pSize - buffer size.
1897 \return status of the NV read operation
1898 \sa
1899 -------------------------------------------------------------------------*/
1900VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1901{
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 /* Send the NV structure and size */
1903 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1904 *pSize = sizeof(sHalNv);
1905
1906 return VOS_STATUS_SUCCESS;
1907}
1908
Jeff Johnson295189b2012-06-20 16:38:30 -07001909/**------------------------------------------------------------------------
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001910 \brief vos_nv_getBuffer -
1911 \param pBuffer - to return the buffer address
1912 pSize - buffer size.
1913 \return status of the NV read operation
1914 \sa
1915 -------------------------------------------------------------------------*/
1916VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1917{
1918 /* Send the NV structure and size */
1919 VOS_STATUS status;
1920
1921 status = vos_nv_isEmbeddedNV();
1922
1923 if (VOS_STATUS_SUCCESS == status)
1924 {
1925 *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
1926 *pSize = nvReadEncodeBufSize;
1927 }
1928 else
1929 {
1930 *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
1931 *pSize = sizeof(sHalNv);
1932 }
1933
1934 return VOS_STATUS_SUCCESS;
1935}
1936
1937
1938VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
1939{
1940 /* Send the NV structure and size */
1941 *pNvBuffer = (v_VOID_t *)(pDictFile);
1942 *pSize = nDictionarySize;
1943
1944 return VOS_STATUS_SUCCESS;
1945}
1946
1947VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
1948{
1949 if (MAGIC_NUMBER == magicNumber)
1950 {
1951 return VOS_STATUS_SUCCESS;
1952 }
1953
1954 return VOS_STATUS_E_FAILURE;
1955}
1956
1957VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
1958{
1959 vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
1960 (size-sizeof(v_U32_t)));
1961
1962 return VOS_STATUS_SUCCESS;
1963}
1964
1965/**------------------------------------------------------------------------
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 \brief vos_nv_setRegDomain -
1967 \param clientCtxt - Client Context, Not used for PRIMA
1968 regId - Regulatory Domain ID
1969 \return status set REG domain operation
1970 \sa
1971 -------------------------------------------------------------------------*/
1972VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId)
1973{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05301974 v_CONTEXT_t pVosContext = NULL;
1975 hdd_context_t *pHddCtx = NULL;
1976 struct wiphy *wiphy = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 /* Client Context Argumant not used for PRIMA */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05301978 if (regId >= REGDOMAIN_COUNT)
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 {
1980 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1981 "VOS set reg domain, invalid REG domain ID %d", regId);
1982 return VOS_STATUS_E_INVAL;
1983 }
1984
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05301985 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1986 if (NULL != pVosContext)
1987 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1988 else
1989 return VOS_STATUS_E_EXISTS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 /* Set correct channel information based on REG Domain */
1991 regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
1992
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05301993 /* when CRDA is not running then we are world roaming.
1994 In this case if 11d is enabled, then country code should
1995 be update on basis of world roaming */
1996 if ((NULL != pHddCtx) && (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
1997 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) == 0))
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05301998 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05301999 wiphy = pHddCtx->wiphy;
2000 regulatory_hint(wiphy, "00");
2001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 return VOS_STATUS_SUCCESS;
2003}
2004
2005/**------------------------------------------------------------------------
2006 \brief vos_nv_getChannelEnabledState -
2007 \param rfChannel - input channel enum to know evabled state
2008 \return eNVChannelEnabledType enabled state for channel
2009 * enabled
2010 * disabled
2011 * DFS
2012 \sa
2013 -------------------------------------------------------------------------*/
2014eNVChannelEnabledType vos_nv_getChannelEnabledState
2015(
2016 v_U32_t rfChannel
2017)
2018{
2019 v_U32_t channelLoop;
2020 eRfChannels channelEnum = INVALID_RF_CHANNEL;
2021
2022 for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++)
2023 {
2024 if(rfChannels[channelLoop].channelNum == rfChannel)
2025 {
2026 channelEnum = (eRfChannels)channelLoop;
2027 break;
2028 }
2029 }
2030
2031 if(INVALID_RF_CHANNEL == channelEnum)
2032 {
2033 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb88db982012-12-10 13:34:59 -08002034 "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 return NV_CHANNEL_INVALID;
2036 }
2037
2038 return regChannels[channelEnum].enabled;
2039}
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002040
2041/******************************************************************
2042 Add CRDA regulatory support
2043*******************************************************************/
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002044
2045static int bw20_ch_index_to_bw40_ch_index(int k)
2046{
2047 int m = -1;
2048 if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
2049 {
2050 m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
2051 if (m > RF_CHAN_BOND_11)
2052 m = RF_CHAN_BOND_11;
2053 }
2054 else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
2055 {
2056 m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
2057 if (m > RF_CHAN_BOND_214)
2058 m = RF_CHAN_BOND_214;
2059 }
2060 else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
2061 {
2062 m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
2063 if (m > RF_CHAN_BOND_62)
2064 m = RF_CHAN_BOND_62;
2065 }
2066 else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
2067 {
2068 m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
2069 if (m > RF_CHAN_BOND_138)
2070 m = RF_CHAN_BOND_138;
2071 }
2072 else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
2073 {
2074 m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
2075 if (m > RF_CHAN_BOND_163)
2076 m = RF_CHAN_BOND_163;
2077 }
2078return m;
2079}
2080
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002081void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
2082{
2083 int k;
2084 pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
2085 countryCode[0], countryCode[1], domain_id);
2086 for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
2087 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2088 NV_CHANNEL_ENABLE;
2089 /* Max Tx Power 20dBm */
2090 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
2091 }
2092 /* enable ch 12 to ch 14 passive scan */
2093 pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
2094 for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
2095 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2096 NV_CHANNEL_DFS;
2097 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2098 }
2099 pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
2100 for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
2101 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2102 NV_CHANNEL_DFS;
2103 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2104 }
2105#ifdef PASSIVE_SCAN_4_9GHZ
2106 pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
2107 for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
2108 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
2109 NV_CHANNEL_DFS;
2110 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
2111 }
2112#endif
2113 if (domain_id == NUM_REG_DOMAINS-1)
2114 { /* init time */
2115 crda_alpha2[0] = countryCode[0];
2116 crda_alpha2[1] = countryCode[1];
2117 crda_regulatory_entry_valid = VOS_TRUE;
2118 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
2119 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
2120 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2121 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2122 }
2123 if (domain_id == NUM_REG_DOMAINS-2)
2124 { /* none-default country */
2125 run_time_alpha2[0] = countryCode[0];
2126 run_time_alpha2[1] = countryCode[1];
2127 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2128 }
2129}
2130
2131static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
2132 struct regulatory_request *request,
2133 v_U8_t nBandCapability,
2134 int domain_id)
2135{
2136 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
2137 pr_info("Country 00 special handling to enable passive scan.\n");
2138 crda_regulatory_entry_default(request->alpha2, domain_id);
2139 }
2140 return 0;
2141}
2142
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002143/* create_crda_regulatory_entry should be called from user command or 11d country IE */
2144static int create_crda_regulatory_entry(struct wiphy *wiphy,
2145 struct regulatory_request *request,
2146 v_U8_t nBandCapability)
2147{
2148 int i, j, m;
2149 int k = 0, n = 0;
2150
2151 if (run_time_alpha2[0]==request->alpha2[0] &&
2152 run_time_alpha2[1]==request->alpha2[1] &&
2153 crda_regulatory_run_time_entry_valid == VOS_TRUE)
2154 return 0; /* already created */
2155
2156 /* 20MHz channels */
2157 if (nBandCapability == eCSR_BAND_24)
2158 pr_info("BandCapability is set to 2G only.\n");
2159 for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
2160 {
2161 if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
2162 continue;
2163 else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
2164 continue;
2165 if (wiphy->bands[i] == NULL)
2166 {
2167 pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
2168 return -1;
2169 }
2170 // internal channels[] is one continous array for both 2G and 5G bands
2171 // m is internal starting channel index for each band
2172 if (i == 0)
2173 m = 0;
2174 else
2175 m = wiphy->bands[i-1]->n_channels + m;
2176 for (j=0;j<wiphy->bands[i]->n_channels;j++)
2177 {
2178 // k = (m + j) is internal current channel index for 20MHz channel
2179 // n is internal channel index for corresponding 40MHz channel
2180 k = m + j;
2181 n = bw20_ch_index_to_bw40_ch_index(k);
2182 if (n == -1)
2183 return -1;
2184 if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
2185 {
2186 if (pnvEFSTable == NULL)
2187 {
2188 pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
2189 return -1;
2190 }
2191 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2192 NV_CHANNEL_DISABLE;
2193 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2194 NV_CHANNEL_DISABLE;
2195 //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
2196 // rfChannels[n].channelNum);
2197 }
2198 else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
2199 {
2200 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2201 NV_CHANNEL_DFS;
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002202 // max_power is in mBm = 100 * dBm
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002203 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002204 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002205 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2206 {
2207 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2208 NV_CHANNEL_DFS;
2209 // 40MHz channel power is half of 20MHz (-3dB) ??
2210 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002211 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002212 }
2213 }
2214 else // Enable is only last flag we support
2215 {
2216 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
2217 NV_CHANNEL_ENABLE;
2218 // max_power is in dBm
2219 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002220 (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002221 if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
2222 {
2223 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
2224 NV_CHANNEL_ENABLE;
2225 // 40MHz channel power is half of 20MHz (-3dB) ??
2226 pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002227 (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002228 }
2229 }
2230 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2231 real gain which should be provided by the real design */
2232 }
2233 }
2234 if (k == 0)
2235 return -1;
2236 run_time_alpha2[0] = request->alpha2[0];
2237 run_time_alpha2[1] = request->alpha2[1];
2238 crda_regulatory_run_time_entry_valid = VOS_TRUE;
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002239 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002240return 0;
2241}
2242v_BOOL_t is_crda_regulatory_entry_valid(void)
2243{
2244return crda_regulatory_entry_valid;
2245}
2246
2247/* Handling routines for the conversion from regd rules (start/end freq) to channel index
2248start freq + 10000 = center freq of the 20MHz start channel
2249end freq - 10000 = center freq of the 20MHz end channel
2250start freq + 20000 = center freq of the 40MHz start channel
2251end freq - 20000 = center freq of the 40MHz end channel
2252*/
2253static int bw20_start_freq_to_channel_index(u32 freq_khz)
2254{
2255int i;
2256u32 center_freq = freq_khz + 10000;
2257 //Has to compare from low freq to high freq
2258 //RF_SUBBAND_2_4_GHZ
2259 for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
2260 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2261 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002262 //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
2263 for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
2264 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2265 return i;
2266 //RF_SUBBAND_5_LOW_GHZ
2267 for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
2268 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2269 return i;
2270 //RF_SUBBAND_5_MID_GHZ
2271 for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
2272 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2273 return i;
2274 //RF_SUBBAND_5_HIGH_GHZ
2275 for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
2276 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2277 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002278return -1;
2279}
2280
2281static int bw20_end_freq_to_channel_index(u32 freq_khz)
2282{
2283int i;
2284u32 center_freq = freq_khz - 10000;
2285 //Has to compare from high freq to low freq
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002286 //RF_SUBBAND_5_HIGH_GHZ
2287 for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
2288 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2289 return i;
2290 //RF_SUBBAND_5_MID_GHZ
2291 for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
2292 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2293 return i;
2294 //RF_SUBBAND_5_LOW_GHZ
2295 for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
2296 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2297 return i;
2298 //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
2299 for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
2300 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2301 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002302 //RF_SUBBAND_2_4_GHZ
2303 for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
2304 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2305 return i;
2306return -1;
2307}
2308
2309static int bw40_start_freq_to_channel_index(u32 freq_khz)
2310{
2311int i;
2312u32 center_freq = freq_khz + 20000;
2313 //Has to compare from low freq to high freq
2314 //RF_SUBBAND_2_4_GHZ
2315 for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
2316 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2317 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002318 //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
2319 for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
2320 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2321 return i;
2322 //RF_SUBBAND_5_LOW_GHZ
2323 for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
2324 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2325 return i;
2326 //RF_SUBBAND_5_MID_GHZ
2327 for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
2328 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2329 return i;
2330 //RF_SUBBAND_5_HIGH_GHZ
2331 for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
2332 if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
2333 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002334return -1;
2335}
2336
2337static int bw40_end_freq_to_channel_index(u32 freq_khz)
2338{
2339int i;
2340u32 center_freq = freq_khz - 20000;
2341 //Has to compare from high freq to low freq
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002342 //RF_SUBBAND_5_HIGH_GHZ
2343 for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
2344 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2345 return i;
2346 //RF_SUBBAND_5_MID_GHZ
2347 for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
2348 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2349 return i;
2350 //RF_SUBBAND_5_LOW_GHZ
2351 for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
2352 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2353 return i;
2354 //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
2355 for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
2356 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2357 return i;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002358 //RF_SUBBAND_2_4_GHZ
2359 for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
2360 if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
2361 return i;
2362return -1;
2363}
2364
2365static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
2366{
2367 switch (nBandCapability)
2368 {
2369 case eCSR_BAND_ALL:
2370 return VOS_TRUE;
2371 case eCSR_BAND_24:
2372 if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
2373 return VOS_TRUE;
2374 if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
2375 return VOS_TRUE; // 2.4G 40MHz channel
2376 break;
2377 case eCSR_BAND_5G:
2378 if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
2379 return VOS_TRUE;
2380 if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
2381 return VOS_TRUE; // 2.4G 40MHz channel
2382 break;
2383 default:
2384 break;
2385 }
2386 return VOS_FALSE;
2387}
2388
2389/* create_crda_regulatory_entry_from_regd should be called during init time */
2390static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
2391 struct regulatory_request *request,
2392 v_U8_t nBandCapability)
2393{
2394 int i, j, n, domain_id;
2395 int bw20_start_channel_index, bw20_end_channel_index;
2396 int bw40_start_channel_index, bw40_end_channel_index;
2397
2398 if (wiphy == NULL || wiphy->regd == NULL)
2399 {
2400 wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
2401 return -1;
2402 }
2403 if (crda_regulatory_entry_valid == VOS_FALSE)
2404 domain_id = NUM_REG_DOMAINS-1; /* init time */
2405 else
2406 domain_id = NUM_REG_DOMAINS-2; /* none-default country */
2407 for (n = 0; n < NUM_RF_CHANNELS; n++)
2408 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
2409
2410 for (i=0;i<wiphy->regd->n_reg_rules;i++)
2411 {
2412 wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
2413 bw20_start_channel_index =
2414 bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2415 bw20_end_channel_index =
2416 bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2417 if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
2418 {
2419 wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
2420 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2421 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2422 continue; // skip this rull, but continue to next rule
2423 }
2424 wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2425 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2426 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2427 bw20_start_channel_index, bw20_end_channel_index);
2428 for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
2429 {
2430 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2431 {
2432 wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
2433 rfChannels[j].channelNum);
2434 continue; // skip this channel, continue to next
2435 }
2436 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2437 {
2438 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2439 wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2440 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2441 }
2442 else
2443 {
2444 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2445 wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
2446 wiphy->regd->reg_rules[i].power_rule.max_eirp);
2447 }
2448 /* max_eirp is in mBm (= 100 * dBm) unit */
2449 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2450 (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
2451 }
2452 /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
2453 real gain which should be provided by the real design */
2454 if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
2455 {
2456 wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
2457 bw40_start_channel_index =
2458 bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
2459 bw40_end_channel_index =
2460 bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2461 if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
2462 {
2463 wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
2464 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2465 wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
2466 continue; // skip this rull, but continue to next rule
2467 }
2468 wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
2469 wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
2470 wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
2471 bw40_start_channel_index, bw40_end_channel_index);
2472 for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
2473 {
2474 if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
2475 continue; // skip this channel, continue to next
2476 if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
2477 {
2478 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
2479 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
2480 }
2481 else
2482 {
2483 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
2484 wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
2485 }
2486 /* set 40MHz channel power as half (- 3 dB) of 20MHz */
2487 pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
2488 (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
2489 }
2490 }
2491 }
2492 /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
2493 NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
2494 these flags and has no implementation yet. */
2495 if (crda_regulatory_entry_valid == VOS_FALSE)
2496 { /* init time */
2497 crda_alpha2[0] = request->alpha2[0];
2498 crda_alpha2[1] = request->alpha2[1];
2499 crda_regulatory_entry_valid = VOS_TRUE;
2500 }
2501 else
2502 { /* none-default country */
2503 run_time_alpha2[0] = request->alpha2[0];
2504 run_time_alpha2[1] = request->alpha2[1];
2505 crda_regulatory_run_time_entry_valid = VOS_TRUE;
2506 }
Yunsen Wange3ba1fb2013-04-05 15:04:43 -07002507 crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002508 return 0;
2509}
2510
2511/*
2512 * Function: wlan_hdd_crda_reg_notifier
2513 * This function is called from cfg80211 core to provide regulatory settings
2514 * after new country is requested or intersected (init, user input or 11d)
2515 * This function is used to create a CRDA regulatory settings entry into internal
2516 * regulatory setting table.
2517 */
Yue Maf49ba872013-08-19 12:04:25 -07002518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2519void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
2520 struct regulatory_request *request)
2521#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002522int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
2523 struct regulatory_request *request)
Yue Maf49ba872013-08-19 12:04:25 -07002524#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002525{
2526 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302527 v_REGDOMAIN_t domainIdCurrent;
2528 tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
2529 tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
2530 tANI_U8 nBandCapability;
2531 int i,j,k,m;
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002532 wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
2533 " %c%c\n", request->alpha2[0], request->alpha2[1]);
2534 if (request->initiator == NL80211_REGDOM_SET_BY_USER)
2535 {
2536 wiphy_dbg(wiphy, "info: set by user\n");
2537 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
Yue Maf49ba872013-08-19 12:04:25 -07002538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2539 return;
2540#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002541 return 0;
Yue Maf49ba872013-08-19 12:04:25 -07002542#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002543 // ToDo
2544 /* Don't change default country code to CRDA country code by user req */
2545 /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
2546 regd for new country settings */
2547 //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2548 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2549 }
2550 else if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
2551 {
2552 wiphy_dbg(wiphy, "info: set by country IE\n");
2553 if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
Yue Maf49ba872013-08-19 12:04:25 -07002554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2555 return;
2556#else
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002557 return 0;
Yue Maf49ba872013-08-19 12:04:25 -07002558#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002559 // ToDo
2560 /* Intersect of 11d and crda settings */
2561
2562 /* Don't change default country code to CRDA country code by 11d req */
2563 /* for every adapter call sme_ChangeCountryCode to trigger read regd
2564 for intersected new country settings */
2565 // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2566 // &country_code[0], pAdapter, pHddCtx->pvosContext);
2567 }
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05302568 else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
2569 (request->initiator == NL80211_REGDOM_SET_BY_CORE))
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002570 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302571 if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
2572 {
2573 wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
2574#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2575 return;
2576#else
2577 return 0;
2578#endif
2579 }
2580 if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
2581 ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
2582 {
2583 wiphy_dbg(wiphy, "info: set by driver ERROR\n");
2584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2585 return;
2586#else
2587 return 0;
2588#endif
2589 }
2590 wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002591 /* if set by driver itself, it means driver can accept the crda
2592 regulatory settings and wiphy->regd should be populated with crda
2593 settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
2594 correctly, this may be fixed by later kernel */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302595 if (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05302596 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302597 {
Madan Mohan Koyyalamudi99ba3582013-05-16 12:52:48 +05302598 if (create_crda_regulatory_entry_from_regd(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
2599 {
2600 pr_info("crda entry created.\n");
2601 if (crda_alpha2[0] == request->alpha2[0] && crda_alpha2[1] == request->alpha2[1])
2602 {
2603 /* first CRDA request should be from init time */
2604 /* Change default country code to CRDA country code, assume indoor */
2605 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = request->alpha2[0];
2606 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = request->alpha2[1];
2607 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
2608 pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
2609 wiphy_dbg(wiphy, "info: init time default country code is %c%c%c\n",
2610 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
2611 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
2612 pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2]);
2613 }
2614 else /* second or later CRDA request after init time */
2615 {
2616 wiphy_dbg(wiphy, "info: crda none-default country code is %c%c\n",
2617 request->alpha2[0], request->alpha2[1]);
2618 }
2619 // hdd will read regd for this country after complete
2620 }
2621 complete(&pHddCtx->driver_crda_req);
2622 }
2623 else
2624 {
2625 nBandCapability = pHddCtx->cfg_ini->nBandCapability;
2626 for (i=0, m=0; i<IEEE80211_NUM_BANDS; i++)
2627 {
2628 if (NULL == wiphy->bands[i])
2629 {
2630 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2631 "error: wiphy->bands[i] is NULL, i = %d", i);
2632 continue;
2633 }
2634
2635 // internal channels[] is one continous array for both 2G and 5G bands
2636 // m is internal starting channel index for each band
2637 if (0 == i)
2638 {
2639 m = 0;
2640 }
2641 else
2642 {
2643 m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
2644 }
2645
2646 for (j=0; j<wiphy->bands[i]->n_channels; j++)
2647 {
2648 // k = (m + j) is internal current channel index for 20MHz channel
2649 // n is internal channel index for corresponding 40MHz channel
2650 k = m + j;
2651 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
2652 {
2653 // Enable social channels for P2P
2654 if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
2655 2437 == wiphy->bands[i]->channels[j].center_freq ||
2656 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
2657 NV_CHANNEL_ENABLE == regChannels[k].enabled)
2658 {
2659 wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2660 }
2661 else
2662 {
2663 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
2664 }
2665 continue;
2666 }
2667 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
2668 {
2669 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
2670 continue;
2671 }
2672
2673 if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
2674 NV_CHANNEL_INVALID == regChannels[k].enabled)
2675 {
2676 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
2677 }
2678 else if (NV_CHANNEL_DFS == regChannels[k].enabled)
2679 {
2680 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
2681 |IEEE80211_CHAN_RADAR);
2682 wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
2683 }
2684 else
2685 {
2686 wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
2687 |IEEE80211_CHAN_PASSIVE_SCAN
2688 |IEEE80211_CHAN_NO_IBSS
2689 |IEEE80211_CHAN_RADAR);
2690 }
2691 }
2692 }
2693 /* Haven't seen any condition that will set by driver after init.
2694 If we do, then we should also call sme_ChangeCountryCode */
2695 for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ ]->n_channels; j++)
2696 {
2697 // p2p UNII-1 band channels are passive when domain is FCC.
2698 if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
2699 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
2700 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
2701 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
2702 (ccode[0]== 'U'&& ccode[1]=='S'))
2703 {
2704 wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
2705 }
2706 else if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
2707 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
2708 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
2709 wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
2710 (ccode[0]!= 'U'&& ccode[1]!='S'))
2711 {
2712 wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
2713 }
2714 }
2715 if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
2716 {
2717 request->processed = 1;
2718 }
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05302719 }
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002720 }
Yue Maf49ba872013-08-19 12:04:25 -07002721#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
2722 return;
2723#else
2724 return 0;
2725#endif
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07002726}