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