3ca97ad00c7f0bceeab8ff916f63ceb04a772670
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / drivers / net / wireless / bcmdhd4361 / dhd_custom_sec.c
1 /*
2 * Customer HW 4 dependant file
3 *
4 * Copyright (C) 1999-2019, Broadcom.
5 *
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
11 *
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
19 *
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
23 *
24 *
25 * <<Broadcom-WL-IPTag/Open:>>
26 *
27 * $Id: dhd_custom_sec.c 334946 2012-05-24 20:38:00Z $
28 */
29 #if defined(CUSTOMER_HW4) || defined(CUSTOMER_HW40)
30 #include <typedefs.h>
31 #include <linuxver.h>
32 #include <osl.h>
33
34 #include <ethernet.h>
35 #include <dngl_stats.h>
36 #include <bcmutils.h>
37 #include <dhd.h>
38 #include <dhd_dbg.h>
39 #include <dhd_linux.h>
40 #include <bcmdevs.h>
41
42 #include <linux/fcntl.h>
43 #include <linux/fs.h>
44
45 #if defined(ARGOS_CPU_SCHEDULER) && !defined(DHD_LB_IRQSET)
46 extern int argos_irq_affinity_setup_label(unsigned int irq, const char *label,
47 struct cpumask *affinity_cpu_mask,
48 struct cpumask *default_cpu_mask);
49 #endif /* ARGOS_CPU_SCHEDULER && !DHD_LB_IRQSET */
50
51 #if !defined(DHD_USE_CLMINFO_PARSER)
52 const struct cntry_locales_custom translate_custom_table[] = {
53 /* default ccode/regrev */
54 {"", "XZ", 11}, /* Universal if Country code is unknown or empty */
55 {"IR", "XZ", 11}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
56 {"SD", "XZ", 11}, /* Universal if Country code is SUDAN */
57 {"PS", "XZ", 11}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
58 {"TL", "XZ", 11}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
59 {"MH", "XZ", 11}, /* Universal if Country code is MARSHALL ISLANDS */
60 {"SX", "XZ", 11}, /* Universal if Country code is Sint Maarten */
61 {"CC", "XZ", 11}, /* Universal if Country code is COCOS (KEELING) ISLANDS */
62 {"HM", "XZ", 11}, /* Universal if Country code is HEARD ISLAND AND MCDONALD ISLANDS */
63 {"PN", "XZ", 11}, /* Universal if Country code is PITCAIRN */
64 {"AQ", "XZ", 11}, /* Universal if Country code is ANTARCTICA */
65 {"AX", "XZ", 11}, /* Universal if Country code is ALAND ISLANDS */
66 {"BV", "XZ", 11}, /* Universal if Country code is BOUVET ISLAND */
67 {"GS", "XZ", 11}, /* Universal if Country code is
68 * SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
69 */
70 {"SH", "XZ", 11}, /* Universal if Country code is SAINT HELENA */
71 {"SJ", "XZ", 11}, /* Universal if Country code is SVALBARD AND JAN MAYEN */
72 {"SS", "XZ", 11}, /* Universal if Country code is SOUTH SUDAN */
73 {"GL", "GP", 2},
74 {"AL", "AL", 2},
75 {"AS", "AS", 12},
76 {"AI", "AI", 1},
77 {"AF", "AD", 0},
78 {"AG", "AG", 2},
79 {"AR", "AU", 6},
80 {"AW", "AW", 2},
81 {"AU", "AU", 6},
82 {"AT", "AT", 4},
83 {"AZ", "AZ", 2},
84 {"BS", "BS", 2},
85 {"BH", "BH", 4},
86 {"BD", "BD", 1},
87 {"BY", "BY", 3},
88 {"BE", "BE", 4},
89 {"BM", "BM", 12},
90 {"BA", "BA", 2},
91 {"BR", "BR", 2},
92 {"VG", "VG", 2},
93 {"BN", "BN", 4},
94 {"BG", "BG", 4},
95 {"KH", "KH", 2},
96 {"KY", "KY", 3},
97 {"CN", "CN", 38},
98 {"CO", "CO", 17},
99 {"CR", "CR", 17},
100 {"HR", "HR", 4},
101 {"CY", "CY", 4},
102 {"CZ", "CZ", 4},
103 {"DK", "DK", 4},
104 {"EE", "EE", 4},
105 {"ET", "ET", 2},
106 {"FI", "FI", 4},
107 {"FR", "FR", 5},
108 {"GF", "GF", 2},
109 {"DE", "DE", 7},
110 {"GR", "GR", 4},
111 {"GD", "GD", 2},
112 {"GP", "GP", 2},
113 {"GU", "GU", 30},
114 {"HK", "HK", 2},
115 {"HU", "HU", 4},
116 {"IS", "IS", 4},
117 {"IN", "IN", 3},
118 {"ID", "ID", 1},
119 {"IE", "IE", 5},
120 {"IL", "IL", 14},
121 {"IT", "IT", 4},
122 {"JO", "JO", 3},
123 {"KE", "SA", 0},
124 {"KW", "KW", 5},
125 {"LA", "LA", 2},
126 {"LV", "LV", 4},
127 {"LB", "LB", 5},
128 {"LS", "LS", 2},
129 {"LI", "LI", 4},
130 {"LT", "LT", 4},
131 {"LU", "LU", 3},
132 {"MO", "SG", 0},
133 {"MK", "MK", 2},
134 {"MW", "MW", 1},
135 #if defined(BCM4359_CHIP)
136 {"DZ", "DZ", 2},
137 #elif defined(DHD_SUPPORT_GB_999)
138 {"DZ", "GB", 999},
139 #else
140 {"DZ", "GB", 6},
141 #endif /* BCM4359_CHIP */
142 {"MV", "MV", 3},
143 {"MT", "MT", 4},
144 {"MQ", "MQ", 2},
145 {"MR", "MR", 2},
146 {"MU", "MU", 2},
147 {"YT", "YT", 2},
148 {"MX", "MX", 44},
149 {"MD", "MD", 2},
150 {"MC", "MC", 1},
151 {"ME", "ME", 2},
152 {"MA", "MA", 2},
153 {"NL", "NL", 4},
154 {"AN", "GD", 2},
155 {"NZ", "NZ", 4},
156 {"NO", "NO", 4},
157 {"OM", "OM", 4},
158 {"PA", "PA", 17},
159 {"PG", "AU", 6},
160 {"PY", "PY", 2},
161 {"PE", "PE", 20},
162 {"PH", "PH", 5},
163 {"PL", "PL", 4},
164 {"PT", "PT", 4},
165 {"PR", "PR", 38},
166 {"RE", "RE", 2},
167 {"RO", "RO", 4},
168 {"SN", "MA", 2},
169 {"RS", "RS", 2},
170 {"SK", "SK", 4},
171 {"SI", "SI", 4},
172 {"ES", "ES", 4},
173 {"LK", "LK", 1},
174 {"SE", "SE", 4},
175 {"CH", "CH", 4},
176 {"TH", "TH", 5},
177 {"TT", "TT", 3},
178 {"TR", "TR", 7},
179 {"AE", "AE", 6},
180 #ifdef DHD_SUPPORT_GB_999
181 {"GB", "GB", 999},
182 #else
183 {"GB", "GB", 6},
184 #endif /* DHD_SUPPORT_GB_999 */
185 {"UY", "VE", 3},
186 {"VI", "PR", 38},
187 {"VA", "VA", 2},
188 {"VE", "VE", 3},
189 {"VN", "VN", 4},
190 {"ZM", "LA", 2},
191 {"EC", "EC", 21},
192 {"SV", "SV", 25},
193 #if defined(BCM4358_CHIP) || defined(BCM4359_CHIP)
194 {"KR", "KR", 70},
195 #else
196 {"KR", "KR", 48},
197 #endif // endif
198 #if defined(BCM4359_CHIP)
199 {"TW", "TW", 65},
200 {"JP", "JP", 968},
201 {"RU", "RU", 986},
202 {"UA", "UA", 16},
203 {"ZA", "ZA", 19},
204 {"AM", "AM", 1},
205 {"MY", "MY", 19},
206 #else
207 {"TW", "TW", 1},
208 {"JP", "JP", 45},
209 {"RU", "RU", 13},
210 {"UA", "UA", 8},
211 {"ZA", "ZA", 6},
212 {"MY", "MY", 3},
213 #endif /* BCM4359_CHIP */
214 {"GT", "GT", 1},
215 {"MN", "MN", 1},
216 {"NI", "NI", 2},
217 {"UZ", "MA", 2},
218 {"EG", "EG", 13},
219 {"TN", "TN", 1},
220 {"AO", "AD", 0},
221 {"BT", "BJ", 0},
222 {"BW", "BJ", 0},
223 {"LY", "LI", 4},
224 {"BO", "NG", 0},
225 {"UM", "PR", 38},
226 /* Support FCC 15.407 (Part 15E) Changes, effective June 2 2014 */
227 /* US/988, Q2/993 country codes with higher power on UNII-1 5G band */
228 #if defined(DHD_SUPPORT_US_949)
229 {"US", "US", 949},
230 #elif defined(DHD_SUPPORT_US_945)
231 {"US", "US", 945},
232 #else
233 {"US", "US", 988},
234 #endif /* DHD_SUPPORT_US_949 */
235 #if defined(DHD_SUPPORT_QA_6)
236 /* Support Qatar 5G band 36-64 100-144 149-165 channels
237 * This QA/6 should be used only HERO project and
238 * FW version should be sync up with 9.96.11 or higher version.
239 * If Use the old FW ver before 9.96.11 in HERO project, Country QA/6 is not supported.
240 * So when changing the country code to QA, It will be returned to fail and
241 * still previous Country code
242 */
243 {"QA", "QA", 6},
244 #endif /* DHD_SUPPORT_QA_6 */
245 {"CU", "US", 988},
246 {"CA", "Q2", 993},
247 };
248 #else
249 struct cntry_locales_custom translate_custom_table[NUM_OF_COUNTRYS];
250 #endif /* !DHD_USE_CLMINFO_PARSER */
251
252 /* Customized Locale convertor
253 * input : ISO 3166-1 country abbreviation
254 * output: customized cspec
255 */
256 void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
257 {
258 int size, i;
259
260 size = ARRAYSIZE(translate_custom_table);
261
262 if (cspec == 0)
263 return;
264
265 if (size == 0)
266 return;
267
268 for (i = 0; i < size; i++) {
269 if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
270 memcpy(cspec->ccode,
271 translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
272 cspec->rev = translate_custom_table[i].custom_locale_rev;
273 return;
274 }
275 }
276 return;
277 }
278
279 #define PSMINFO PLATFORM_PATH".psm.info"
280 #define ANTINFO PLATFORM_PATH".ant.info"
281 #define WIFIVERINFO PLATFORM_PATH".wifiver.info"
282 #define LOGTRACEINFO PLATFORM_PATH".logtrace.info"
283 #define SOFTAPINFO PLATFORM_PATH".softap.info"
284
285 #ifdef DHD_PM_CONTROL_FROM_FILE
286 extern bool g_pm_control;
287 extern uint32 pmmode_val;
288 void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
289 {
290 #ifndef DHD_EXPORT_CNTL_FILE
291 struct file *fp = NULL;
292 char *filepath = PSMINFO;
293 #endif /* DHD_EXPORT_CNTL_FILE */
294 char power_val = 0;
295 int ret = 0;
296 #ifdef DHD_ENABLE_LPC
297 uint32 lpc = 0;
298 #endif /* DHD_ENABLE_LPC */
299
300 #ifndef DHD_EXPORT_CNTL_FILE
301 g_pm_control = FALSE;
302 fp = filp_open(filepath, O_RDONLY, 0);
303 if (IS_ERR(fp) || (fp == NULL)) {
304 /* Enable PowerSave Mode */
305 dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
306 sizeof(uint), TRUE, 0);
307 DHD_ERROR(("[WIFI_SEC] %s: %s doesn't exist"
308 " so set PM to %d\n",
309 __FUNCTION__, filepath, *power_mode));
310 return;
311 } else {
312 kernel_read(fp, fp->f_pos, &power_val, 1);
313 DHD_ERROR(("[WIFI_SEC] %s: POWER_VAL = %c \r\n", __FUNCTION__, power_val));
314 filp_close(fp, NULL);
315 }
316 #else
317 if (!g_pm_control) {
318 /* Enable PowerSave Mode */
319 dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
320 sizeof(uint), TRUE, 0);
321 DHD_ERROR(("[WIFI_SEC] %s: doesn't set from sysfs"
322 " so set PM to %d\n",
323 __FUNCTION__, *power_mode));
324 return;
325 } else {
326 power_val = (char)pmmode_val;
327 }
328 #endif /* !DHD_EXPORT_CNTL_FILE */
329
330 #ifdef DHD_EXPORT_CNTL_FILE
331 if (power_val == 0) {
332 #else
333 if (power_val == '0') {
334 #endif /* DHD_EXPORT_CNTL_FILE */
335 #ifdef ROAM_ENABLE
336 uint roamvar = 1;
337 #endif // endif
338 uint32 wl_updown = 1;
339
340 *power_mode = PM_OFF;
341 /* Disable PowerSave Mode */
342 dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
343 sizeof(uint), TRUE, 0);
344 #ifndef CUSTOM_SET_ANTNPM
345 /* Turn off MPC in AP mode */
346 ret = dhd_iovar(dhd, 0, "mpc", (char *)power_mode, sizeof(*power_mode),
347 NULL, 0, TRUE);
348 #endif /* !CUSTOM_SET_ANTNPM */
349 g_pm_control = TRUE;
350 #ifdef ROAM_ENABLE
351 /* Roaming off of dongle */
352 ret = dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar), NULL,
353 0, TRUE);
354 #endif // endif
355 #ifdef DHD_ENABLE_LPC
356 /* Set lpc 0 */
357 ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
358 if (ret < 0) {
359 DHD_ERROR(("[WIFI_SEC] %s: Set lpc failed %d\n",
360 __FUNCTION__, ret));
361 }
362 #endif /* DHD_ENABLE_LPC */
363 #ifdef DHD_PCIE_RUNTIMEPM
364 DHD_ERROR(("[WIFI_SEC] %s : Turn Runtime PM off \n", __FUNCTION__));
365 /* Turn Runtime PM off */
366 dhdpcie_block_runtime_pm(dhd);
367 #endif /* DHD_PCIE_RUNTIMEPM */
368 /* Disable ocl */
369 if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_updown,
370 sizeof(wl_updown), TRUE, 0)) < 0) {
371 DHD_ERROR(("[WIFI_SEC] %s: WLC_UP faield %d\n", __FUNCTION__, ret));
372 }
373
374 #ifndef CUSTOM_SET_OCLOFF
375 {
376 uint32 ocl_enable = 0;
377 ret = dhd_iovar(dhd, 0, "ocl_enable", (char *)&ocl_enable,
378 sizeof(ocl_enable), NULL, 0, TRUE);
379 if (ret < 0) {
380 DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d failed %d\n",
381 __FUNCTION__, ocl_enable, ret));
382 } else {
383 DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d OK %d\n",
384 __FUNCTION__, ocl_enable, ret));
385 }
386 }
387 #else
388 dhd->ocl_off = TRUE;
389 #endif /* CUSTOM_SET_OCLOFF */
390 #ifdef WLADPS
391 if ((ret = dhd_enable_adps(dhd, ADPS_DISABLE)) < 0) {
392 DHD_ERROR(("[WIFI_SEC] %s: dhd_enable_adps failed %d\n",
393 __FUNCTION__, ret));
394 }
395 #endif /* WLADPS */
396
397 if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_updown,
398 sizeof(wl_updown), TRUE, 0)) < 0) {
399 DHD_ERROR(("[WIFI_SEC] %s: WLC_DOWN faield %d\n",
400 __FUNCTION__, ret));
401 }
402 } else {
403 dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
404 sizeof(uint), TRUE, 0);
405 }
406 }
407 #endif /* DHD_PM_CONTROL_FROM_FILE */
408
409 #ifdef MIMO_ANT_SETTING
410 int get_ant_val_from_file(uint32 *read_val)
411 {
412 int ret = -1;
413 struct file *fp = NULL;
414 char *filepath = ANTINFO;
415 char *p_ant_val = NULL;
416 uint32 ant_val = 0;
417
418 /* Read antenna settings from the file */
419 fp = filp_open(filepath, O_RDONLY, 0);
420 if (IS_ERR(fp)) {
421 DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
422 ret = -ENOENT;
423 return ret;
424 } else {
425 ret = kernel_read(fp, 0, (char *)&ant_val, sizeof(uint32));
426 if (ret < 0) {
427 DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
428 filp_close(fp, NULL);
429 return ret;
430 }
431
432 p_ant_val = (char *)&ant_val;
433 p_ant_val[sizeof(uint32) - 1] = '\0';
434 ant_val = bcm_atoi(p_ant_val);
435
436 DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
437 filp_close(fp, NULL);
438
439 /* Check value from the file */
440 if (ant_val < 1 || ant_val > 3) {
441 DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
442 __FUNCTION__, ant_val, filepath));
443 return -1;
444 }
445 }
446 *read_val = ant_val;
447 return ret;
448 }
449
450 int dhd_sel_ant_from_file(dhd_pub_t *dhd)
451 {
452 int ret = -1;
453 uint32 ant_val = 0;
454 uint32 btc_mode = 0;
455 uint chip_id = dhd_bus_chip_id(dhd);
456 #ifndef CUSTOM_SET_ANTNPM
457 wl_config_t rsdb_mode;
458
459 memset(&rsdb_mode, 0, sizeof(rsdb_mode));
460 #endif /* !CUSTOM_SET_ANTNPM */
461
462 /* Check if this chip can support MIMO */
463 if (chip_id != BCM4350_CHIP_ID &&
464 chip_id != BCM4354_CHIP_ID &&
465 chip_id != BCM43569_CHIP_ID &&
466 chip_id != BCM4358_CHIP_ID &&
467 chip_id != BCM4359_CHIP_ID &&
468 chip_id != BCM4355_CHIP_ID &&
469 chip_id != BCM4347_CHIP_ID &&
470 chip_id != BCM4361_CHIP_ID &&
471 chip_id != BCM4375_CHIP_ID) {
472 DHD_ERROR(("[WIFI_SEC] %s: This chipset does not support MIMO\n",
473 __FUNCTION__));
474 return ret;
475 }
476
477 #ifndef DHD_EXPORT_CNTL_FILE
478 ret = get_ant_val_from_file(&ant_val);
479 #else
480 ant_val = (uint32)antsel;
481 #endif /* !DHD_EXPORT_CNTL_FILE */
482 if (ant_val == 0) {
483 #ifdef CUSTOM_SET_ANTNPM
484 dhd->mimo_ant_set = 0;
485 #endif /* CUSTOM_SET_ANTNPM */
486 return ret;
487 }
488 DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
489
490 /* bt coex mode off */
491 if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
492 ret = dhd_iovar(dhd, 0, "btc_mode", (char *)&btc_mode, sizeof(btc_mode), NULL, 0,
493 TRUE);
494 if (ret) {
495 DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
496 "btc_mode, ret=%d\n",
497 __FUNCTION__, ret));
498 return ret;
499 }
500 }
501
502 #ifndef CUSTOM_SET_ANTNPM
503 /* rsdb mode off */
504 DHD_ERROR(("[WIFI_SEC] %s: %s the RSDB mode!\n",
505 __FUNCTION__, rsdb_mode.config ? "Enable" : "Disable"));
506 ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode), NULL, 0, TRUE);
507 if (ret) {
508 DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
509 "rsdb_mode, ret=%d\n", __FUNCTION__, ret));
510 return ret;
511 }
512
513 /* Select Antenna */
514 ret = dhd_iovar(dhd, 0, "txchain", (char *)&ant_val, sizeof(ant_val), NULL, 0, TRUE);
515 if (ret) {
516 DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
517 __FUNCTION__, ret));
518 return ret;
519 }
520
521 ret = dhd_iovar(dhd, 0, "rxchain", (char *)&ant_val, sizeof(ant_val), NULL, 0, TRUE);
522 if (ret) {
523 DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
524 __FUNCTION__, ret));
525 return ret;
526 }
527 #else
528 dhd->mimo_ant_set = ant_val;
529 DHD_ERROR(("[WIFI_SEC] %s: mimo_ant_set = %d\n", __FUNCTION__, dhd->mimo_ant_set));
530 #endif /* !CUSTOM_SET_ANTNPM */
531 return 0;
532 }
533 #endif /* MIMO_ANTENNA_SETTING */
534
535 #ifdef LOGTRACE_FROM_FILE
536 /*
537 * LOGTRACEINFO = .logtrace.info
538 * - logtrace = 1 => Enable LOGTRACE Event
539 * - logtrace = 0 => Disable LOGTRACE Event
540 * - file not exist => Disable LOGTRACE Event
541 */
542 int dhd_logtrace_from_file(dhd_pub_t *dhd)
543 {
544 #ifndef DHD_EXPORT_CNTL_FILE
545 struct file *fp = NULL;
546 int ret = -1;
547 uint32 logtrace = 0;
548 char *filepath = LOGTRACEINFO;
549 char *p_logtrace = NULL;
550
551 /* Read LOGTRACE Event on/off request from the file */
552 fp = filp_open(filepath, O_RDONLY, 0);
553 if (IS_ERR(fp)) {
554 DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
555 return 0;
556 } else {
557 ret = kernel_read(fp, 0, (char *)&logtrace, sizeof(uint32));
558 if (ret < 0) {
559 DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
560 filp_close(fp, NULL);
561 return 0;
562 }
563
564 p_logtrace = (char *)&logtrace;
565 p_logtrace[sizeof(uint32) - 1] = '\0';
566 logtrace = bcm_atoi(p_logtrace);
567
568 DHD_ERROR(("[WIFI_SEC] %s: LOGTRACE On/Off from file = %d\n",
569 __FUNCTION__, logtrace));
570 filp_close(fp, NULL);
571
572 /* Check value from the file */
573 if (logtrace > 2) {
574 DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
575 __FUNCTION__, logtrace, filepath));
576 return 0;
577 }
578 }
579
580 return (int)logtrace;
581 #else
582 DHD_ERROR(("[WIFI_SEC] %s : LOGTRACE On/Off from sysfs = %d\n",
583 __FUNCTION__, (int)logtrace_val));
584 return (int)logtrace_val;
585 #endif /* !DHD_EXPORT_CNTL_FILE */
586 }
587 #endif /* LOGTRACE_FROM_FILE */
588
589 #ifdef USE_WFA_CERT_CONF
590 #ifndef DHD_EXPORT_CNTL_FILE
591 int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
592 {
593 struct file *fp = NULL;
594 char *filepath = NULL;
595 int val = 0;
596 char *p_val = NULL;
597
598 if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
599 (mode >= PARAM_LAST_VALUE)) {
600 DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
601 return BCME_ERROR;
602 }
603
604 switch (mode) {
605 #ifdef BCMSDIO
606 case SET_PARAM_BUS_TXGLOM_MODE:
607 filepath = PLATFORM_PATH".bustxglom.info";
608 break;
609 #endif /* BCMSDIO */
610 #if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
611 case SET_PARAM_ROAMOFF:
612 filepath = PLATFORM_PATH".roamoff.info";
613 break;
614 #endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
615 #ifdef USE_WL_FRAMEBURST
616 case SET_PARAM_FRAMEBURST:
617 filepath = PLATFORM_PATH".frameburst.info";
618 break;
619 #endif /* USE_WL_FRAMEBURST */
620 #ifdef USE_WL_TXBF
621 case SET_PARAM_TXBF:
622 filepath = PLATFORM_PATH".txbf.info";
623 break;
624 #endif /* USE_WL_TXBF */
625 #ifdef PROP_TXSTATUS
626 case SET_PARAM_PROPTX:
627 filepath = PLATFORM_PATH".proptx.info";
628 break;
629 #endif /* PROP_TXSTATUS */
630 default:
631 DHD_ERROR(("[WIFI_SEC] %s: File to find file name for index=%d\n",
632 __FUNCTION__, mode));
633 return BCME_ERROR;
634 }
635 fp = filp_open(filepath, O_RDONLY, 0);
636 if (IS_ERR(fp) || (fp == NULL)) {
637 DHD_ERROR(("[WIFI_SEC] %s: File open failed, file path=%s\n",
638 __FUNCTION__, filepath));
639 return BCME_ERROR;
640 } else {
641 if (kernel_read(fp, fp->f_pos, (char *)&val, sizeof(uint32)) < 0) {
642 filp_close(fp, NULL);
643 /* File operation is failed so we will return error code */
644 DHD_ERROR(("[WIFI_SEC] %s: read failed, file path=%s\n",
645 __FUNCTION__, filepath));
646 return BCME_ERROR;
647 }
648 filp_close(fp, NULL);
649 }
650
651 p_val = (char *)&val;
652 p_val[sizeof(uint32) - 1] = '\0';
653 val = bcm_atoi(p_val);
654
655 switch (mode) {
656 #if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
657 case SET_PARAM_ROAMOFF:
658 #endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
659 #ifdef USE_WL_FRAMEBURST
660 case SET_PARAM_FRAMEBURST:
661 #endif /* USE_WL_FRAMEBURST */
662 #ifdef USE_WL_TXBF
663 case SET_PARAM_TXBF:
664 #endif /* USE_WL_TXBF */
665 #ifdef PROP_TXSTATUS
666 case SET_PARAM_PROPTX:
667 #endif /* PROP_TXSTATUS */
668 if (val < 0 || val > 1) {
669 DHD_ERROR(("[WIFI_SEC] %s: value[%d] is out of range\n",
670 __FUNCTION__, *read_val));
671 return BCME_ERROR;
672 }
673 break;
674 default:
675 return BCME_ERROR;
676 }
677 *read_val = (uint)val;
678 return BCME_OK;
679 }
680 #else
681 int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
682 {
683 uint val = 0;
684
685 if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
686 (mode >= PARAM_LAST_VALUE)) {
687 DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
688 return BCME_ERROR;
689 }
690
691 switch (mode) {
692 #ifdef BCMSDIO
693 case SET_PARAM_BUS_TXGLOM_MODE:
694 if (bus_txglom == VALUENOTSET)
695 return BCME_ERROR;
696 else
697 val = (uint)bus_txglom;
698 break;
699 #endif /* BCMSDIO */
700 #if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
701 case SET_PARAM_ROAMOFF:
702 if (roam_off == VALUENOTSET)
703 return BCME_ERROR;
704 else
705 val = (uint)roam_off;
706 break;
707 #endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
708 #ifdef USE_WL_FRAMEBURST
709 case SET_PARAM_FRAMEBURST:
710 if (frameburst == VALUENOTSET)
711 return BCME_ERROR;
712 else
713 val = (uint)frameburst;
714 break;
715 #endif /* USE_WL_FRAMEBURST */
716 #ifdef USE_WL_TXBF
717 case SET_PARAM_TXBF:
718 if (txbf == VALUENOTSET)
719 return BCME_ERROR;
720 else
721 val = (uint)txbf;
722 break;
723 #endif /* USE_WL_TXBF */
724 #ifdef PROP_TXSTATUS
725 case SET_PARAM_PROPTX:
726 if (proptx == VALUENOTSET)
727 return BCME_ERROR;
728 else
729 val = (uint)proptx;
730 break;
731 #endif /* PROP_TXSTATUS */
732 default:
733 return BCME_ERROR;
734 }
735 *read_val = val;
736 return BCME_OK;
737 }
738 #endif /* !DHD_EXPORT_CNTL_FILE */
739 #endif /* USE_WFA_CERT_CONF */
740
741 #ifdef WRITE_WLANINFO
742 #define FIRM_PREFIX "Firm_ver:"
743 #define DHD_PREFIX "DHD_ver:"
744 #define NV_PREFIX "Nv_info:"
745 #define CLM_PREFIX "CLM_ver:"
746 #define max_len(a, b) ((sizeof(a)/(2)) - (strlen(b)) - (3))
747 #define tstr_len(a, b) ((strlen(a)) + (strlen(b)) + (3))
748
749 char version_info[MAX_VERSION_LEN];
750 char version_old_info[MAX_VERSION_LEN];
751
752 int write_filesystem(struct file *file, unsigned long long offset,
753 unsigned char* data, unsigned int size)
754 {
755 mm_segment_t oldfs;
756 int ret;
757
758 oldfs = get_fs();
759 set_fs(get_ds());
760
761 ret = vfs_write(file, data, size, &offset);
762
763 set_fs(oldfs);
764 return ret;
765 }
766
767 uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p, char *clm_ver)
768 {
769 #ifndef DHD_EXPORT_CNTL_FILE
770 struct file *fp = NULL;
771 char *filepath = WIFIVERINFO;
772 #endif /* DHD_EXPORT_CNTL_FILE */
773 struct file *nvfp = NULL;
774 int min_len, str_len = 0;
775 int ret = 0;
776 char* nvram_buf;
777 char temp_buf[256];
778
779 DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));
780
781 DHD_INFO(("[WIFI_SEC] firmware version : %s\n", firm_ver));
782 DHD_INFO(("[WIFI_SEC] dhd driver version : %s\n", dhd_ver));
783 DHD_INFO(("[WIFI_SEC] nvram path : %s\n", nvram_p));
784 DHD_INFO(("[WIFI_SEC] clm version : %s\n", clm_ver));
785
786 memset(version_info, 0, sizeof(version_info));
787
788 if (strlen(dhd_ver)) {
789 min_len = min(strlen(dhd_ver), max_len(temp_buf, DHD_PREFIX));
790 min_len += strlen(DHD_PREFIX) + 3;
791 DHD_INFO(("[WIFI_SEC] DHD ver length : %d\n", min_len));
792 snprintf(version_info+str_len, min_len, DHD_PREFIX " %s\n", dhd_ver);
793 str_len = strlen(version_info);
794
795 DHD_INFO(("[WIFI_SEC] Driver version_info len : %d\n", str_len));
796 DHD_INFO(("[WIFI_SEC] Driver version_info : %s\n", version_info));
797 } else {
798 DHD_ERROR(("[WIFI_SEC] Driver version is missing.\n"));
799 }
800
801 if (strlen(firm_ver)) {
802 min_len = min(strlen(firm_ver), max_len(temp_buf, FIRM_PREFIX));
803 min_len += strlen(FIRM_PREFIX) + 3;
804 DHD_INFO(("[WIFI_SEC] firmware ver length : %d\n", min_len));
805 snprintf(version_info+str_len, min_len, FIRM_PREFIX " %s\n", firm_ver);
806 str_len = strlen(version_info);
807
808 DHD_INFO(("[WIFI_SEC] Firmware version_info len : %d\n", str_len));
809 DHD_INFO(("[WIFI_SEC] Firmware version_info : %s\n", version_info));
810 } else {
811 DHD_ERROR(("[WIFI_SEC] Firmware version is missing.\n"));
812 }
813
814 if (nvram_p) {
815 memset(temp_buf, 0, sizeof(temp_buf));
816 nvfp = filp_open(nvram_p, O_RDONLY, 0);
817 if (IS_ERR(nvfp) || (nvfp == NULL)) {
818 DHD_ERROR(("[WIFI_SEC] %s: Nvarm File open failed.\n", __FUNCTION__));
819 return -1;
820 } else {
821 ret = kernel_read(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf));
822 filp_close(nvfp, NULL);
823 }
824
825 if (strlen(temp_buf)) {
826 nvram_buf = temp_buf;
827 bcmstrtok(&nvram_buf, "\n", 0);
828 DHD_INFO(("[WIFI_SEC] nvram tolkening : %s(%zu) \n",
829 temp_buf, strlen(temp_buf)));
830 snprintf(version_info+str_len, tstr_len(temp_buf, NV_PREFIX),
831 NV_PREFIX " %s\n", temp_buf);
832 str_len = strlen(version_info);
833 DHD_INFO(("[WIFI_SEC] NVRAM version_info : %s\n", version_info));
834 DHD_INFO(("[WIFI_SEC] NVRAM version_info len : %d, nvram len : %zu\n",
835 str_len, strlen(temp_buf)));
836 } else {
837 DHD_ERROR(("[WIFI_SEC] NVRAM info is missing.\n"));
838 }
839 } else {
840 DHD_ERROR(("[WIFI_SEC] Not exist nvram path\n"));
841 }
842
843 if (strlen(clm_ver)) {
844 min_len = min(strlen(clm_ver), max_len(temp_buf, CLM_PREFIX));
845 min_len += strlen(CLM_PREFIX) + 3;
846 DHD_INFO(("[WIFI_SEC] clm ver length : %d\n", min_len));
847 snprintf(version_info+str_len, min_len, CLM_PREFIX " %s\n", clm_ver);
848 str_len = strlen(version_info);
849
850 DHD_INFO(("[WIFI_SEC] CLM version_info len : %d\n", str_len));
851 DHD_INFO(("[WIFI_SEC] CLM version_info : %s\n", version_info));
852 } else {
853 DHD_ERROR(("[WIFI_SEC] CLM version is missing.\n"));
854 }
855
856 DHD_INFO(("[WIFI_SEC] version_info : %s, strlen : %zu\n",
857 version_info, strlen(version_info)));
858
859 #ifndef DHD_EXPORT_CNTL_FILE
860 fp = filp_open(filepath, O_RDONLY, 0);
861 if (IS_ERR(fp) || (fp == NULL)) {
862 DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n", __FUNCTION__));
863 } else {
864 memset(version_old_info, 0, sizeof(version_old_info));
865 ret = kernel_read(fp, fp->f_pos, version_old_info, sizeof(version_info));
866 filp_close(fp, NULL);
867 DHD_INFO(("[WIFI_SEC] kernel_read ret : %d.\n", ret));
868 if (strcmp(version_info, version_old_info) == 0) {
869 DHD_ERROR(("[WIFI_SEC] .wifiver.info already saved.\n"));
870 return 0;
871 }
872 }
873
874 fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
875 if (IS_ERR(fp) || (fp == NULL)) {
876 DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n",
877 __FUNCTION__));
878 } else {
879 ret = write_filesystem(fp, fp->f_pos, version_info, sizeof(version_info));
880 DHD_INFO(("[WIFI_SEC] sec_save_wlinfo done. ret : %d\n", ret));
881 DHD_ERROR(("[WIFI_SEC] save .wifiver.info file.\n"));
882 filp_close(fp, NULL);
883 }
884 #endif /* DHD_EXPORT_CNTL_FILE */
885 return ret;
886 }
887 #endif /* WRITE_WLANINFO */
888
889 #ifdef SUPPORT_MULTIPLE_BOARD_REV_FROM_HW
890 unsigned int system_hw_rev;
891 static int
892 __init get_hw_rev(char *arg)
893 {
894 get_option(&arg, &system_hw_rev);
895 printk("dhd : hw_rev : %d\n", system_hw_rev);
896 return 0;
897 }
898
899 early_param("androidboot.hw_rev", get_hw_rev);
900 #endif /* SUPPORT_MULTIPLE_BOARD_REV_FROM_HW */
901 #endif /* CUSTOMER_HW4 || CUSTOMER_HW40 */
902
903 #ifdef GEN_SOFTAP_INFO_FILE
904 #define SOFTAP_INFO_FILE_FIRST_LINE "#.softap.info"
905 /*
906 * # Whether both wifi and hotspot can be turned on at the same time?
907 * DualBandConcurrency
908 * # 5Ghz band support?
909 * 5G
910 * # How many clients can be connected?
911 * maxClient
912 * # Does hotspot support PowerSave mode?
913 * PowerSave
914 * # Does android_net_wifi_set_Country_Code_Hal feature supported?
915 * HalFn_setCountryCodeHal
916 * # Does android_net_wifi_getValidChannels supported?
917 * HalFn_getValidChannels
918 */
919 const char *softap_info_items[] = {
920 "DualBandConcurrency",
921 #ifdef DHD_SOFTAP_DUAL_IF_INFO
922 "DualInterface",
923 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
924 "5G", "maxClient", "PowerSave",
925 "HalFn_setCountryCodeHal", "HalFn_getValidChannels", NULL
926 };
927 #if defined(BCM4361_CHIP)
928 const char *softap_info_values[] = {
929 "yes",
930 #ifdef DHD_SOFTAP_DUAL_IF_INFO
931 "yes",
932 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
933 "yes", "10", "yes", "yes", "yes", NULL
934 };
935 #elif defined(BCM4359_CHIP)
936 const char *softap_info_values[] = {
937 "yes",
938 #ifdef DHD_SOFTAP_DUAL_IF_INFO
939 #ifdef CONFIG_WLAN_GRACE
940 "yes",
941 #else
942 "no",
943 #endif /* CONFIG_WLAN_GRACE */
944 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
945 "yes", "10", "yes", "yes", "yes", NULL
946 };
947 #elif defined(BCM43454_CHIP) || defined(BCM43455_CHIP) || defined(BCM43456_CHIP)
948 const char *softap_info_values[] = {
949 #ifdef WL_RESTRICTED_APSTA_SCC
950 "yes",
951 #else
952 "no",
953 #endif /* WL_RESTRICTED_APSTA_SCC */
954 #ifdef DHD_SOFTAP_DUAL_IF_INFO
955 #ifdef WL_RESTRICTED_APSTA_SCC
956 "yes",
957 #else
958 "no",
959 #endif /* WL_RESTRICTED_APSTA_SCC */
960 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
961 "yes", "10", "no", "yes", "yes", NULL
962 };
963 #elif defined(BCM43430_CHIP)
964 const char *softap_info_values[] = {
965 "no",
966 #ifdef DHD_SOFTAP_DUAL_IF_INFO
967 "no",
968 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
969 "no", "10", "no", "yes", "yes", NULL
970 };
971 #else
972 const char *softap_info_values[] = {
973 "UNDEF",
974 #ifdef DHD_SOFTAP_DUAL_IF_INFO
975 "UNDEF",
976 #endif /* DHD_SOFTAP_DUAL_IF_INFO */
977 "UNDEF", "UNDEF", "UNDEF", "UNDEF", "UNDEF", NULL
978 };
979 #endif /* defined(BCM4361_CHIP) */
980 #endif /* GEN_SOFTAP_INFO_FILE */
981
982 #ifdef GEN_SOFTAP_INFO_FILE
983 uint32 sec_save_softap_info(void)
984 {
985 #ifndef DHD_EXPORT_CNTL_FILE
986 struct file *fp = NULL;
987 char *filepath = SOFTAPINFO;
988 #endif /* DHD_EXPORT_CNTL_FILE */
989 char temp_buf[SOFTAP_INFO_BUF_SZ];
990 int ret = -1, idx = 0, rem = 0, written = 0;
991 char *pos = NULL;
992
993 DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));
994 memset(temp_buf, 0, sizeof(temp_buf));
995
996 pos = temp_buf;
997 rem = sizeof(temp_buf);
998 written = snprintf(pos, sizeof(temp_buf), "%s\n",
999 SOFTAP_INFO_FILE_FIRST_LINE);
1000 do {
1001 int len = strlen(softap_info_items[idx]) +
1002 strlen(softap_info_values[idx]) + 2;
1003 pos += written;
1004 rem -= written;
1005 if (len > rem) {
1006 break;
1007 }
1008 written = snprintf(pos, rem, "%s=%s\n",
1009 softap_info_items[idx], softap_info_values[idx]);
1010 } while (softap_info_items[++idx] != NULL);
1011
1012 #ifndef DHD_EXPORT_CNTL_FILE
1013 fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
1014 if (IS_ERR(fp) || (fp == NULL)) {
1015 DHD_ERROR(("[WIFI_SEC] %s: %s File open failed.\n",
1016 SOFTAPINFO, __FUNCTION__));
1017 } else {
1018 ret = write_filesystem(fp, fp->f_pos, temp_buf, strlen(temp_buf));
1019 DHD_INFO(("[WIFI_SEC] %s done. ret : %d\n", __FUNCTION__, ret));
1020 DHD_ERROR(("[WIFI_SEC] save %s file.\n", SOFTAPINFO));
1021 filp_close(fp, NULL);
1022 }
1023 #else
1024 strlcpy(softapinfostr, temp_buf, SOFTAP_INFO_BUF_SZ);
1025
1026 ret = BCME_OK;
1027 #endif /* !DHD_EXPORT_CNTL_FILE */
1028 return ret;
1029 }
1030 #endif /* GEN_SOFTAP_INFO_FILE */
1031
1032 #if defined(FORCE_DISABLE_SINGLECORE_SCAN)
1033 void
1034 dhd_force_disable_singlcore_scan(dhd_pub_t *dhd)
1035 {
1036 int ret = 0;
1037 struct file *fp = NULL;
1038 char *filepath = PLATFORM_PATH".cid.info";
1039 char vender[10] = {0, };
1040 uint32 pm_bcnrx = 0;
1041 uint32 scan_ps = 0;
1042
1043 if (BCM4354_CHIP_ID != dhd_bus_chip_id(dhd))
1044 return;
1045
1046 fp = filp_open(filepath, O_RDONLY, 0);
1047 if (IS_ERR(fp)) {
1048 DHD_ERROR(("%s file open error\n", filepath));
1049 } else {
1050 ret = kernel_read(fp, 0, (char *)vender, 5);
1051
1052 if (ret > 0 && NULL != strstr(vender, "wisol")) {
1053 DHD_ERROR(("wisol module : set pm_bcnrx=0, set scan_ps=0\n"));
1054
1055 ret = dhd_iovar(dhd, 0, "pm_bcnrx", (char *)&pm_bcnrx, sizeof(pm_bcnrx),
1056 NULL, 0, TRUE);
1057 if (ret < 0)
1058 DHD_ERROR(("Set pm_bcnrx error (%d)\n", ret));
1059
1060 ret = dhd_iovar(dhd, 0, "scan_ps", (char *)&scan_ps, sizeof(scan_ps), NULL,
1061 0, TRUE);
1062 if (ret < 0)
1063 DHD_ERROR(("Set scan_ps error (%d)\n", ret));
1064 }
1065 filp_close(fp, NULL);
1066 }
1067 }
1068 #endif /* FORCE_DISABLE_SINGLECORE_SCAN */
1069 #if defined(ARGOS_CPU_SCHEDULER) && !defined(DHD_LB_IRQSET) && \
1070 !defined(CONFIG_SOC_EXYNOS7870)
1071 void
1072 set_irq_cpucore(unsigned int irq, cpumask_var_t default_cpu_mask,
1073 cpumask_var_t affinity_cpu_mask)
1074 {
1075 argos_irq_affinity_setup_label(irq,
1076 ARGOS_IRQ_WIFI_TABLE_LABEL,
1077 affinity_cpu_mask, default_cpu_mask);
1078
1079 argos_irq_affinity_setup_label(irq,
1080 ARGOS_P2P_TABLE_LABEL,
1081 affinity_cpu_mask, default_cpu_mask);
1082 }
1083 #endif /* SET_PCIE_IRQ_CPU_CORE && !DHD_LB_IRQSET && !CONFIG_SOC_EXYNOS7870 */