import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6630 / wlan / os / linux / gl_wext_priv.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#8 $
3 */
4
5 /*! \file gl_wext_priv.c
6 \brief This file includes private ioctl support.
7 */
8
9
10
11 /*
12 ** $Log: gl_wext_priv.c $
13 **
14 ** 08 09 2013 eason.tsai
15 ** [BORA00002255] [MT6630 Wi-Fi][Driver] develop
16 ** update ICAP support code
17 **
18 ** 08 09 2013 terry.wu
19 ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
20 ** 1. Add new TX done result code "TX_RESULT_QUEUE_CLEARANCE"
21 ** 2. Fix runtime warning for wrong memory mode of kfree mgmt pool
22 ** 3. Fix memory dump command
23 **
24 ** 07 24 2013 yuche.tsai
25 ** [BORA00002398] [MT6630][Volunteer Patch] P2P Driver Re-Design for Multiple BSS support
26 ** Update for Hot-Spot code.
27 **
28 ** 07 17 2013 yuche.tsai
29 ** [BORA00002398] [MT6630][Volunteer Patch] P2P Driver Re-Design for Multiple BSS support
30 ** MT6630 P2P first connection check point 1.
31 **
32 ** 07 04 2013 terry.wu
33 ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
34 ** Update for 1st Connection.
35 **
36 ** 09 17 2012 cm.chang
37 ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
38 ** Duplicate source from MT6620 v2.3 driver branch
39 ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
40 **
41 ** 08 24 2012 cp.wu
42 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
43 ** .
44 **
45 ** 08 24 2012 cp.wu
46 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
47 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
48 *
49 * 07 17 2012 yuche.tsai
50 * NULL
51 * Let netdev bring up.
52 *
53 * 06 13 2012 yuche.tsai
54 * NULL
55 * Update maintrunk driver.
56 * Add support for driver compose assoc request frame.
57 *
58 * 03 20 2012 wh.su
59 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function[WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code
60 * use return to avoid the ioctl return not supported
61 *
62 * 03 02 2012 terry.wu
63 * NULL
64 * Snc CFG80211 modification for ICS migration from branch 2.2.
65 *
66 * 01 16 2012 wh.su
67 * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
68 * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
69 *
70 * 01 05 2012 wh.su
71 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
72 * Adding the related ioctl / wlan oid function to set the Tx power cfg.
73 *
74 * 01 02 2012 wh.su
75 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
76 * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
77 *
78 * 11 10 2011 cp.wu
79 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
80 * 1. eliminaite direct calls to printk in porting layer.
81 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
82 *
83 * 11 02 2011 chinghwa.yu
84 * [WCXRP00000063] Update BCM CoEx design and settings
85 * Fixed typo.
86 *
87 * 09 20 2011 chinglan.wang
88 * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
89 * .
90 *
91 * 07 28 2011 chinghwa.yu
92 * [WCXRP00000063] Update BCM CoEx design and settings
93 * Add BWCS cmd and event.
94 *
95 * 07 18 2011 chinghwa.yu
96 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
97 * Add CMD/Event for RDD and BWCS.
98 *
99 * 03 17 2011 chinglan.wang
100 * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
101 * .
102 *
103 * 03 07 2011 terry.wu
104 * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
105 * Toggle non-standard debug messages to comments.
106 *
107 * 01 27 2011 cm.chang
108 * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default
109 * .
110 *
111 * 01 26 2011 wh.su
112 * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux
113 * adding the SW cmd ioctl support, use set/get structure ioctl.
114 *
115 * 01 20 2011 eddie.chen
116 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
117 * Adjust OID order.
118 *
119 * 01 20 2011 eddie.chen
120 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
121 * Add Oid for sw control debug command
122 *
123 * 01 07 2011 cm.chang
124 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
125 * Add a new compiling option to control if MCR read/write is permitted
126 *
127 * 12 31 2010 cm.chang
128 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
129 * Add some iwpriv commands to support test mode operation
130 *
131 * 12 15 2010 george.huang
132 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
133 * Support set PS profile and set WMM-PS related iwpriv.
134 *
135 * 11 08 2010 wh.su
136 * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
137 * add the message check code from mt5921.
138 *
139 * 10 18 2010 cp.wu
140 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
141 * complete implementation of Android NVRAM access
142 *
143 * 09 24 2010 cp.wu
144 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
145 * correct typo for NVRAM access.
146 *
147 * 09 23 2010 cp.wu
148 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
149 * add skeleton for NVRAM integration
150 *
151 * 08 04 2010 cp.wu
152 * NULL
153 * revert changelist #15371, efuse read/write access will be done by RF test approach
154 *
155 * 08 04 2010 cp.wu
156 * NULL
157 * add OID definitions for EFUSE read/write access.
158 *
159 * 07 08 2010 cp.wu
160 *
161 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
162 *
163 * 06 06 2010 kevin.huang
164 * [WPD00003832][MT6620 5931] Create driver base
165 * [MT6620 5931] Create driver base
166 *
167 * 06 01 2010 cp.wu
168 * [WPD00001943]Create WiFi test driver framework on WinXP
169 * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool
170 *
171 * 05 29 2010 jeffrey.chang
172 * [WPD00003826]Initial import for Linux port
173 * fix private ioctl for rftest
174 *
175 * 04 21 2010 jeffrey.chang
176 * [WPD00003826]Initial import for Linux port
177 * add for private ioctl support
178 ** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090
179 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
180 ** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090
181 ** Remove unused functions
182 ** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090
183 ** Fix compile warning
184 ** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090
185 ** Fix compile warning
186 ** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090
187 ** Refine lines to supress compile warning
188 ** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090
189 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
190 ** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090
191 ** Add Linux SDIO (with mmc core) support.
192 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
193 ** Fix compile warning in Linux.
194 ** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089
195 ** Add mandatory and private IO control for Linux BWCS
196 ** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088
197 ** fixed the compiling error at linux
198 ** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088
199 ** mark the code not used at linux supplicant v0.6.7
200 ** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425
201 ** 1. Add PTA_ENABLED flag
202 ** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088
203 ** adjust the code for meet the coding style, and add assert check
204 ** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104
205 ** Support GPIO2 mode
206 ** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084
207 ** modify variable name
208 ** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104
209 ** Add exception handle about length in function priv_set_struct()
210 ** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104
211 ** Support PRIV_CMD_BT_COEXIST
212 ** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461
213 ** Add priv oid to support WMM_PS_TEST
214 ** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461
215 ** Update after wlanoidSetPowerMode changed
216 ** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461
217 ** Add IOCTL for Power Mode
218 ** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461
219 ** Not use wlanoidSetCSUMOffloadForLinux()
220 ** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084
221 ** rename wlanoid
222 ** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084
223 ** rename for wlanoidSetBeaconIntervalForLinux
224 ** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461
225 ** Add iwpriv support for AdHocMode setting
226 ** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461
227 ** Add priv IOCTL for VOIP setting
228 ** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461
229 ** Add priv ioctl to turn on / off roaming
230 ** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461
231 ** Add CSUM offload priv ioctl for Linux
232 ** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461
233 ** Unify priv ioctl
234 ** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088
235 ** add WPS code
236 ** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425
237 ** 1. Update wlanQueryInformation and wlanSetInformation
238 */
239
240 /*******************************************************************************
241 * C O M P I L E R F L A G S
242 ********************************************************************************
243 */
244
245 /*******************************************************************************
246 * E X T E R N A L R E F E R E N C E S
247 ********************************************************************************
248 */
249 #include "precomp.h"
250 #include "gl_os.h"
251 #include "gl_wext_priv.h"
252 #if CFG_SUPPORT_WAPI
253 #include "gl_sec.h"
254 #endif
255 #if CFG_ENABLE_WIFI_DIRECT
256 #include "gl_p2p_os.h"
257 #endif
258
259
260
261 /*******************************************************************************
262 * C O N S T A N T S
263 ********************************************************************************
264 */
265 #define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY))
266
267 /*******************************************************************************
268 * F U N C T I O N D E C L A R A T I O N S
269 ********************************************************************************
270 */
271
272 static int
273 priv_get_ndis(IN struct net_device *prNetDev,
274 IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen);
275
276 static int
277 priv_set_ndis(IN struct net_device *prNetDev,
278 IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen);
279
280 static void
281 priv_driver_get_chip_config_16(PUINT_8 pucStartAddr,
282 UINT_32 u4Length, UINT_32 u4Line, int i4TotalLen, INT_32 i4BytesWritten, char *pcCommand);
283
284 static void
285 priv_driver_get_chip_config_4(PUINT_32 pu4StartAddr,
286 UINT_32 u4Length, UINT_32 u4Line, int i4TotalLen, INT_32 i4BytesWritten, char *pcCommand);
287
288
289
290
291 #if 0 /* CFG_SUPPORT_WPS */
292 static int
293 priv_set_appie(IN struct net_device *prNetDev,
294 IN struct iw_request_info *prIwReqInfo,
295 IN union iwreq_data *prIwReqData, OUT char *pcExtra);
296
297 static int
298 priv_set_filter(IN struct net_device *prNetDev,
299 IN struct iw_request_info *prIwReqInfo,
300 IN union iwreq_data *prIwReqData, OUT char *pcExtra);
301 #endif /* CFG_SUPPORT_WPS */
302
303 static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry);
304
305 #if 0
306 static WLAN_STATUS
307 reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo,
308 OUT PVOID pvQueryBuffer,
309 IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
310
311 static WLAN_STATUS
312 reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo,
313 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
314 #endif
315
316 static WLAN_STATUS
317 reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo,
318 IN PVOID pvSetBuffer,
319 IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen);
320
321 /*******************************************************************************
322 * P R I V A T E D A T A
323 ********************************************************************************
324 */
325 static UINT_8 aucOidBuf[4096] = { 0 };
326
327 /* OID processing table */
328 /* Order is important here because the OIDs should be in order of
329 increasing value for binary searching. */
330 static WLAN_REQ_ENTRY arWlanOidReqTable[] = {
331 /*
332 {(NDIS_OID)rOid,
333 (PUINT_8)pucOidName,
334 fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen,
335 pfOidQueryHandler,
336 pfOidSetHandler}
337 */
338 /* General Operational Characteristics */
339
340 /* Ethernet Operational Characteristics */
341 {OID_802_3_CURRENT_ADDRESS,
342 DISP_STRING("OID_802_3_CURRENT_ADDRESS"),
343 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6,
344 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr,
345 NULL},
346
347 /* OID_802_3_MULTICAST_LIST */
348 /* OID_802_3_MAXIMUM_LIST_SIZE */
349 /* Ethernet Statistics */
350
351 /* NDIS 802.11 Wireless LAN OIDs */
352 {OID_802_11_SUPPORTED_RATES,
353 DISP_STRING("OID_802_11_SUPPORTED_RATES"),
354 TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX),
355 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates,
356 NULL}
357 ,
358 /*
359 {OID_802_11_CONFIGURATION,
360 DISP_STRING("OID_802_11_CONFIGURATION"),
361 TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T),
362 (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration,
363 (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration},
364 */
365 {OID_PNP_SET_POWER,
366 DISP_STRING("OID_PNP_SET_POWER"),
367 TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE),
368 NULL,
369 (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState}
370 ,
371
372 /* Custom OIDs */
373 {OID_CUSTOM_OID_INTERFACE_VERSION,
374 DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"),
375 TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4,
376 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion,
377 NULL}
378 ,
379
380 /*
381 #if PTA_ENABLED
382 {OID_CUSTOM_BT_COEXIST_CTRL,
383 DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"),
384 FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T),
385 NULL,
386 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl},
387 #endif
388 */
389
390 /*
391 {OID_CUSTOM_POWER_MANAGEMENT_PROFILE,
392 DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"),
393 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
394 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam,
395 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam},
396 {OID_CUSTOM_PATTERN_CONFIG,
397 DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"),
398 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUC_T),
399 NULL,
400 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig},
401 {OID_CUSTOM_BG_SSID_SEARCH_CONFIG,
402 DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"),
403 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
404 NULL,
405 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam},
406 {OID_CUSTOM_VOIP_SETUP,
407 DISP_STRING("OID_CUSTOM_VOIP_SETUP"),
408 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
409 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus,
410 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus},
411 {OID_CUSTOM_ADD_TS,
412 DISP_STRING("OID_CUSTOM_ADD_TS"),
413 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
414 NULL,
415 (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS},
416 {OID_CUSTOM_DEL_TS,
417 DISP_STRING("OID_CUSTOM_DEL_TS"),
418 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
419 NULL,
420 (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS},
421 */
422
423 /*
424 #if CFG_LP_PATTERN_SEARCH_SLT
425 {OID_CUSTOM_SLT,
426 DISP_STRING("OID_CUSTOM_SLT"),
427 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
428 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult,
429 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode},
430 #endif
431
432 {OID_CUSTOM_ROAMING_EN,
433 DISP_STRING("OID_CUSTOM_ROAMING_EN"),
434 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
435 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction,
436 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction},
437 {OID_CUSTOM_WMM_PS_TEST,
438 DISP_STRING("OID_CUSTOM_WMM_PS_TEST"),
439 TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4,
440 NULL,
441 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest},
442 {OID_CUSTOM_COUNTRY_STRING,
443 DISP_STRING("OID_CUSTOM_COUNTRY_STRING"),
444 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
445 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry,
446 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry},
447
448 #if CFG_SUPPORT_802_11D
449 {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY,
450 DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"),
451 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
452 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap,
453 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap},
454 #endif
455
456 {OID_CUSTOM_GPIO2_MODE,
457 DISP_STRING("OID_CUSTOM_GPIO2_MODE"),
458 FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T),
459 NULL,
460 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode},
461 {OID_CUSTOM_CONTINUOUS_POLL,
462 DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"),
463 FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T),
464 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval,
465 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile},
466 {OID_CUSTOM_DISABLE_BEACON_DETECTION,
467 DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"),
468 FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
469 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc,
470 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc},
471 */
472
473 /* WPS */
474 /*
475 {OID_CUSTOM_DISABLE_PRIVACY_CHECK,
476 DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"),
477 FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
478 NULL,
479 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck},
480 */
481
482 {OID_CUSTOM_MCR_RW,
483 DISP_STRING("OID_CUSTOM_MCR_RW"),
484 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUC_T),
485 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead,
486 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite}
487 ,
488
489 {OID_CUSTOM_EEPROM_RW,
490 DISP_STRING("OID_CUSTOM_EEPROM_RW"),
491 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_T),
492 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead,
493 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite}
494 ,
495
496 {OID_CUSTOM_SW_CTRL,
497 DISP_STRING("OID_CUSTOM_SW_CTRL"),
498 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUC_T),
499 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead,
500 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite}
501 ,
502
503 {OID_CUSTOM_MEM_DUMP,
504 DISP_STRING("OID_CUSTOM_MEM_DUMP"),
505 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUC_T),
506 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump,
507 NULL}
508 ,
509
510 {OID_CUSTOM_TEST_MODE,
511 DISP_STRING("OID_CUSTOM_TEST_MODE"),
512 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
513 NULL,
514 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode}
515 ,
516
517 /*
518 {OID_CUSTOM_TEST_RX_STATUS,
519 DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"),
520 FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUC_T),
521 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus,
522 NULL},
523 {OID_CUSTOM_TEST_TX_STATUS,
524 DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"),
525 FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUC_T),
526 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus,
527 NULL},
528 */
529 {OID_CUSTOM_ABORT_TEST_MODE,
530 DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"),
531 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
532 NULL,
533 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode}
534 ,
535 {OID_CUSTOM_MTK_WIFI_TEST,
536 DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"),
537 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUC_T),
538 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest,
539 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest}
540 ,
541 {OID_CUSTOM_TEST_ICAP_MODE,
542 DISP_STRING("OID_CUSTOM_TEST_ICAP_MODE"),
543 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
544 NULL,
545 (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestIcapMode}
546 ,
547
548 /* OID_CUSTOM_EMULATION_VERSION_CONTROL */
549
550 /* BWCS */
551 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
552 {OID_CUSTOM_BWCS_CMD,
553 DISP_STRING("OID_CUSTOM_BWCS_CMD"),
554 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T),
555 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT,
556 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT}
557 ,
558 #endif
559
560 /* {OID_CUSTOM_SINGLE_ANTENNA,
561 DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"),
562 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4,
563 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna,
564 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna},
565 {OID_CUSTOM_SET_PTA,
566 DISP_STRING("OID_CUSTOM_SET_PTA"),
567 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4,
568 (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta,
569 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta},
570 */
571
572 {OID_CUSTOM_MTK_NVRAM_RW,
573 DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"),
574 TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T),
575 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead,
576 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite}
577 ,
578
579 {OID_CUSTOM_CFG_SRC_TYPE,
580 DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"),
581 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T),
582 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType,
583 NULL}
584 ,
585
586 {OID_CUSTOM_EEPROM_TYPE,
587 DISP_STRING("OID_CUSTOM_EEPROM_TYPE"),
588 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T),
589 (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType,
590 NULL}
591 ,
592
593 #if CFG_SUPPORT_WAPI
594 {OID_802_11_WAPI_MODE,
595 DISP_STRING("OID_802_11_WAPI_MODE"),
596 FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4,
597 NULL,
598 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode}
599 ,
600 {OID_802_11_WAPI_ASSOC_INFO,
601 DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"),
602 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
603 NULL,
604 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo}
605 ,
606 {OID_802_11_SET_WAPI_KEY,
607 DISP_STRING("OID_802_11_SET_WAPI_KEY"),
608 FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T),
609 NULL,
610 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey}
611 ,
612 #endif
613
614 #if CFG_SUPPORT_WPS2
615 {OID_802_11_WSC_ASSOC_INFO,
616 DISP_STRING("OID_802_11_WSC_ASSOC_INFO"),
617 FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0,
618 NULL,
619 (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo}
620 ,
621 #endif
622 };
623
624 /*******************************************************************************
625 * F U N C T I O N S
626 ********************************************************************************
627 */
628
629 /*----------------------------------------------------------------------------*/
630 /*!
631 * \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~
632 * SIOCIWLASTPRIV).
633 *
634 * \param[in] prNetDev Net device requested.
635 * \param[in] prIfReq Pointer to ifreq structure.
636 * \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV.
637 *
638 * \retval 0 for success.
639 * \retval -EOPNOTSUPP If cmd is not supported.
640 * \retval -EFAULT For fail.
641 *
642 */
643 /*----------------------------------------------------------------------------*/
644 int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd)
645 {
646 /* prIfReq is verified in the caller function wlanDoIOCTL() */
647 struct iwreq *prIwReq = (struct iwreq *)prIfReq;
648 struct iw_request_info rIwReqInfo;
649
650 /* prNetDev is verified in the caller function wlanDoIOCTL() */
651
652 /* Prepare the call */
653 rIwReqInfo.cmd = (__u16) i4Cmd;
654 rIwReqInfo.flags = 0;
655
656 switch (i4Cmd) {
657 case IOCTL_SET_INT:
658 /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */
659 return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u));
660
661 case IOCTL_GET_INT:
662 /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */
663 return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u));
664
665 case IOCTL_SET_STRUCT:
666 case IOCTL_SET_STRUCT_FOR_EM:
667 return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u));
668
669 case IOCTL_GET_STRUCT:
670 return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u));
671
672 default:
673 return -EOPNOTSUPP;
674
675 } /* end of switch */
676
677 } /* priv_support_ioctl */
678
679
680 #if CFG_SUPPORT_BATCH_SCAN
681
682 EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN];
683
684 UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum)
685 {
686 UINT_32 u4ChannelInMHz;
687
688 if (u4ChannelNum >= 1 && u4ChannelNum <= 13) {
689 u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5;
690 } else if (u4ChannelNum == 14) {
691 u4ChannelInMHz = 2484;
692 } else if (u4ChannelNum == 133) {
693 u4ChannelInMHz = 3665; /* 802.11y */
694 } else if (u4ChannelNum == 137) {
695 u4ChannelInMHz = 3685; /* 802.11y */
696 } else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) {
697 u4ChannelInMHz = 5000 + u4ChannelNum * 5;
698 } else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) {
699 u4ChannelInMHz = 4000 + u4ChannelNum * 5;
700 } else {
701 u4ChannelInMHz = 0;
702 }
703
704 return u4ChannelInMHz;
705 }
706
707 #define TMP_TEXT_LEN_S 40
708 #define TMP_TEXT_LEN_L 60
709 static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */
710
711
712 WLAN_STATUS
713 batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult,
714 OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen)
715 {
716 CHAR *p = pvBuffer;
717 CHAR ssid[ELEM_MAX_LEN_SSID + 1];
718 INT_32 nsize, nsize1, nsize2, nsize3, scancount;
719 INT_32 i, j, nleft;
720 UINT_32 freq;
721
722 P_EVENT_BATCH_RESULT_ENTRY_T prEntry;
723 P_EVENT_BATCH_RESULT_T pBr;
724
725 nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */
726
727 pBr = prEventBatchResult;
728 scancount = 0;
729 for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) {
730 scancount += pBr->ucScanCount;
731 pBr++;
732 }
733
734 nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%ld\nnextcount=%ld\n",
735 scancount, scancount);
736 if (nsize1 < nleft) {
737 p += nsize1 = kalSprintf(p, "%s", text1);
738 nleft -= nsize1;
739 } else
740 goto short_buf;
741
742
743 pBr = prEventBatchResult;
744 for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) {
745 DBGLOG(SCN, TRACE,
746 ("convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft));
747
748 if (pBr->ucScanCount == 0) {
749 pBr++;
750 continue;
751 }
752
753 nleft -= 5; /* -5 for "####\n" */
754
755 /* We only support one round scan result now. */
756 nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount);
757 if (nsize1 < nleft) {
758 p += nsize1 = kalSprintf(p, "%s", text1);
759 nleft -= nsize1;
760 } else
761 goto short_buf;
762
763 for (i = 0; i < pBr->ucScanCount; i++) {
764 prEntry = &pBr->arBatchResult[i];
765
766 nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n",
767 prEntry->aucBssid[0],
768 prEntry->aucBssid[1],
769 prEntry->aucBssid[2],
770 prEntry->aucBssid[3],
771 prEntry->aucBssid[4], prEntry->aucBssid[5]);
772
773 kalMemCopy(ssid,
774 prEntry->aucSSID,
775 (prEntry->ucSSIDLen <
776 ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID));
777 ssid[(prEntry->ucSSIDLen <
778 (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID -
779 1))] = '\0';
780 nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid);
781
782 freq = batchChannelNum2Freq(prEntry->ucFreq);
783 nsize3 =
784 kalSnprintf(text3, TMP_TEXT_LEN_L,
785 "freq=%lu\nlevel=%d\ndist=%lu\ndistSd=%lu\n====\n", freq,
786 prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd);
787
788 nsize = nsize1 + nsize2 + nsize3;
789 if (nsize < nleft) {
790
791 kalStrnCpy(p, text1, TMP_TEXT_LEN_S);
792 p += nsize1;
793
794 kalStrnCpy(p, text2, TMP_TEXT_LEN_L);
795 p += nsize2;
796
797 kalStrnCpy(p, text3, TMP_TEXT_LEN_L);
798 p += nsize3;
799
800 nleft -= nsize;
801 } else {
802 DBGLOG(SCN, TRACE, ("Warning: Early break! (%d)\n", i));
803 break; /* discard following entries, TODO: apcount? */
804 }
805 }
806
807 nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n");
808 p += kalSprintf(p, "%s", text1);
809
810 pBr++;
811 }
812
813 nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n");
814 kalSprintf(p, "%s", text1);
815
816 *pu4RetLen = u4MaxBufferLen - nleft;
817 DBGLOG(SCN, TRACE, ("total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen));
818
819 return WLAN_STATUS_SUCCESS;
820
821 short_buf:
822 DBGLOG(SCN, TRACE,
823 ("Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft),
824 u4MaxBufferLen, pvBuffer));
825 return WLAN_STATUS_INVALID_LENGTH;
826 }
827 #endif
828
829 /*----------------------------------------------------------------------------*/
830 /*!
831 * \brief Private ioctl set int handler.
832 *
833 * \param[in] prNetDev Net device requested.
834 * \param[in] prIwReqInfo Pointer to iwreq structure.
835 * \param[in] prIwReqData The ioctl data structure, use the field of sub-command.
836 * \param[in] pcExtra The buffer with input value
837 *
838 * \retval 0 For success.
839 * \retval -EOPNOTSUPP If cmd is not supported.
840 * \retval -EINVAL If a value is out of range.
841 *
842 */
843 /*----------------------------------------------------------------------------*/
844 int
845 priv_set_int(IN struct net_device *prNetDev,
846 IN struct iw_request_info *prIwReqInfo,
847 IN union iwreq_data *prIwReqData, IN char *pcExtra)
848 {
849 UINT_32 u4SubCmd;
850 PUINT_32 pu4IntBuf;
851 P_NDIS_TRANSPORT_STRUCT prNdisReq;
852 P_GLUE_INFO_T prGlueInfo;
853 UINT_32 u4BufLen = 0;
854 int status = 0;
855 P_PTA_IPC_T prPtaIpc;
856
857 ASSERT(prNetDev);
858 ASSERT(prIwReqInfo);
859 ASSERT(prIwReqData);
860 ASSERT(pcExtra);
861
862 if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) {
863 return -EINVAL;
864 }
865 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
866
867 u4SubCmd = (UINT_32) prIwReqData->mode;
868 pu4IntBuf = (PUINT_32) pcExtra;
869
870 switch (u4SubCmd) {
871 case PRIV_CMD_TEST_MODE:
872 /* printk("TestMode=%ld\n", pu4IntBuf[1]); */
873 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
874
875 if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) {
876 prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE;
877 } else if (pu4IntBuf[1] == 0) {
878 prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE;
879 } else if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY_ICAP) {
880 prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_ICAP_MODE;
881 } else {
882 status = 0;
883 break;
884 }
885 prNdisReq->inNdisOidlength = 0;
886 prNdisReq->outNdisOidLength = 0;
887
888 /* Execute this OID */
889 status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
890 break;
891
892 case PRIV_CMD_TEST_CMD:
893 /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
894 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
895
896 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
897
898 prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST;
899 prNdisReq->inNdisOidlength = 8;
900 prNdisReq->outNdisOidLength = 8;
901
902 /* Execute this OID */
903 status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
904 break;
905
906 #if CFG_SUPPORT_PRIV_MCR_RW
907 case PRIV_CMD_ACCESS_MCR:
908 /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
909 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
910
911 if (!prGlueInfo->fgMcrAccessAllowed) {
912 if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY &&
913 pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) {
914 prGlueInfo->fgMcrAccessAllowed = TRUE;
915 }
916 status = 0;
917 break;
918 }
919
920 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
921
922 prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW;
923 prNdisReq->inNdisOidlength = 8;
924 prNdisReq->outNdisOidLength = 8;
925
926 /* Execute this OID */
927 status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
928 break;
929 #endif
930
931 case PRIV_CMD_SW_CTRL:
932 /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
933 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
934
935 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
936
937 prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
938 prNdisReq->inNdisOidlength = 8;
939 prNdisReq->outNdisOidLength = 8;
940
941 /* Execute this OID */
942 status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
943 break;
944
945
946 #if 0
947 case PRIV_CMD_BEACON_PERIOD:
948 rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, (PVOID) & pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */
949 sizeof(UINT_32), &u4BufLen);
950 break;
951 #endif
952
953 #if CFG_TCP_IP_CHKSUM_OFFLOAD
954 case PRIV_CMD_CSUM_OFFLOAD:
955 {
956 UINT_32 u4CSUMFlags;
957
958
959 if (pu4IntBuf[1] == 1) {
960 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
961 } else if (pu4IntBuf[1] == 0) {
962 u4CSUMFlags = 0;
963 } else {
964 return -EINVAL;
965 }
966
967 if (kalIoctl(prGlueInfo,
968 wlanoidSetCSUMOffload,
969 (PVOID) & u4CSUMFlags,
970 sizeof(UINT_32),
971 FALSE, FALSE, TRUE, &u4BufLen) == WLAN_STATUS_SUCCESS) {
972 if (pu4IntBuf[1] == 1) {
973 prNetDev->features |= NETIF_F_HW_CSUM;
974 } else if (pu4IntBuf[1] == 0) {
975 prNetDev->features &= ~NETIF_F_HW_CSUM;
976 }
977 }
978 }
979 break;
980 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
981
982 case PRIV_CMD_POWER_MODE:
983 {
984 PARAM_POWER_MODE_T rPowerMode;
985 P_BSS_INFO_T prBssInfo = prGlueInfo->prAdapter->prAisBssInfo;
986
987 if (!prBssInfo) {
988 break;
989 }
990
991 rPowerMode.ePowerMode = (PARAM_POWER_MODE) pu4IntBuf[1];
992 rPowerMode.ucBssIdx = prBssInfo->ucBssIndex;
993
994 kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, &rPowerMode, /* pu4IntBuf[0] is used as input SubCmd */
995 sizeof(PARAM_POWER_MODE_T), FALSE, FALSE, TRUE, &u4BufLen);
996 }
997 break;
998
999 case PRIV_CMD_WMM_PS:
1000 {
1001 PARAM_CUSTOM_WMM_PS_TEST_STRUC_T rWmmPsTest;
1002
1003 rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1];
1004 rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2];
1005 rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3];
1006 rWmmPsTest.reserved = 0;
1007
1008 kalIoctl(prGlueInfo,
1009 wlanoidSetWiFiWmmPsTest,
1010 (PVOID) & rWmmPsTest,
1011 sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUC_T),
1012 FALSE, FALSE, TRUE, &u4BufLen);
1013 }
1014 break;
1015
1016 #if 0
1017 case PRIV_CMD_ADHOC_MODE:
1018 rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, (PVOID) & pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */
1019 sizeof(UINT_32), &u4BufLen);
1020 break;
1021 #endif
1022
1023 case PRIV_CUSTOM_BWCS_CMD:
1024
1025 DBGLOG(REQ, INFO,
1026 ("pu4IntBuf[1] = %x, size of PTA_IPC_T = %d.\n", pu4IntBuf[1],
1027 sizeof(PARAM_PTA_IPC_T)));
1028
1029 prPtaIpc = (P_PTA_IPC_T) aucOidBuf;
1030 prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24);
1031 prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16);
1032 prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8);
1033 prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]);
1034
1035 DBGLOG(REQ, INFO,
1036 ("BCM BWCS CMD : PRIV_CUSTOM_BWCS_CMD : aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[3] = %02x.\n",
1037 prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1],
1038 prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]));
1039
1040 #if 0
1041 status = wlanSetInformation(prGlueInfo->prAdapter,
1042 wlanoidSetBT,
1043 (PVOID) & aucOidBuf[0], u4CmdLen, &u4BufLen);
1044 #endif
1045
1046 status = wlanoidSetBT(prGlueInfo->prAdapter,
1047 (PVOID) & aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen);
1048
1049 if (WLAN_STATUS_SUCCESS != status) {
1050 status = -EFAULT;
1051 }
1052
1053 break;
1054
1055 case PRIV_CMD_BAND_CONFIG:
1056 {
1057 DBGLOG(INIT, INFO, ("CMD set_band = %lu\n", (UINT_32) pu4IntBuf[1]));
1058 }
1059 break;
1060
1061 #if CFG_ENABLE_WIFI_DIRECT
1062 case PRIV_CMD_P2P_MODE:
1063 {
1064 PARAM_CUSTOM_P2P_SET_STRUC_T rSetP2P;
1065 WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
1066
1067 rSetP2P.u4Enable = pu4IntBuf[1];
1068 rSetP2P.u4Mode = pu4IntBuf[2];
1069 #if 1
1070 if (!rSetP2P.u4Enable) {
1071 p2pNetUnregister(prGlueInfo, TRUE);
1072 }
1073
1074 rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) & rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */
1075 sizeof(PARAM_CUSTOM_P2P_SET_STRUC_T),
1076 FALSE, FALSE, TRUE, &u4BufLen);
1077
1078 if ((rSetP2P.u4Enable) && (rWlanStatus == WLAN_STATUS_SUCCESS)) {
1079 p2pNetRegister(prGlueInfo, TRUE);
1080 }
1081 #endif
1082
1083 }
1084 break;
1085 #endif
1086
1087 #if (CFG_MET_PACKET_TRACE_SUPPORT == 1)
1088 case PRIV_CMD_MET_PROFILING:
1089 {
1090 //PARAM_CUSTOM_WFD_DEBUG_STRUC_T rWfdDebugModeInfo;
1091 //rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1];
1092 //rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2];
1093 //DBGLOG(REQ, INFO,("WFD Debug Mode:%d Peroid:%d\n",rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod));
1094 prGlueInfo->fgMetProfilingEn = (UINT_8)pu4IntBuf[1];
1095 prGlueInfo->u2MetUdpPort = (UINT_16)pu4IntBuf[2];
1096 //printk("MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->fgMetProfilingEn, prGlueInfo->u2MetUdpPort);
1097
1098
1099 }
1100 break;
1101
1102 #endif
1103
1104 default:
1105 return -EOPNOTSUPP;
1106 }
1107
1108 return status;
1109 }
1110
1111
1112 /*----------------------------------------------------------------------------*/
1113 /*!
1114 * \brief Private ioctl get int handler.
1115 *
1116 * \param[in] pDev Net device requested.
1117 * \param[out] pIwReq Pointer to iwreq structure.
1118 * \param[in] prIwReqData The ioctl req structure, use the field of sub-command.
1119 * \param[out] pcExtra The buffer with put the return value
1120 *
1121 * \retval 0 For success.
1122 * \retval -EOPNOTSUPP If cmd is not supported.
1123 * \retval -EFAULT For fail.
1124 *
1125 */
1126 /*----------------------------------------------------------------------------*/
1127 int
1128 priv_get_int(IN struct net_device *prNetDev,
1129 IN struct iw_request_info *prIwReqInfo,
1130 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
1131 {
1132 UINT_32 u4SubCmd;
1133 PUINT_32 pu4IntBuf;
1134 P_GLUE_INFO_T prGlueInfo;
1135 UINT_32 u4BufLen = 0;
1136 int status = 0;
1137 P_NDIS_TRANSPORT_STRUCT prNdisReq;
1138 INT_32 ch[50];
1139
1140 ASSERT(prNetDev);
1141 ASSERT(prIwReqInfo);
1142 ASSERT(prIwReqData);
1143 ASSERT(pcExtra);
1144 if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) {
1145 return -EINVAL;
1146 }
1147 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1148
1149 u4SubCmd = (UINT_32) prIwReqData->mode;
1150 pu4IntBuf = (PUINT_32) pcExtra;
1151
1152 switch (u4SubCmd) {
1153 case PRIV_CMD_TEST_CMD:
1154 /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */
1155 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1156
1157 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
1158
1159 prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST;
1160 prNdisReq->inNdisOidlength = 8;
1161 prNdisReq->outNdisOidLength = 8;
1162
1163 status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
1164 if (status == 0) {
1165 /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
1166 prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
1167 /*
1168 if (copy_to_user(prIwReqData->data.pointer,
1169 &prNdisReq->ndisOidContent[4], 4)) {
1170 printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n");
1171 return -EFAULT;
1172 }
1173 */
1174 }
1175 return status;
1176
1177 #if CFG_SUPPORT_PRIV_MCR_RW
1178 case PRIV_CMD_ACCESS_MCR:
1179 /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */
1180 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1181
1182 if (!prGlueInfo->fgMcrAccessAllowed) {
1183 status = 0;
1184 return status;
1185 }
1186
1187 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
1188
1189 prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW;
1190 prNdisReq->inNdisOidlength = 8;
1191 prNdisReq->outNdisOidLength = 8;
1192
1193 status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
1194 if (status == 0) {
1195 /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
1196 prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
1197 }
1198 return status;
1199 #endif
1200
1201 case PRIV_CMD_DUMP_MEM:
1202 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1203
1204 #if 1
1205 if (!prGlueInfo->fgMcrAccessAllowed) {
1206 status = 0;
1207 return status;
1208 }
1209 #endif
1210 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
1211
1212 prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP;
1213 prNdisReq->inNdisOidlength = sizeof(PARAM_CUSTOM_MEM_DUMP_STRUC_T);
1214 prNdisReq->outNdisOidLength = sizeof(PARAM_CUSTOM_MEM_DUMP_STRUC_T);
1215
1216 status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
1217 if (status == 0) {
1218 prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0];
1219 }
1220 return status;
1221
1222 case PRIV_CMD_SW_CTRL:
1223 /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */
1224
1225 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1226
1227 kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8);
1228
1229 prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
1230 prNdisReq->inNdisOidlength = 8;
1231 prNdisReq->outNdisOidLength = 8;
1232
1233 status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
1234 if (status == 0) {
1235 /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
1236 prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4];
1237 }
1238 return status;
1239
1240 #if 0
1241 case PRIV_CMD_BEACON_PERIOD:
1242 status = wlanQueryInformation(prGlueInfo->prAdapter,
1243 wlanoidQueryBeaconInterval,
1244 (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
1245 return status;
1246
1247 case PRIV_CMD_POWER_MODE:
1248 status = wlanQueryInformation(prGlueInfo->prAdapter,
1249 wlanoidQuery802dot11PowerSaveProfile,
1250 (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
1251 return status;
1252
1253 case PRIV_CMD_ADHOC_MODE:
1254 status = wlanQueryInformation(prGlueInfo->prAdapter,
1255 wlanoidQueryAdHocMode,
1256 (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen);
1257 return status;
1258 #endif
1259
1260 case PRIV_CMD_BAND_CONFIG:
1261 DBGLOG(INIT, INFO, ("CMD get_band=\n"));
1262 prIwReqData->mode = 0;
1263 return status;
1264
1265 default:
1266 break;
1267 }
1268
1269 u4SubCmd = (UINT_32) prIwReqData->data.flags;
1270
1271 switch (u4SubCmd) {
1272 case PRIV_CMD_GET_CH_LIST:
1273 {
1274 UINT_16 i, j = 0;
1275 UINT_8 NumOfChannel = 50;
1276 UINT_8 ucMaxChannelNum = 50;
1277 RF_CHANNEL_INFO_T aucChannelList[50];
1278
1279 kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel,
1280 aucChannelList);
1281 if (NumOfChannel > 50)
1282 NumOfChannel = 50;
1283
1284 if (kalIsAPmode(prGlueInfo)) {
1285 for (i = 0; i < NumOfChannel; i++) {
1286 if ((aucChannelList[i].ucChannelNum <= 13) ||
1287 (aucChannelList[i].ucChannelNum == 36
1288 || aucChannelList[i].ucChannelNum == 40
1289 || aucChannelList[i].ucChannelNum == 44
1290 || aucChannelList[i].ucChannelNum == 48)) {
1291 ch[j] = (INT_32) aucChannelList[i].ucChannelNum;
1292 j++;
1293 }
1294 }
1295 } else {
1296 for (j = 0; j < NumOfChannel; j++) {
1297 ch[j] = (INT_32) aucChannelList[j].ucChannelNum;
1298 }
1299 }
1300
1301 prIwReqData->data.length = j;
1302 if (copy_to_user
1303 (prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) {
1304 return -EFAULT;
1305 } else
1306 return status;
1307 }
1308 default:
1309 return -EOPNOTSUPP;
1310 }
1311
1312 return status;
1313 } /* priv_get_int */
1314
1315
1316 /*----------------------------------------------------------------------------*/
1317 /*!
1318 * \brief Private ioctl set int array handler.
1319 *
1320 * \param[in] prNetDev Net device requested.
1321 * \param[in] prIwReqInfo Pointer to iwreq structure.
1322 * \param[in] prIwReqData The ioctl data structure, use the field of sub-command.
1323 * \param[in] pcExtra The buffer with input value
1324 *
1325 * \retval 0 For success.
1326 * \retval -EOPNOTSUPP If cmd is not supported.
1327 * \retval -EINVAL If a value is out of range.
1328 *
1329 */
1330 /*----------------------------------------------------------------------------*/
1331 int
1332 priv_set_ints(IN struct net_device *prNetDev,
1333 IN struct iw_request_info *prIwReqInfo,
1334 IN union iwreq_data *prIwReqData, IN char *pcExtra)
1335 {
1336 UINT_32 u4SubCmd, u4BufLen;
1337 P_GLUE_INFO_T prGlueInfo;
1338 int status = 0;
1339 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1340 P_SET_TXPWR_CTRL_T prTxpwr;
1341
1342 ASSERT(prNetDev);
1343 ASSERT(prIwReqInfo);
1344 ASSERT(prIwReqData);
1345 ASSERT(pcExtra);
1346
1347 if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) {
1348 return -EINVAL;
1349 }
1350 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1351
1352 u4SubCmd = (UINT_32) prIwReqData->data.flags;
1353
1354 switch (u4SubCmd) {
1355 case PRIV_CMD_SET_TX_POWER:
1356 {
1357 INT_32 *setting = prIwReqData->data.pointer;
1358 UINT_16 i;
1359
1360 #if 0
1361 printk("Tx power num = %d\n", prIwReqData->data.length);
1362
1363 printk("Tx power setting = %d %d %d %d\n",
1364 setting[0], setting[1], setting[2], setting[3]);
1365 #endif
1366 prTxpwr = &prGlueInfo->rTxPwr;
1367 if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) {
1368 /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */
1369 if (setting[1] == 1 || setting[1] == 0) {
1370 if (setting[2] == 0 || setting[2] == 1)
1371 prTxpwr->c2GLegacyStaPwrOffset = setting[3];
1372 if (setting[2] == 0 || setting[2] == 2)
1373 prTxpwr->c5GLegacyStaPwrOffset = setting[3];
1374 }
1375 if (setting[1] == 2 || setting[1] == 0) {
1376 if (setting[2] == 0 || setting[2] == 1)
1377 prTxpwr->c2GHotspotPwrOffset = setting[3];
1378 if (setting[2] == 0 || setting[2] == 2)
1379 prTxpwr->c5GHotspotPwrOffset = setting[3];
1380 }
1381 if (setting[1] == 3 || setting[1] == 0) {
1382 if (setting[2] == 0 || setting[2] == 1)
1383 prTxpwr->c2GP2pPwrOffset = setting[3];
1384 if (setting[2] == 0 || setting[2] == 2)
1385 prTxpwr->c5GP2pPwrOffset = setting[3];
1386 }
1387 if (setting[1] == 4 || setting[1] == 0) {
1388 if (setting[2] == 0 || setting[2] == 1)
1389 prTxpwr->c2GBowPwrOffset = setting[3];
1390 if (setting[2] == 0 || setting[2] == 2)
1391 prTxpwr->c5GBowPwrOffset = setting[3];
1392 }
1393 } else if (setting[0] == 1 && prIwReqData->data.length == 2) {
1394 prTxpwr->ucConcurrencePolicy = setting[1];
1395 } else if (setting[0] == 2 && prIwReqData->data.length == 3) {
1396 if (setting[1] == 0) {
1397 for (i = 0; i < 14; i++)
1398 prTxpwr->acTxPwrLimit2G[i] = setting[2];
1399 } else if (setting[1] <= 14)
1400 prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2];
1401 } else if (setting[0] == 3 && prIwReqData->data.length == 3) {
1402 if (setting[1] == 0) {
1403 for (i = 0; i < 4; i++)
1404 prTxpwr->acTxPwrLimit5G[i] = setting[2];
1405 } else if (setting[1] <= 4)
1406 prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2];
1407 } else if (setting[0] == 4 && prIwReqData->data.length == 2) {
1408 if (setting[1] == 0) {
1409 wlanDefTxPowerCfg(prGlueInfo->prAdapter);
1410 }
1411 rStatus = kalIoctl(prGlueInfo,
1412 wlanoidSetTxPower,
1413 prTxpwr,
1414 sizeof(SET_TXPWR_CTRL_T),
1415 TRUE, FALSE, FALSE, &u4BufLen);
1416 } else
1417 return -EFAULT;
1418 }
1419 return status;
1420 default:
1421 break;
1422 }
1423
1424 return status;
1425 }
1426
1427
1428 /*----------------------------------------------------------------------------*/
1429 /*!
1430 * \brief Private ioctl get int array handler.
1431 *
1432 * \param[in] pDev Net device requested.
1433 * \param[out] pIwReq Pointer to iwreq structure.
1434 * \param[in] prIwReqData The ioctl req structure, use the field of sub-command.
1435 * \param[out] pcExtra The buffer with put the return value
1436 *
1437 * \retval 0 For success.
1438 * \retval -EOPNOTSUPP If cmd is not supported.
1439 * \retval -EFAULT For fail.
1440 *
1441 */
1442 /*----------------------------------------------------------------------------*/
1443 int
1444 priv_get_ints(IN struct net_device *prNetDev,
1445 IN struct iw_request_info *prIwReqInfo,
1446 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
1447 {
1448 UINT_32 u4SubCmd;
1449 P_GLUE_INFO_T prGlueInfo;
1450 int status = 0;
1451 INT_32 ch[50];
1452
1453 ASSERT(prNetDev);
1454 ASSERT(prIwReqInfo);
1455 ASSERT(prIwReqData);
1456 ASSERT(pcExtra);
1457 if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) {
1458 return -EINVAL;
1459 }
1460 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1461
1462 u4SubCmd = (UINT_32) prIwReqData->data.flags;
1463
1464 switch (u4SubCmd) {
1465 case PRIV_CMD_GET_CH_LIST:
1466 {
1467 UINT_16 i;
1468 UINT_8 NumOfChannel = 50;
1469 UINT_8 ucMaxChannelNum = 50;
1470 RF_CHANNEL_INFO_T aucChannelList[50];
1471
1472 kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel,
1473 aucChannelList);
1474 if (NumOfChannel > 50)
1475 NumOfChannel = 50;
1476
1477 for (i = 0; i < NumOfChannel; i++) {
1478 ch[i] = (INT_32) aucChannelList[i].ucChannelNum;
1479 }
1480
1481 prIwReqData->data.length = NumOfChannel;
1482 if (copy_to_user
1483 (prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) {
1484 return -EFAULT;
1485 } else
1486 return status;
1487 }
1488 default:
1489 break;
1490 }
1491
1492 return status;
1493 } /* priv_get_int */
1494
1495 /*----------------------------------------------------------------------------*/
1496 /*!
1497 * \brief Private ioctl set structure handler.
1498 *
1499 * \param[in] pDev Net device requested.
1500 * \param[in] prIwReqData Pointer to iwreq_data structure.
1501 *
1502 * \retval 0 For success.
1503 * \retval -EOPNOTSUPP If cmd is not supported.
1504 * \retval -EINVAL If a value is out of range.
1505 *
1506 */
1507 /*----------------------------------------------------------------------------*/
1508 int
1509 priv_set_struct(IN struct net_device *prNetDev,
1510 IN struct iw_request_info *prIwReqInfo,
1511 IN union iwreq_data *prIwReqData, IN char *pcExtra)
1512 {
1513 UINT_32 u4SubCmd = 0;
1514 int status = 0;
1515 /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */
1516 UINT_32 u4CmdLen = 0;
1517 P_NDIS_TRANSPORT_STRUCT prNdisReq;
1518 PUINT_32 pu4IntBuf = NULL;
1519
1520 P_GLUE_INFO_T prGlueInfo = NULL;
1521 UINT_32 u4BufLen = 0;
1522
1523 ASSERT(prNetDev);
1524 /* ASSERT(prIwReqInfo); */
1525 ASSERT(prIwReqData);
1526 /* ASSERT(pcExtra); */
1527
1528 kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf));
1529
1530 if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) {
1531 return -EINVAL;
1532 }
1533 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1534
1535 u4SubCmd = (UINT_32) prIwReqData->data.flags;
1536
1537 #if 0
1538 printk(KERN_INFO DRV_NAME "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n",
1539 prIwReqInfo->cmd, u4SubCmd);
1540 #endif
1541
1542 switch (u4SubCmd) {
1543 #if 0 /* PTA_ENABLED */
1544 case PRIV_CMD_BT_COEXIST:
1545 u4CmdLen = prIwReqData->data.length * sizeof(UINT_32);
1546 ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen);
1547 if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) {
1548 return -EFAULT;
1549 }
1550
1551 if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) {
1552 status = -EFAULT; /* return -EFAULT; */
1553 break;
1554 }
1555
1556 rStatus = wlanSetInformation(prGlueInfo->prAdapter,
1557 wlanoidSetBtCoexistCtrl,
1558 (PVOID) & aucOidBuf[0], u4CmdLen, &u4BufLen);
1559 if (WLAN_STATUS_SUCCESS != rStatus) {
1560 status = -EFAULT;
1561 }
1562 break;
1563 #endif
1564
1565 case PRIV_CUSTOM_BWCS_CMD:
1566 u4CmdLen = prIwReqData->data.length * sizeof(UINT_32);
1567 ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen);
1568 if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) {
1569 return -EFAULT;
1570 }
1571 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG
1572 DBGLOG(REQ, INFO,
1573 ("ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n",
1574 u4CmdLen, sizeof(PARAM_PTA_IPC_T), prIwReqData->data));
1575
1576 DBGLOG(REQ, INFO, ("priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n",
1577 prIwReqInfo->cmd, u4SubCmd));
1578
1579 DBGLOG(REQ, INFO, ("*pcExtra = 0x%x\n", *pcExtra));
1580 #endif
1581
1582 if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) {
1583 status = -EFAULT; /* return -EFAULT; */
1584 break;
1585 }
1586 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG
1587 DBGLOG(REQ, INFO, ("priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n",
1588 aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]));
1589 #endif
1590
1591 #if 0
1592 status = wlanSetInformation(prGlueInfo->prAdapter,
1593 wlanoidSetBT,
1594 (PVOID) & aucOidBuf[0], u4CmdLen, &u4BufLen);
1595 #endif
1596
1597 #if 1
1598 status = wlanoidSetBT(prGlueInfo->prAdapter,
1599 (PVOID) & aucOidBuf[0], u4CmdLen, &u4BufLen);
1600 #endif
1601
1602 if (WLAN_STATUS_SUCCESS != status) {
1603 status = -EFAULT;
1604 }
1605
1606 break;
1607
1608 #if CFG_SUPPORT_WPS2
1609 case PRIV_CMD_WSC_PROBE_REQ:
1610 {
1611 /* retrieve IE for Probe Request */
1612 if (prIwReqData->data.length > 0) {
1613 if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer,
1614 prIwReqData->data.length)) {
1615 status = -EFAULT;
1616 break;
1617 }
1618 prGlueInfo->u2WSCIELen = prIwReqData->data.length;
1619 } else {
1620 prGlueInfo->u2WSCIELen = 0;
1621 }
1622 }
1623 break;
1624 #endif
1625 case PRIV_CMD_OID:
1626 if (copy_from_user(&aucOidBuf[0],
1627 prIwReqData->data.pointer, prIwReqData->data.length)) {
1628 status = -EFAULT;
1629 break;
1630 }
1631 if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) {
1632 DBGLOG(REQ, INFO, ("pcExtra buffer is valid\n"));
1633 } else
1634 DBGLOG(REQ, INFO, ("pcExtra 0x%p\n", pcExtra));
1635
1636 /* Execute this OID */
1637 status =
1638 priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen);
1639 /* Copy result to user space */
1640 ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen;
1641
1642 if (copy_to_user(prIwReqData->data.pointer,
1643 &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) {
1644 DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n"));
1645 status = -EFAULT;
1646 }
1647
1648 break;
1649
1650 case PRIV_CMD_SW_CTRL:
1651 pu4IntBuf = (PUINT_32) prIwReqData->data.pointer;
1652 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1653
1654 /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */
1655 if (copy_from_user(&prNdisReq->ndisOidContent[0],
1656 prIwReqData->data.pointer, prIwReqData->data.length)) {
1657 status = -EFAULT;
1658 break;
1659 }
1660 prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
1661 prNdisReq->inNdisOidlength = 8;
1662 prNdisReq->outNdisOidLength = 8;
1663
1664 /* Execute this OID */
1665 status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen);
1666 break;
1667
1668 default:
1669 return -EOPNOTSUPP;
1670 }
1671
1672 return status;
1673 }
1674
1675 /*----------------------------------------------------------------------------*/
1676 /*!
1677 * \brief Private ioctl get struct handler.
1678 *
1679 * \param[in] pDev Net device requested.
1680 * \param[out] pIwReq Pointer to iwreq structure.
1681 * \param[in] cmd Private sub-command.
1682 *
1683 * \retval 0 For success.
1684 * \retval -EFAULT If copy from user space buffer fail.
1685 * \retval -EOPNOTSUPP Parameter "cmd" not recognized.
1686 *
1687 */
1688 /*----------------------------------------------------------------------------*/
1689 int
1690 priv_get_struct(IN struct net_device *prNetDev,
1691 IN struct iw_request_info *prIwReqInfo,
1692 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
1693 {
1694 UINT_32 u4SubCmd = 0;
1695 P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL;
1696
1697 P_GLUE_INFO_T prGlueInfo = NULL;
1698 UINT_32 u4BufLen = 0;
1699 PUINT_32 pu4IntBuf = NULL;
1700 int status = 0;
1701 UINT_32 u4CopyDataMax = 0;
1702
1703 kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf));
1704
1705 ASSERT(prNetDev);
1706 ASSERT(prIwReqData);
1707 if (!prNetDev || !prIwReqData) {
1708 DBGLOG(REQ, INFO, ("priv_get_struct(): invalid param(0x%p, 0x%p)\n",
1709 prNetDev, prIwReqData));
1710 return -EINVAL;
1711 }
1712
1713 u4SubCmd = (UINT_32) prIwReqData->data.flags;
1714 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1715 ASSERT(prGlueInfo);
1716 if (!prGlueInfo) {
1717 DBGLOG(REQ, INFO, ("priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n",
1718 prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))));
1719 return -EINVAL;
1720 }
1721 #if 0
1722 printk(KERN_INFO DRV_NAME "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n",
1723 prIwReqInfo->cmd, u4SubCmd);
1724 #endif
1725 memset(aucOidBuf, 0, sizeof(aucOidBuf));
1726
1727 switch (u4SubCmd) {
1728 case PRIV_CMD_OID:
1729 if (copy_from_user(&aucOidBuf[0],
1730 prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) {
1731 DBGLOG(REQ, INFO, ("priv_get_struct() copy_from_user oidBuf fail\n"));
1732 return -EFAULT;
1733 }
1734
1735 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1736 #if 0
1737 printk(KERN_NOTICE "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n",
1738 cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength);
1739 #endif
1740 if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) {
1741 prNdisReq->outNdisOidLength = u4BufLen;
1742 if (copy_to_user(prIwReqData->data.pointer,
1743 &aucOidBuf[0],
1744 u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) -
1745 sizeof(prNdisReq->ndisOidContent))) {
1746 DBGLOG(REQ, INFO,
1747 ("priv_get_struct() copy_to_user oidBuf fail(1)\n"));
1748 return -EFAULT;
1749 }
1750 return 0;
1751 } else {
1752 prNdisReq->outNdisOidLength = u4BufLen;
1753 if (copy_to_user(prIwReqData->data.pointer,
1754 &aucOidBuf[0],
1755 OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) {
1756 DBGLOG(REQ, INFO,
1757 ("priv_get_struct() copy_to_user oidBuf fail(2)\n"));
1758 }
1759 return -EFAULT;
1760 }
1761 break;
1762
1763 case PRIV_CMD_SW_CTRL:
1764 pu4IntBuf = (PUINT_32) prIwReqData->data.pointer;
1765 prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0];
1766
1767 u4CopyDataMax = sizeof(aucOidBuf) - OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent);
1768 if ((prIwReqData->data.length > u4CopyDataMax)
1769 || copy_from_user(&prNdisReq->ndisOidContent[0],
1770 prIwReqData->data.pointer,
1771 prIwReqData->data.length)) {
1772 DBGLOG(REQ, INFO, ("priv_get_struct() copy_from_user oidBuf fail\n"));
1773 return -EFAULT;
1774 }
1775
1776 prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL;
1777 prNdisReq->inNdisOidlength = 8;
1778 prNdisReq->outNdisOidLength = 8;
1779
1780 status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen);
1781 if (status == 0) {
1782 prNdisReq->outNdisOidLength = u4BufLen;
1783 /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */
1784
1785 if (copy_to_user(prIwReqData->data.pointer,
1786 &prNdisReq->ndisOidContent[4],
1787 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)){
1788 DBGLOG(REQ, INFO,
1789 ("priv_get_struct() copy_to_user oidBuf fail(2)\n"));
1790 }
1791 }
1792 return 0;
1793 break;
1794 default:
1795 DBGLOG(REQ, WARN, ("get struct cmd:0x%lx\n", u4SubCmd));
1796 return -EOPNOTSUPP;
1797 }
1798 } /* priv_get_struct */
1799
1800 /*----------------------------------------------------------------------------*/
1801 /*!
1802 * \brief The routine handles a set operation for a single OID.
1803 *
1804 * \param[in] pDev Net device requested.
1805 * \param[in] ndisReq Ndis request OID information copy from user.
1806 * \param[out] outputLen_p If the call is successful, returns the number of
1807 * bytes written into the query buffer. If the
1808 * call failed due to invalid length of the query
1809 * buffer, returns the amount of storage needed..
1810 *
1811 * \retval 0 On success.
1812 * \retval -EOPNOTSUPP If cmd is not supported.
1813 *
1814 */
1815 /*----------------------------------------------------------------------------*/
1816 static int
1817 priv_set_ndis(IN struct net_device *prNetDev,
1818 IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen)
1819 {
1820 P_WLAN_REQ_ENTRY prWlanReqEntry = NULL;
1821 WLAN_STATUS status = WLAN_STATUS_SUCCESS;
1822 P_GLUE_INFO_T prGlueInfo = NULL;
1823 UINT_32 u4SetInfoLen = 0;
1824
1825 ASSERT(prNetDev);
1826 ASSERT(prNdisReq);
1827 ASSERT(pu4OutputLen);
1828
1829 if (!prNetDev || !prNdisReq || !pu4OutputLen) {
1830 DBGLOG(REQ, INFO, ("priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n",
1831 prNetDev, prNdisReq, pu4OutputLen));
1832 return -EINVAL;
1833 }
1834
1835 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1836 ASSERT(prGlueInfo);
1837 if (!prGlueInfo) {
1838 DBGLOG(REQ, INFO, ("priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n",
1839 prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))));
1840 return -EINVAL;
1841 }
1842 #if 0
1843 printk(KERN_INFO DRV_NAME "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n",
1844 prNdisReq->ndisOidCmd);
1845 #endif
1846
1847 if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) {
1848 /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */
1849 return -EOPNOTSUPP;
1850 }
1851
1852 if (NULL == prWlanReqEntry->pfOidSetHandler) {
1853 /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */
1854 return -EOPNOTSUPP;
1855 }
1856 #if 0
1857 printk(KERN_INFO DRV_NAME "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName);
1858 #endif
1859
1860 if (prWlanReqEntry->fgSetBufLenChecking) {
1861 if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) {
1862 DBGLOG(REQ, WARN, ("Set %s: Invalid length (current=%ld, needed=%ld)\n",
1863 prWlanReqEntry->pucOidName,
1864 prNdisReq->inNdisOidlength,
1865 prWlanReqEntry->u4InfoBufLen));
1866
1867 *pu4OutputLen = prWlanReqEntry->u4InfoBufLen;
1868 return -EINVAL;
1869 }
1870 }
1871
1872 if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) {
1873 /* GLUE sw info only */
1874 status = prWlanReqEntry->pfOidSetHandler(prGlueInfo,
1875 prNdisReq->ndisOidContent,
1876 prNdisReq->inNdisOidlength, &u4SetInfoLen);
1877 } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) {
1878 /* multiple sw operations */
1879 status = prWlanReqEntry->pfOidSetHandler(prGlueInfo,
1880 prNdisReq->ndisOidContent,
1881 prNdisReq->inNdisOidlength, &u4SetInfoLen);
1882 } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) {
1883 /* driver core */
1884
1885 status = kalIoctl(prGlueInfo,
1886 (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler,
1887 prNdisReq->ndisOidContent,
1888 prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, &u4SetInfoLen);
1889 } else {
1890 DBGLOG(REQ, INFO, ("priv_set_ndis(): unsupported OID method:0x%x\n",
1891 prWlanReqEntry->eOidMethod));
1892 return -EOPNOTSUPP;
1893 }
1894
1895 *pu4OutputLen = u4SetInfoLen;
1896
1897 switch (status) {
1898 case WLAN_STATUS_SUCCESS:
1899 break;
1900
1901 case WLAN_STATUS_INVALID_LENGTH:
1902 /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */
1903 /* prWlanReqEntry->pucOidName, */
1904 /* prNdisReq->inNdisOidlength, */
1905 /* u4SetInfoLen)); */
1906 break;
1907 }
1908
1909 if (WLAN_STATUS_SUCCESS != status) {
1910 return -EFAULT;
1911 }
1912
1913 return 0;
1914 } /* priv_set_ndis */
1915
1916 /*----------------------------------------------------------------------------*/
1917 /*!
1918 * \brief The routine handles a query operation for a single OID. Basically we
1919 * return information about the current state of the OID in question.
1920 *
1921 * \param[in] pDev Net device requested.
1922 * \param[in] ndisReq Ndis request OID information copy from user.
1923 * \param[out] outputLen_p If the call is successful, returns the number of
1924 * bytes written into the query buffer. If the
1925 * call failed due to invalid length of the query
1926 * buffer, returns the amount of storage needed..
1927 *
1928 * \retval 0 On success.
1929 * \retval -EOPNOTSUPP If cmd is not supported.
1930 * \retval -EINVAL invalid input parameters
1931 *
1932 */
1933 /*----------------------------------------------------------------------------*/
1934 static int
1935 priv_get_ndis(IN struct net_device *prNetDev,
1936 IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen)
1937 {
1938 P_WLAN_REQ_ENTRY prWlanReqEntry = NULL;
1939 UINT_32 u4BufLen = 0;
1940 WLAN_STATUS status = WLAN_STATUS_SUCCESS;
1941 P_GLUE_INFO_T prGlueInfo = NULL;
1942
1943 ASSERT(prNetDev);
1944 ASSERT(prNdisReq);
1945 ASSERT(pu4OutputLen);
1946
1947 if (!prNetDev || !prNdisReq || !pu4OutputLen) {
1948 DBGLOG(REQ, INFO, ("priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n",
1949 prNetDev, prNdisReq, pu4OutputLen));
1950 return -EINVAL;
1951 }
1952
1953 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1954 ASSERT(prGlueInfo);
1955 if (!prGlueInfo) {
1956 DBGLOG(REQ, INFO, ("priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n",
1957 prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))));
1958 return -EINVAL;
1959 }
1960 #if 0
1961 printk(KERN_INFO DRV_NAME "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n",
1962 prNdisReq->ndisOidCmd);
1963 #endif
1964
1965 if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) {
1966 /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */
1967 return -EOPNOTSUPP;
1968 }
1969
1970
1971 if (NULL == prWlanReqEntry->pfOidQueryHandler) {
1972 /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */
1973 return -EOPNOTSUPP;
1974 }
1975 #if 0
1976 printk(KERN_INFO DRV_NAME "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName);
1977 #endif
1978
1979 if (prWlanReqEntry->fgQryBufLenChecking) {
1980 if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) {
1981 /* Not enough room in InformationBuffer. Punt */
1982 /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */
1983 /* prWlanReqEntry->pucOidName, */
1984 /* prNdisReq->inNdisOidlength, */
1985 /* prWlanReqEntry->u4InfoBufLen)); */
1986
1987 *pu4OutputLen = prWlanReqEntry->u4InfoBufLen;
1988
1989 status = WLAN_STATUS_INVALID_LENGTH;
1990 return -EINVAL;
1991 }
1992 }
1993
1994
1995 if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) {
1996 /* GLUE sw info only */
1997 status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo,
1998 prNdisReq->ndisOidContent,
1999 prNdisReq->inNdisOidlength, &u4BufLen);
2000 } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) {
2001 /* multiple sw operations */
2002 status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo,
2003 prNdisReq->ndisOidContent,
2004 prNdisReq->inNdisOidlength, &u4BufLen);
2005 } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) {
2006 /* driver core */
2007
2008 status = kalIoctl(prGlueInfo,
2009 (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler,
2010 prNdisReq->ndisOidContent,
2011 prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, &u4BufLen);
2012 } else {
2013 DBGLOG(REQ, INFO, ("priv_set_ndis(): unsupported OID method:0x%x\n",
2014 prWlanReqEntry->eOidMethod));
2015 return -EOPNOTSUPP;
2016 }
2017
2018 *pu4OutputLen = u4BufLen;
2019
2020 switch (status) {
2021 case WLAN_STATUS_SUCCESS:
2022 break;
2023
2024 case WLAN_STATUS_INVALID_LENGTH:
2025 /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */
2026 /* prWlanReqEntry->pucOidName, */
2027 /* prNdisReq->inNdisOidlength, */
2028 /* u4BufLen)); */
2029 break;
2030 }
2031
2032 if (WLAN_STATUS_SUCCESS != status) {
2033 return -EOPNOTSUPP;
2034 }
2035
2036 return 0;
2037 } /* priv_get_ndis */
2038
2039 /*----------------------------------------------------------------------------*/
2040 /*!
2041 * \brief This routine is called to search desired OID.
2042 *
2043 * \param rOid[in] Desired NDIS_OID
2044 * \param ppWlanReqEntry[out] Found registered OID entry
2045 *
2046 * \retval TRUE: Matched OID is found
2047 * \retval FALSE: No matched OID is found
2048 */
2049 /*----------------------------------------------------------------------------*/
2050 static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry)
2051 {
2052 INT_32 i, j, k;
2053
2054 i = 0;
2055 j = NUM_SUPPORTED_OIDS - 1;
2056
2057 while (i <= j) {
2058 k = (i + j) / 2;
2059
2060 if (rOid == arWlanOidReqTable[k].rOid) {
2061 *ppWlanReqEntry = &arWlanOidReqTable[k];
2062 return TRUE;
2063 } else if (rOid < arWlanOidReqTable[k].rOid) {
2064 j = k - 1;
2065 } else {
2066 i = k + 1;
2067 }
2068 }
2069
2070 return FALSE;
2071 } /* reqSearchSupportedOidEntry */
2072
2073
2074
2075 /*----------------------------------------------------------------------------*/
2076 /*!
2077 * \brief Private ioctl driver handler.
2078 *
2079 * \param[in] pDev Net device requested.
2080 * \param[out] pIwReq Pointer to iwreq structure.
2081 * \param[in] cmd Private sub-command.
2082 *
2083 * \retval 0 For success.
2084 * \retval -EFAULT If copy from user space buffer fail.
2085 * \retval -EOPNOTSUPP Parameter "cmd" not recognized.
2086 *
2087 */
2088 /*----------------------------------------------------------------------------*/
2089 int
2090 priv_set_driver(IN struct net_device *prNetDev,
2091 IN struct iw_request_info *prIwReqInfo,
2092 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
2093 {
2094 UINT_32 u4SubCmd = 0;
2095 UINT_16 u2Cmd = 0;
2096
2097 P_GLUE_INFO_T prGlueInfo = NULL;
2098 INT_32 i4BytesWritten = 0;
2099
2100 ASSERT(prNetDev);
2101 ASSERT(prIwReqData);
2102 if (!prNetDev || !prIwReqData) {
2103 DBGLOG(REQ, INFO, ("priv_set_driver(): invalid param(0x%p, 0x%p)\n",
2104 prNetDev, prIwReqData));
2105 return -EINVAL;
2106 }
2107
2108 u2Cmd = prIwReqInfo->cmd;
2109 DBGLOG(REQ, INFO, ("prIwReqInfo->cmd %u\n", u2Cmd));
2110
2111 u4SubCmd = (UINT_32) prIwReqData->data.flags;
2112 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2113 ASSERT(prGlueInfo);
2114 if (!prGlueInfo) {
2115 DBGLOG(REQ, INFO, ("priv_set_driver(): invalid prGlueInfo(0x%p, 0x%p)\n",
2116 prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))));
2117 return -EINVAL;
2118 }
2119
2120 /* trick,hack in ./net/wireless/wext-priv.c ioctl_private_iw_point */
2121 /* becasue the cmd number is odd (get), the input string will not be copy_to_user */
2122
2123 DBGLOG(REQ, INFO, ("prIwReqData->data.length %u\n", prIwReqData->data.length));
2124
2125 /* Use GET tyep becauase large data by iwpriv. */
2126
2127 ASSERT(IW_IS_GET(u2Cmd));
2128 if (prIwReqData->data.length != 0) {
2129 if (!access_ok(VERIFY_READ, prIwReqData->data.pointer, prIwReqData->data.length)) {
2130 DBGLOG(REQ, INFO,
2131 ("%s access_ok Read fail written = %d\n", __func__,
2132 i4BytesWritten));
2133 return -EFAULT;
2134 }
2135 if (copy_from_user(pcExtra, prIwReqData->data.pointer, prIwReqData->data.length)) {
2136 DBGLOG(REQ, INFO,
2137 ("%s copy_form_user fail written = %d\n", __func__,
2138 prIwReqData->data.length));
2139 return -EFAULT;
2140 }
2141 }
2142
2143 if (pcExtra) {
2144 DBGLOG(REQ, INFO, ("pcExtra %s\n", pcExtra));
2145 /* Please check max length in rIwPrivTable */
2146 DBGLOG(REQ, INFO,
2147 ("%s prIwReqData->data.length = %d\n", __func__,
2148 prIwReqData->data.length));
2149 i4BytesWritten =
2150 priv_driver_cmds(prNetDev, pcExtra, 2000 /*prIwReqData->data.length */);
2151 DBGLOG(REQ, INFO, ("%s i4BytesWritten = %d\n", __func__, i4BytesWritten));
2152 }
2153
2154 DBGLOG(REQ, INFO, ("pcExtra done\n"));
2155
2156 if (i4BytesWritten > 0) {
2157
2158 if (i4BytesWritten > 2000) {
2159 i4BytesWritten = 2000;
2160 }
2161 prIwReqData->data.length = i4BytesWritten; /* the iwpriv will use the length */
2162
2163 } else if (i4BytesWritten == 0) {
2164 prIwReqData->data.length = i4BytesWritten;
2165 }
2166
2167 #if 0
2168 /* trick,hack in ./net/wireless/wext-priv.c ioctl_private_iw_point */
2169 /* becasue the cmd number is even (set), the return string will not be copy_to_user */
2170 ASSERT(IW_IS_SET(u2Cmd));
2171 if (!access_ok(VERIFY_WRITE, prIwReqData->data.pointer, i4BytesWritten)) {
2172 DBGLOG(REQ, INFO,
2173 ("%s access_ok Write fail written = %d\n", __func__, i4BytesWritten));
2174 return -EFAULT;
2175 }
2176 if (copy_to_user(prIwReqData->data.pointer, pcExtra, i4BytesWritten)) {
2177 DBGLOG(REQ, INFO,
2178 ("%s copy_to_user fail written = %d\n", __func__, i4BytesWritten));
2179 return -EFAULT;
2180 }
2181 #endif
2182
2183 return 0;
2184
2185 } /* priv_set_driver */
2186
2187
2188 #if 0
2189 /*----------------------------------------------------------------------------*/
2190 /*!
2191 * \brief This routine is called to query the radio configuration used in IBSS
2192 * mode and RF test mode.
2193 *
2194 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
2195 * \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query.
2196 * \param[in] u4QueryBufferLen The length of the query buffer.
2197 * \param[out] pu4QueryInfoLen If the call is successful, returns the number of
2198 * bytes written into the query buffer. If the call
2199 * failed due to invalid length of the query buffer,
2200 * returns the amount of storage needed.
2201 *
2202 * \retval WLAN_STATUS_SUCCESS
2203 * \retval WLAN_STATUS_INVALID_LENGTH
2204 */
2205 /*----------------------------------------------------------------------------*/
2206 static WLAN_STATUS
2207 reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo,
2208 OUT PVOID pvQueryBuffer,
2209 IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
2210 {
2211 P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer;
2212 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2213 UINT_32 u4QueryInfoLen = 0;
2214
2215 DEBUGFUNC("wlanoidQueryConfiguration");
2216
2217
2218 ASSERT(prGlueInfo);
2219 ASSERT(pu4QueryInfoLen);
2220
2221 *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T);
2222 if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) {
2223 return WLAN_STATUS_INVALID_LENGTH;
2224 }
2225
2226 ASSERT(pvQueryBuffer);
2227
2228 kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T));
2229
2230 /* Update the current radio configuration. */
2231 prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T);
2232
2233 #if defined(_HIF_SDIO)
2234 rStatus = sdio_io_ctrl(prGlueInfo,
2235 wlanoidSetBeaconInterval,
2236 &prQueryConfig->u4BeaconPeriod,
2237 sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
2238 #else
2239 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
2240 wlanoidQueryBeaconInterval,
2241 &prQueryConfig->u4BeaconPeriod,
2242 sizeof(UINT_32), &u4QueryInfoLen);
2243 #endif
2244 if (rStatus != WLAN_STATUS_SUCCESS) {
2245 return rStatus;
2246 }
2247 #if defined(_HIF_SDIO)
2248 rStatus = sdio_io_ctrl(prGlueInfo,
2249 wlanoidQueryAtimWindow,
2250 &prQueryConfig->u4ATIMWindow,
2251 sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
2252 #else
2253 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
2254 wlanoidQueryAtimWindow,
2255 &prQueryConfig->u4ATIMWindow,
2256 sizeof(UINT_32), &u4QueryInfoLen);
2257 #endif
2258 if (rStatus != WLAN_STATUS_SUCCESS) {
2259 return rStatus;
2260 }
2261 #if defined(_HIF_SDIO)
2262 rStatus = sdio_io_ctrl(prGlueInfo,
2263 wlanoidQueryFrequency,
2264 &prQueryConfig->u4DSConfig,
2265 sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen);
2266 #else
2267 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
2268 wlanoidQueryFrequency,
2269 &prQueryConfig->u4DSConfig,
2270 sizeof(UINT_32), &u4QueryInfoLen);
2271 #endif
2272 if (rStatus != WLAN_STATUS_SUCCESS) {
2273 return rStatus;
2274 }
2275
2276 prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
2277
2278 return rStatus;
2279
2280 } /* end of reqExtQueryConfiguration() */
2281
2282
2283 /*----------------------------------------------------------------------------*/
2284 /*!
2285 * \brief This routine is called to set the radio configuration used in IBSS
2286 * mode.
2287 *
2288 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
2289 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set.
2290 * \param[in] u4SetBufferLen The length of the set buffer.
2291 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2292 * bytes read from the set buffer. If the call failed
2293 * due to invalid length of the set buffer, returns
2294 * the amount of storage needed.
2295 *
2296 * \retval WLAN_STATUS_SUCCESS
2297 * \retval WLAN_STATUS_INVALID_LENGTH
2298 * \retval WLAN_STATUS_NOT_ACCEPTED
2299 */
2300 /*----------------------------------------------------------------------------*/
2301 static WLAN_STATUS
2302 reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo,
2303 IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
2304 {
2305 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2306 P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer;
2307 UINT_32 u4SetInfoLen = 0;
2308
2309 DEBUGFUNC("wlanoidSetConfiguration");
2310
2311
2312 ASSERT(prGlueInfo);
2313 ASSERT(pu4SetInfoLen);
2314
2315 *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T);
2316
2317 if (u4SetBufferLen < *pu4SetInfoLen) {
2318 return WLAN_STATUS_INVALID_LENGTH;
2319 }
2320
2321 /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */
2322 if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) {
2323 return WLAN_STATUS_NOT_ACCEPTED;
2324 }
2325
2326 ASSERT(pvSetBuffer);
2327
2328 #if defined(_HIF_SDIO)
2329 rStatus = sdio_io_ctrl(prGlueInfo,
2330 wlanoidSetBeaconInterval,
2331 &prNewConfig->u4BeaconPeriod,
2332 sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
2333 #else
2334 rStatus = wlanSetInformation(prGlueInfo->prAdapter,
2335 wlanoidSetBeaconInterval,
2336 &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen);
2337 #endif
2338 if (rStatus != WLAN_STATUS_SUCCESS) {
2339 return rStatus;
2340 }
2341 #if defined(_HIF_SDIO)
2342 rStatus = sdio_io_ctrl(prGlueInfo,
2343 wlanoidSetAtimWindow,
2344 &prNewConfig->u4ATIMWindow,
2345 sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
2346 #else
2347 rStatus = wlanSetInformation(prGlueInfo->prAdapter,
2348 wlanoidSetAtimWindow,
2349 &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen);
2350 #endif
2351 if (rStatus != WLAN_STATUS_SUCCESS) {
2352 return rStatus;
2353 }
2354 #if defined(_HIF_SDIO)
2355 rStatus = sdio_io_ctrl(prGlueInfo,
2356 wlanoidSetFrequency,
2357 &prNewConfig->u4DSConfig,
2358 sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen);
2359 #else
2360 rStatus = wlanSetInformation(prGlueInfo->prAdapter,
2361 wlanoidSetFrequency,
2362 &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen);
2363 #endif
2364
2365 if (rStatus != WLAN_STATUS_SUCCESS) {
2366 return rStatus;
2367 }
2368
2369 return rStatus;
2370
2371 } /* end of reqExtSetConfiguration() */
2372
2373 #endif
2374 /*----------------------------------------------------------------------------*/
2375 /*!
2376 * \brief This routine is called to set beacon detection function enable/disable state
2377 * This is mainly designed for usage under BT inquiry state (disable function).
2378 *
2379 * \param[in] pvAdapter Pointer to the Adapter structure
2380 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2381 * \param[in] u4SetBufferLen The length of the set buffer
2382 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2383 * bytes read from the set buffer. If the call failed due to invalid length of
2384 * the set buffer, returns the amount of storage needed.
2385 *
2386 * \retval WLAN_STATUS_SUCCESS
2387 * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong.
2388 * \retval WLAN_STATUS_INVALID_LENGTH
2389 *
2390 */
2391 /*----------------------------------------------------------------------------*/
2392 static WLAN_STATUS
2393 reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo,
2394 IN PVOID pvSetBuffer,
2395 IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen)
2396 {
2397 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2398
2399 ASSERT(prGlueInfo);
2400 ASSERT(pvSetBuffer);
2401 ASSERT(pu4SetInfoLen);
2402
2403 /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */
2404
2405 /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */
2406 /* wlanoidSetAcpiDevicePowerState, */
2407 /* pvSetBuffer, */
2408 /* u4SetBufferLen, */
2409 /* pu4SetInfoLen); */
2410 return rStatus;
2411 }
2412
2413 #define CMD_START "START"
2414 #define CMD_STOP "STOP"
2415 #define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
2416 #define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
2417 #define CMD_RSSI "RSSI"
2418 #define CMD_LINKSPEED "LINKSPEED"
2419 #define CMD_RXFILTER_START "RXFILTER-START"
2420 #define CMD_RXFILTER_STOP "RXFILTER-STOP"
2421 #define CMD_RXFILTER_ADD "RXFILTER-ADD"
2422 #define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
2423 #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
2424 #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
2425 #define CMD_BTCOEXMODE "BTCOEXMODE"
2426 #define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
2427 #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
2428 #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
2429 #define CMD_SETFWPATH "SETFWPATH"
2430 #define CMD_SETBAND "SETBAND"
2431 #define CMD_GETBAND "GETBAND"
2432 #define CMD_COUNTRY "COUNTRY"
2433 #define CMD_P2P_SET_NOA "P2P_SET_NOA"
2434 #define CMD_P2P_GET_NOA "P2P_GET_NOA"
2435 #define CMD_P2P_SET_PS "P2P_SET_PS"
2436 #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
2437 #define CMD_SETROAMMODE "SETROAMMODE"
2438 #define CMD_MIRACAST "MIRACAST"
2439
2440
2441 #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR"
2442 #define CMD_PNOSETUP_SET "PNOSETUP "
2443 #define CMD_PNOENABLE_SET "PNOFORCE"
2444 #define CMD_PNODEBUG_SET "PNODEBUG"
2445 #define CMD_WLS_BATCHING "WLS_BATCHING"
2446
2447 #define CMD_OKC_SET_PMK "SET_PMK"
2448 #define CMD_OKC_ENABLE "OKC_ENABLE"
2449
2450 /* miracast related definition */
2451 #define MIRACAST_MODE_OFF 0
2452 #define MIRACAST_MODE_SOURCE 1
2453 #define MIRACAST_MODE_SINK 2
2454
2455 #ifndef MIRACAST_AMPDU_SIZE
2456 #define MIRACAST_AMPDU_SIZE 8
2457 #endif
2458
2459 #ifndef MIRACAST_MCHAN_ALGO
2460 #define MIRACAST_MCHAN_ALGO 1
2461 #endif
2462
2463 #ifndef MIRACAST_MCHAN_BW
2464 #define MIRACAST_MCHAN_BW 25
2465 #endif
2466
2467 #define CMD_BAND_AUTO 0
2468 #define CMD_BAND_5G 1
2469 #define CMD_BAND_2G 2
2470 #define CMD_BAND_ALL 3
2471
2472 /* Mediatek private command */
2473
2474 #define CMD_SET_SW_CTRL "SET_SW_CTRL"
2475 #define CMD_GET_SW_CTRL "GET_SW_CTRL"
2476 #define CMD_SET_CFG "SET_CFG"
2477 #define CMD_GET_CFG "GET_CFG"
2478 #define CMD_SET_CHIP "SET_CHIP"
2479 #define CMD_GET_CHIP "GET_CHIP"
2480 #define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL"
2481 #define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL"
2482
2483
2484 static UINT_8 g_ucMiracastMode = MIRACAST_MODE_OFF;
2485
2486
2487 typedef struct cmd_tlv {
2488 char prefix;
2489 char version;
2490 char subver;
2491 char reserved;
2492 } cmd_tlv_t;
2493
2494 typedef struct priv_driver_cmd_s {
2495 char *buf;
2496 int used_len;
2497 int total_len;
2498 } priv_driver_cmd_t;
2499
2500
2501 int priv_driver_set_dbg_level(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2502 {
2503 P_GLUE_INFO_T prGlueInfo = NULL;
2504 INT_32 i4BytesWritten = 0;
2505 INT_32 i4Argc = 0;
2506 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
2507 UINT_32 u4DbgIdx, u4DbgMask;
2508 BOOLEAN fgIsCmdAccept = FALSE;
2509
2510 ASSERT(prNetDev);
2511 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2512 return -1;
2513 }
2514 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2515
2516 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2517 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2518 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2519
2520
2521 if (i4Argc >= 3) {
2522 u4DbgIdx = kalStrtoul(apcArgv[1], NULL, 0);
2523 u4DbgMask = kalStrtoul(apcArgv[2], NULL, 0);
2524
2525 /* DBG level special control */
2526 if (u4DbgIdx == 0xFFFFFFFF) {
2527 fgIsCmdAccept = TRUE;
2528 wlanSetDebugLevel(DBG_ALL_MODULE_IDX, u4DbgMask);
2529 i4BytesWritten =
2530 snprintf(pcCommand, i4TotalLen,
2531 "Set ALL DBG module log level to [0x%02x]!",
2532 (UINT_8) u4DbgMask);
2533 } else if (u4DbgIdx == 0xFFFFFFFE) {
2534 fgIsCmdAccept = TRUE;
2535 wlanDebugInit();
2536 i4BytesWritten =
2537 snprintf(pcCommand, i4TotalLen,
2538 "Reset ALL DBG module log level to DEFAULT!");
2539 } else if (u4DbgIdx < DBG_MODULE_NUM) {
2540 fgIsCmdAccept = TRUE;
2541 wlanSetDebugLevel(u4DbgIdx, u4DbgMask);
2542 i4BytesWritten =
2543 snprintf(pcCommand, i4TotalLen,
2544 "Set DBG module[%lu] log level to [0x%02x]!", u4DbgIdx,
2545 (UINT_8) u4DbgMask);
2546 }
2547 }
2548
2549 if (!fgIsCmdAccept) {
2550 i4BytesWritten =
2551 snprintf(pcCommand, i4TotalLen, "Set DBG module log level failed!");
2552 }
2553
2554 return i4BytesWritten;
2555
2556 } /* priv_driver_set_sw_ctrl */
2557
2558 int priv_driver_get_dbg_level(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2559 {
2560 P_GLUE_INFO_T prGlueInfo = NULL;
2561 INT_32 i4BytesWritten = 0;
2562 INT_32 i4Argc = 0;
2563 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
2564 UINT_32 u4DbgIdx, u4DbgMask;
2565 BOOLEAN fgIsCmdAccept = FALSE;
2566
2567 ASSERT(prNetDev);
2568 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2569 return -1;
2570 }
2571 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2572
2573 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2574 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2575 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2576
2577 if (i4Argc >= 2) {
2578 u4DbgIdx = kalStrtoul(apcArgv[1], NULL, 0);
2579
2580 if (wlanGetDebugLevel(u4DbgIdx, &u4DbgMask) == WLAN_STATUS_SUCCESS) {
2581 fgIsCmdAccept = TRUE;
2582 i4BytesWritten =
2583 snprintf(pcCommand, i4TotalLen,
2584 "Get DBG module[%lu] log level => [0x%02x]!", u4DbgIdx,
2585 (UINT_8) u4DbgMask);
2586 }
2587 }
2588
2589 if (!fgIsCmdAccept) {
2590 i4BytesWritten =
2591 snprintf(pcCommand, i4TotalLen, "Get DBG module log level failed!");
2592 }
2593
2594 return i4BytesWritten;
2595
2596 } /* priv_driver_get_sw_ctrl */
2597
2598 static int
2599 priv_driver_get_sw_ctrl(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2600 {
2601 P_GLUE_INFO_T prGlueInfo = NULL;
2602 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2603 UINT_32 u4BufLen = 0;
2604 INT_32 i4BytesWritten = 0;
2605 INT_32 i4Argc = 0;
2606 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
2607
2608 PARAM_CUSTOM_SW_CTRL_STRUC_T rSwCtrlInfo;
2609
2610 ASSERT(prNetDev);
2611 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2612 return -1;
2613 }
2614 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2615
2616 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2617 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2618 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2619
2620 if (i4Argc >= 2) {
2621 rSwCtrlInfo.u4Id = kalStrtoul(apcArgv[1], NULL, 0);
2622 rSwCtrlInfo.u4Data = 0;
2623
2624 DBGLOG(REQ, LOUD, ("id is %x\n", rSwCtrlInfo.u4Id));
2625
2626 rStatus = kalIoctl(prGlueInfo,
2627 wlanoidQuerySwCtrlRead,
2628 &rSwCtrlInfo, sizeof(rSwCtrlInfo), TRUE, TRUE, TRUE, &u4BufLen);
2629
2630 DBGLOG(REQ, LOUD, ("rStatus %u\n", rStatus));
2631 if (rStatus != WLAN_STATUS_SUCCESS) {
2632 return -1;
2633 }
2634
2635 i4BytesWritten =
2636 snprintf(pcCommand, i4TotalLen, "0x%08x", (unsigned int)rSwCtrlInfo.u4Data);
2637 DBGLOG(REQ, INFO, ("%s: command result is %s\n", __func__, pcCommand));
2638 }
2639
2640 return i4BytesWritten;
2641
2642 } /* priv_driver_get_sw_ctrl */
2643
2644
2645 int priv_driver_set_sw_ctrl(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2646 {
2647 P_GLUE_INFO_T prGlueInfo = NULL;
2648 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2649 UINT_32 u4BufLen = 0;
2650 INT_32 i4BytesWritten = 0;
2651 INT_32 i4Argc = 0;
2652 PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
2653
2654 PARAM_CUSTOM_SW_CTRL_STRUC_T rSwCtrlInfo;
2655
2656 ASSERT(prNetDev);
2657 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2658 return -1;
2659 }
2660 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2661
2662 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2663 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2664 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2665
2666 if (i4Argc >= 3) {
2667 rSwCtrlInfo.u4Id = kalStrtoul(apcArgv[1], NULL, 0);
2668 rSwCtrlInfo.u4Data = kalStrtoul(apcArgv[2], NULL, 0);
2669
2670 rStatus = kalIoctl(prGlueInfo,
2671 wlanoidSetSwCtrlWrite,
2672 &rSwCtrlInfo,
2673 sizeof(rSwCtrlInfo), FALSE, FALSE, TRUE, &u4BufLen);
2674
2675 if (rStatus != WLAN_STATUS_SUCCESS) {
2676 return -1;
2677 }
2678
2679 }
2680
2681 return i4BytesWritten;
2682
2683 } /* priv_driver_set_sw_ctrl */
2684
2685 int priv_driver_set_cfg(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2686 {
2687 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2688 P_GLUE_INFO_T prGlueInfo = NULL;
2689 P_ADAPTER_T prAdapter = NULL;
2690 UINT_32 u4BufLen = 0;
2691 INT_32 i4BytesWritten = 0;
2692 INT_32 i4Argc = 0;
2693 PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
2694
2695 PARAM_CUSTOM_KEY_CFG_STRUC_T rKeyCfgInfo;
2696
2697 ASSERT(prNetDev);
2698 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2699 return -1;
2700 }
2701 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2702
2703 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2704 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2705 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2706 prAdapter = prGlueInfo->prAdapter;
2707
2708 kalMemZero(&rKeyCfgInfo, sizeof(rKeyCfgInfo));
2709
2710 if (i4Argc >= 3) {
2711 /* wlanCfgSet(prAdapter, apcArgv[1], apcArgv[2], 0); */
2712 /* Call by wlanoid becasue the set_cfg will trigger callback */
2713 kalStrnCpy(rKeyCfgInfo.aucKey, apcArgv[1], WLAN_CFG_KEY_LEN_MAX);
2714 kalStrnCpy(rKeyCfgInfo.aucValue, apcArgv[2], WLAN_CFG_KEY_LEN_MAX);
2715 rStatus = kalIoctl(prGlueInfo,
2716 wlanoidSetKeyCfg,
2717 &rKeyCfgInfo,
2718 sizeof(rKeyCfgInfo), FALSE, FALSE, TRUE, &u4BufLen);
2719
2720 if (rStatus != WLAN_STATUS_SUCCESS) {
2721 return -1;
2722 }
2723 }
2724
2725 return i4BytesWritten;
2726
2727 } /* priv_driver_set_cfg */
2728
2729 int priv_driver_get_cfg(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2730 {
2731 P_GLUE_INFO_T prGlueInfo = NULL;
2732 P_ADAPTER_T prAdapter = NULL;
2733 INT_32 i4BytesWritten = 0;
2734 INT_32 i4Argc = 0;
2735 PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
2736 CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX];
2737
2738 ASSERT(prNetDev);
2739 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2740 return -1;
2741 }
2742
2743 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2744
2745 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2746 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
2747 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
2748 prAdapter = prGlueInfo->prAdapter;
2749
2750 if (i4Argc >= 2) {
2751 /* by wlanoid ? */
2752 if (wlanCfgGet(prAdapter, apcArgv[1], aucValue, "", 0) == WLAN_STATUS_SUCCESS) {
2753 kalStrnCpy(pcCommand, aucValue, WLAN_CFG_VALUE_LEN_MAX);
2754 i4BytesWritten = kalStrnLen(pcCommand, WLAN_CFG_VALUE_LEN_MAX);
2755 }
2756 }
2757
2758 return i4BytesWritten;
2759
2760 } /* priv_driver_get_cfg */
2761
2762
2763 int
2764 priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2765 {
2766 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2767 P_GLUE_INFO_T prGlueInfo = NULL;
2768 P_ADAPTER_T prAdapter = NULL;
2769 UINT_32 u4BufLen = 0;
2770 INT_32 i4BytesWritten = 0;
2771 UINT_32 u4CmdLen = 0;
2772 UINT_32 u4PrefixLen = 0;
2773 /* INT_32 i4Argc = 0; */
2774 /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */
2775
2776 PARAM_CUSTOM_CHIP_CONFIG_STRUC_T rChipConfigInfo;
2777
2778 ASSERT(prNetDev);
2779 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2780 return -1;
2781 }
2782 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2783 prAdapter = prGlueInfo->prAdapter;
2784
2785 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2786 /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */
2787 /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */
2788 /* */
2789 u4CmdLen = kalStrnLen(pcCommand, i4TotalLen);
2790 u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */;
2791
2792 kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo));
2793
2794 /* if(i4Argc >= 2) { */
2795 if (u4CmdLen > u4PrefixLen) {
2796
2797 rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE;
2798 /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
2799 rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen;
2800 /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
2801 kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, CHIP_CONFIG_RESP_SIZE);
2802
2803 rStatus = kalIoctl(prGlueInfo,
2804 wlanoidSetChipConfig,
2805 &rChipConfigInfo,
2806 sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, &u4BufLen);
2807
2808 if (rStatus != WLAN_STATUS_SUCCESS) {
2809 DBGLOG(REQ, INFO, ("%s: kalIoctl ret=%d\n", __func__, rStatus));
2810 i4BytesWritten = -1;
2811 }
2812 }
2813
2814 return i4BytesWritten;
2815
2816 } /* priv_driver_set_chip_config */
2817
2818 int
2819 priv_driver_get_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2820 {
2821 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2822 P_GLUE_INFO_T prGlueInfo = NULL;
2823 P_ADAPTER_T prAdapter = NULL;
2824 INT_32 i4BytesWritten = 0;
2825 UINT_32 u4BufLen = 0;
2826 UINT_32 u2MsgSize = 0;
2827 UINT_32 u4CmdLen = 0;
2828 UINT_32 u4PrefixLen = 0;
2829 /* INT_32 i4Argc = 0; */
2830 /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; */
2831
2832 PARAM_CUSTOM_CHIP_CONFIG_STRUC_T rChipConfigInfo;
2833
2834 ASSERT(prNetDev);
2835 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2836 return -1;
2837 }
2838
2839 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2840 prAdapter = prGlueInfo->prAdapter;
2841
2842 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
2843 /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */
2844 /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */
2845
2846 u4CmdLen = kalStrnLen(pcCommand, i4TotalLen);
2847 u4PrefixLen = kalStrLen(CMD_GET_CHIP) + 1 /*space */;
2848
2849 /* if(i4Argc >= 2) { */
2850 if (u4CmdLen > u4PrefixLen) {
2851 rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_ASCII;
2852 /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
2853 rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen;
2854 /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */
2855 kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, CHIP_CONFIG_RESP_SIZE);
2856 rStatus = kalIoctl(prGlueInfo,
2857 wlanoidQueryChipConfig,
2858 &rChipConfigInfo,
2859 sizeof(rChipConfigInfo), TRUE, TRUE, TRUE, &u4BufLen);
2860
2861 if (rStatus != WLAN_STATUS_SUCCESS) {
2862 DBGLOG(REQ, INFO, ("%s: kalIoctl ret=%d\n", __func__, rStatus));
2863 return -1;
2864 }
2865
2866 /* Check respType */
2867 u2MsgSize = rChipConfigInfo.u2MsgSize;
2868 DBGLOG(REQ, INFO, ("%s: RespTyep %u\n", __func__, rChipConfigInfo.ucRespType));
2869 DBGLOG(REQ, INFO, ("%s: u2MsgSize %u\n", __func__, rChipConfigInfo.u2MsgSize));
2870
2871 if (u2MsgSize > sizeof(rChipConfigInfo.aucCmd)) {
2872 DBGLOG(REQ, INFO,
2873 ("%s: u2MsgSize error ret=%u\n", __func__,
2874 rChipConfigInfo.u2MsgSize));
2875 return -1;
2876 }
2877
2878 if (u2MsgSize > 0) {
2879
2880 if (rChipConfigInfo.ucRespType == CHIP_CONFIG_TYPE_ASCII) {
2881 i4BytesWritten =
2882 snprintf(pcCommand + i4BytesWritten, i4TotalLen, "%s",
2883 rChipConfigInfo.aucCmd);
2884 } else {
2885 UINT_32 u4Length;
2886 UINT_32 u4Line;
2887
2888 if (rChipConfigInfo.ucRespType == CHIP_CONFIG_TYPE_MEM8) {
2889 PUINT_8 pucStartAddr = NULL;
2890 pucStartAddr = (PUINT_8) rChipConfigInfo.aucCmd;
2891 /* align 16 bytes becuase one print line is 16 bytes */
2892 u4Length = (((u2MsgSize + 15) >> 4)) << 4;
2893 u4Line = 0;
2894 priv_driver_get_chip_config_16(pucStartAddr, u4Length, u4Line, i4TotalLen, i4BytesWritten, pcCommand);
2895 } else {
2896 PUINT_32 pu4StartAddr = NULL;
2897 pu4StartAddr = (PUINT_32) rChipConfigInfo.aucCmd;
2898 /* align 16 bytes becuase one print line is 16 bytes */
2899 u4Length = (((u2MsgSize + 15) >> 4)) << 4;
2900 u4Line = 0;
2901
2902 if (IS_ALIGN_4((ULONG) pu4StartAddr)) {
2903 priv_driver_get_chip_config_4(pu4StartAddr, u4Length, u4Line, i4TotalLen, i4BytesWritten, pcCommand);
2904 } else {
2905 DBGLOG(REQ, INFO,
2906 ("%s: rChipConfigInfo.aucCmd is not 4 bytes alignment %p\n",
2907 __func__, rChipConfigInfo.aucCmd));
2908 }
2909 } /* ChipConfigInfo.ucRespType */
2910 }
2911 }
2912 /* u2MsgSize > 0 */
2913 DBGLOG(REQ, INFO, ("%s: command result is %s\n", __func__, pcCommand));
2914 }
2915 /* i4Argc */
2916 return i4BytesWritten;
2917
2918 } /* priv_driver_get_chip_config */
2919
2920 static void
2921 priv_driver_get_chip_config_16(PUINT_8 pucStartAddr, UINT_32 u4Length, UINT_32 u4Line, int i4TotalLen, INT_32 i4BytesWritten, char *pcCommand)
2922 {
2923
2924 while (u4Length >= 16) {
2925 if (i4TotalLen > i4BytesWritten) {
2926 i4BytesWritten +=
2927 snprintf(pcCommand + i4BytesWritten,
2928 i4TotalLen - i4BytesWritten,
2929 "%04lx %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n",
2930 u4Line, pucStartAddr[0],
2931 pucStartAddr[1],
2932 pucStartAddr[2],
2933 pucStartAddr[3],
2934 pucStartAddr[4],
2935 pucStartAddr[5],
2936 pucStartAddr[6],
2937 pucStartAddr[7],
2938 pucStartAddr[8],
2939 pucStartAddr[9],
2940 pucStartAddr[10],
2941 pucStartAddr[11],
2942 pucStartAddr[12],
2943 pucStartAddr[13],
2944 pucStartAddr[14],
2945 pucStartAddr[15]);
2946 }
2947
2948 pucStartAddr += 16;
2949 u4Length -= 16;
2950 u4Line += 16;
2951 } /* u4Length */
2952 }
2953
2954 static void
2955 priv_driver_get_chip_config_4(PUINT_32 pu4StartAddr, UINT_32 u4Length, UINT_32 u4Line, int i4TotalLen, INT_32 i4BytesWritten, char *pcCommand)
2956 {
2957 while (u4Length >= 16) {
2958 if (i4TotalLen > i4BytesWritten) {
2959 i4BytesWritten +=
2960 snprintf(pcCommand +
2961 i4BytesWritten,
2962 i4TotalLen -
2963 i4BytesWritten,
2964 "%04lx %08lx %08lx %08lx %08lx\n",
2965 u4Line,
2966 pu4StartAddr[0],
2967 pu4StartAddr[1],
2968 pu4StartAddr[2],
2969 pu4StartAddr[3]);
2970 }
2971
2972 pu4StartAddr += 4;
2973 u4Length -= 16;
2974 u4Line += 4;
2975 } /* u4Length */
2976 }
2977
2978 int priv_driver_get_linkspeed(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
2979 {
2980 P_GLUE_INFO_T prGlueInfo = NULL;
2981 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2982 UINT_32 u4BufLen = 0;
2983 UINT_32 u4Rate = 0;
2984 UINT_32 u4LinkSpeed = 0;
2985 INT_32 i4BytesWritten = 0;
2986
2987 ASSERT(prNetDev);
2988 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
2989 return -1;
2990 }
2991 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2992
2993 if (!netif_carrier_ok(prNetDev)) {
2994 return -1;
2995 }
2996
2997 rStatus = kalIoctl(prGlueInfo,
2998 wlanoidQueryLinkSpeed,
2999 &u4Rate, sizeof(u4Rate), TRUE, TRUE, TRUE, &u4BufLen);
3000
3001 if (rStatus != WLAN_STATUS_SUCCESS) {
3002 return -1;
3003 }
3004
3005 u4LinkSpeed = u4Rate * 100;
3006 i4BytesWritten = snprintf(pcCommand, i4TotalLen, "LinkSpeed %u", (unsigned int)u4LinkSpeed);
3007 DBGLOG(REQ, INFO, ("%s: command result is %s\n", __func__, pcCommand));
3008 return i4BytesWritten;
3009
3010 } /* priv_driver_get_linkspeed */
3011
3012
3013 int priv_driver_set_band(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
3014 {
3015 P_ADAPTER_T prAdapter = NULL;
3016 P_GLUE_INFO_T prGlueInfo = NULL;
3017 INT_32 i4Argc = 0;
3018 UINT_8 ucBand = 0;
3019 UINT_8 ucBssIndex;
3020 ENUM_BAND_T eBand = BAND_NULL;
3021 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
3022
3023 ASSERT(prNetDev);
3024 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
3025 return -1;
3026 }
3027 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3028
3029 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
3030 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
3031 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
3032
3033 prAdapter = prGlueInfo->prAdapter;
3034 if (i4Argc >= 2) {
3035 ucBand = kalStrtoul(apcArgv[1], NULL, 0);
3036 ucBssIndex = wlanGetAisBssIndex(prGlueInfo->prAdapter);
3037 eBand = BAND_NULL;
3038 if (ucBand == CMD_BAND_5G)
3039 eBand = BAND_5G;
3040 else if (ucBand == CMD_BAND_2G)
3041 eBand = BAND_2G4;
3042 prAdapter->aePreferBand[ucBssIndex] = eBand;
3043 /* XXX call wlanSetPreferBandByNetwork directly in different thread */
3044 /* wlanSetPreferBandByNetwork (prAdapter, eBand, ucBssIndex); */
3045 }
3046
3047 return 0;
3048 }
3049
3050
3051 int priv_driver_set_country(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
3052 {
3053
3054 P_GLUE_INFO_T prGlueInfo = NULL;
3055 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3056 UINT_32 u4BufLen = 0;
3057 INT_32 i4Argc = 0;
3058 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
3059 UINT_8 aucCountry[2];
3060
3061 ASSERT(prNetDev);
3062 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
3063 return -1;
3064 }
3065 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3066
3067 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
3068 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
3069 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
3070
3071 if (i4Argc >= 2) {
3072 /* command like "COUNTRY US", "COUNTRY EU" and "COUNTRY JP" */
3073 aucCountry[0] = apcArgv[1][0];
3074 aucCountry[1] = apcArgv[1][1];
3075
3076 rStatus = kalIoctl(prGlueInfo,
3077 wlanoidSetCountryCode,
3078 &aucCountry[0], 2, FALSE, FALSE, TRUE, &u4BufLen);
3079
3080 if (rStatus != WLAN_STATUS_SUCCESS)
3081 return -1;
3082 }
3083 return 0;
3084 }
3085
3086 int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
3087 {
3088
3089 P_ADAPTER_T prAdapter = NULL;
3090 P_GLUE_INFO_T prGlueInfo = NULL;
3091 UINT_32 i4BytesWritten = 0;
3092 /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */
3093 /* UINT_32 u4BufLen = 0; */
3094 INT_32 i4Argc = 0;
3095 UINT_8 ucMode = 0;
3096 P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
3097 P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate =
3098 (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL;
3099 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
3100
3101 ASSERT(prNetDev);
3102 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
3103 return -1;
3104 }
3105
3106
3107
3108 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3109
3110 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
3111 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
3112 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
3113
3114
3115 prAdapter = prGlueInfo->prAdapter;
3116 if (i4Argc >= 2) {
3117
3118 ucMode = kalStrtoul(apcArgv[1], NULL, 0);
3119
3120 if (g_ucMiracastMode == ucMode) {
3121 /* XXX: continue or skip */
3122 }
3123
3124 g_ucMiracastMode = ucMode;
3125 prMsgWfdCfgUpdate =
3126 cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T));
3127
3128 if (prMsgWfdCfgUpdate != NULL) {
3129
3130 prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings);
3131 prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE;
3132 prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings;
3133
3134 if (ucMode == MIRACAST_MODE_OFF) {
3135 prWfdCfgSettings->ucWfdEnable = 0;
3136 snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0");
3137 } else if (ucMode == MIRACAST_MODE_SOURCE) {
3138 prWfdCfgSettings->ucWfdEnable = 1;
3139 snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1");
3140 } else if (ucMode == MIRACAST_MODE_SINK) {
3141 prWfdCfgSettings->ucWfdEnable = 2;
3142 snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2");
3143 } else {
3144 prWfdCfgSettings->ucWfdEnable = 0;
3145 snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0");
3146 }
3147
3148 mboxSendMsg(prAdapter,
3149 MBOX_ID_0,
3150 (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF);
3151
3152 priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen);
3153 } /* prMsgWfdCfgUpdate */
3154 else {
3155 ASSERT(FALSE);
3156 i4BytesWritten = -1;
3157 }
3158 }
3159
3160 /* i4Argc */
3161 return i4BytesWritten;
3162 }
3163
3164 int
3165 priv_driver_set_suspend_mode(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
3166 {
3167 P_GLUE_INFO_T prGlueInfo = NULL;
3168 INT_32 i4Argc = 0;
3169 PCHAR apcArgv[WLAN_CFG_ARGV_MAX];
3170 BOOLEAN fgEnable;
3171
3172 ASSERT(prNetDev);
3173 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
3174 return -1;
3175 }
3176 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3177
3178 DBGLOG(REQ, LOUD, ("command is %s\n", pcCommand));
3179 wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
3180 DBGLOG(REQ, LOUD, ("argc is %i\n", i4Argc));
3181
3182 if (i4Argc >= 2) {
3183 fgEnable = (kalStrtoul(apcArgv[1], NULL, 0) == 1) ? TRUE : FALSE;
3184
3185 DBGLOG(REQ, INFO, ("%s: Set suspend mode [%u]\n", __func__, fgEnable));
3186
3187 if (prGlueInfo->fgIsInSuspendMode == fgEnable) {
3188 DBGLOG(REQ, INFO, ("%s: Already in suspend mode, SKIP!\n", __func__));
3189 return 0;
3190 }
3191
3192 prGlueInfo->fgIsInSuspendMode = fgEnable;
3193
3194 wlanSetSuspendMode(prGlueInfo, fgEnable);
3195 p2pSetSuspendMode(prGlueInfo, fgEnable);
3196 }
3197
3198 return 0;
3199 }
3200
3201
3202 #if CFG_SUPPORT_BATCH_SCAN
3203 #define CMD_BATCH_SET "WLS_BATCHING SET"
3204 #define CMD_BATCH_GET "WLS_BATCHING GET"
3205 #define CMD_BATCH_STOP "WLS_BATCHING STOP"
3206 #endif
3207
3208
3209 INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen)
3210 {
3211 P_GLUE_INFO_T prGlueInfo = NULL;
3212 INT_32 i4BytesWritten = 0;
3213 INT_32 i4CmdFound = 0;
3214
3215 if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) {
3216 return -1;
3217 }
3218 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3219
3220 if (i4CmdFound == 0) {
3221 i4CmdFound = 1;
3222 if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
3223 /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */
3224 } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
3225 i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen);
3226 } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
3227 } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) {
3228 } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) {
3229 } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
3230 /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */
3231 } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
3232 i4BytesWritten =
3233 priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen);
3234 } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
3235 i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen);
3236 } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
3237 /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */
3238 } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
3239 i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen);
3240 } else if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) {
3241 i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen);
3242 }
3243 /* Mediatek private command */
3244 else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) {
3245 i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen);
3246 } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) {
3247 i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen);
3248 } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) {
3249 i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen);
3250 } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) {
3251 i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen);
3252 } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) {
3253 i4BytesWritten =
3254 priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen);
3255 } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) {
3256 i4BytesWritten =
3257 priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen);
3258 } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) {
3259 i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen);
3260 } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) {
3261 i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen);
3262 }
3263 #if CFG_SUPPORT_BATCH_SCAN
3264 else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) {
3265 kalIoctl(prGlueInfo,
3266 wlanoidSetBatchScanReq,
3267 (PVOID) pcCommand,
3268 i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten);
3269 } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) {
3270 /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */
3271 /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */
3272 /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */
3273
3274 UINT_32 u4BufLen;
3275 int i;
3276 /* int rlen=0; */
3277
3278 for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) {
3279 g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */
3280 kalIoctl(prGlueInfo,
3281 wlanoidQueryBatchScanResult,
3282 (PVOID) & g_rEventBatchResult[i],
3283 sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen);
3284 }
3285
3286 #if 0
3287 DBGLOG(SCN, INFO,
3288 ("Batch Scan Results, scan count = %u\n",
3289 g_rEventBatchResult.ucScanCount));
3290 for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) {
3291 prEntry = &g_rEventBatchResult.arBatchResult[i];
3292 DBGLOG(SCN, INFO, ("Entry %u\n", i));
3293 DBGLOG(SCN, INFO,
3294 (" BSSID = " MACSTR "\n",
3295 MAC2STR(prEntry->aucBssid)));
3296 DBGLOG(SCN, INFO, (" SSID = %s\n", prEntry->aucSSID));
3297 DBGLOG(SCN, INFO, (" SSID len = %u\n", prEntry->ucSSIDLen));
3298 DBGLOG(SCN, INFO, (" RSSI = %d\n", prEntry->cRssi));
3299 DBGLOG(SCN, INFO, (" Freq = %u\n", prEntry->ucFreq));
3300 }
3301 #endif
3302
3303 batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen,
3304 &i4BytesWritten);
3305
3306 /* Dump for debug */
3307 /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, TRUE); */
3308
3309 } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) {
3310 kalIoctl(prGlueInfo,
3311 wlanoidSetBatchScanReq,
3312 (PVOID) pcCommand,
3313 i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten);
3314 }
3315 #endif
3316 else {
3317 i4CmdFound = 0;
3318 }
3319 }
3320 /* i4CmdFound */
3321 if (i4CmdFound == 0) {
3322 DBGLOG(REQ, INFO, ("Unknown driver command %s - ignored\n", pcCommand));
3323 }
3324
3325 if (i4BytesWritten >= 0) {
3326 if ((i4BytesWritten == 0) && (i4TotalLen > 0)) {
3327 /* reset the command buffer */
3328 pcCommand[0] = '\0';
3329 }
3330
3331 if (i4BytesWritten >= i4TotalLen) {
3332 DBGLOG(REQ, INFO,
3333 ("%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__,
3334 i4BytesWritten, i4TotalLen));
3335 i4BytesWritten = i4TotalLen;
3336 } else {
3337 pcCommand[i4BytesWritten] = '\0';
3338 i4BytesWritten++;
3339 }
3340 }
3341
3342
3343
3344 return i4BytesWritten;
3345
3346 } /* priv_driver_cmds */
3347
3348
3349 int
3350 priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd)
3351 {
3352 P_GLUE_INFO_T prGlueInfo = NULL;
3353 int ret = 0;
3354 char *pcCommand = NULL;
3355 int i4BytesWritten = 0;
3356 int i4TotalLen = 0;
3357 priv_driver_cmd_t priv_cmd;
3358
3359 if (!prReq->ifr_data) {
3360 ret = -EINVAL;
3361 goto exit;
3362 }
3363
3364 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3365 ASSERT(prGlueInfo);
3366 if (!prGlueInfo) {
3367 DBGLOG(REQ, WARN, ("No glue info\n"));
3368 ret = -EFAULT;
3369 goto exit;
3370 }
3371 if (prGlueInfo->u4ReadyFlag == 0) {
3372 ret = -EINVAL;
3373 goto exit;
3374 }
3375
3376 if (copy_from_user(&priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) {
3377 DBGLOG(REQ, INFO, ("%s: copy_from_user fail\n", __func__));
3378 ret = -EFAULT;
3379 goto exit;
3380 }
3381
3382 i4TotalLen = priv_cmd.total_len;
3383
3384 if (i4TotalLen <= 0) {
3385 ret = -EINVAL;
3386 goto exit;
3387 }
3388
3389 if (!access_ok(VERIFY_READ, priv_cmd.buf, i4TotalLen)) {
3390 DBGLOG(REQ, INFO, ("%s: copy_from_user fail %d\n", __func__, i4TotalLen));
3391 ret = -ENOMEM;
3392 goto exit;
3393 }
3394
3395 pcCommand = kmalloc(i4TotalLen, GFP_KERNEL);
3396 if (!pcCommand) {
3397 DBGLOG(REQ, INFO,
3398 ("%s: failed to allocate memory size %d\n", __func__, i4TotalLen));
3399 ret = -ENOMEM;
3400 goto exit;
3401 }
3402
3403
3404 if (copy_from_user(pcCommand, priv_cmd.buf, i4TotalLen)) {
3405 ret = -EFAULT;
3406 goto exit;
3407 }
3408
3409 DBGLOG(REQ, INFO,
3410 ("%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name));
3411
3412 i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen);
3413
3414 if (i4BytesWritten < 0) {
3415 DBGLOG(REQ, INFO,
3416 ("%s: command %s Written is %d\n", __func__, pcCommand, i4BytesWritten));
3417 if (i4TotalLen >= 3) {
3418 snprintf(pcCommand, 3, "OK");
3419 i4BytesWritten = strlen("OK");
3420 }
3421 }
3422
3423 if (i4BytesWritten >= 0) {
3424 if ((i4BytesWritten == 0) && (i4TotalLen > 0)) {
3425 /* Reset the command buffers */
3426 pcCommand[0] = '\0';
3427 }
3428 if (i4BytesWritten >= i4TotalLen) {
3429 DBGLOG(REQ, INFO,
3430 ("%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__,
3431 i4BytesWritten, i4TotalLen));
3432 i4BytesWritten = i4TotalLen;
3433 } else {
3434 pcCommand[i4BytesWritten] = '\0';
3435 i4BytesWritten++;
3436 }
3437 priv_cmd.used_len = i4BytesWritten;
3438 if (copy_to_user(priv_cmd.buf, pcCommand, i4BytesWritten)) {
3439 DBGLOG(REQ, WARN, ("failed to copy data to user buffer\n"));
3440 ret = -EFAULT;
3441 }
3442 if (copy_to_user(prReq->ifr_data, &priv_cmd, sizeof(priv_driver_cmd_t))) {
3443 DBGLOG(REQ, WARN, ("failed to copy driver_cmd to user buffer\n"));
3444 ret = -EFAULT;
3445 }
3446
3447 }
3448
3449 exit:
3450 if (pcCommand) {
3451 kfree(pcCommand);
3452 }
3453
3454 return ret;
3455 } /* priv_support_driver_cmd */