2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 $
6 \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver.
14 * 06 13 2012 yuche.tsai
16 * Update maintrunk driver.
17 * Add support for driver compose assoc request frame.
20 * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
21 * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
24 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
25 * Adding the related ioctl / wlan oid function to set the Tx power cfg.
28 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
29 * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
32 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
33 * 1. eliminaite direct calls to printk in porting layer.
34 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
37 * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
38 * adding the 802.11w related function and define .
40 * 09 23 2011 tsaiyuan.hsu
41 * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state
42 * avoid entering D3 state after deep sleep.
44 * 07 28 2011 chinghwa.yu
45 * [WCXRP00000063] Update BCM CoEx design and settings
46 * Add BWCS cmd and event.
49 * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query the ap address
50 * Remove the netif check while query bssid and ssid
52 * 07 26 2011 chinglan.wang
54 * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection..
56 * 07 18 2011 chinghwa.yu
57 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
58 * Add CMD/Event for RDD and BWCS.
60 * 05 17 2011 eddie.chen
61 * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
62 * Initilize the vairlabes.
64 * 05 11 2011 jeffrey.chang
65 * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
66 * modify set_tx_pow ioctl
69 * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring
70 * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of essid storage array.
73 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
74 * improve portability for awareness of early version of linux kernel and wireless extension.
76 * 03 17 2011 chinglan.wang
77 * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
81 * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
82 * Toggle non-standard debug messages to comments.
85 * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get essid
86 * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running.
88 * 02 08 2011 george.huang
89 * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
90 * Support querying power mode OID.
93 * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0
94 * not doing mem alloc. while set ie length already 0
96 * 01 20 2011 eddie.chen
97 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
100 * 01 20 2011 eddie.chen
101 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
104 * 01 20 2011 eddie.chen
105 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
106 * Add Oid for sw control debug command
108 * 01 11 2011 chinglan.wang
110 * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish successfully.
111 * Use the WPS function to connect AP, the privacy bit always is set to 1. .
113 * 01 07 2011 cm.chang
114 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
115 * Add a new compiling option to control if MCR read/write is permitted
118 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
119 * separate kalMemAlloc() into virtually-continous and physically-continous types
120 * to ease slab system pressure
123 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
124 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
126 * 12 31 2010 cm.chang
127 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
128 * Add some iwpriv commands to support test mode operation
130 * 12 15 2010 george.huang
131 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
132 * Support set PS profile and set WMM-PS related iwpriv.
134 * 12 15 2010 george.huang
135 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
136 * Allow change PS profile function (throught wext_set_power()).
138 * 12 14 2010 jeffrey.chang
139 * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID
142 * 12 13 2010 chinglan.wang
144 * Add WPS 1.0 feature flag to enable the WPS 1.0 function.
146 * 12 07 2010 cm.chang
147 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
148 * Fix compiling error
150 * 12 07 2010 cm.chang
151 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
152 * 1. Country code is from NVRAM or supplicant
153 * 2. Change band definition in CMD/EVENT.
156 * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1
160 * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
161 * add the message check code from mt5921.
163 * 10 19 2010 jeffrey.chang
164 * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power saving
165 * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving
167 * 10 18 2010 jeffrey.chang
168 * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
169 * refine the scan ioctl to prevent hanging of Android UI
172 * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
173 * add the scan result with wapi ie.
176 * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
177 * fixed the wapi ie assigned issue.
181 * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function.
183 * 09 21 2010 kevin.huang
184 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
185 * Eliminate Linux Compile Warning
189 * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
193 * Androi/Linux: return current operating channel information
197 * adding the wapi support for integration test.
199 * 08 02 2010 jeffrey.chang
201 * enable remove key ioctl
203 * 08 02 2010 jeffrey.chang
205 * 1) modify tx service thread to avoid busy looping
206 * 2) add spin lock declartion for linux build
208 * 07 28 2010 jeffrey.chang
210 * 1) enable encyption ioctls
211 * 2) temporarily disable remove keys ioctl to prevent TX1 busy
213 * 07 28 2010 jeffrey.chang
215 * 1) remove unused spinlocks
216 * 2) enable encyption ioctls
217 * 3) fix scan ioctl which may cause supplicant to hang
219 * 07 19 2010 jeffrey.chang
221 * add kal api for scanning done
223 * 07 19 2010 jeffrey.chang
225 * for linux driver migration
227 * 07 19 2010 jeffrey.chang
229 * Linux port modification
233 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
235 * 06 06 2010 kevin.huang
236 * [WPD00003832][MT6620 5931] Create driver base
237 * [MT6620 5931] Create driver base
239 * 05 28 2010 jeffrey.chang
240 * [WPD00003826]Initial import for Linux port
241 * remove unused macro and debug messages
243 * 05 14 2010 jeffrey.chang
244 * [WPD00003826]Initial import for Linux port
245 * Add dissassoication support for wpa supplicant
247 * 04 22 2010 jeffrey.chang
248 * [WPD00003826]Initial import for Linux port
250 * 1) modify rx path code for supporting Wi-Fi direct
251 * 2) modify config.h since Linux dont need to consider retaining packet
253 * 04 21 2010 jeffrey.chang
254 * [WPD00003826]Initial import for Linux port
255 * add for private ioctl support
257 * 04 19 2010 jeffrey.chang
258 * [WPD00003826]Initial import for Linux port
259 * Add ioctl of power management
261 * 04 19 2010 jeffrey.chang
262 * [WPD00003826]Initial import for Linux port
263 * remove debug message
265 * 04 14 2010 jeffrey.chang
266 * [WPD00003826]Initial import for Linux port
267 * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
270 * 04 12 2010 jeffrey.chang
271 * [WPD00003826]Initial import for Linux port
272 * remove debug messages for pre-release
275 * [WPD00001943]Create WiFi test driver framework on WinXP
276 * rWlanInfo should be placed at adapter rather than glue due to most operations
277 * * * * * * * * are done in adapter layer.
279 * 04 02 2010 jeffrey.chang
280 * [WPD00003826]Initial import for Linux port
283 * 04 01 2010 jeffrey.chang
284 * [WPD00003826]Initial import for Linux port
285 * enable pmksa cache operation
287 * 03 31 2010 jeffrey.chang
288 * [WPD00003826]Initial import for Linux port
289 * fix ioctl which may cause cmdinfo memory leak
292 * [WPD00003816][MT6620 Wi-Fi] Adding the security support
293 * modify the wapi related code for new driver's design.
295 * 03 30 2010 jeffrey.chang
296 * [WPD00003826]Initial import for Linux port
297 * emulate NDIS Pending OID facility
299 * 03 24 2010 jeffrey.chang
300 * [WPD00003826]Initial import for Linux port
301 * initial import for Linux port
302 ** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090
303 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
304 ** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090
305 ** Remove unused variables
306 ** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090
307 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
308 ** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088
309 ** adding the wapi ioctl support
310 ** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090
311 ** Add Linux SDIO (with mmc core) support.
312 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
313 ** Fix compile warning in Linux.
314 ** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089
315 ** fix compiling warning
316 ** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089
317 ** Add mandatory and private IO control for Linux BWCS
318 ** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088
319 ** fixed the compiling error
320 ** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088
321 ** add the privacy setting from linux supplicant ap selection
322 ** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088
323 ** fixed the compling error
324 ** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088
325 ** rename some variable with pre-fix to avoid the misunderstanding
326 ** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088
327 ** fixed compiling error
328 ** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088
329 ** adjust the code for meet the coding style, and add assert check
330 ** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461
331 ** Update after wlanoidSetPowerMode changed
332 ** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084
334 ** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461
335 ** Add set desired rate in Linux STD IOCTL
336 ** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088
337 ** add pmkid ioctl and indicate
338 ** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461
339 ** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461
340 ** Refine WPS related priv ioctl for unified interface
342 ** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088
343 ** move the configuration code from set essid function,
344 ** remove the non-used code
345 ** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461
347 ** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461
348 ** Add Set Frequency & Channel oid support for Linux
349 ** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461
350 ** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461
351 ** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter
352 ** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425
354 ** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461
356 ** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425
357 ** 1. Fix compiling erros
359 ** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425
360 ** 1. Add WMM-PS setting
361 ** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088
362 ** fixed the compiler error
363 ** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088
365 ** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425
366 ** 1. Update wlanQueryInformation
369 /*******************************************************************************
370 * C O M P I L E R F L A G S
371 ********************************************************************************
374 /*******************************************************************************
375 * E X T E R N A L R E F E R E N C E S
376 ********************************************************************************
382 #include "wlan_oid.h"
385 #include "gl_wext_priv.h"
393 /* compatibility to wireless extensions */
396 /*******************************************************************************
398 ********************************************************************************
400 const long channel_freq[] = {
401 2412, 2417, 2422, 2427, 2432, 2437, 2442,
402 2447, 2452, 2457, 2462, 2467, 2472, 2484
405 #define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
408 case 1: khz = 2412000; break; \
409 case 2: khz = 2417000; break; \
410 case 3: khz = 2422000; break; \
411 case 4: khz = 2427000; break; \
412 case 5: khz = 2432000; break; \
413 case 6: khz = 2437000; break; \
414 case 7: khz = 2442000; break; \
415 case 8: khz = 2447000; break; \
416 case 9: khz = 2452000; break; \
417 case 10: khz = 2457000; break; \
418 case 11: khz = 2462000; break; \
419 case 12: khz = 2467000; break; \
420 case 13: khz = 2472000; break; \
421 case 14: khz = 2484000; break; \
422 case 36: /* UNII */ khz = 5180000; break; \
423 case 40: /* UNII */ khz = 5200000; break; \
424 case 44: /* UNII */ khz = 5220000; break; \
425 case 48: /* UNII */ khz = 5240000; break; \
426 case 52: /* UNII */ khz = 5260000; break; \
427 case 56: /* UNII */ khz = 5280000; break; \
428 case 60: /* UNII */ khz = 5300000; break; \
429 case 64: /* UNII */ khz = 5320000; break; \
430 case 149: /* UNII */ khz = 5745000; break; \
431 case 153: /* UNII */ khz = 5765000; break; \
432 case 157: /* UNII */ khz = 5785000; break; \
433 case 161: /* UNII */ khz = 5805000; break; \
434 case 165: /* UNII */ khz = 5825000; break; \
435 case 100: /* HiperLAN2 */ khz = 5500000; break; \
436 case 104: /* HiperLAN2 */ khz = 5520000; break; \
437 case 108: /* HiperLAN2 */ khz = 5540000; break; \
438 case 112: /* HiperLAN2 */ khz = 5560000; break; \
439 case 116: /* HiperLAN2 */ khz = 5580000; break; \
440 case 120: /* HiperLAN2 */ khz = 5600000; break; \
441 case 124: /* HiperLAN2 */ khz = 5620000; break; \
442 case 128: /* HiperLAN2 */ khz = 5640000; break; \
443 case 132: /* HiperLAN2 */ khz = 5660000; break; \
444 case 136: /* HiperLAN2 */ khz = 5680000; break; \
445 case 140: /* HiperLAN2 */ khz = 5700000; break; \
446 case 34: /* Japan MMAC */ khz = 5170000; break; \
447 case 38: /* Japan MMAC */ khz = 5190000; break; \
448 case 42: /* Japan MMAC */ khz = 5210000; break; \
449 case 46: /* Japan MMAC */ khz = 5230000; break; \
450 case 184: /* Japan */ khz = 4920000; break; \
451 case 188: /* Japan */ khz = 4940000; break; \
452 case 192: /* Japan */ khz = 4960000; break; \
453 case 196: /* Japan */ khz = 4980000; break; \
454 case 208: /* Japan, means J08 */ khz = 5040000; break; \
455 case 212: /* Japan, means J12 */ khz = 5060000; break; \
456 case 216: /* Japan, means J16 */ khz = 5080000; break; \
457 default: khz = 2412000; break; \
462 #define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0]))
464 #define MAX_SSID_LEN 32
467 /*******************************************************************************
469 ********************************************************************************
472 /*******************************************************************************
473 * P U B L I C D A T A
474 ********************************************************************************
476 /* NOTE: name in iwpriv_args only have 16 bytes */
477 static const struct iw_priv_args rIwPrivTable[] = {
478 {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""},
479 {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
480 {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""},
481 {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""},
482 {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""},
484 {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
485 {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""},
487 {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""},
488 {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""},
489 {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""},
491 /* added for set_oid and get_oid */
492 {IOCTL_SET_STRUCT, 256, 0, ""},
493 {IOCTL_GET_STRUCT, 0, 256, ""},
495 /* sub-ioctl definitions */
497 {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain" },
498 {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain" },
501 #if CFG_TCP_IP_CHKSUM_OFFLOAD
502 {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum" },
503 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
505 {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode" },
506 {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode" },
508 {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps" },
510 {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode" },
511 {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd" },
512 {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_test_result" },
513 #if CFG_SUPPORT_PRIV_MCR_RW
514 {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr" },
515 {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mcr" },
517 {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl" },
518 {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_sw_ctrl" },
520 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
521 {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"},
522 /* GET STRUCT sub-ioctls commands */
523 {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bwcs"},
526 /* SET STRUCT sub-ioctls commands */
527 {PRIV_CMD_OID, 256, 0, "set_oid"},
528 /* GET STRUCT sub-ioctls commands */
529 {PRIV_CMD_OID, 0, 256, "get_oid"},
531 {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band" },
532 {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band" },
534 {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower" },
535 {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list" },
536 {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mem" },
538 #if CFG_ENABLE_WIFI_DIRECT
539 {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode" },
541 {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code" },
544 static const iw_handler rIwPrivHandler[] = {
545 [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int,
546 [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int,
547 [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
548 [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
549 [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL,
550 [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL,
551 [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL,
552 [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL,
553 [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct,
554 [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct,
555 [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct,
556 [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints,
557 [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints,
560 const struct iw_handler_def wext_handler_def = {
562 .num_private = (__u16)sizeof(rIwPrivHandler)/sizeof(iw_handler),
563 .num_private_args = (__u16)sizeof(rIwPrivTable)/sizeof(struct iw_priv_args),
564 .standard = (iw_handler *) NULL,
565 .private = rIwPrivHandler,
566 .private_args = rIwPrivTable,
567 .get_wireless_stats = wext_get_wireless_stats,
570 /*******************************************************************************
571 * P R I V A T E D A T A
572 ********************************************************************************
575 /*******************************************************************************
577 ********************************************************************************
580 /*******************************************************************************
581 * F U N C T I O N D E C L A R A T I O N S
582 ********************************************************************************
585 /*******************************************************************************
587 ********************************************************************************
590 /*----------------------------------------------------------------------------*/
592 * \brief Find the desired WPA/RSN Information Element according to desiredElemID.
594 * \param[in] pucIEStart IE starting address.
595 * \param[in] i4TotalIeLen Total length of all the IE.
596 * \param[in] ucDesiredElemId Desired element ID.
597 * \param[out] ppucDesiredIE Pointer to the desired IE.
599 * \retval TRUE Find the desired IE.
600 * \retval FALSE Desired IE not found.
604 /*----------------------------------------------------------------------------*/
606 wextSrchDesiredWPAIE (
607 IN PUINT_8 pucIEStart,
608 IN INT_32 i4TotalIeLen,
609 IN UINT_8 ucDesiredElemId,
610 OUT PUINT_8 *ppucDesiredIE
613 INT_32 i4InfoElemLen;
616 ASSERT(ppucDesiredIE);
618 while (i4TotalIeLen >= 2) {
619 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
621 if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
622 if (ucDesiredElemId != 0xDD) {
624 *ppucDesiredIE = &pucIEStart[0];
628 /* EID == 0xDD, check WPA IE */
629 if (pucIEStart[1] >= 4) {
630 if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) {
631 *ppucDesiredIE = &pucIEStart[0];
634 } /* check WPA IE length */
635 } /* check EID == 0xDD */
636 } /* check desired EID */
638 /* Select next information element. */
639 i4TotalIeLen -= i4InfoElemLen;
640 pucIEStart += i4InfoElemLen;
644 } /* parseSearchDesiredWPAIE */
648 /*----------------------------------------------------------------------------*/
650 * \brief Find the desired WAPI Information Element .
652 * \param[in] pucIEStart IE starting address.
653 * \param[in] i4TotalIeLen Total length of all the IE.
654 * \param[out] ppucDesiredIE Pointer to the desired IE.
656 * \retval TRUE Find the desired IE.
657 * \retval FALSE Desired IE not found.
661 /*----------------------------------------------------------------------------*/
663 wextSrchDesiredWAPIIE (
664 IN PUINT_8 pucIEStart,
665 IN INT_32 i4TotalIeLen,
666 OUT PUINT_8 *ppucDesiredIE
669 INT_32 i4InfoElemLen;
672 ASSERT(ppucDesiredIE);
674 while (i4TotalIeLen >= 2) {
675 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
677 if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) {
678 *ppucDesiredIE = &pucIEStart[0];
680 } /* check desired EID */
682 /* Select next information element. */
683 i4TotalIeLen -= i4InfoElemLen;
684 pucIEStart += i4InfoElemLen;
688 } /* wextSrchDesiredWAPIIE */
693 /*----------------------------------------------------------------------------*/
695 * \brief Find the desired WPS Information Element according to desiredElemID.
697 * \param[in] pucIEStart IE starting address.
698 * \param[in] i4TotalIeLen Total length of all the IE.
699 * \param[in] ucDesiredElemId Desired element ID.
700 * \param[out] ppucDesiredIE Pointer to the desired IE.
702 * \retval TRUE Find the desired IE.
703 * \retval FALSE Desired IE not found.
707 /*----------------------------------------------------------------------------*/
709 wextSrchDesiredWPSIE (
710 IN PUINT_8 pucIEStart,
711 IN INT_32 i4TotalIeLen,
712 IN UINT_8 ucDesiredElemId,
713 OUT PUINT_8 *ppucDesiredIE)
715 INT_32 i4InfoElemLen;
718 ASSERT(ppucDesiredIE);
720 while (i4TotalIeLen >= 2) {
721 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
723 if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
724 if (ucDesiredElemId != 0xDD) {
726 *ppucDesiredIE = &pucIEStart[0];
730 /* EID == 0xDD, check WPS IE */
731 if (pucIEStart[1] >= 4) {
732 if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) {
733 *ppucDesiredIE = &pucIEStart[0];
736 } /* check WPS IE length */
737 } /* check EID == 0xDD */
738 } /* check desired EID */
740 /* Select next information element. */
741 i4TotalIeLen -= i4InfoElemLen;
742 pucIEStart += i4InfoElemLen;
746 } /* parseSearchDesiredWPSIE */
750 /*----------------------------------------------------------------------------*/
752 * \brief Get the name of the protocol used on the air.
754 * \param[in] prDev Net device requested.
755 * \param[in] prIwrInfo NULL.
756 * \param[out] pcName Buffer to store protocol name string
757 * \param[in] pcExtra NULL.
759 * \retval 0 For success.
761 * \note If netif_carrier_ok, protocol name is returned;
762 * otherwise, "disconnected" is returned.
764 /*----------------------------------------------------------------------------*/
767 IN struct net_device *prNetDev,
768 IN struct iw_request_info *prIwrInfo,
773 ENUM_PARAM_NETWORK_TYPE_T eNetWorkType;
775 P_GLUE_INFO_T prGlueInfo = NULL;
776 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
777 UINT_32 u4BufLen = 0;
781 if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) {
784 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
786 if (netif_carrier_ok(prNetDev)) {
788 rStatus = kalIoctl(prGlueInfo,
789 wlanoidQueryNetworkTypeInUse,
791 sizeof(eNetWorkType),
798 switch(eNetWorkType) {
799 case PARAM_NETWORK_TYPE_DS:
800 strcpy(pcName, "IEEE 802.11b");
802 case PARAM_NETWORK_TYPE_OFDM24:
803 strcpy(pcName, "IEEE 802.11bgn");
805 case PARAM_NETWORK_TYPE_AUTOMODE:
806 case PARAM_NETWORK_TYPE_OFDM5:
807 strcpy(pcName, "IEEE 802.11abgn");
809 case PARAM_NETWORK_TYPE_FH:
811 strcpy(pcName, "IEEE 802.11");
816 strcpy(pcName, "Disconnected");
820 } /* wext_get_name */
822 /*----------------------------------------------------------------------------*/
824 * \brief To set the operating channel in the wireless device.
826 * \param[in] prDev Net device requested.
827 * \param[in] prIwrInfo NULL
828 * \param[in] prFreq Buffer to store frequency information
829 * \param[in] pcExtra NULL
831 * \retval 0 For success.
832 * \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS.
833 * \retval -EINVAL Invalid channel frequency.
835 * \note If infrastructure mode is IBSS, new channel frequency is set to device.
836 * The range of channel number depends on different regulatory domain.
838 /*----------------------------------------------------------------------------*/
841 IN struct net_device *prNetDev,
842 IN struct iw_request_info *prIwReqInfo,
843 IN struct iw_freq *prIwFreq,
849 UINT_32 u4ChnlFreq; /* Store channel or frequency information */
851 P_GLUE_INFO_T prGlueInfo = NULL;
852 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
853 UINT_32 u4BufLen = 0;
857 if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) {
860 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
863 printk("set m:%d, e:%d, i:%d, flags:%d\n",
864 prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags);
867 /* If setting by frequency, convert to a channel */
868 if ((prIwFreq->e == 1) &&
869 (prIwFreq->m >= (int) 2.412e8) &&
870 (prIwFreq->m <= (int) 2.484e8)) {
872 /* Change to KHz format */
873 u4ChnlFreq = (UINT_32)(prIwFreq->m / (KILO / 10));
875 rStatus = kalIoctl(prGlueInfo,
884 if (WLAN_STATUS_SUCCESS != rStatus) {
888 /* Setting by channel number */
889 else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) {
893 /* Change to channel number format */
894 u4ChnlFreq = (UINT_32)prIwFreq->m;
896 rStatus = kalIoctl(prGlueInfo,
908 if (WLAN_STATUS_SUCCESS != rStatus) {
917 } /* wext_set_freq */
920 /*----------------------------------------------------------------------------*/
922 * \brief To get the operating channel in the wireless device.
924 * \param[in] prDev Net device requested.
925 * \param[in] prIwrInfo NULL.
926 * \param[out] prFreq Buffer to store frequency information.
927 * \param[in] pcExtra NULL.
929 * \retval 0 If netif_carrier_ok.
930 * \retval -ENOTCONN Otherwise
932 * \note If netif_carrier_ok, channel frequency information is stored in pFreq.
934 /*----------------------------------------------------------------------------*/
937 IN struct net_device *prNetDev,
938 IN struct iw_request_info *prIwrInfo,
939 OUT struct iw_freq *prIwFreq,
943 UINT_32 u4Channel = 0;
946 P_GLUE_INFO_T prGlueInfo = NULL;
947 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
948 UINT_32 u4BufLen = 0;
952 if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) {
955 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
957 /* GeorgeKuo: TODO skip checking in IBSS mode */
958 if (!netif_carrier_ok(prNetDev)) {
962 rStatus = kalIoctl(prGlueInfo,
963 wlanoidQueryFrequency,
972 prIwFreq->m = (int) u4Channel; /* freq in KHz */
977 } /* wext_get_freq */
980 /*----------------------------------------------------------------------------*/
982 * \brief To set operating mode.
984 * \param[in] prDev Net device requested.
985 * \param[in] prIwrInfo NULL.
986 * \param[in] pu4Mode Pointer to new operation mode.
987 * \param[in] pcExtra NULL.
989 * \retval 0 For success.
990 * \retval -EOPNOTSUPP If new mode is not supported.
992 * \note Device will run in new operation mode if it is valid.
994 /*----------------------------------------------------------------------------*/
997 IN struct net_device *prNetDev,
998 IN struct iw_request_info *prIwReqInfo,
999 IN unsigned int *pu4Mode,
1003 ENUM_PARAM_OP_MODE_T eOpMode;
1005 P_GLUE_INFO_T prGlueInfo = NULL;
1006 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1007 UINT_32 u4BufLen = 0;
1011 if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) {
1014 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1018 eOpMode = NET_TYPE_AUTO_SWITCH;
1022 eOpMode = NET_TYPE_IBSS;
1026 eOpMode = NET_TYPE_INFRA;
1030 DBGLOG(INIT, INFO, ("%s(): Set UNSUPPORTED Mode = %d.\n", __FUNCTION__, *pu4Mode));
1034 //printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode);
1036 rStatus = kalIoctl(prGlueInfo,
1037 wlanoidSetInfrastructureMode,
1047 /* after set operation mode, key table are cleared */
1049 /* reset wpa info */
1050 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
1051 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
1052 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
1053 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
1054 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
1055 #if CFG_SUPPORT_802_11W
1056 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
1060 } /* wext_set_mode */
1062 /*----------------------------------------------------------------------------*/
1064 * \brief To get operating mode.
1066 * \param[in] prNetDev Net device requested.
1067 * \param[in] prIwReqInfo NULL.
1068 * \param[out] pu4Mode Buffer to store operating mode information.
1069 * \param[in] pcExtra NULL.
1071 * \retval 0 If data is valid.
1072 * \retval -EINVAL Otherwise.
1074 * \note If netif_carrier_ok, operating mode information is stored in pu4Mode.
1076 /*----------------------------------------------------------------------------*/
1079 IN struct net_device *prNetDev,
1080 IN struct iw_request_info *prIwReqInfo,
1081 OUT unsigned int *pu4Mode,
1085 ENUM_PARAM_OP_MODE_T eOpMode;
1087 P_GLUE_INFO_T prGlueInfo = NULL;
1088 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1089 UINT_32 u4BufLen = 0;
1093 if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) {
1096 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1098 rStatus = kalIoctl(prGlueInfo,
1099 wlanoidQueryInfrastructureMode,
1112 *pu4Mode = IW_MODE_ADHOC;
1115 case NET_TYPE_INFRA:
1116 *pu4Mode = IW_MODE_INFRA;
1119 case NET_TYPE_AUTO_SWITCH:
1120 *pu4Mode = IW_MODE_AUTO;
1124 DBGLOG(INIT, INFO, ("%s(): Get UNKNOWN Mode.\n", __FUNCTION__));
1129 } /* wext_get_mode */
1131 /*----------------------------------------------------------------------------*/
1133 * \brief To get the valid range for each configurable STA setting value.
1135 * \param[in] prDev Net device requested.
1136 * \param[in] prIwrInfo NULL.
1137 * \param[in] prData Pointer to iw_point structure, not used.
1138 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1139 * function, wext_support_ioctl() or ioctl_standard_call() in
1142 * \retval 0 If data is valid.
1144 * \note The extra buffer (pcExtra) is filled with information from driver.
1146 /*----------------------------------------------------------------------------*/
1149 IN struct net_device *prNetDev,
1150 IN struct iw_request_info *prIwrInfo,
1151 IN struct iw_point *prData,
1155 struct iw_range *prRange = NULL;
1156 PARAM_RATES_EX aucSuppRate = {0}; /* data buffers */
1159 P_GLUE_INFO_T prGlueInfo = NULL;
1160 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1161 UINT_32 u4BufLen = 0;
1165 if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) {
1168 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1170 prRange = (struct iw_range *) pcExtra;
1172 memset(prRange, 0, sizeof(*prRange));
1173 prRange->throughput = 20000000; /* 20Mbps */
1174 prRange->min_nwid = 0; /* not used */
1175 prRange->max_nwid = 0; /* not used */
1177 /* scan_capa not implemented */
1179 /* event_capa[6]: kernel + driver capabilities */
1180 prRange->event_capa[0] = (IW_EVENT_CAPA_K_0
1181 | IW_EVENT_CAPA_MASK(SIOCGIWAP)
1182 | IW_EVENT_CAPA_MASK(SIOCGIWSCAN)
1183 /* can't display meaningful string in iwlist
1184 | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW)
1185 | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)
1186 | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE)
1187 | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND)
1190 prRange->event_capa[1] = IW_EVENT_CAPA_K_1;
1192 /* report 2.4G channel and frequency only */
1193 prRange->num_channels = (__u16) NUM_CHANNELS;
1194 prRange->num_frequency = (__u8) NUM_CHANNELS;
1195 for (i = 0; i < NUM_CHANNELS; i++) {
1196 /* iwlib takes this number as channel number */
1197 prRange->freq[i].i = i + 1;
1198 prRange->freq[i].m = channel_freq[i];
1199 prRange->freq[i].e = 6; /* Values in table in MHz */
1204 wlanoidQuerySupportedRates,
1206 sizeof(aucSuppRate),
1215 for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX ; i++) {
1216 if (aucSuppRate[i] == 0) {
1219 prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */
1221 prRange->num_bitrates = i;
1223 prRange->min_rts = 0;
1224 prRange->max_rts = 2347;
1225 prRange->min_frag = 256;
1226 prRange->max_frag = 2346;
1228 prRange->min_pmp = 0; /* power management by driver */
1229 prRange->max_pmp = 0; /* power management by driver */
1230 prRange->min_pmt = 0; /* power management by driver */
1231 prRange->max_pmt = 0; /* power management by driver */
1232 prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */
1233 prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */
1234 prRange->pm_capa = IW_POWER_ON; /* power management by driver */
1236 prRange->encoding_size[0] = 5; /* wep40 */
1237 prRange->encoding_size[1] = 16; /* tkip */
1238 prRange->encoding_size[2] = 16; /* ckip */
1239 prRange->encoding_size[3] = 16; /* ccmp */
1240 prRange->encoding_size[4] = 13; /* wep104 */
1241 prRange->encoding_size[5] = 16; /* wep128 */
1242 prRange->num_encoding_sizes = 6;
1243 prRange->max_encoding_tokens = 6; /* token? */
1245 #if WIRELESS_EXT < 17
1246 prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */
1248 prRange->txpower_capa = IW_TXPOW_RELATIVE;
1250 prRange->num_txpower = 5;
1251 prRange->txpower[0] = 0; /* minimum */
1252 prRange->txpower[1] = 25; /* 25% */
1253 prRange->txpower[2] = 50; /* 50% */
1254 prRange->txpower[3] = 100; /* 100% */
1256 prRange->we_version_compiled = WIRELESS_EXT;
1257 prRange->we_version_source = WIRELESS_EXT;
1259 prRange->retry_capa = IW_RETRY_LIMIT;
1260 prRange->retry_flags = IW_RETRY_LIMIT;
1261 prRange->min_retry = 7;
1262 prRange->max_retry = 7;
1263 prRange->r_time_flags = IW_RETRY_ON;
1264 prRange->min_r_time = 0;
1265 prRange->max_r_time = 0;
1267 /* signal strength and link quality */
1268 /* Just define range here, reporting value moved to wext_get_stats() */
1269 prRange->sensitivity = -83; /* fixed value */
1270 prRange->max_qual.qual = 100; /* max 100% */
1271 prRange->max_qual.level = (__u8)(0x100 - 0); /* max 0 dbm */
1272 prRange->max_qual.noise = (__u8)(0x100 - 0); /* max 0 dbm */
1275 #if WIRELESS_EXT > 17
1276 prRange->enc_capa = IW_ENC_CAPA_WPA |
1278 IW_ENC_CAPA_CIPHER_TKIP |
1279 IW_ENC_CAPA_CIPHER_CCMP;
1282 /* min_pms; Minimal PM saving */
1283 /* max_pms; Maximal PM saving */
1284 /* pms_flags; How to decode max/min PM saving */
1286 /* modul_capa; IW_MODUL_* bit field */
1287 /* bitrate_capa; Types of bitrates supported */
1290 } /* wext_get_range */
1293 /*----------------------------------------------------------------------------*/
1295 * \brief To set BSSID of AP to connect.
1297 * \param[in] prDev Net device requested.
1298 * \param[in] prIwrInfo NULL.
1299 * \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID.
1300 * \param[in] pcExtra NULL.
1302 * \retval 0 For success.
1304 * \note Desired AP's BSSID is set to driver.
1306 /*----------------------------------------------------------------------------*/
1309 IN struct net_device *prDev,
1310 IN struct iw_request_info *prIwrInfo,
1311 IN struct sockaddr *prAddr,
1319 /*----------------------------------------------------------------------------*/
1321 * \brief To get AP MAC address.
1323 * \param[in] prDev Net device requested.
1324 * \param[in] prIwrInfo NULL.
1325 * \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID.
1326 * \param[in] pcExtra NULL.
1328 * \retval 0 If netif_carrier_ok.
1329 * \retval -ENOTCONN Otherwise.
1331 * \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data.
1333 /*----------------------------------------------------------------------------*/
1336 IN struct net_device *prNetDev,
1337 IN struct iw_request_info *prIwrInfo,
1338 OUT struct sockaddr *prAddr,
1342 P_GLUE_INFO_T prGlueInfo = NULL;
1343 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1344 UINT_32 u4BufLen = 0;
1348 if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) {
1351 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1353 //if (!netif_carrier_ok(prNetDev)) {
1354 // return -ENOTCONN;
1357 if(prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED){
1358 memset(prAddr, 0, 6);
1362 rStatus = kalIoctl(prGlueInfo,
1375 /*----------------------------------------------------------------------------*/
1377 * \brief To set mlme operation request.
1379 * \param[in] prDev Net device requested.
1380 * \param[in] prIwrInfo NULL.
1381 * \param[in] prData Pointer of iw_point header.
1382 * \param[in] pcExtra Pointer to iw_mlme structure mlme request information.
1384 * \retval 0 For success.
1385 * \retval -EOPNOTSUPP unsupported IW_MLME_ command.
1386 * \retval -EINVAL Set MLME Fail, different bssid.
1388 * \note Driver will start mlme operation if valid.
1390 /*----------------------------------------------------------------------------*/
1393 IN struct net_device *prNetDev,
1394 IN struct iw_request_info *prIwrInfo,
1395 IN struct iw_point *prData,
1399 struct iw_mlme *prMlme = NULL;
1402 P_GLUE_INFO_T prGlueInfo = NULL;
1403 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1404 UINT_32 u4BufLen = 0;
1408 if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) {
1411 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1413 prMlme = (struct iw_mlme *)pcExtra;
1414 if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) {
1415 if (!netif_carrier_ok(prNetDev)) {
1416 DBGLOG(INIT, INFO, ("[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"));
1420 rStatus = kalIoctl(prGlueInfo,
1421 wlanoidSetDisassociate,
1432 DBGLOG(INIT, INFO, ("[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd));
1435 } /* wext_set_mlme */
1437 /*----------------------------------------------------------------------------*/
1439 * \brief To issue scan request.
1441 * \param[in] prDev Net device requested.
1442 * \param[in] prIwrInfo NULL.
1443 * \param[in] prData NULL.
1444 * \param[in] pcExtra NULL.
1446 * \retval 0 For success.
1447 * \retval -EFAULT Tx power is off.
1449 * \note Device will start scanning.
1451 /*----------------------------------------------------------------------------*/
1454 IN struct net_device *prNetDev,
1455 IN struct iw_request_info *prIwrInfo,
1456 IN union iwreq_data *prData,
1460 P_GLUE_INFO_T prGlueInfo = NULL;
1461 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1462 UINT_32 u4BufLen = 0;
1466 if (FALSE == GLUE_CHK_DEV(prNetDev)) {
1469 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1471 #if WIRELESS_EXT > 17
1474 essid_len = ((struct iw_scan_req *)(((struct iw_point*)prData)->pointer))->essid_len;
1478 init_completion(&prGlueInfo->rScanComp);
1480 // TODO: parse flags and issue different scan requests?
1482 rStatus = kalIoctl(prGlueInfo,
1483 wlanoidSetBssidListScan,
1492 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ);
1493 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
1497 } /* wext_set_scan */
1500 /*----------------------------------------------------------------------------*/
1502 * \brief To write the ie to buffer
1505 /*----------------------------------------------------------------------------*/
1506 static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data,
1510 char *pos = buf, *end = buf + buf_size;
1516 for (i = 0; i < len; i++) {
1517 ret = snprintf(pos, end - pos, "%02x",
1519 if (ret < 0 || ret >= end - pos) {
1530 /*----------------------------------------------------------------------------*/
1532 * \brief To get scan results, transform results from driver's format to WE's.
1534 * \param[in] prDev Net device requested.
1535 * \param[in] prIwrInfo NULL.
1536 * \param[out] prData Pointer to iw_point structure, pData->length is the size of
1537 * pcExtra buffer before used, and is updated after filling scan
1539 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1540 * function, wext_support_ioctl() or ioctl_standard_call() in
1543 * \retval 0 For success.
1544 * \retval -ENOMEM If dynamic memory allocation fail.
1545 * \retval -E2BIG Invalid length.
1547 * \note Scan results is filled into pcExtra buffer, data size is updated in
1550 /*----------------------------------------------------------------------------*/
1553 IN struct net_device *prNetDev,
1554 IN struct iw_request_info *prIwrInfo,
1555 IN OUT struct iw_point *prData,
1561 P_PARAM_BSSID_LIST_EX_T prList = NULL;
1562 P_PARAM_BSSID_EX_T prBss = NULL;
1563 P_PARAM_VARIABLE_IE_T prDesiredIE = NULL;
1564 struct iw_event iwEvent; /* local iw_event buffer */
1566 /* write pointer of extra buffer */
1568 /* pointer to the end of last full entry in extra buffer */
1569 char *pcValidEntryEnd = NULL;
1570 char *pcEnd = NULL; /* end of extra buffer */
1572 UINT_32 u4AllocBufLen = 0;
1574 /* arrange rate information */
1575 UINT_32 u4HighestRate = 0;
1576 char aucRatesBuf[64];
1582 P_GLUE_INFO_T prGlueInfo = NULL;
1583 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1584 UINT_32 u4BufLen = 0;
1589 if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) {
1592 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1594 /* Initialize local variables */
1596 pcValidEntryEnd = pcExtra;
1597 pcEnd = pcExtra + prData->length; /* end of extra buffer */
1599 /* Allocate another query buffer with the same size of extra buffer */
1600 u4AllocBufLen = prData->length;
1601 prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
1602 if (prList == NULL) {
1603 DBGLOG(INIT, INFO, ("[wifi] no memory for scan list:%d\n", prData->length));
1607 prList->u4NumberOfItems = 0;
1609 /* wait scan done */
1610 //printk ("wait for scan results\n");
1611 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ);
1613 rStatus = kalIoctl(prGlueInfo,
1614 wlanoidQueryBssidList,
1623 if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
1624 /* Buffer length is not large enough. */
1625 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
1627 #if WIRELESS_EXT >= 17
1628 /* This feature is supported in WE-17 or above, limited by iwlist.
1629 ** Return -E2BIG and iwlist will request again with a larger buffer.
1632 /* Update length to give application a hint on result length */
1633 prData->length = (__u16)u4BufLen;
1636 /* Realloc a larger query buffer here, but don't write too much to extra
1637 ** buffer when filling it later.
1639 kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
1641 u4AllocBufLen = u4BufLen;
1642 prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
1643 if (prList == NULL) {
1644 DBGLOG(INIT, INFO, ("[wifi] no memory for larger scan list :%ld\n", u4BufLen));
1648 prList->NumberOfItems = 0;
1650 rStatus = kalIoctl(prGlueInfo,
1651 wlanoidQueryBssidList,
1660 if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
1661 DBGLOG(INIT, INFO, ("[wifi] larger buf:%d result:%ld\n", u4AllocBufLen, u4BufLen));
1663 prData->length = (__u16)u4BufLen;
1666 #endif /* WIRELESS_EXT >= 17 */
1671 if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) {
1672 DBGLOG(INIT, INFO, ("[wifi] strange scan result count:%ld\n",
1673 prList->u4NumberOfItems));
1677 /* Copy required data from pList to pcExtra */
1678 prBss = &prList->arBssid[0]; /* set to the first entry */
1679 for (i = 0; i < prList->u4NumberOfItems; ++i) {
1681 iwEvent.cmd = SIOCGIWAP;
1682 iwEvent.len = IW_EV_ADDR_LEN;
1683 if ((pcCur + iwEvent.len) > pcEnd)
1685 iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER;
1686 memcpy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress, ETH_ALEN);
1687 memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN);
1688 pcCur += IW_EV_ADDR_LEN;
1691 iwEvent.cmd = SIOCGIWESSID;
1692 /* Modification to user space pointer(essid.pointer) is not needed. */
1693 iwEvent.u.essid.length = (__u16)prBss->rSsid.u4SsidLen;
1694 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length;
1696 if ((pcCur + iwEvent.len) > pcEnd)
1698 iwEvent.u.essid.flags = 1;
1699 iwEvent.u.essid.pointer = NULL;
1701 #if WIRELESS_EXT <= 18
1702 memcpy(pcCur, &iwEvent, iwEvent.len);
1704 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1705 memcpy(pcCur + IW_EV_LCP_LEN,
1706 &iwEvent.u.data.length,
1707 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1709 memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length);
1710 pcCur += iwEvent.len;
1712 iwEvent.cmd = SIOCGIWFREQ;
1713 iwEvent.len = IW_EV_FREQ_LEN;
1714 if ((pcCur + iwEvent.len) > pcEnd)
1716 iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig;
1717 iwEvent.u.freq.e = 3; /* (in KHz) */
1718 iwEvent.u.freq.i = 0;
1719 memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN);
1720 pcCur += IW_EV_FREQ_LEN;
1722 /* Operation Mode */
1723 iwEvent.cmd = SIOCGIWMODE;
1724 iwEvent.len = IW_EV_UINT_LEN;
1725 if ((pcCur + iwEvent.len) > pcEnd)
1727 if (prBss->eOpMode == NET_TYPE_IBSS) {
1728 iwEvent.u.mode = IW_MODE_ADHOC;
1730 else if (prBss->eOpMode == NET_TYPE_INFRA) {
1731 iwEvent.u.mode = IW_MODE_INFRA;
1734 iwEvent.u.mode = IW_MODE_AUTO;
1736 memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN);
1737 pcCur += IW_EV_UINT_LEN;
1740 iwEvent.cmd = IWEVQUAL;
1741 iwEvent.len = IW_EV_QUAL_LEN;
1742 if ((pcCur + iwEvent.len) > pcEnd)
1744 iwEvent.u.qual.qual = 0; /* Quality not available now */
1745 /* -100 < Rssi < -10, normalized by adding 0x100 */
1746 iwEvent.u.qual.level = 0x100 + prBss->rRssi;
1747 iwEvent.u.qual.noise = 0; /* Noise not available now */
1748 iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED \
1749 | IW_QUAL_NOISE_INVALID;
1750 memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN);
1751 pcCur += IW_EV_QUAL_LEN;
1754 iwEvent.cmd = SIOCGIWENCODE;
1755 iwEvent.len = IW_EV_POINT_LEN;
1756 if ((pcCur + iwEvent.len) > pcEnd)
1758 iwEvent.u.data.pointer = NULL;
1759 iwEvent.u.data.flags = 0;
1760 iwEvent.u.data.length = 0;
1761 if(!prBss->u4Privacy) {
1762 iwEvent.u.data.flags |= IW_ENCODE_DISABLED;
1764 #if WIRELESS_EXT <= 18
1765 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1767 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1768 memcpy(pcCur + IW_EV_LCP_LEN,
1769 &iwEvent.u.data.length,
1770 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1772 pcCur += IW_EV_POINT_LEN;
1774 /* rearrange rate information */
1775 u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):");
1777 for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) {
1778 UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F;
1783 if (curRate > u4HighestRate) {
1784 u4HighestRate = curRate;
1787 if (curRate == RATE_5_5M) {
1788 u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5");
1791 u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2);
1794 if (u4BufIndex > sizeof(aucRatesBuf)) {
1795 //printk("rate info too long\n");
1800 /* Report Highest Rates */
1801 iwEvent.cmd = SIOCGIWRATE;
1802 iwEvent.len = IW_EV_PARAM_LEN;
1803 if ((pcCur + iwEvent.len) > pcEnd)
1805 iwEvent.u.bitrate.value = u4HighestRate * 500000;
1806 iwEvent.u.bitrate.fixed = 0;
1807 iwEvent.u.bitrate.disabled = 0;
1808 iwEvent.u.bitrate.flags = 0;
1809 memcpy(pcCur, &iwEvent, iwEvent.len);
1810 pcCur += iwEvent.len;
1812 #if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */
1813 /* Report Residual Rates */
1814 iwEvent.cmd = IWEVCUSTOM;
1815 iwEvent.u.data.length = u4BufIndex;
1816 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1817 if ((pcCur + iwEvent.len) > pcEnd)
1819 iwEvent.u.data.flags = 0;
1820 #if WIRELESS_EXT <= 18
1821 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1823 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1824 memcpy(pcCur + IW_EV_LCP_LEN,
1825 &iwEvent.u.data.length,
1826 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1828 memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex);
1829 pcCur += iwEvent.len;
1830 #endif /* WIRELESS_EXT >= 15 */
1833 if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1834 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
1836 (PUINT_8 *)&prDesiredIE)) {
1837 iwEvent.cmd = IWEVGENIE;
1838 iwEvent.u.data.flags = 1;
1839 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1840 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1841 if ((pcCur + iwEvent.len) > pcEnd)
1843 #if WIRELESS_EXT <= 18
1844 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1846 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1847 memcpy(pcCur + IW_EV_LCP_LEN,
1848 &iwEvent.u.data.length,
1849 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1851 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1852 pcCur += iwEvent.len;
1855 #if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */
1856 if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1857 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
1859 (PUINT_8 *)&prDesiredIE)) {
1860 iwEvent.cmd = IWEVGENIE;
1861 iwEvent.u.data.flags = 1;
1862 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1863 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1864 if ((pcCur + iwEvent.len) > pcEnd)
1866 #if WIRELESS_EXT <= 18
1867 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1869 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1870 memcpy(pcCur + IW_EV_LCP_LEN,
1871 &iwEvent.u.data.length,
1872 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1874 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1875 pcCur += iwEvent.len;
1880 /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */
1881 /* pBss->IEs starts from timestamp */
1882 if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1883 prBss->u4IELength -sizeof(PARAM_FIXED_IEs),
1885 (PUINT_8 *)&prDesiredIE)) {
1887 iwEvent.cmd = IWEVGENIE;
1888 iwEvent.u.data.flags = 1;
1889 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1890 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1891 if ((pcCur + iwEvent.len) > pcEnd)
1893 #if WIRELESS_EXT <= 18
1894 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1896 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1897 memcpy(pcCur + IW_EV_LCP_LEN,
1898 &iwEvent.u.data.length,
1899 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1901 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1902 pcCur += iwEvent.len;
1905 #if CFG_SUPPORT_WAPI /* Android+ */
1906 if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1907 prBss->u4IELength -sizeof(PARAM_FIXED_IEs),
1908 (PUINT_8 *)&prDesiredIE)) {
1911 iwEvent.cmd = IWEVGENIE;
1912 iwEvent.u.data.flags = 1;
1913 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1914 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1915 if ((pcCur + iwEvent.len) > pcEnd)
1917 #if WIRELESS_EXT <= 18
1918 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1920 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1921 memcpy(pcCur + IW_EV_LCP_LEN,
1922 &iwEvent.u.data.length,
1923 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1925 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1926 pcCur += iwEvent.len;
1928 iwEvent.cmd = IWEVCUSTOM;
1929 iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */;
1930 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1931 if ((pcCur + iwEvent.len) > pcEnd)
1933 iwEvent.u.data.flags = 1;
1935 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1936 memcpy(pcCur + IW_EV_LCP_LEN,
1937 &iwEvent.u.data.length,
1938 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1940 pcCur += (IW_EV_POINT_LEN);
1942 pcCur += sprintf(pcCur, "wapi_ie=");
1944 snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *)prDesiredIE, prDesiredIE->ucLength + 2);
1946 pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */;
1950 /* Complete an entry. Update end of valid entry */
1951 pcValidEntryEnd = pcCur;
1952 /* Extract next bss */
1953 prBss = (P_PARAM_BSSID_EX_T)((char *)prBss + prBss->u4Length);
1956 /* Update valid data length for caller function and upper layer
1959 prData->length = (pcValidEntryEnd - pcExtra);
1960 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
1962 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
1965 /* free local query buffer */
1967 kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
1971 } /* wext_get_scan */
1973 /*----------------------------------------------------------------------------*/
1975 * \brief To set desired network name ESSID.
1977 * \param[in] prDev Net device requested.
1978 * \param[in] prIwrInfo NULL.
1979 * \param[in] prEssid Pointer of iw_point header.
1980 * \param[in] pcExtra Pointer to buffer srtoring essid string.
1982 * \retval 0 If netif_carrier_ok.
1983 * \retval -E2BIG Essid string length is too big.
1984 * \retval -EINVAL pcExtra is null pointer.
1985 * \retval -EFAULT Driver fail to set new essid.
1987 * \note If string lengh is ok, device will try connecting to the new network.
1989 /*----------------------------------------------------------------------------*/
1992 IN struct net_device *prNetDev,
1993 IN struct iw_request_info *prIwrInfo,
1994 IN struct iw_point *prEssid,
1998 PARAM_SSID_T rNewSsid;
2000 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
2001 ENUM_PARAM_AUTH_MODE_T eAuthMode;
2003 P_GLUE_INFO_T prGlueInfo = NULL;
2004 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2005 UINT_32 u4BufLen = 0;
2010 if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) {
2013 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2015 if (prEssid->length > IW_ESSID_MAX_SIZE) {
2021 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
2022 eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
2023 AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
2024 //printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n",
2025 // (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared");
2029 switch(prGlueInfo->rWpaInfo.u4KeyMgmt) {
2030 case IW_AUTH_KEY_MGMT_802_1X:
2032 (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
2033 AUTH_MODE_WPA : AUTH_MODE_WPA2;
2034 //printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n",
2035 // (eAuthMode == AUTH_MODE_WPA) ? "" : "2");
2037 case IW_AUTH_KEY_MGMT_PSK:
2039 (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
2040 AUTH_MODE_WPA_PSK: AUTH_MODE_WPA2_PSK;
2041 //printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n",
2042 // (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2");
2044 #if CFG_SUPPORT_WAPI /* Android+ */
2045 case IW_AUTH_KEY_MGMT_WAPI_PSK:
2047 case IW_AUTH_KEY_MGMT_WAPI_CERT:
2051 //#if defined (IW_AUTH_KEY_MGMT_WPA_NONE)
2052 // case IW_AUTH_KEY_MGMT_WPA_NONE:
2053 // eAuthMode = AUTH_MODE_WPA_NONE;
2054 // //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n");
2057 #if CFG_SUPPORT_802_11W
2058 case IW_AUTH_KEY_MGMT_802_1X_SHA256:
2059 eAuthMode = AUTH_MODE_WPA2;
2061 case IW_AUTH_KEY_MGMT_PSK_SHA256:
2062 eAuthMode = AUTH_MODE_WPA2_PSK;
2066 //printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n",
2067 // prGlueInfo->rWpaInfo.u4KeyMgmt);
2068 eAuthMode = AUTH_MODE_AUTO_SWITCH;
2074 rStatus = kalIoctl(prGlueInfo,
2084 /* set encryption status */
2085 cipher = prGlueInfo->rWpaInfo.u4CipherGroup |
2086 prGlueInfo->rWpaInfo.u4CipherPairwise;
2087 if (cipher & IW_AUTH_CIPHER_CCMP) {
2088 //printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n");
2089 eEncStatus = ENUM_ENCRYPTION3_ENABLED;
2091 else if (cipher & IW_AUTH_CIPHER_TKIP) {
2092 //printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n");
2093 eEncStatus = ENUM_ENCRYPTION2_ENABLED;
2095 else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
2096 //printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n");
2097 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
2099 else if (cipher & IW_AUTH_CIPHER_NONE){
2100 //printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n");
2101 if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
2102 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
2104 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2107 //printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n");
2108 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2111 rStatus = kalIoctl(prGlueInfo,
2112 wlanoidSetEncryptionStatus,
2121 #if WIRELESS_EXT < 21
2122 /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before
2123 ** 2.6.19. Cut the trailing '\0'.
2125 rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0;
2127 rNewSsid.u4SsidLen = prEssid->length;
2129 kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen);
2132 rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0';
2133 printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid);
2136 if (kalIoctl(prGlueInfo,
2139 sizeof(PARAM_SSID_T),
2144 &u4BufLen) != WLAN_STATUS_SUCCESS) {
2145 //printk(KERN_WARNING "Fail to set ssid\n");
2151 } /* wext_set_essid */
2153 /*----------------------------------------------------------------------------*/
2155 * \brief To get current network name ESSID.
2157 * \param[in] prDev Net device requested.
2158 * \param[in] prIwrInfo NULL.
2159 * \param[in] prEssid Pointer to iw_point structure containing essid information.
2160 * \param[out] pcExtra Pointer to buffer srtoring essid string.
2162 * \retval 0 If netif_carrier_ok.
2163 * \retval -ENOTCONN Otherwise.
2165 * \note If netif_carrier_ok, network essid is stored in pcExtra.
2167 /*----------------------------------------------------------------------------*/
2168 //static PARAM_SSID_T ssid;
2171 IN struct net_device *prNetDev,
2172 IN struct iw_request_info *prIwrInfo,
2173 IN struct iw_point *prEssid,
2177 //PARAM_SSID_T ssid;
2179 P_PARAM_SSID_T prSsid;
2180 P_GLUE_INFO_T prGlueInfo = NULL;
2181 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2182 UINT_32 u4BufLen = 0;
2188 if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) {
2191 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2193 //if (!netif_carrier_ok(prNetDev)) {
2194 // return -ENOTCONN;
2197 prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE);
2203 rStatus = kalIoctl(prGlueInfo,
2206 sizeof(PARAM_SSID_T),
2213 if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) {
2214 kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen);
2215 prEssid->length = prSsid->u4SsidLen;
2219 kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T));
2222 } /* wext_get_essid */
2227 /*----------------------------------------------------------------------------*/
2229 * \brief To set tx desired bit rate. Three cases here
2230 * iwconfig wlan0 auto -> Set to origianl supported rate set.
2231 * iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate.
2232 * iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps
2234 * \param[in] prNetDev Pointer to the net_device handler.
2235 * \param[in] prIwReqInfo Pointer to the Request Info.
2236 * \param[in] prRate Pointer to the Rate Parameter.
2237 * \param[in] pcExtra Pointer to the extra buffer.
2239 * \retval 0 Update desired rate.
2240 * \retval -EINVAL Wrong parameter
2242 /*----------------------------------------------------------------------------*/
2245 IN struct net_device *prNetDev,
2246 IN struct iw_request_info *prIwReqInfo,
2247 IN struct iw_param *prRate,
2251 PARAM_RATES_EX aucSuppRate = {0};
2252 PARAM_RATES_EX aucNewRate = {0};
2253 UINT_32 u4NewRateLen = 0;
2256 P_GLUE_INFO_T prGlueInfo = NULL;
2257 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2258 UINT_32 u4BufLen = 0;
2262 if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) {
2265 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2268 printk("value = %d, fixed = %d, disable = %d, flags = %d\n",
2269 prRate->value, prRate->fixed, prRate->disabled, prRate->flags);
2272 rStatus = wlanQueryInformation(
2273 prGlueInfo->prAdapter,
2274 wlanoidQuerySupportedRates,
2276 sizeof(aucSuppRate),
2280 if (prRate->value < 0) {
2281 if (prRate->fixed == 0) {
2282 /* iwconfig wlan0 rate auto */
2284 /* set full supported rate to device */
2285 /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */
2286 rStatus = wlanSetInformation(
2287 prGlueInfo->prAdapter,
2288 wlanoidSetDesiredRates,
2290 sizeof(aucSuppRate),
2295 /* iwconfig wlan0 rate fixed */
2297 /* fix rate to what? DO NOTHING */
2303 aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */
2305 for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) {
2306 /* check the given value is supported */
2307 if (aucSuppRate[i] == 0) {
2311 if (aucNewRate[0] == aucSuppRate[i]) {
2317 if (u4NewRateLen == 0) {
2318 /* the given value is not supported */
2319 /* return error or use given rate as upper bound? */
2323 if (prRate->fixed == 0) {
2324 /* add all rates lower than desired rate */
2325 for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) {
2326 if (aucSuppRate[i] == 0) {
2330 if (aucSuppRate[i] < aucNewRate[0]) {
2331 aucNewRate[u4NewRateLen++] = aucSuppRate[i];
2336 rStatus = wlanSetInformation(
2337 prGlueInfo->prAdapter,
2338 wlanoidSetDesiredRates,
2343 } /* wext_set_rate */
2347 /*----------------------------------------------------------------------------*/
2349 * \brief To get current tx bit rate.
2351 * \param[in] prDev Net device requested.
2352 * \param[in] prIwrInfo NULL.
2353 * \param[out] prRate Pointer to iw_param structure to store current tx rate.
2354 * \param[in] pcExtra NULL.
2356 * \retval 0 If netif_carrier_ok.
2357 * \retval -ENOTCONN Otherwise.
2359 * \note If netif_carrier_ok, current tx rate is stored in pRate.
2361 /*----------------------------------------------------------------------------*/
2364 IN struct net_device *prNetDev,
2365 IN struct iw_request_info *prIwrInfo,
2366 OUT struct iw_param *prRate,
2370 P_GLUE_INFO_T prGlueInfo = NULL;
2371 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2372 UINT_32 u4BufLen = 0;
2377 if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) {
2380 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2382 if (!netif_carrier_ok(prNetDev)) {
2387 rStatus = kalIoctl(prGlueInfo,
2388 wlanoidQueryLinkSpeed,
2397 if (rStatus != WLAN_STATUS_SUCCESS) {
2401 prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */
2405 } /* wext_get_rate */
2408 /*----------------------------------------------------------------------------*/
2410 * \brief To set RTS/CTS theshold.
2412 * \param[in] prDev Net device requested.
2413 * \param[in] prIwrInfo NULL.
2414 * \param[in] prRts Pointer to iw_param structure containing rts threshold.
2415 * \param[in] pcExtra NULL.
2417 * \retval 0 For success.
2418 * \retval -EINVAL Given value is out of range.
2420 * \note If given value is valid, device will follow the new setting.
2422 /*----------------------------------------------------------------------------*/
2425 IN struct net_device *prNetDev,
2426 IN struct iw_request_info *prIwrInfo,
2427 IN struct iw_param *prRts,
2431 PARAM_RTS_THRESHOLD u4RtsThresh;
2433 P_GLUE_INFO_T prGlueInfo = NULL;
2434 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2435 UINT_32 u4BufLen = 0;
2439 if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) {
2442 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2444 if (prRts->disabled == 1) {
2447 else if (prRts->value < 0 || prRts->value > 2347) {
2451 u4RtsThresh = (PARAM_RTS_THRESHOLD)prRts->value;
2454 rStatus = kalIoctl(prGlueInfo,
2455 wlanoidSetRtsThreshold,
2457 sizeof(u4RtsThresh),
2466 prRts->value = (typeof(prRts->value ))u4RtsThresh;
2467 prRts->disabled = (prRts->value > 2347) ? 1 : 0;
2471 } /* wext_set_rts */
2473 /*----------------------------------------------------------------------------*/
2475 * \brief To get RTS/CTS theshold.
2477 * \param[in] prDev Net device requested.
2478 * \param[in] prIwrInfo NULL.
2479 * \param[out] prRts Pointer to iw_param structure containing rts threshold.
2480 * \param[in] pcExtra NULL.
2482 * \retval 0 Success.
2484 * \note RTS threshold is stored in pRts.
2486 /*----------------------------------------------------------------------------*/
2489 IN struct net_device *prNetDev,
2490 IN struct iw_request_info *prIwrInfo,
2491 OUT struct iw_param *prRts,
2495 PARAM_RTS_THRESHOLD u4RtsThresh;
2497 P_GLUE_INFO_T prGlueInfo = NULL;
2498 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2499 UINT_32 u4BufLen = 0;
2503 if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) {
2506 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2508 rStatus = kalIoctl(prGlueInfo,
2509 wlanoidQueryRtsThreshold,
2511 sizeof(u4RtsThresh),
2520 prRts->value = (typeof(prRts->value ))u4RtsThresh;
2521 prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0;
2525 } /* wext_get_rts */
2527 /*----------------------------------------------------------------------------*/
2529 * \brief To get fragmentation threshold.
2531 * \param[in] prDev Net device requested.
2532 * \param[in] prIwrInfo NULL.
2533 * \param[out] prFrag Pointer to iw_param structure containing frag threshold.
2534 * \param[in] pcExtra NULL.
2536 * \retval 0 Success.
2538 * \note RTS threshold is stored in pFrag. Fragmentation is disabled.
2540 /*----------------------------------------------------------------------------*/
2543 IN struct net_device *prNetDev,
2544 IN struct iw_request_info *prIwrInfo,
2545 OUT struct iw_param *prFrag,
2551 prFrag->value = 2346;
2553 prFrag->disabled = 1;
2555 } /* wext_get_frag */
2558 /*----------------------------------------------------------------------------*/
2560 * \brief To set TX power, or enable/disable the radio.
2562 * \param[in] prDev Net device requested.
2563 * \param[in] prIwrInfo NULL.
2564 * \param[in] prTxPow Pointer to iw_param structure containing tx power setting.
2565 * \param[in] pcExtra NULL.
2567 * \retval 0 Success.
2569 * \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used
2570 * to enable/disable the radio.
2572 /*----------------------------------------------------------------------------*/
2576 IN struct net_device *prNetDev,
2577 IN struct iw_request_info *prIwrInfo,
2578 IN struct iw_param *prTxPow,
2583 //PARAM_DEVICE_POWER_STATE ePowerState;
2584 ENUM_ACPI_STATE_T ePowerState;
2586 P_GLUE_INFO_T prGlueInfo = NULL;
2587 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2588 UINT_32 u4BufLen = 0;
2592 if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) {
2595 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2597 if(prTxPow->disabled){
2598 /* <1> disconnect */
2599 rStatus = kalIoctl(prGlueInfo,
2600 wlanoidSetDisassociate,
2608 if (rStatus != WLAN_STATUS_SUCCESS) {
2609 DBGLOG(INIT, INFO, ("######set disassoc failed\n"));
2611 DBGLOG(INIT, INFO, ("######set assoc ok\n"));
2614 /* <2> mark to power state flag*/
2615 ePowerState = ACPI_STATE_D0;
2616 DBGLOG(INIT, INFO, ("set to acpi d3(0)\n"));
2617 wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
2621 ePowerState = ACPI_STATE_D0;
2622 DBGLOG(INIT, INFO, ("set to acpi d0\n"));
2623 wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
2626 prGlueInfo->ePowerState = ePowerState;
2629 } /* wext_set_txpow */
2634 /*----------------------------------------------------------------------------*/
2636 * \brief To get TX power.
2638 * \param[in] prDev Net device requested.
2639 * \param[in] prIwrInfo NULL.
2640 * \param[out] prTxPow Pointer to iw_param structure containing tx power setting.
2641 * \param[in] pcExtra NULL.
2643 * \retval 0 Success.
2645 * \note Tx power is stored in pTxPow.
2647 /*----------------------------------------------------------------------------*/
2650 IN struct net_device *prNetDev,
2651 IN struct iw_request_info *prIwrInfo,
2652 OUT struct iw_param *prTxPow,
2656 //PARAM_DEVICE_POWER_STATE ePowerState;
2658 P_GLUE_INFO_T prGlueInfo = NULL;
2662 if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) {
2665 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2667 /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not
2668 * current state. Use GLUE_INFO_T to store state.
2670 //ePowerState = prGlueInfo->ePowerState;
2672 /* TxPow parameters: Fixed at relative 100% */
2673 #if WIRELESS_EXT < 17
2674 prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */
2676 prTxPow->flags = IW_TXPOW_RELATIVE;
2678 prTxPow->value = 100;
2680 //prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE;
2681 prTxPow->disabled = TRUE;
2684 } /* wext_get_txpow */
2687 /*----------------------------------------------------------------------------*/
2689 * \brief To get encryption cipher and key.
2691 * \param[in] prDev Net device requested.
2692 * \param[in] prIwrInfo NULL.
2693 * \param[out] prEnc Pointer to iw_point structure containing securiry information.
2694 * \param[in] pcExtra Buffer to store key content.
2696 * \retval 0 Success.
2698 * \note Securiry information is stored in pEnc except key content.
2700 /*----------------------------------------------------------------------------*/
2703 IN struct net_device *prNetDev,
2704 IN struct iw_request_info *prIwrInfo,
2705 OUT struct iw_point *prEnc,
2710 //ENUM_ENCRYPTION_STATUS_T eEncMode;
2711 ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode;
2713 P_GLUE_INFO_T prGlueInfo = NULL;
2714 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2715 UINT_32 u4BufLen = 0;
2719 if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) {
2722 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2725 rStatus = kalIoctl(prGlueInfo,
2726 wlanoidQueryEncryptionStatus,
2738 case ENUM_WEP_DISABLED:
2739 prEnc->flags = IW_ENCODE_DISABLED;
2741 case ENUM_WEP_ENABLED:
2742 prEnc->flags = IW_ENCODE_ENABLED;
2744 case ENUM_WEP_KEY_ABSENT:
2745 prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2748 prEnc->flags = IW_ENCODE_ENABLED;
2752 /* Cipher, Key Content, Key ID can't be queried */
2753 prEnc->flags |= IW_ENCODE_NOKEY;
2756 } /* wext_get_encode */
2760 /*----------------------------------------------------------------------------*/
2762 * \brief To set encryption cipher and key.
2764 * \param[in] prDev Net device requested.
2765 * \param[in] prIwrInfo NULL.
2766 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
2767 * \param[in] pcExtra Pointer to key string buffer.
2769 * \retval 0 Success.
2770 * \retval -EINVAL Key ID error for WEP.
2771 * \retval -EFAULT Setting parameters to driver fail.
2772 * \retval -EOPNOTSUPP Key size not supported.
2774 * \note Securiry information is stored in pEnc.
2776 /*----------------------------------------------------------------------------*/
2777 static UINT_8 wepBuf[48];
2781 IN struct net_device *prNetDev,
2782 IN struct iw_request_info *prIwrInfo,
2783 IN struct iw_point *prEnc,
2788 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
2789 ENUM_PARAM_AUTH_MODE_T eAuthMode;
2790 //UINT_8 wepBuf[48];
2791 P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
2793 P_GLUE_INFO_T prGlueInfo = NULL;
2794 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2795 UINT_32 u4BufLen = 0;
2800 if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) {
2803 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2805 /* reset to default mode */
2806 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
2807 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
2808 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
2809 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
2810 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
2811 #if CFG_SUPPORT_802_11W
2812 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
2815 /* iwconfig wlan0 key off */
2816 if ( (prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED ) {
2817 eAuthMode = AUTH_MODE_OPEN;
2819 rStatus = kalIoctl(prGlueInfo,
2829 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2831 rStatus = kalIoctl(prGlueInfo,
2832 wlanoidSetEncryptionStatus,
2844 /* iwconfig wlan0 key 0123456789 */
2845 /* iwconfig wlan0 key s:abcde */
2846 /* iwconfig wlan0 key 0123456789 [1] */
2847 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
2848 /* check key size for WEP */
2849 if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) {
2850 /* prepare PARAM_WEP key structure */
2851 prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
2852 (prEnc->flags & IW_ENCODE_INDEX) -1 : 0;
2853 if (prWepKey->u4KeyIndex > 3) {
2854 /* key id is out of range */
2857 prWepKey->u4KeyIndex |= 0x80000000;
2858 prWepKey->u4Length = 12 + prEnc->length;
2859 prWepKey->u4KeyLength = prEnc->length;
2860 kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length);
2863 rStatus = kalIoctl(prGlueInfo,
2873 if (rStatus != WLAN_STATUS_SUCCESS) {
2874 DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus));
2878 /* change to auto switch */
2879 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY |
2880 IW_AUTH_ALG_OPEN_SYSTEM;
2881 eAuthMode = AUTH_MODE_AUTO_SWITCH;
2883 rStatus = kalIoctl(prGlueInfo,
2893 if (rStatus != WLAN_STATUS_SUCCESS) {
2894 //printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus);
2898 prGlueInfo->rWpaInfo.u4CipherPairwise =
2899 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
2900 prGlueInfo->rWpaInfo.u4CipherGroup =
2901 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
2903 eEncStatus = ENUM_WEP_ENABLED;
2906 rStatus = kalIoctl(prGlueInfo,
2907 wlanoidSetEncryptionStatus,
2909 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T),
2916 if (rStatus != WLAN_STATUS_SUCCESS) {
2917 //printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus);
2925 } /* wext_set_encode */
2928 /*----------------------------------------------------------------------------*/
2930 * \brief To set power management.
2932 * \param[in] prDev Net device requested.
2933 * \param[in] prIwrInfo NULL.
2934 * \param[in] prPower Pointer to iw_param structure containing tx power setting.
2935 * \param[in] pcExtra NULL.
2937 * \retval 0 Success.
2939 * \note New Power Management Mode is set to driver.
2941 /*----------------------------------------------------------------------------*/
2944 IN struct net_device *prNetDev,
2945 IN struct iw_request_info *prIwrInfo,
2946 IN struct iw_param *prPower,
2951 PARAM_POWER_MODE ePowerMode;
2952 INT_32 i4PowerValue;
2954 P_GLUE_INFO_T prGlueInfo = NULL;
2955 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2956 UINT_32 u4BufLen = 0;
2960 if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
2963 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2965 //printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n",
2966 // prPower->value, prPower->disabled, prPower->flags);
2968 if(prPower->disabled){
2969 ePowerMode = Param_PowerModeCAM;
2972 i4PowerValue = prPower->value;
2973 #if WIRELESS_EXT < 21
2974 i4PowerValue /= 1000000;
2976 if (i4PowerValue == 0) {
2977 ePowerMode = Param_PowerModeCAM;
2978 } else if (i4PowerValue == 1) {
2979 ePowerMode = Param_PowerModeMAX_PSP;
2980 } else if (i4PowerValue == 2) {
2981 ePowerMode = Param_PowerModeFast_PSP;
2984 DBGLOG(INIT, INFO, ("%s(): unsupported power management mode value = %d.\n",
2993 rStatus = kalIoctl(prGlueInfo,
2994 wlanoidSet802dot11PowerSaveProfile,
3003 if (rStatus != WLAN_STATUS_SUCCESS) {
3004 //printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus);
3010 } /* wext_set_power */
3013 /*----------------------------------------------------------------------------*/
3015 * \brief To get power management.
3017 * \param[in] prDev Net device requested.
3018 * \param[in] prIwrInfo NULL.
3019 * \param[out] prPower Pointer to iw_param structure containing tx power setting.
3020 * \param[in] pcExtra NULL.
3022 * \retval 0 Success.
3024 * \note Power management mode is stored in pTxPow->value.
3026 /*----------------------------------------------------------------------------*/
3029 IN struct net_device *prNetDev,
3030 IN struct iw_request_info *prIwrInfo,
3031 OUT struct iw_param *prPower,
3036 P_GLUE_INFO_T prGlueInfo = NULL;
3037 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3038 UINT_32 u4BufLen = 0;
3039 PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM;
3043 if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
3046 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3049 #if defined(_HIF_SDIO)
3050 rStatus = sdio_io_ctrl(prGlueInfo,
3051 wlanoidQuery802dot11PowerSaveProfile,
3058 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
3059 wlanoidQuery802dot11PowerSaveProfile,
3065 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
3066 wlanoidQuery802dot11PowerSaveProfile,
3072 if (rStatus != WLAN_STATUS_SUCCESS) {
3077 prPower->disabled = 1;
3079 if (Param_PowerModeCAM == ePowerMode) {
3081 prPower->disabled = 1;
3083 else if (Param_PowerModeMAX_PSP == ePowerMode ) {
3085 prPower->disabled = 0;
3087 else if (Param_PowerModeFast_PSP == ePowerMode ) {
3089 prPower->disabled = 0;
3092 prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
3093 #if WIRELESS_EXT < 21
3094 prPower->value *= 1000000;
3097 //printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n",
3098 // prPower->value, prPower->disabled, prPower->flags);
3101 } /* wext_get_power */
3103 /*----------------------------------------------------------------------------*/
3105 * \brief To set authentication parameters.
3107 * \param[in] prDev Net device requested.
3108 * \param[in] prIwrInfo NULL.
3109 * \param[in] rpAuth Pointer to iw_param structure containing authentication information.
3110 * \param[in] pcExtra Pointer to key string buffer.
3112 * \retval 0 Success.
3113 * \retval -EINVAL Key ID error for WEP.
3114 * \retval -EFAULT Setting parameters to driver fail.
3115 * \retval -EOPNOTSUPP Key size not supported.
3117 * \note Securiry information is stored in pEnc.
3119 /*----------------------------------------------------------------------------*/
3122 IN struct net_device *prNetDev,
3123 IN struct iw_request_info *prIwrInfo,
3124 IN struct iw_param *prAuth,
3128 P_GLUE_INFO_T prGlueInfo = NULL;
3132 if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) {
3135 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3137 /* Save information to glue info and process later when ssid is set. */
3138 switch(prAuth->flags & IW_AUTH_INDEX) {
3139 case IW_AUTH_WPA_VERSION:
3140 #if CFG_SUPPORT_WAPI
3141 if (wlanQueryWapiMode(prGlueInfo->prAdapter)){
3142 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3143 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
3146 prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
3149 prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
3153 case IW_AUTH_CIPHER_PAIRWISE:
3154 prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value;
3157 case IW_AUTH_CIPHER_GROUP:
3158 prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value;
3161 case IW_AUTH_KEY_MGMT:
3162 prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value;
3163 #if CFG_SUPPORT_WAPI
3164 if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK ||
3165 prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) {
3167 WLAN_STATUS rStatus;
3169 rStatus = kalIoctl(prGlueInfo,
3178 DBGLOG(INIT, INFO, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value));
3181 if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS)
3182 prGlueInfo->fgWpsActive = TRUE;
3184 prGlueInfo->fgWpsActive = FALSE;
3187 case IW_AUTH_80211_AUTH_ALG:
3188 prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value;
3191 case IW_AUTH_PRIVACY_INVOKED:
3192 prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value;
3194 #if CFG_SUPPORT_802_11W
3196 //printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value);
3197 prGlueInfo->rWpaInfo.u4Mfp = prAuth->value;
3200 #if CFG_SUPPORT_WAPI
3201 case IW_AUTH_WAPI_ENABLED:
3204 WLAN_STATUS rStatus;
3206 rStatus = kalIoctl(prGlueInfo,
3216 DBGLOG(INIT, INFO, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value));
3221 printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags);
3226 } /* wext_set_auth */
3229 /*----------------------------------------------------------------------------*/
3231 * \brief To set encryption cipher and key.
3233 * \param[in] prDev Net device requested.
3234 * \param[in] prIwrInfo NULL.
3235 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
3236 * \param[in] pcExtra Pointer to key string buffer.
3238 * \retval 0 Success.
3239 * \retval -EINVAL Key ID error for WEP.
3240 * \retval -EFAULT Setting parameters to driver fail.
3241 * \retval -EOPNOTSUPP Key size not supported.
3243 * \note Securiry information is stored in pEnc.
3245 /*----------------------------------------------------------------------------*/
3246 #if CFG_SUPPORT_WAPI
3247 UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */
3249 UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */
3253 wext_set_encode_ext (
3254 IN struct net_device *prNetDev,
3255 IN struct iw_request_info *prIwrInfo,
3256 IN struct iw_point *prEnc,
3260 P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf;
3261 P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf;
3264 P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
3266 struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *) pcExtra;
3268 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
3269 ENUM_PARAM_AUTH_MODE_T eAuthMode;
3270 //ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH;
3272 #if CFG_SUPPORT_WAPI
3273 P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
3276 P_GLUE_INFO_T prGlueInfo = NULL;
3277 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3278 UINT_32 u4BufLen = 0;
3282 if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) {
3285 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3287 memset(keyStructBuf, 0, sizeof(keyStructBuf));
3289 #if CFG_SUPPORT_WAPI
3290 if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
3291 if (prEnc->flags & IW_ENCODE_DISABLED) {
3292 //printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n");
3296 prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX);
3297 prWpiKey->ucKeyID --;
3298 if (prWpiKey->ucKeyID > 1) {
3299 /* key id is out of range */
3300 //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID);
3304 if (prIWEncExt->key_len != 32) {
3305 /* key length not valid */
3306 //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len);
3310 //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags);
3312 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3313 prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
3314 prWpiKey->eDirection = ENUM_WPI_RX;
3316 else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3317 prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
3318 prWpiKey->eDirection = ENUM_WPI_RX_TX;
3322 memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2);
3325 memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6);
3327 memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
3328 prWpiKey->u4LenWPIEK = 16;
3330 memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
3331 prWpiKey->u4LenWPICK = 16;
3333 rStatus = kalIoctl(prGlueInfo,
3336 sizeof(PARAM_WPI_KEY_T),
3343 if (rStatus != WLAN_STATUS_SUCCESS) {
3344 //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus);
3352 if ( (prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) {
3353 prRemoveKey->u4Length = sizeof(*prRemoveKey);
3354 memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3356 printk("IW_ENCODE_DISABLED: ID:%d, Addr:[" MACSTR "]\n",
3357 prRemoveKey->KeyIndex, MAC2STR(prRemoveKey->BSSID));
3360 rStatus = kalIoctl(prGlueInfo,
3361 wlanoidSetRemoveKey,
3363 prRemoveKey->u4Length,
3371 if (rStatus != WLAN_STATUS_SUCCESS) {
3372 DBGLOG(INIT, INFO, ("remove key error:%lx\n", rStatus));
3378 //printk ("alg %x\n", prIWEncExt->alg);
3380 switch (prIWEncExt->alg) {
3381 case IW_ENCODE_ALG_NONE:
3383 case IW_ENCODE_ALG_WEP:
3384 /* iwconfig wlan0 key 0123456789 */
3385 /* iwconfig wlan0 key s:abcde */
3386 /* iwconfig wlan0 key 0123456789 [1] */
3387 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3388 /* check key size for WEP */
3389 if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) {
3390 /* prepare PARAM_WEP key structure */
3391 prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
3392 (prEnc->flags & IW_ENCODE_INDEX) -1 : 0;
3393 if (prWepKey->u4KeyIndex > 3) {
3394 /* key id is out of range */
3397 prWepKey->u4KeyIndex |= 0x80000000;
3398 prWepKey->u4Length = 12 + prIWEncExt->key_len;
3399 prWepKey->u4KeyLength = prIWEncExt->key_len;
3400 //kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len);
3401 kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
3404 rStatus = kalIoctl(prGlueInfo,
3414 if (rStatus != WLAN_STATUS_SUCCESS) {
3415 DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus));
3419 /* change to auto switch */
3420 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY |
3421 IW_AUTH_ALG_OPEN_SYSTEM;
3422 eAuthMode = AUTH_MODE_AUTO_SWITCH;
3424 rStatus = kalIoctl(prGlueInfo,
3434 if (rStatus != WLAN_STATUS_SUCCESS) {
3435 DBGLOG(INIT, INFO, ("wlanoidSetAuthMode fail 0x%lx\n", rStatus));
3439 prGlueInfo->rWpaInfo.u4CipherPairwise =
3440 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
3441 prGlueInfo->rWpaInfo.u4CipherGroup =
3442 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
3444 eEncStatus = ENUM_WEP_ENABLED;
3447 rStatus = kalIoctl(prGlueInfo,
3448 wlanoidSetEncryptionStatus,
3450 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T),
3457 if (rStatus != WLAN_STATUS_SUCCESS) {
3458 DBGLOG(INIT, INFO, ("wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus));
3463 DBGLOG(INIT, INFO, ("key length %x\n", prIWEncExt->key_len));
3464 DBGLOG(INIT, INFO, ("key error\n"));
3468 case IW_ENCODE_ALG_TKIP:
3469 case IW_ENCODE_ALG_CCMP:
3470 #if CFG_SUPPORT_802_11W
3471 case IW_ENCODE_ALG_AES_CMAC:
3476 prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
3477 (prEnc->flags & IW_ENCODE_INDEX) -1: 0;
3478 #if CFG_SUPPORT_802_11W
3479 if (prKey->u4KeyIndex > 5)
3481 if (prKey->u4KeyIndex > 3)
3484 DBGLOG(INIT, INFO, ("key index error:0x%lx\n", prKey->u4KeyIndex));
3485 /* key id is out of range */
3489 /* bit(31) and bit(30) are shared by pKey and pRemoveKey */
3491 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3492 prKey->u4KeyIndex |= 0x1UL << 31;
3495 /* Pairwise Key Bit(30) */
3496 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3501 prKey->u4KeyIndex |= 0x1UL << 30;
3506 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3507 prKey->u4KeyIndex |= 0x1UL << 29;
3508 memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
3512 memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3514 /* switch tx/rx MIC key for sta */
3515 if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) {
3516 memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16);
3517 memcpy(((PUINT_8)prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8);
3518 memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8);
3521 memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
3524 prKey->u4KeyLength = prIWEncExt->key_len;
3525 prKey->u4Length = ((UINT_32)&(((P_PARAM_KEY_T)0)->aucKeyMaterial)) + prKey->u4KeyLength;
3528 rStatus = kalIoctl(prGlueInfo,
3538 if (rStatus != WLAN_STATUS_SUCCESS) {
3539 DBGLOG(INIT, INFO, ("add key error:%lx\n", rStatus));
3547 } /* wext_set_encode_ext */
3550 /*----------------------------------------------------------------------------*/
3552 * \brief Set country code
3554 * \param[in] prDev Net device requested.
3555 * \param[in] prIwrInfo NULL.
3556 * \param[in] pu4Mode Pointer to new operation mode.
3557 * \param[in] pcExtra NULL.
3559 * \retval 0 For success.
3560 * \retval -EOPNOTSUPP If new mode is not supported.
3562 * \note Device will run in new operation mode if it is valid.
3564 /*----------------------------------------------------------------------------*/
3567 IN struct net_device *prNetDev,
3568 IN struct iwreq *iwr
3571 P_GLUE_INFO_T prGlueInfo;
3572 WLAN_STATUS rStatus;
3574 UINT_8 aucCountry[2];
3578 /* iwr->u.data.pointer should be like "COUNTRY US", "COUNTRY EU"
3581 if (FALSE == GLUE_CHK_PR2(prNetDev, iwr) ||
3582 !iwr->u.data.pointer || iwr->u.data.length < 10) {
3585 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3587 aucCountry[0] = *((PUINT_8)iwr->u.data.pointer + 8);
3588 aucCountry[1] = *((PUINT_8)iwr->u.data.pointer + 9);
3590 rStatus = kalIoctl(prGlueInfo,
3591 wlanoidSetCountryCode,
3603 /*----------------------------------------------------------------------------*/
3605 * \brief ioctl() (Linux Wireless Extensions) routines
3607 * \param[in] prDev Net device requested.
3608 * \param[in] ifr The ifreq structure for seeting the wireless extension.
3609 * \param[in] i4Cmd The wireless extension ioctl command.
3611 * \retval zero On success.
3612 * \retval -EOPNOTSUPP If the cmd is not supported.
3613 * \retval -EFAULT If copy_to_user goes wrong.
3614 * \retval -EINVAL If any value's out of range.
3618 /*----------------------------------------------------------------------------*/
3620 wext_support_ioctl (
3621 IN struct net_device *prDev,
3622 IN struct ifreq *prIfReq,
3626 /* prIfReq is verified in the caller function wlanDoIOCTL() */
3627 struct iwreq *iwr = (struct iwreq*)prIfReq;
3628 struct iw_request_info rIwReqInfo;
3630 char *prExtraBuf = NULL;
3631 UINT_32 u4ExtraSize = 0;
3633 /* prDev is verified in the caller function wlanDoIOCTL() */
3635 //printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd);
3637 /* Prepare the call */
3638 rIwReqInfo.cmd = (__u16)i4Cmd;
3639 rIwReqInfo.flags = 0;
3642 case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */
3643 ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL);
3646 /* case SIOCSIWNWID: 0x8B02, deprecated */
3647 /* case SIOCGIWNWID: 0x8B03, deprecated */
3649 case SIOCSIWFREQ: /* 0x8B04, set channel */
3650 ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL);
3653 case SIOCGIWFREQ: /* 0x8B05, get channel */
3654 ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL);
3657 case SIOCSIWMODE: /* 0x8B06, set operation mode */
3658 ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL);
3662 case SIOCGIWMODE: /* 0x8B07, get operation mode */
3663 ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL);
3666 /* case SIOCSIWSENS: 0x8B08, unsupported */
3667 /* case SIOCGIWSENS: 0x8B09, unsupported */
3669 /* case SIOCSIWRANGE: 0x8B0A, unused */
3670 case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */
3671 if (iwr->u.data.pointer != NULL) {
3672 /* Buffer size shoule be large enough */
3673 if (iwr->u.data.length < sizeof(struct iw_range)) {
3678 prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE);
3684 /* reset all fields */
3685 memset(prExtraBuf, 0, sizeof(struct iw_range));
3686 iwr->u.data.length = sizeof(struct iw_range);
3688 ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf);
3689 /* Push up to the caller */
3690 if (copy_to_user(iwr->u.data.pointer,
3692 iwr->u.data.length)) {
3696 kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range));
3704 case SIOCSIWPRIV: /* 0x8B0C, Country */
3705 ret = wext_set_country(prDev, iwr);
3708 /* case SIOCGIWPRIV: 0x8B0D, handled in wlan_do_ioctl() */
3709 /* caes SIOCSIWSTATS: 0x8B0E, unused */
3710 /* case SIOCGIWSTATS:
3711 get statistics, intercepted by wireless_process_ioctl() in wireless.c,
3712 redirected to dev_iwstats(), dev->get_wireless_stats().
3714 /* case SIOCSIWSPY: 0x8B10, unsupported */
3715 /* case SIOCGIWSPY: 0x8B11, unsupported*/
3716 /* case SIOCSIWTHRSPY: 0x8B12, unsupported */
3717 /* case SIOCGIWTHRSPY: 0x8B13, unsupported*/
3719 case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */
3720 if (iwr->u.ap_addr.sa_data[0] == 0 &&
3721 iwr->u.ap_addr.sa_data[1] == 0 &&
3722 iwr->u.ap_addr.sa_data[2] == 0 &&
3723 iwr->u.ap_addr.sa_data[3] == 0 &&
3724 iwr->u.ap_addr.sa_data[4] == 0 &&
3725 iwr->u.ap_addr.sa_data[5] == 0) {
3726 /* WPA Supplicant will set 000000000000 in
3727 ** wpa_driver_wext_deinit(), do nothing here or disassoc again?
3733 ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
3737 case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */
3738 ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
3741 case SIOCSIWMLME: /* 0x8B16, request MLME operation */
3742 /* Fixed length structure */
3743 if (iwr->u.data.length != sizeof(struct iw_mlme)) {
3744 DBGLOG(INIT, INFO, ("MLME buffer strange:%d\n", iwr->u.data.length));
3749 if (!iwr->u.data.pointer) {
3754 prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE);
3760 if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) {
3764 ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf);
3767 kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme));
3771 /* case SIOCGIWAPLIST: 0x8B17, deprecated */
3772 case SIOCSIWSCAN: /* 0x8B18, scan request */
3773 if (iwr->u.data.pointer == NULL) {
3774 ret = wext_set_scan(prDev, NULL, NULL, NULL);
3776 #if WIRELESS_EXT > 17
3777 else if (iwr->u.data.length == sizeof(struct iw_scan_req)) {
3778 prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE);
3783 if (copy_from_user(prExtraBuf, ((struct iw_scan_req *) (iwr->u.data.pointer))->essid,
3784 ((struct iw_scan_req *) (iwr->u.data.pointer))->essid_len)) {
3787 ret = wext_set_scan(prDev, NULL, (union iwreq_data *) &(iwr->u.data), prExtraBuf);
3790 kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN);
3799 case SIOCGIWSCAN: /* 0x8B19, get scan results */
3800 if (!iwr->u.data.pointer|| !iwr->u.essid.pointer) {
3805 u4ExtraSize = iwr->u.data.length;
3806 /* allocate the same size of kernel buffer to store scan results. */
3807 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
3813 /* iwr->u.data.length may be updated by wext_get_scan() */
3814 ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf);
3816 if (ret == -E2BIG) {
3817 DBGLOG(INIT, INFO, ("[wifi] wext_get_scan -E2BIG\n"));
3821 /* check updated length is valid */
3822 ASSERT(iwr->u.data.length <= u4ExtraSize);
3823 if (iwr->u.data.length > u4ExtraSize) {
3824 DBGLOG(INIT, INFO, ("Updated result length is larger than allocated (%d > %ld)\n",
3825 iwr->u.data.length, u4ExtraSize));
3826 iwr->u.data.length = u4ExtraSize;
3829 if (copy_to_user(iwr->u.data.pointer,
3831 iwr->u.data.length)) {
3836 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
3844 case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */
3845 if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) {
3849 if (!iwr->u.essid.pointer) {
3854 prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE);
3860 if (copy_from_user(prExtraBuf,
3861 iwr->u.essid.pointer,
3862 iwr->u.essid.length)) {
3866 /* Add trailing '\0' for printk */
3867 //prExtraBuf[iwr->u.essid.length] = 0;
3868 //printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length);
3869 ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
3870 //printk ("set essid %d\n", ret);
3873 kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4);
3879 case SIOCGIWESSID: /* 0x8B1B, get SSID */
3880 if (!iwr->u.essid.pointer) {
3885 if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) {
3886 DBGLOG(INIT, INFO, ("[wifi] iwr->u.essid.length:%d too small\n",
3887 iwr->u.essid.length));
3888 ret = -E2BIG; /* let caller try larger buffer */
3892 prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE);
3898 /* iwr->u.essid.length is updated by wext_get_essid() */
3900 ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
3902 if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) {
3907 kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE);
3912 /* case SIOCSIWNICKN: 0x8B1C, not supported */
3913 /* case SIOCGIWNICKN: 0x8B1D, not supported */
3915 case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */
3916 //ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL);
3919 case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */
3920 ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL);
3923 case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */
3924 ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL);
3927 case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */
3928 ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL);
3931 /* case SIOCSIWFRAG: 0x8B24, unsupported */
3932 case SIOCGIWFRAG: /* 0x8B25, get frag threshold */
3933 ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL);
3936 case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */
3937 ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL);
3940 case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */
3941 ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL);
3944 /* case SIOCSIWRETRY: 0x8B28, unsupported */
3945 /* case SIOCGIWRETRY: 0x8B29, unsupported */
3948 case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */
3949 /* Only DISABLED case has NULL pointer and length == 0 */
3950 if (iwr->u.encoding.pointer) {
3951 if (iwr->u.encoding.length > 16) {
3956 u4ExtraSize = iwr->u.encoding.length;
3957 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
3963 if (copy_from_user(prExtraBuf,
3964 iwr->u.encoding.pointer,
3965 iwr->u.encoding.length)) {
3969 else if (iwr->u.encoding.length != 0) {
3975 ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf);
3979 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
3984 case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */
3986 ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL);
3989 case SIOCSIWPOWER: /* 0x8B2C, set power management */
3990 ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL);
3993 case SIOCGIWPOWER: /* 0x8B2D, get power management */
3994 ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL);
3997 #if WIRELESS_EXT > 17
3998 case SIOCSIWGENIE: /* 0x8B30, set gen ie */
3999 if (iwr->u.data.pointer) {
4000 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4001 if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) {
4002 /* Fixed length structure */
4003 #if CFG_SUPPORT_WAPI
4004 if (iwr->u.data.length > 42 /* The max wapi ie buffer */) {
4009 u4ExtraSize = iwr->u.data.length;
4011 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4016 if (copy_from_user(prExtraBuf,
4017 iwr->u.data.pointer,
4018 iwr->u.data.length)) {
4022 WLAN_STATUS rStatus;
4024 #if CFG_SUPPORT_WAPI
4025 rStatus = kalIoctl(prGlueInfo,
4026 wlanoidSetWapiAssocInfo,
4035 if (rStatus != WLAN_STATUS_SUCCESS) {
4036 //printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", rStatus);
4038 #if CFG_SUPPORT_WPS2
4039 PUINT_8 prDesiredIE = NULL;
4040 if (wextSrchDesiredWPSIE(prExtraBuf,
4043 (PUINT_8 *)&prDesiredIE)) {
4044 rStatus = kalIoctl(prGlueInfo,
4045 wlanoidSetWSCAssocInfo,
4047 IE_SIZE(prDesiredIE),
4053 if (rStatus != WLAN_STATUS_SUCCESS) {
4054 //printk(KERN_INFO "[WSC] set WSC assoc info error:%lx\n", rStatus);
4058 #if CFG_SUPPORT_WAPI
4062 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4069 case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */
4074 case SIOCSIWAUTH: /* 0x8B32, set auth mode params */
4075 ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL);
4078 /* case SIOCGIWAUTH: 0x8B33, unused? */
4079 case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */
4080 if (iwr->u.encoding.pointer) {
4081 u4ExtraSize = iwr->u.encoding.length;
4082 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4088 if (copy_from_user(prExtraBuf,
4089 iwr->u.encoding.pointer,
4090 iwr->u.encoding.length)) {
4094 else if (iwr->u.encoding.length != 0) {
4100 ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf);
4104 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4109 /* case SIOCGIWENCODEEXT: 0x8B35, unused? */
4111 case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */
4113 if (iwr->u.data.pointer) {
4114 /* Fixed length structure */
4115 if (iwr->u.data.length != sizeof(struct iw_pmksa)) {
4120 u4ExtraSize = sizeof(struct iw_pmksa);
4121 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4127 if (copy_from_user(prExtraBuf,
4128 iwr->u.data.pointer,
4129 sizeof(struct iw_pmksa))) {
4133 switch(((struct iw_pmksa *)prExtraBuf)->cmd) {
4136 printk(KERN_INFO "IW_PMKSA_ADD [" MACSTR "]\n",
4137 MAC2STR(((struct iw_pmksa *)pExtraBuf)->bssid.sa_data));
4140 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4141 WLAN_STATUS rStatus;
4143 P_PARAM_PMKID_T prPmkid;
4145 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
4147 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_ADD\n"));
4152 prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
4153 prPmkid->u4BSSIDInfoCount = 1;
4154 kalMemCopy(prPmkid->arBSSIDInfo->arBSSID,
4155 ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data,
4157 kalMemCopy(prPmkid->arBSSIDInfo->arPMKID,
4158 ((struct iw_pmksa *)prExtraBuf)->pmkid,
4161 rStatus = kalIoctl(prGlueInfo,
4164 sizeof(PARAM_PMKID_T),
4171 if (rStatus != WLAN_STATUS_SUCCESS) {
4172 DBGLOG(INIT, INFO, ("add pmkid error:%lx\n", rStatus));
4174 kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
4177 case IW_PMKSA_REMOVE:
4179 printk(KERN_INFO "IW_PMKSA_REMOVE [" MACSTR "]\n",
4180 MAC2STR(((struct iw_pmksa *)buf)->bssid.sa_data));
4183 case IW_PMKSA_FLUSH:
4185 printk(KERN_INFO "IW_PMKSA_FLUSH\n");
4188 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4189 WLAN_STATUS rStatus;
4191 P_PARAM_PMKID_T prPmkid;
4193 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE);
4195 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
4200 prPmkid->u4Length = 8;
4201 prPmkid->u4BSSIDInfoCount = 0;
4203 rStatus = kalIoctl(prGlueInfo,
4206 sizeof(PARAM_PMKID_T),
4213 if (rStatus != WLAN_STATUS_SUCCESS) {
4214 DBGLOG(INIT, INFO, ("flush pmkid error:%lx\n", rStatus));
4216 kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
4220 DBGLOG(INIT, INFO, ("UNKNOWN iw_pmksa command:%d\n",
4221 ((struct iw_pmksa *)prExtraBuf)->cmd));
4228 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4232 else if (iwr->u.data.length != 0) {
4242 /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */
4247 //printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret);
4250 } /* wext_support_ioctl */
4254 /*----------------------------------------------------------------------------*/
4256 * \brief To send an event (RAW socket pacekt) to user process actively.
4258 * \param[in] prGlueInfo Glue layer info.
4259 * \param[in] u4cmd Whcih event command we want to indicate to user process.
4260 * \param[in] pData Data buffer to be indicated.
4261 * \param[in] dataLen Available data size in pData.
4265 * \note Event is indicated to upper layer if cmd is supported and data is valid.
4266 * Using of kernel symbol wireless_send_event(), which is defined in
4267 * <net/iw_handler.h> after WE-14 (2.4.20).
4269 /*----------------------------------------------------------------------------*/
4271 wext_indicate_wext_event (
4272 IN P_GLUE_INFO_T prGlueInfo,
4273 IN unsigned int u4Cmd,
4274 IN unsigned char *pucData,
4275 IN unsigned int u4dataLen
4278 union iwreq_data wrqu;
4279 unsigned char *pucExtraInfo = NULL;
4280 #if WIRELESS_EXT >= 15
4281 unsigned char *pucDesiredIE = NULL;
4282 unsigned char aucExtraInfoBuf[200];
4284 #if WIRELESS_EXT < 18
4288 memset(&wrqu, 0, sizeof(wrqu));
4292 memcpy(&wrqu.power, pucData, u4dataLen);
4295 complete_all(&prGlueInfo->rScanComp);
4300 memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);
4303 memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4307 case IWEVASSOCREQIE:
4308 #if WIRELESS_EXT < 15
4309 /* under WE-15, no suitable Event can be used */
4310 goto skip_indicate_event;
4312 /* do supplicant a favor, parse to the start of WPA/RSN IE */
4313 if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) {
4317 else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
4321 else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
4324 #if CFG_SUPPORT_WAPI /* Android+ */
4325 else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) {
4326 //printk("wextSrchDesiredWAPIIE!!\n");
4331 /* no WPA/RSN IE found, skip this event */
4332 goto skip_indicate_event;
4335 #if WIRELESS_EXT < 18
4336 /* under WE-18, only IWEVCUSTOM can be used */
4338 pucExtraInfo = aucExtraInfoBuf;
4339 pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs=");
4340 /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */
4341 /* translate binary string to hex string, requirement of IWEVCUSTOM */
4342 for (i = 0; i < pucDesiredIE[1] + 2 ; ++i) {
4343 pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]);
4345 pucExtraInfo = aucExtraInfoBuf;
4346 wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2;
4348 /* IWEVASSOCREQIE, indicate binary string */
4349 pucExtraInfo = pucDesiredIE;
4350 wrqu.data.length = pucDesiredIE[1] + 2;
4352 #endif /* WIRELESS_EXT < 15 */
4355 case IWEVMICHAELMICFAILURE:
4356 #if WIRELESS_EXT < 15
4357 /* under WE-15, no suitable Event can be used */
4358 goto skip_indicate_event;
4361 P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T)pucData;
4362 /* under WE-18, only IWEVCUSTOM can be used */
4364 pucExtraInfo = aucExtraInfoBuf;
4365 pucExtraInfo += sprintf(pucExtraInfo,
4366 "MLME-MICHAELMICFAILURE.indication ");
4367 pucExtraInfo += sprintf(pucExtraInfo,
4369 (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ?
4370 "groupcast " : "unicast ");
4372 wrqu.data.length = pucExtraInfo - aucExtraInfoBuf;
4373 pucExtraInfo = aucExtraInfoBuf;
4375 #endif /* WIRELESS_EXT < 15 */
4379 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 &&
4380 prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) {
4382 /* only used in WPA2 */
4383 #if WIRELESS_EXT >= 18
4384 P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T)pucData;
4386 struct iw_pmkid_cand rPmkidCand;
4387 pucExtraInfo = aucExtraInfoBuf;
4389 rPmkidCand.flags = prPmkidCand->u4Flags;
4390 rPmkidCand.index = 0;
4391 kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6);
4393 kalMemCopy(pucExtraInfo, (PUINT_8)&rPmkidCand, sizeof(struct iw_pmkid_cand));
4394 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4396 /* pmkid canadidate list is supported after WE-18 */
4397 /* indicate struct iw_pmkid_cand */
4399 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */
4400 goto skip_indicate_event;
4404 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */
4405 goto skip_indicate_event;
4411 pucExtraInfo = aucExtraInfoBuf;
4412 kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T));
4413 wrqu.data.length = sizeof(PTA_IPC_T);
4417 /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */
4418 goto skip_indicate_event;
4421 /* Send event to user space */
4422 wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo);
4424 skip_indicate_event:
4426 } /* wext_indicate_wext_event */
4429 /*----------------------------------------------------------------------------*/
4431 * \brief A method of struct net_device, to get the network interface statistical
4434 * Whenever an application needs to get statistics for the interface, this method
4435 * is called. This happens, for example, when ifconfig or netstat -i is run.
4437 * \param[in] pDev Pointer to struct net_device.
4439 * \return net_device_stats buffer pointer.
4442 /*----------------------------------------------------------------------------*/
4443 struct iw_statistics *
4444 wext_get_wireless_stats (
4445 struct net_device *prDev
4449 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
4450 P_GLUE_INFO_T prGlueInfo = NULL;
4451 struct iw_statistics *pStats = NULL;
4456 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4462 pStats = (struct iw_statistics *) (&(prGlueInfo->rIwStats));
4464 if (!prDev || !netif_carrier_ok(prDev)) {
4465 /* network not connected */
4469 rStatus = kalIoctl(prGlueInfo,
4481 } /* wlan_get_wireless_stats */
4483 /*----------------------------------------------------------------------------*/
4485 * \brief To report the private supported IOCTLs table to user space.
4487 * \param[in] prNetDev Net device requested.
4488 * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
4489 * user space buffer in gl_iwpriv_table.
4491 * \retval 0 For success.
4492 * \retval -E2BIG For user's buffer size is too small.
4493 * \retval -EFAULT For fail.
4496 /*----------------------------------------------------------------------------*/
4499 IN struct net_device *prNetDev,
4500 IN struct ifreq *prIfReq
4503 /* prIfReq is verified in the caller function wlanDoIOCTL() */
4504 struct iwreq *prIwReq = (struct iwreq *)prIfReq;
4505 struct iw_point *prData= (struct iw_point *)&prIwReq->u.data;
4506 UINT_16 u2BufferSize = 0;
4508 u2BufferSize = prData->length;
4510 /* update our private table size */
4511 prData->length = (__u16)sizeof(rIwPrivTable)/sizeof(struct iw_priv_args);
4513 if (u2BufferSize < prData->length) {
4517 if (prData->length) {
4518 if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) {
4524 } /* wext_get_priv */
4526 #endif /* WIRELESS_EXT */