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