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, ""},
490 /* added for set_oid and get_oid */
491 {IOCTL_SET_STRUCT, 256, 0, ""},
492 {IOCTL_GET_STRUCT, 0, 256, ""},
494 /* sub-ioctl definitions */
496 {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain" },
497 {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain" },
500 #if CFG_TCP_IP_CHKSUM_OFFLOAD
501 {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum" },
502 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
504 {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode" },
505 {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode" },
507 {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps" },
509 {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode" },
510 {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd" },
511 {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" },
512 #if CFG_SUPPORT_PRIV_MCR_RW
513 {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr" },
514 {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mcr" },
516 {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl" },
517 {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" },
519 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
520 {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"},
521 /* GET STRUCT sub-ioctls commands */
522 {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bwcs"},
525 /* SET STRUCT sub-ioctls commands */
526 {PRIV_CMD_OID, 256, 0, "set_oid"},
527 /* GET STRUCT sub-ioctls commands */
528 {PRIV_CMD_OID, 0, 256, "get_oid"},
530 {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band" },
531 {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band" },
533 {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower" },
534 {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list" },
535 {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_mem" },
537 #if CFG_ENABLE_WIFI_DIRECT
538 {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode" },
542 static const iw_handler rIwPrivHandler[] = {
543 [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int,
544 [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int,
545 [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
546 [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL,
547 [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL,
548 [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL,
549 [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL,
550 [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL,
551 [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct,
552 [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct,
553 [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct,
554 [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints,
555 [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints,
558 const struct iw_handler_def wext_handler_def = {
560 .num_private = (__u16)sizeof(rIwPrivHandler)/sizeof(iw_handler),
561 .num_private_args = (__u16)sizeof(rIwPrivTable)/sizeof(struct iw_priv_args),
562 .standard = (iw_handler *) NULL,
563 .private = rIwPrivHandler,
564 .private_args = rIwPrivTable,
565 .get_wireless_stats = wext_get_wireless_stats,
568 /*******************************************************************************
569 * P R I V A T E D A T A
570 ********************************************************************************
573 /*******************************************************************************
575 ********************************************************************************
578 /*******************************************************************************
579 * F U N C T I O N D E C L A R A T I O N S
580 ********************************************************************************
583 /*******************************************************************************
585 ********************************************************************************
588 /*----------------------------------------------------------------------------*/
590 * \brief Find the desired WPA/RSN Information Element according to desiredElemID.
592 * \param[in] pucIEStart IE starting address.
593 * \param[in] i4TotalIeLen Total length of all the IE.
594 * \param[in] ucDesiredElemId Desired element ID.
595 * \param[out] ppucDesiredIE Pointer to the desired IE.
597 * \retval TRUE Find the desired IE.
598 * \retval FALSE Desired IE not found.
602 /*----------------------------------------------------------------------------*/
604 wextSrchDesiredWPAIE (
605 IN PUINT_8 pucIEStart,
606 IN INT_32 i4TotalIeLen,
607 IN UINT_8 ucDesiredElemId,
608 OUT PUINT_8 *ppucDesiredIE
611 INT_32 i4InfoElemLen;
614 ASSERT(ppucDesiredIE);
616 while (i4TotalIeLen >= 2) {
617 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
619 if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
620 if (ucDesiredElemId != 0xDD) {
622 *ppucDesiredIE = &pucIEStart[0];
626 /* EID == 0xDD, check WPA IE */
627 if (pucIEStart[1] >= 4) {
628 if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) {
629 *ppucDesiredIE = &pucIEStart[0];
632 } /* check WPA IE length */
633 } /* check EID == 0xDD */
634 } /* check desired EID */
636 /* Select next information element. */
637 i4TotalIeLen -= i4InfoElemLen;
638 pucIEStart += i4InfoElemLen;
642 } /* parseSearchDesiredWPAIE */
646 /*----------------------------------------------------------------------------*/
648 * \brief Find the desired WAPI Information Element .
650 * \param[in] pucIEStart IE starting address.
651 * \param[in] i4TotalIeLen Total length of all the IE.
652 * \param[out] ppucDesiredIE Pointer to the desired IE.
654 * \retval TRUE Find the desired IE.
655 * \retval FALSE Desired IE not found.
659 /*----------------------------------------------------------------------------*/
661 wextSrchDesiredWAPIIE (
662 IN PUINT_8 pucIEStart,
663 IN INT_32 i4TotalIeLen,
664 OUT PUINT_8 *ppucDesiredIE
667 INT_32 i4InfoElemLen;
670 ASSERT(ppucDesiredIE);
672 while (i4TotalIeLen >= 2) {
673 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
675 if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) {
676 *ppucDesiredIE = &pucIEStart[0];
678 } /* check desired EID */
680 /* Select next information element. */
681 i4TotalIeLen -= i4InfoElemLen;
682 pucIEStart += i4InfoElemLen;
686 } /* wextSrchDesiredWAPIIE */
691 /*----------------------------------------------------------------------------*/
693 * \brief Find the desired WPS Information Element according to desiredElemID.
695 * \param[in] pucIEStart IE starting address.
696 * \param[in] i4TotalIeLen Total length of all the IE.
697 * \param[in] ucDesiredElemId Desired element ID.
698 * \param[out] ppucDesiredIE Pointer to the desired IE.
700 * \retval TRUE Find the desired IE.
701 * \retval FALSE Desired IE not found.
705 /*----------------------------------------------------------------------------*/
707 wextSrchDesiredWPSIE (
708 IN PUINT_8 pucIEStart,
709 IN INT_32 i4TotalIeLen,
710 IN UINT_8 ucDesiredElemId,
711 OUT PUINT_8 *ppucDesiredIE)
713 INT_32 i4InfoElemLen;
716 ASSERT(ppucDesiredIE);
718 while (i4TotalIeLen >= 2) {
719 i4InfoElemLen = (INT_32) pucIEStart[1] + 2;
721 if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) {
722 if (ucDesiredElemId != 0xDD) {
724 *ppucDesiredIE = &pucIEStart[0];
728 /* EID == 0xDD, check WPS IE */
729 if (pucIEStart[1] >= 4) {
730 if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) {
731 *ppucDesiredIE = &pucIEStart[0];
734 } /* check WPS IE length */
735 } /* check EID == 0xDD */
736 } /* check desired EID */
738 /* Select next information element. */
739 i4TotalIeLen -= i4InfoElemLen;
740 pucIEStart += i4InfoElemLen;
744 } /* parseSearchDesiredWPSIE */
748 /*----------------------------------------------------------------------------*/
750 * \brief Get the name of the protocol used on the air.
752 * \param[in] prDev Net device requested.
753 * \param[in] prIwrInfo NULL.
754 * \param[out] pcName Buffer to store protocol name string
755 * \param[in] pcExtra NULL.
757 * \retval 0 For success.
759 * \note If netif_carrier_ok, protocol name is returned;
760 * otherwise, "disconnected" is returned.
762 /*----------------------------------------------------------------------------*/
765 IN struct net_device *prNetDev,
766 IN struct iw_request_info *prIwrInfo,
771 ENUM_PARAM_NETWORK_TYPE_T eNetWorkType;
773 P_GLUE_INFO_T prGlueInfo = NULL;
774 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
775 UINT_32 u4BufLen = 0;
779 if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) {
782 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
784 if (netif_carrier_ok(prNetDev)) {
786 rStatus = kalIoctl(prGlueInfo,
787 wlanoidQueryNetworkTypeInUse,
789 sizeof(eNetWorkType),
796 switch(eNetWorkType) {
797 case PARAM_NETWORK_TYPE_DS:
798 strcpy(pcName, "IEEE 802.11b");
800 case PARAM_NETWORK_TYPE_OFDM24:
801 strcpy(pcName, "IEEE 802.11bgn");
803 case PARAM_NETWORK_TYPE_AUTOMODE:
804 case PARAM_NETWORK_TYPE_OFDM5:
805 strcpy(pcName, "IEEE 802.11abgn");
807 case PARAM_NETWORK_TYPE_FH:
809 strcpy(pcName, "IEEE 802.11");
814 strcpy(pcName, "Disconnected");
818 } /* wext_get_name */
820 /*----------------------------------------------------------------------------*/
822 * \brief To set the operating channel in the wireless device.
824 * \param[in] prDev Net device requested.
825 * \param[in] prIwrInfo NULL
826 * \param[in] prFreq Buffer to store frequency information
827 * \param[in] pcExtra NULL
829 * \retval 0 For success.
830 * \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS.
831 * \retval -EINVAL Invalid channel frequency.
833 * \note If infrastructure mode is IBSS, new channel frequency is set to device.
834 * The range of channel number depends on different regulatory domain.
836 /*----------------------------------------------------------------------------*/
839 IN struct net_device *prNetDev,
840 IN struct iw_request_info *prIwReqInfo,
841 IN struct iw_freq *prIwFreq,
847 UINT_32 u4ChnlFreq; /* Store channel or frequency information */
849 P_GLUE_INFO_T prGlueInfo = NULL;
850 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
851 UINT_32 u4BufLen = 0;
855 if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) {
858 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
861 printk("set m:%d, e:%d, i:%d, flags:%d\n",
862 prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags);
865 /* If setting by frequency, convert to a channel */
866 if ((prIwFreq->e == 1) &&
867 (prIwFreq->m >= (int) 2.412e8) &&
868 (prIwFreq->m <= (int) 2.484e8)) {
870 /* Change to KHz format */
871 u4ChnlFreq = (UINT_32)(prIwFreq->m / (KILO / 10));
873 rStatus = kalIoctl(prGlueInfo,
882 if (WLAN_STATUS_SUCCESS != rStatus) {
886 /* Setting by channel number */
887 else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) {
891 /* Change to channel number format */
892 u4ChnlFreq = (UINT_32)prIwFreq->m;
894 rStatus = kalIoctl(prGlueInfo,
906 if (WLAN_STATUS_SUCCESS != rStatus) {
915 } /* wext_set_freq */
918 /*----------------------------------------------------------------------------*/
920 * \brief To get the operating channel in the wireless device.
922 * \param[in] prDev Net device requested.
923 * \param[in] prIwrInfo NULL.
924 * \param[out] prFreq Buffer to store frequency information.
925 * \param[in] pcExtra NULL.
927 * \retval 0 If netif_carrier_ok.
928 * \retval -ENOTCONN Otherwise
930 * \note If netif_carrier_ok, channel frequency information is stored in pFreq.
932 /*----------------------------------------------------------------------------*/
935 IN struct net_device *prNetDev,
936 IN struct iw_request_info *prIwrInfo,
937 OUT struct iw_freq *prIwFreq,
941 UINT_32 u4Channel = 0;
944 P_GLUE_INFO_T prGlueInfo = NULL;
945 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
946 UINT_32 u4BufLen = 0;
950 if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) {
953 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
955 /* GeorgeKuo: TODO skip checking in IBSS mode */
956 if (!netif_carrier_ok(prNetDev)) {
960 rStatus = kalIoctl(prGlueInfo,
961 wlanoidQueryFrequency,
970 prIwFreq->m = (int) u4Channel; /* freq in KHz */
975 } /* wext_get_freq */
978 /*----------------------------------------------------------------------------*/
980 * \brief To set operating mode.
982 * \param[in] prDev Net device requested.
983 * \param[in] prIwrInfo NULL.
984 * \param[in] pu4Mode Pointer to new operation mode.
985 * \param[in] pcExtra NULL.
987 * \retval 0 For success.
988 * \retval -EOPNOTSUPP If new mode is not supported.
990 * \note Device will run in new operation mode if it is valid.
992 /*----------------------------------------------------------------------------*/
995 IN struct net_device *prNetDev,
996 IN struct iw_request_info *prIwReqInfo,
997 IN unsigned int *pu4Mode,
1001 ENUM_PARAM_OP_MODE_T eOpMode;
1003 P_GLUE_INFO_T prGlueInfo = NULL;
1004 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1005 UINT_32 u4BufLen = 0;
1009 if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) {
1012 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1016 eOpMode = NET_TYPE_AUTO_SWITCH;
1020 eOpMode = NET_TYPE_IBSS;
1024 eOpMode = NET_TYPE_INFRA;
1028 DBGLOG(INIT, INFO, ("%s(): Set UNSUPPORTED Mode = %d.\n", __FUNCTION__, *pu4Mode));
1032 //printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode);
1034 rStatus = kalIoctl(prGlueInfo,
1035 wlanoidSetInfrastructureMode,
1045 /* after set operation mode, key table are cleared */
1047 /* reset wpa info */
1048 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
1049 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
1050 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
1051 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
1052 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
1053 #if CFG_SUPPORT_802_11W
1054 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
1058 } /* wext_set_mode */
1060 /*----------------------------------------------------------------------------*/
1062 * \brief To get operating mode.
1064 * \param[in] prNetDev Net device requested.
1065 * \param[in] prIwReqInfo NULL.
1066 * \param[out] pu4Mode Buffer to store operating mode information.
1067 * \param[in] pcExtra NULL.
1069 * \retval 0 If data is valid.
1070 * \retval -EINVAL Otherwise.
1072 * \note If netif_carrier_ok, operating mode information is stored in pu4Mode.
1074 /*----------------------------------------------------------------------------*/
1077 IN struct net_device *prNetDev,
1078 IN struct iw_request_info *prIwReqInfo,
1079 OUT unsigned int *pu4Mode,
1083 ENUM_PARAM_OP_MODE_T eOpMode;
1085 P_GLUE_INFO_T prGlueInfo = NULL;
1086 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1087 UINT_32 u4BufLen = 0;
1091 if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) {
1094 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1096 rStatus = kalIoctl(prGlueInfo,
1097 wlanoidQueryInfrastructureMode,
1110 *pu4Mode = IW_MODE_ADHOC;
1113 case NET_TYPE_INFRA:
1114 *pu4Mode = IW_MODE_INFRA;
1117 case NET_TYPE_AUTO_SWITCH:
1118 *pu4Mode = IW_MODE_AUTO;
1122 DBGLOG(INIT, INFO, ("%s(): Get UNKNOWN Mode.\n", __FUNCTION__));
1127 } /* wext_get_mode */
1129 /*----------------------------------------------------------------------------*/
1131 * \brief To get the valid range for each configurable STA setting value.
1133 * \param[in] prDev Net device requested.
1134 * \param[in] prIwrInfo NULL.
1135 * \param[in] prData Pointer to iw_point structure, not used.
1136 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1137 * function, wext_support_ioctl() or ioctl_standard_call() in
1140 * \retval 0 If data is valid.
1142 * \note The extra buffer (pcExtra) is filled with information from driver.
1144 /*----------------------------------------------------------------------------*/
1147 IN struct net_device *prNetDev,
1148 IN struct iw_request_info *prIwrInfo,
1149 IN struct iw_point *prData,
1153 struct iw_range *prRange = NULL;
1154 PARAM_RATES_EX aucSuppRate = {0}; /* data buffers */
1157 P_GLUE_INFO_T prGlueInfo = NULL;
1158 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1159 UINT_32 u4BufLen = 0;
1163 if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) {
1166 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1168 prRange = (struct iw_range *) pcExtra;
1170 memset(prRange, 0, sizeof(*prRange));
1171 prRange->throughput = 20000000; /* 20Mbps */
1172 prRange->min_nwid = 0; /* not used */
1173 prRange->max_nwid = 0; /* not used */
1175 /* scan_capa not implemented */
1177 /* event_capa[6]: kernel + driver capabilities */
1178 prRange->event_capa[0] = (IW_EVENT_CAPA_K_0
1179 | IW_EVENT_CAPA_MASK(SIOCGIWAP)
1180 | IW_EVENT_CAPA_MASK(SIOCGIWSCAN)
1181 /* can't display meaningful string in iwlist
1182 | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW)
1183 | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)
1184 | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE)
1185 | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND)
1188 prRange->event_capa[1] = IW_EVENT_CAPA_K_1;
1190 /* report 2.4G channel and frequency only */
1191 prRange->num_channels = (__u16) NUM_CHANNELS;
1192 prRange->num_frequency = (__u8) NUM_CHANNELS;
1193 for (i = 0; i < NUM_CHANNELS; i++) {
1194 /* iwlib takes this number as channel number */
1195 prRange->freq[i].i = i + 1;
1196 prRange->freq[i].m = channel_freq[i];
1197 prRange->freq[i].e = 6; /* Values in table in MHz */
1202 wlanoidQuerySupportedRates,
1204 sizeof(aucSuppRate),
1213 for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX ; i++) {
1214 if (aucSuppRate[i] == 0) {
1217 prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */
1219 prRange->num_bitrates = i;
1221 prRange->min_rts = 0;
1222 prRange->max_rts = 2347;
1223 prRange->min_frag = 256;
1224 prRange->max_frag = 2346;
1226 prRange->min_pmp = 0; /* power management by driver */
1227 prRange->max_pmp = 0; /* power management by driver */
1228 prRange->min_pmt = 0; /* power management by driver */
1229 prRange->max_pmt = 0; /* power management by driver */
1230 prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */
1231 prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */
1232 prRange->pm_capa = IW_POWER_ON; /* power management by driver */
1234 prRange->encoding_size[0] = 5; /* wep40 */
1235 prRange->encoding_size[1] = 16; /* tkip */
1236 prRange->encoding_size[2] = 16; /* ckip */
1237 prRange->encoding_size[3] = 16; /* ccmp */
1238 prRange->encoding_size[4] = 13; /* wep104 */
1239 prRange->encoding_size[5] = 16; /* wep128 */
1240 prRange->num_encoding_sizes = 6;
1241 prRange->max_encoding_tokens = 6; /* token? */
1243 #if WIRELESS_EXT < 17
1244 prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */
1246 prRange->txpower_capa = IW_TXPOW_RELATIVE;
1248 prRange->num_txpower = 5;
1249 prRange->txpower[0] = 0; /* minimum */
1250 prRange->txpower[1] = 25; /* 25% */
1251 prRange->txpower[2] = 50; /* 50% */
1252 prRange->txpower[3] = 100; /* 100% */
1254 prRange->we_version_compiled = WIRELESS_EXT;
1255 prRange->we_version_source = WIRELESS_EXT;
1257 prRange->retry_capa = IW_RETRY_LIMIT;
1258 prRange->retry_flags = IW_RETRY_LIMIT;
1259 prRange->min_retry = 7;
1260 prRange->max_retry = 7;
1261 prRange->r_time_flags = IW_RETRY_ON;
1262 prRange->min_r_time = 0;
1263 prRange->max_r_time = 0;
1265 /* signal strength and link quality */
1266 /* Just define range here, reporting value moved to wext_get_stats() */
1267 prRange->sensitivity = -83; /* fixed value */
1268 prRange->max_qual.qual = 100; /* max 100% */
1269 prRange->max_qual.level = (__u8)(0x100 - 0); /* max 0 dbm */
1270 prRange->max_qual.noise = (__u8)(0x100 - 0); /* max 0 dbm */
1273 #if WIRELESS_EXT > 17
1274 prRange->enc_capa = IW_ENC_CAPA_WPA |
1276 IW_ENC_CAPA_CIPHER_TKIP |
1277 IW_ENC_CAPA_CIPHER_CCMP;
1280 /* min_pms; Minimal PM saving */
1281 /* max_pms; Maximal PM saving */
1282 /* pms_flags; How to decode max/min PM saving */
1284 /* modul_capa; IW_MODUL_* bit field */
1285 /* bitrate_capa; Types of bitrates supported */
1288 } /* wext_get_range */
1291 /*----------------------------------------------------------------------------*/
1293 * \brief To set BSSID of AP to connect.
1295 * \param[in] prDev Net device requested.
1296 * \param[in] prIwrInfo NULL.
1297 * \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID.
1298 * \param[in] pcExtra NULL.
1300 * \retval 0 For success.
1302 * \note Desired AP's BSSID is set to driver.
1304 /*----------------------------------------------------------------------------*/
1307 IN struct net_device *prDev,
1308 IN struct iw_request_info *prIwrInfo,
1309 IN struct sockaddr *prAddr,
1317 /*----------------------------------------------------------------------------*/
1319 * \brief To get AP MAC address.
1321 * \param[in] prDev Net device requested.
1322 * \param[in] prIwrInfo NULL.
1323 * \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID.
1324 * \param[in] pcExtra NULL.
1326 * \retval 0 If netif_carrier_ok.
1327 * \retval -ENOTCONN Otherwise.
1329 * \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data.
1331 /*----------------------------------------------------------------------------*/
1334 IN struct net_device *prNetDev,
1335 IN struct iw_request_info *prIwrInfo,
1336 OUT struct sockaddr *prAddr,
1340 P_GLUE_INFO_T prGlueInfo = NULL;
1341 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1342 UINT_32 u4BufLen = 0;
1346 if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) {
1349 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1351 //if (!netif_carrier_ok(prNetDev)) {
1352 // return -ENOTCONN;
1355 if(prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED){
1356 memset(prAddr, 0, 6);
1360 rStatus = kalIoctl(prGlueInfo,
1373 /*----------------------------------------------------------------------------*/
1375 * \brief To set mlme operation request.
1377 * \param[in] prDev Net device requested.
1378 * \param[in] prIwrInfo NULL.
1379 * \param[in] prData Pointer of iw_point header.
1380 * \param[in] pcExtra Pointer to iw_mlme structure mlme request information.
1382 * \retval 0 For success.
1383 * \retval -EOPNOTSUPP unsupported IW_MLME_ command.
1384 * \retval -EINVAL Set MLME Fail, different bssid.
1386 * \note Driver will start mlme operation if valid.
1388 /*----------------------------------------------------------------------------*/
1391 IN struct net_device *prNetDev,
1392 IN struct iw_request_info *prIwrInfo,
1393 IN struct iw_point *prData,
1397 struct iw_mlme *prMlme = NULL;
1400 P_GLUE_INFO_T prGlueInfo = NULL;
1401 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1402 UINT_32 u4BufLen = 0;
1406 if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) {
1409 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1411 prMlme = (struct iw_mlme *)pcExtra;
1412 if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) {
1413 if (!netif_carrier_ok(prNetDev)) {
1414 DBGLOG(INIT, INFO, ("[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"));
1418 rStatus = kalIoctl(prGlueInfo,
1419 wlanoidSetDisassociate,
1430 DBGLOG(INIT, INFO, ("[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd));
1433 } /* wext_set_mlme */
1435 /*----------------------------------------------------------------------------*/
1437 * \brief To issue scan request.
1439 * \param[in] prDev Net device requested.
1440 * \param[in] prIwrInfo NULL.
1441 * \param[in] prData NULL.
1442 * \param[in] pcExtra NULL.
1444 * \retval 0 For success.
1445 * \retval -EFAULT Tx power is off.
1447 * \note Device will start scanning.
1449 /*----------------------------------------------------------------------------*/
1452 IN struct net_device *prNetDev,
1453 IN struct iw_request_info *prIwrInfo,
1454 IN union iwreq_data *prData,
1458 P_GLUE_INFO_T prGlueInfo = NULL;
1459 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1460 UINT_32 u4BufLen = 0;
1464 if (FALSE == GLUE_CHK_DEV(prNetDev)) {
1467 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1469 #if WIRELESS_EXT > 17
1472 essid_len = ((struct iw_scan_req *)(((struct iw_point*)prData)->pointer))->essid_len;
1476 init_completion(&prGlueInfo->rScanComp);
1478 // TODO: parse flags and issue different scan requests?
1480 rStatus = kalIoctl(prGlueInfo,
1481 wlanoidSetBssidListScan,
1490 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ);
1491 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
1495 } /* wext_set_scan */
1498 /*----------------------------------------------------------------------------*/
1500 * \brief To write the ie to buffer
1503 /*----------------------------------------------------------------------------*/
1504 static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data,
1508 char *pos = buf, *end = buf + buf_size;
1514 for (i = 0; i < len; i++) {
1515 ret = snprintf(pos, end - pos, "%02x",
1517 if (ret < 0 || ret >= end - pos) {
1528 /*----------------------------------------------------------------------------*/
1530 * \brief To get scan results, transform results from driver's format to WE's.
1532 * \param[in] prDev Net device requested.
1533 * \param[in] prIwrInfo NULL.
1534 * \param[out] prData Pointer to iw_point structure, pData->length is the size of
1535 * pcExtra buffer before used, and is updated after filling scan
1537 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1538 * function, wext_support_ioctl() or ioctl_standard_call() in
1541 * \retval 0 For success.
1542 * \retval -ENOMEM If dynamic memory allocation fail.
1543 * \retval -E2BIG Invalid length.
1545 * \note Scan results is filled into pcExtra buffer, data size is updated in
1548 /*----------------------------------------------------------------------------*/
1551 IN struct net_device *prNetDev,
1552 IN struct iw_request_info *prIwrInfo,
1553 IN OUT struct iw_point *prData,
1559 P_PARAM_BSSID_LIST_EX_T prList = NULL;
1560 P_PARAM_BSSID_EX_T prBss = NULL;
1561 P_PARAM_VARIABLE_IE_T prDesiredIE = NULL;
1562 struct iw_event iwEvent; /* local iw_event buffer */
1564 /* write pointer of extra buffer */
1566 /* pointer to the end of last full entry in extra buffer */
1567 char *pcValidEntryEnd = NULL;
1568 char *pcEnd = NULL; /* end of extra buffer */
1570 UINT_32 u4AllocBufLen = 0;
1572 /* arrange rate information */
1573 UINT_32 u4HighestRate = 0;
1574 char aucRatesBuf[64];
1580 P_GLUE_INFO_T prGlueInfo = NULL;
1581 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1582 UINT_32 u4BufLen = 0;
1587 if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) {
1590 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
1592 /* Initialize local variables */
1594 pcValidEntryEnd = pcExtra;
1595 pcEnd = pcExtra + prData->length; /* end of extra buffer */
1597 /* Allocate another query buffer with the same size of extra buffer */
1598 u4AllocBufLen = prData->length;
1599 prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
1600 if (prList == NULL) {
1601 DBGLOG(INIT, INFO, ("[wifi] no memory for scan list:%d\n", prData->length));
1605 prList->u4NumberOfItems = 0;
1607 /* wait scan done */
1608 //printk ("wait for scan results\n");
1609 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ);
1611 rStatus = kalIoctl(prGlueInfo,
1612 wlanoidQueryBssidList,
1621 if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
1622 /* Buffer length is not large enough. */
1623 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
1625 #if WIRELESS_EXT >= 17
1626 /* This feature is supported in WE-17 or above, limited by iwlist.
1627 ** Return -E2BIG and iwlist will request again with a larger buffer.
1630 /* Update length to give application a hint on result length */
1631 prData->length = (__u16)u4BufLen;
1634 /* Realloc a larger query buffer here, but don't write too much to extra
1635 ** buffer when filling it later.
1637 kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
1639 u4AllocBufLen = u4BufLen;
1640 prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE);
1641 if (prList == NULL) {
1642 DBGLOG(INIT, INFO, ("[wifi] no memory for larger scan list :%ld\n", u4BufLen));
1646 prList->NumberOfItems = 0;
1648 rStatus = kalIoctl(prGlueInfo,
1649 wlanoidQueryBssidList,
1658 if (rStatus == WLAN_STATUS_INVALID_LENGTH) {
1659 DBGLOG(INIT, INFO, ("[wifi] larger buf:%d result:%ld\n", u4AllocBufLen, u4BufLen));
1661 prData->length = (__u16)u4BufLen;
1664 #endif /* WIRELESS_EXT >= 17 */
1669 if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) {
1670 DBGLOG(INIT, INFO, ("[wifi] strange scan result count:%ld\n",
1671 prList->u4NumberOfItems));
1675 /* Copy required data from pList to pcExtra */
1676 prBss = &prList->arBssid[0]; /* set to the first entry */
1677 for (i = 0; i < prList->u4NumberOfItems; ++i) {
1679 iwEvent.cmd = SIOCGIWAP;
1680 iwEvent.len = IW_EV_ADDR_LEN;
1681 if ((pcCur + iwEvent.len) > pcEnd)
1683 iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER;
1684 memcpy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress, ETH_ALEN);
1685 memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN);
1686 pcCur += IW_EV_ADDR_LEN;
1689 iwEvent.cmd = SIOCGIWESSID;
1690 /* Modification to user space pointer(essid.pointer) is not needed. */
1691 iwEvent.u.essid.length = (__u16)prBss->rSsid.u4SsidLen;
1692 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length;
1694 if ((pcCur + iwEvent.len) > pcEnd)
1696 iwEvent.u.essid.flags = 1;
1697 iwEvent.u.essid.pointer = NULL;
1699 #if WIRELESS_EXT <= 18
1700 memcpy(pcCur, &iwEvent, iwEvent.len);
1702 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1703 memcpy(pcCur + IW_EV_LCP_LEN,
1704 &iwEvent.u.data.length,
1705 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1707 memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length);
1708 pcCur += iwEvent.len;
1710 iwEvent.cmd = SIOCGIWFREQ;
1711 iwEvent.len = IW_EV_FREQ_LEN;
1712 if ((pcCur + iwEvent.len) > pcEnd)
1714 iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig;
1715 iwEvent.u.freq.e = 3; /* (in KHz) */
1716 iwEvent.u.freq.i = 0;
1717 memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN);
1718 pcCur += IW_EV_FREQ_LEN;
1720 /* Operation Mode */
1721 iwEvent.cmd = SIOCGIWMODE;
1722 iwEvent.len = IW_EV_UINT_LEN;
1723 if ((pcCur + iwEvent.len) > pcEnd)
1725 if (prBss->eOpMode == NET_TYPE_IBSS) {
1726 iwEvent.u.mode = IW_MODE_ADHOC;
1728 else if (prBss->eOpMode == NET_TYPE_INFRA) {
1729 iwEvent.u.mode = IW_MODE_INFRA;
1732 iwEvent.u.mode = IW_MODE_AUTO;
1734 memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN);
1735 pcCur += IW_EV_UINT_LEN;
1738 iwEvent.cmd = IWEVQUAL;
1739 iwEvent.len = IW_EV_QUAL_LEN;
1740 if ((pcCur + iwEvent.len) > pcEnd)
1742 iwEvent.u.qual.qual = 0; /* Quality not available now */
1743 /* -100 < Rssi < -10, normalized by adding 0x100 */
1744 iwEvent.u.qual.level = 0x100 + prBss->rRssi;
1745 iwEvent.u.qual.noise = 0; /* Noise not available now */
1746 iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED \
1747 | IW_QUAL_NOISE_INVALID;
1748 memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN);
1749 pcCur += IW_EV_QUAL_LEN;
1752 iwEvent.cmd = SIOCGIWENCODE;
1753 iwEvent.len = IW_EV_POINT_LEN;
1754 if ((pcCur + iwEvent.len) > pcEnd)
1756 iwEvent.u.data.pointer = NULL;
1757 iwEvent.u.data.flags = 0;
1758 iwEvent.u.data.length = 0;
1759 if(!prBss->u4Privacy) {
1760 iwEvent.u.data.flags |= IW_ENCODE_DISABLED;
1762 #if WIRELESS_EXT <= 18
1763 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1765 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1766 memcpy(pcCur + IW_EV_LCP_LEN,
1767 &iwEvent.u.data.length,
1768 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1770 pcCur += IW_EV_POINT_LEN;
1772 /* rearrange rate information */
1773 u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):");
1775 for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) {
1776 UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F;
1781 if (curRate > u4HighestRate) {
1782 u4HighestRate = curRate;
1785 if (curRate == RATE_5_5M) {
1786 u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5");
1789 u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2);
1792 if (u4BufIndex > sizeof(aucRatesBuf)) {
1793 //printk("rate info too long\n");
1798 /* Report Highest Rates */
1799 iwEvent.cmd = SIOCGIWRATE;
1800 iwEvent.len = IW_EV_PARAM_LEN;
1801 if ((pcCur + iwEvent.len) > pcEnd)
1803 iwEvent.u.bitrate.value = u4HighestRate * 500000;
1804 iwEvent.u.bitrate.fixed = 0;
1805 iwEvent.u.bitrate.disabled = 0;
1806 iwEvent.u.bitrate.flags = 0;
1807 memcpy(pcCur, &iwEvent, iwEvent.len);
1808 pcCur += iwEvent.len;
1810 #if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */
1811 /* Report Residual Rates */
1812 iwEvent.cmd = IWEVCUSTOM;
1813 iwEvent.u.data.length = u4BufIndex;
1814 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1815 if ((pcCur + iwEvent.len) > pcEnd)
1817 iwEvent.u.data.flags = 0;
1818 #if WIRELESS_EXT <= 18
1819 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1821 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1822 memcpy(pcCur + IW_EV_LCP_LEN,
1823 &iwEvent.u.data.length,
1824 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1826 memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex);
1827 pcCur += iwEvent.len;
1828 #endif /* WIRELESS_EXT >= 15 */
1831 if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1832 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
1834 (PUINT_8 *)&prDesiredIE)) {
1835 iwEvent.cmd = IWEVGENIE;
1836 iwEvent.u.data.flags = 1;
1837 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1838 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1839 if ((pcCur + iwEvent.len) > pcEnd)
1841 #if WIRELESS_EXT <= 18
1842 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1844 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1845 memcpy(pcCur + IW_EV_LCP_LEN,
1846 &iwEvent.u.data.length,
1847 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1849 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1850 pcCur += iwEvent.len;
1853 #if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */
1854 if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1855 prBss->u4IELength - sizeof(PARAM_FIXED_IEs),
1857 (PUINT_8 *)&prDesiredIE)) {
1858 iwEvent.cmd = IWEVGENIE;
1859 iwEvent.u.data.flags = 1;
1860 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1861 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1862 if ((pcCur + iwEvent.len) > pcEnd)
1864 #if WIRELESS_EXT <= 18
1865 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1867 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1868 memcpy(pcCur + IW_EV_LCP_LEN,
1869 &iwEvent.u.data.length,
1870 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1872 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1873 pcCur += iwEvent.len;
1878 /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */
1879 /* pBss->IEs starts from timestamp */
1880 if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1881 prBss->u4IELength -sizeof(PARAM_FIXED_IEs),
1883 (PUINT_8 *)&prDesiredIE)) {
1885 iwEvent.cmd = IWEVGENIE;
1886 iwEvent.u.data.flags = 1;
1887 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1888 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1889 if ((pcCur + iwEvent.len) > pcEnd)
1891 #if WIRELESS_EXT <= 18
1892 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1894 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1895 memcpy(pcCur + IW_EV_LCP_LEN,
1896 &iwEvent.u.data.length,
1897 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1899 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1900 pcCur += iwEvent.len;
1903 #if CFG_SUPPORT_WAPI /* Android+ */
1904 if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)],
1905 prBss->u4IELength -sizeof(PARAM_FIXED_IEs),
1906 (PUINT_8 *)&prDesiredIE)) {
1909 iwEvent.cmd = IWEVGENIE;
1910 iwEvent.u.data.flags = 1;
1911 iwEvent.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
1912 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1913 if ((pcCur + iwEvent.len) > pcEnd)
1915 #if WIRELESS_EXT <= 18
1916 memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN);
1918 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1919 memcpy(pcCur + IW_EV_LCP_LEN,
1920 &iwEvent.u.data.length,
1921 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1923 memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength);
1924 pcCur += iwEvent.len;
1926 iwEvent.cmd = IWEVCUSTOM;
1927 iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */;
1928 iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length;
1929 if ((pcCur + iwEvent.len) > pcEnd)
1931 iwEvent.u.data.flags = 1;
1933 memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN);
1934 memcpy(pcCur + IW_EV_LCP_LEN,
1935 &iwEvent.u.data.length,
1936 sizeof(struct iw_point) - IW_EV_POINT_OFF);
1938 pcCur += (IW_EV_POINT_LEN);
1940 pcCur += sprintf(pcCur, "wapi_ie=");
1942 snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *)prDesiredIE, prDesiredIE->ucLength + 2);
1944 pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */;
1948 /* Complete an entry. Update end of valid entry */
1949 pcValidEntryEnd = pcCur;
1950 /* Extract next bss */
1951 prBss = (P_PARAM_BSSID_EX_T)((char *)prBss + prBss->u4Length);
1954 /* Update valid data length for caller function and upper layer
1957 prData->length = (pcValidEntryEnd - pcExtra);
1958 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
1960 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
1963 /* free local query buffer */
1965 kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen);
1969 } /* wext_get_scan */
1971 /*----------------------------------------------------------------------------*/
1973 * \brief To set desired network name ESSID.
1975 * \param[in] prDev Net device requested.
1976 * \param[in] prIwrInfo NULL.
1977 * \param[in] prEssid Pointer of iw_point header.
1978 * \param[in] pcExtra Pointer to buffer srtoring essid string.
1980 * \retval 0 If netif_carrier_ok.
1981 * \retval -E2BIG Essid string length is too big.
1982 * \retval -EINVAL pcExtra is null pointer.
1983 * \retval -EFAULT Driver fail to set new essid.
1985 * \note If string lengh is ok, device will try connecting to the new network.
1987 /*----------------------------------------------------------------------------*/
1990 IN struct net_device *prNetDev,
1991 IN struct iw_request_info *prIwrInfo,
1992 IN struct iw_point *prEssid,
1996 PARAM_SSID_T rNewSsid;
1998 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
1999 ENUM_PARAM_AUTH_MODE_T eAuthMode;
2001 P_GLUE_INFO_T prGlueInfo = NULL;
2002 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2003 UINT_32 u4BufLen = 0;
2008 if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) {
2011 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2013 if (prEssid->length > IW_ESSID_MAX_SIZE) {
2019 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
2020 eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
2021 AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
2022 //printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n",
2023 // (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared");
2027 switch(prGlueInfo->rWpaInfo.u4KeyMgmt) {
2028 case IW_AUTH_KEY_MGMT_802_1X:
2030 (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
2031 AUTH_MODE_WPA : AUTH_MODE_WPA2;
2032 //printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n",
2033 // (eAuthMode == AUTH_MODE_WPA) ? "" : "2");
2035 case IW_AUTH_KEY_MGMT_PSK:
2037 (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ?
2038 AUTH_MODE_WPA_PSK: AUTH_MODE_WPA2_PSK;
2039 //printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n",
2040 // (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2");
2042 #if CFG_SUPPORT_WAPI /* Android+ */
2043 case IW_AUTH_KEY_MGMT_WAPI_PSK:
2045 case IW_AUTH_KEY_MGMT_WAPI_CERT:
2049 //#if defined (IW_AUTH_KEY_MGMT_WPA_NONE)
2050 // case IW_AUTH_KEY_MGMT_WPA_NONE:
2051 // eAuthMode = AUTH_MODE_WPA_NONE;
2052 // //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n");
2055 #if CFG_SUPPORT_802_11W
2056 case IW_AUTH_KEY_MGMT_802_1X_SHA256:
2057 eAuthMode = AUTH_MODE_WPA2;
2059 case IW_AUTH_KEY_MGMT_PSK_SHA256:
2060 eAuthMode = AUTH_MODE_WPA2_PSK;
2064 //printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n",
2065 // prGlueInfo->rWpaInfo.u4KeyMgmt);
2066 eAuthMode = AUTH_MODE_AUTO_SWITCH;
2072 rStatus = kalIoctl(prGlueInfo,
2082 /* set encryption status */
2083 cipher = prGlueInfo->rWpaInfo.u4CipherGroup |
2084 prGlueInfo->rWpaInfo.u4CipherPairwise;
2085 if (cipher & IW_AUTH_CIPHER_CCMP) {
2086 //printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n");
2087 eEncStatus = ENUM_ENCRYPTION3_ENABLED;
2089 else if (cipher & IW_AUTH_CIPHER_TKIP) {
2090 //printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n");
2091 eEncStatus = ENUM_ENCRYPTION2_ENABLED;
2093 else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
2094 //printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n");
2095 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
2097 else if (cipher & IW_AUTH_CIPHER_NONE){
2098 //printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n");
2099 if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
2100 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
2102 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2105 //printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n");
2106 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2109 rStatus = kalIoctl(prGlueInfo,
2110 wlanoidSetEncryptionStatus,
2119 #if WIRELESS_EXT < 21
2120 /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before
2121 ** 2.6.19. Cut the trailing '\0'.
2123 rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0;
2125 rNewSsid.u4SsidLen = prEssid->length;
2127 kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen);
2130 rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0';
2131 printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid);
2134 if (kalIoctl(prGlueInfo,
2137 sizeof(PARAM_SSID_T),
2142 &u4BufLen) != WLAN_STATUS_SUCCESS) {
2143 //printk(KERN_WARNING "Fail to set ssid\n");
2149 } /* wext_set_essid */
2151 /*----------------------------------------------------------------------------*/
2153 * \brief To get current network name ESSID.
2155 * \param[in] prDev Net device requested.
2156 * \param[in] prIwrInfo NULL.
2157 * \param[in] prEssid Pointer to iw_point structure containing essid information.
2158 * \param[out] pcExtra Pointer to buffer srtoring essid string.
2160 * \retval 0 If netif_carrier_ok.
2161 * \retval -ENOTCONN Otherwise.
2163 * \note If netif_carrier_ok, network essid is stored in pcExtra.
2165 /*----------------------------------------------------------------------------*/
2166 //static PARAM_SSID_T ssid;
2169 IN struct net_device *prNetDev,
2170 IN struct iw_request_info *prIwrInfo,
2171 IN struct iw_point *prEssid,
2175 //PARAM_SSID_T ssid;
2177 P_PARAM_SSID_T prSsid;
2178 P_GLUE_INFO_T prGlueInfo = NULL;
2179 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2180 UINT_32 u4BufLen = 0;
2186 if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) {
2189 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2191 //if (!netif_carrier_ok(prNetDev)) {
2192 // return -ENOTCONN;
2195 prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE);
2201 rStatus = kalIoctl(prGlueInfo,
2204 sizeof(PARAM_SSID_T),
2211 if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) {
2212 kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen);
2213 prEssid->length = prSsid->u4SsidLen;
2217 kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T));
2220 } /* wext_get_essid */
2225 /*----------------------------------------------------------------------------*/
2227 * \brief To set tx desired bit rate. Three cases here
2228 * iwconfig wlan0 auto -> Set to origianl supported rate set.
2229 * iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate.
2230 * iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps
2232 * \param[in] prNetDev Pointer to the net_device handler.
2233 * \param[in] prIwReqInfo Pointer to the Request Info.
2234 * \param[in] prRate Pointer to the Rate Parameter.
2235 * \param[in] pcExtra Pointer to the extra buffer.
2237 * \retval 0 Update desired rate.
2238 * \retval -EINVAL Wrong parameter
2240 /*----------------------------------------------------------------------------*/
2243 IN struct net_device *prNetDev,
2244 IN struct iw_request_info *prIwReqInfo,
2245 IN struct iw_param *prRate,
2249 PARAM_RATES_EX aucSuppRate = {0};
2250 PARAM_RATES_EX aucNewRate = {0};
2251 UINT_32 u4NewRateLen = 0;
2254 P_GLUE_INFO_T prGlueInfo = NULL;
2255 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2256 UINT_32 u4BufLen = 0;
2260 if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) {
2263 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2266 printk("value = %d, fixed = %d, disable = %d, flags = %d\n",
2267 prRate->value, prRate->fixed, prRate->disabled, prRate->flags);
2270 rStatus = wlanQueryInformation(
2271 prGlueInfo->prAdapter,
2272 wlanoidQuerySupportedRates,
2274 sizeof(aucSuppRate),
2278 if (prRate->value < 0) {
2279 if (prRate->fixed == 0) {
2280 /* iwconfig wlan0 rate auto */
2282 /* set full supported rate to device */
2283 /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */
2284 rStatus = wlanSetInformation(
2285 prGlueInfo->prAdapter,
2286 wlanoidSetDesiredRates,
2288 sizeof(aucSuppRate),
2293 /* iwconfig wlan0 rate fixed */
2295 /* fix rate to what? DO NOTHING */
2301 aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */
2303 for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) {
2304 /* check the given value is supported */
2305 if (aucSuppRate[i] == 0) {
2309 if (aucNewRate[0] == aucSuppRate[i]) {
2315 if (u4NewRateLen == 0) {
2316 /* the given value is not supported */
2317 /* return error or use given rate as upper bound? */
2321 if (prRate->fixed == 0) {
2322 /* add all rates lower than desired rate */
2323 for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) {
2324 if (aucSuppRate[i] == 0) {
2328 if (aucSuppRate[i] < aucNewRate[0]) {
2329 aucNewRate[u4NewRateLen++] = aucSuppRate[i];
2334 rStatus = wlanSetInformation(
2335 prGlueInfo->prAdapter,
2336 wlanoidSetDesiredRates,
2341 } /* wext_set_rate */
2345 /*----------------------------------------------------------------------------*/
2347 * \brief To get current tx bit rate.
2349 * \param[in] prDev Net device requested.
2350 * \param[in] prIwrInfo NULL.
2351 * \param[out] prRate Pointer to iw_param structure to store current tx rate.
2352 * \param[in] pcExtra NULL.
2354 * \retval 0 If netif_carrier_ok.
2355 * \retval -ENOTCONN Otherwise.
2357 * \note If netif_carrier_ok, current tx rate is stored in pRate.
2359 /*----------------------------------------------------------------------------*/
2362 IN struct net_device *prNetDev,
2363 IN struct iw_request_info *prIwrInfo,
2364 OUT struct iw_param *prRate,
2368 P_GLUE_INFO_T prGlueInfo = NULL;
2369 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2370 UINT_32 u4BufLen = 0;
2375 if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) {
2378 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2380 if (!netif_carrier_ok(prNetDev)) {
2385 rStatus = kalIoctl(prGlueInfo,
2386 wlanoidQueryLinkSpeed,
2395 if (rStatus != WLAN_STATUS_SUCCESS) {
2399 prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */
2403 } /* wext_get_rate */
2406 /*----------------------------------------------------------------------------*/
2408 * \brief To set RTS/CTS theshold.
2410 * \param[in] prDev Net device requested.
2411 * \param[in] prIwrInfo NULL.
2412 * \param[in] prRts Pointer to iw_param structure containing rts threshold.
2413 * \param[in] pcExtra NULL.
2415 * \retval 0 For success.
2416 * \retval -EINVAL Given value is out of range.
2418 * \note If given value is valid, device will follow the new setting.
2420 /*----------------------------------------------------------------------------*/
2423 IN struct net_device *prNetDev,
2424 IN struct iw_request_info *prIwrInfo,
2425 IN struct iw_param *prRts,
2429 PARAM_RTS_THRESHOLD u4RtsThresh;
2431 P_GLUE_INFO_T prGlueInfo = NULL;
2432 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2433 UINT_32 u4BufLen = 0;
2437 if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) {
2440 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2442 if (prRts->disabled == 1) {
2445 else if (prRts->value < 0 || prRts->value > 2347) {
2449 u4RtsThresh = (PARAM_RTS_THRESHOLD)prRts->value;
2452 rStatus = kalIoctl(prGlueInfo,
2453 wlanoidSetRtsThreshold,
2455 sizeof(u4RtsThresh),
2464 prRts->value = (typeof(prRts->value ))u4RtsThresh;
2465 prRts->disabled = (prRts->value > 2347) ? 1 : 0;
2469 } /* wext_set_rts */
2471 /*----------------------------------------------------------------------------*/
2473 * \brief To get RTS/CTS theshold.
2475 * \param[in] prDev Net device requested.
2476 * \param[in] prIwrInfo NULL.
2477 * \param[out] prRts Pointer to iw_param structure containing rts threshold.
2478 * \param[in] pcExtra NULL.
2480 * \retval 0 Success.
2482 * \note RTS threshold is stored in pRts.
2484 /*----------------------------------------------------------------------------*/
2487 IN struct net_device *prNetDev,
2488 IN struct iw_request_info *prIwrInfo,
2489 OUT struct iw_param *prRts,
2493 PARAM_RTS_THRESHOLD u4RtsThresh;
2495 P_GLUE_INFO_T prGlueInfo = NULL;
2496 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2497 UINT_32 u4BufLen = 0;
2501 if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) {
2504 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2506 rStatus = kalIoctl(prGlueInfo,
2507 wlanoidQueryRtsThreshold,
2509 sizeof(u4RtsThresh),
2518 prRts->value = (typeof(prRts->value ))u4RtsThresh;
2519 prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0;
2523 } /* wext_get_rts */
2525 /*----------------------------------------------------------------------------*/
2527 * \brief To get fragmentation threshold.
2529 * \param[in] prDev Net device requested.
2530 * \param[in] prIwrInfo NULL.
2531 * \param[out] prFrag Pointer to iw_param structure containing frag threshold.
2532 * \param[in] pcExtra NULL.
2534 * \retval 0 Success.
2536 * \note RTS threshold is stored in pFrag. Fragmentation is disabled.
2538 /*----------------------------------------------------------------------------*/
2541 IN struct net_device *prNetDev,
2542 IN struct iw_request_info *prIwrInfo,
2543 OUT struct iw_param *prFrag,
2549 prFrag->value = 2346;
2551 prFrag->disabled = 1;
2553 } /* wext_get_frag */
2556 /*----------------------------------------------------------------------------*/
2558 * \brief To set TX power, or enable/disable the radio.
2560 * \param[in] prDev Net device requested.
2561 * \param[in] prIwrInfo NULL.
2562 * \param[in] prTxPow Pointer to iw_param structure containing tx power setting.
2563 * \param[in] pcExtra NULL.
2565 * \retval 0 Success.
2567 * \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used
2568 * to enable/disable the radio.
2570 /*----------------------------------------------------------------------------*/
2574 IN struct net_device *prNetDev,
2575 IN struct iw_request_info *prIwrInfo,
2576 IN struct iw_param *prTxPow,
2581 //PARAM_DEVICE_POWER_STATE ePowerState;
2582 ENUM_ACPI_STATE_T ePowerState;
2584 P_GLUE_INFO_T prGlueInfo = NULL;
2585 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2586 UINT_32 u4BufLen = 0;
2590 if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) {
2593 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2595 if(prTxPow->disabled){
2596 /* <1> disconnect */
2597 rStatus = kalIoctl(prGlueInfo,
2598 wlanoidSetDisassociate,
2606 if (rStatus != WLAN_STATUS_SUCCESS) {
2607 DBGLOG(INIT, INFO, ("######set disassoc failed\n"));
2609 DBGLOG(INIT, INFO, ("######set assoc ok\n"));
2612 /* <2> mark to power state flag*/
2613 ePowerState = ACPI_STATE_D0;
2614 DBGLOG(INIT, INFO, ("set to acpi d3(0)\n"));
2615 wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
2619 ePowerState = ACPI_STATE_D0;
2620 DBGLOG(INIT, INFO, ("set to acpi d0\n"));
2621 wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState);
2624 prGlueInfo->ePowerState = ePowerState;
2627 } /* wext_set_txpow */
2632 /*----------------------------------------------------------------------------*/
2634 * \brief To get TX power.
2636 * \param[in] prDev Net device requested.
2637 * \param[in] prIwrInfo NULL.
2638 * \param[out] prTxPow Pointer to iw_param structure containing tx power setting.
2639 * \param[in] pcExtra NULL.
2641 * \retval 0 Success.
2643 * \note Tx power is stored in pTxPow.
2645 /*----------------------------------------------------------------------------*/
2648 IN struct net_device *prNetDev,
2649 IN struct iw_request_info *prIwrInfo,
2650 OUT struct iw_param *prTxPow,
2654 //PARAM_DEVICE_POWER_STATE ePowerState;
2656 P_GLUE_INFO_T prGlueInfo = NULL;
2660 if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) {
2663 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2665 /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not
2666 * current state. Use GLUE_INFO_T to store state.
2668 //ePowerState = prGlueInfo->ePowerState;
2670 /* TxPow parameters: Fixed at relative 100% */
2671 #if WIRELESS_EXT < 17
2672 prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */
2674 prTxPow->flags = IW_TXPOW_RELATIVE;
2676 prTxPow->value = 100;
2678 //prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE;
2679 prTxPow->disabled = TRUE;
2682 } /* wext_get_txpow */
2685 /*----------------------------------------------------------------------------*/
2687 * \brief To get encryption cipher and key.
2689 * \param[in] prDev Net device requested.
2690 * \param[in] prIwrInfo NULL.
2691 * \param[out] prEnc Pointer to iw_point structure containing securiry information.
2692 * \param[in] pcExtra Buffer to store key content.
2694 * \retval 0 Success.
2696 * \note Securiry information is stored in pEnc except key content.
2698 /*----------------------------------------------------------------------------*/
2701 IN struct net_device *prNetDev,
2702 IN struct iw_request_info *prIwrInfo,
2703 OUT struct iw_point *prEnc,
2708 //ENUM_ENCRYPTION_STATUS_T eEncMode;
2709 ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode;
2711 P_GLUE_INFO_T prGlueInfo = NULL;
2712 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2713 UINT_32 u4BufLen = 0;
2717 if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) {
2720 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2723 rStatus = kalIoctl(prGlueInfo,
2724 wlanoidQueryEncryptionStatus,
2736 case ENUM_WEP_DISABLED:
2737 prEnc->flags = IW_ENCODE_DISABLED;
2739 case ENUM_WEP_ENABLED:
2740 prEnc->flags = IW_ENCODE_ENABLED;
2742 case ENUM_WEP_KEY_ABSENT:
2743 prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2746 prEnc->flags = IW_ENCODE_ENABLED;
2750 /* Cipher, Key Content, Key ID can't be queried */
2751 prEnc->flags |= IW_ENCODE_NOKEY;
2754 } /* wext_get_encode */
2758 /*----------------------------------------------------------------------------*/
2760 * \brief To set encryption cipher and key.
2762 * \param[in] prDev Net device requested.
2763 * \param[in] prIwrInfo NULL.
2764 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
2765 * \param[in] pcExtra Pointer to key string buffer.
2767 * \retval 0 Success.
2768 * \retval -EINVAL Key ID error for WEP.
2769 * \retval -EFAULT Setting parameters to driver fail.
2770 * \retval -EOPNOTSUPP Key size not supported.
2772 * \note Securiry information is stored in pEnc.
2774 /*----------------------------------------------------------------------------*/
2775 static UINT_8 wepBuf[48];
2779 IN struct net_device *prNetDev,
2780 IN struct iw_request_info *prIwrInfo,
2781 IN struct iw_point *prEnc,
2786 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
2787 ENUM_PARAM_AUTH_MODE_T eAuthMode;
2788 //UINT_8 wepBuf[48];
2789 P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
2791 P_GLUE_INFO_T prGlueInfo = NULL;
2792 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2793 UINT_32 u4BufLen = 0;
2798 if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) {
2801 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2803 /* reset to default mode */
2804 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
2805 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
2806 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
2807 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
2808 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
2809 #if CFG_SUPPORT_802_11W
2810 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
2813 /* iwconfig wlan0 key off */
2814 if ( (prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED ) {
2815 eAuthMode = AUTH_MODE_OPEN;
2817 rStatus = kalIoctl(prGlueInfo,
2827 eEncStatus = ENUM_ENCRYPTION_DISABLED;
2829 rStatus = kalIoctl(prGlueInfo,
2830 wlanoidSetEncryptionStatus,
2842 /* iwconfig wlan0 key 0123456789 */
2843 /* iwconfig wlan0 key s:abcde */
2844 /* iwconfig wlan0 key 0123456789 [1] */
2845 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
2846 /* check key size for WEP */
2847 if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) {
2848 /* prepare PARAM_WEP key structure */
2849 prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
2850 (prEnc->flags & IW_ENCODE_INDEX) -1 : 0;
2851 if (prWepKey->u4KeyIndex > 3) {
2852 /* key id is out of range */
2855 prWepKey->u4KeyIndex |= 0x80000000;
2856 prWepKey->u4Length = 12 + prEnc->length;
2857 prWepKey->u4KeyLength = prEnc->length;
2858 kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length);
2861 rStatus = kalIoctl(prGlueInfo,
2871 if (rStatus != WLAN_STATUS_SUCCESS) {
2872 DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus));
2876 /* change to auto switch */
2877 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY |
2878 IW_AUTH_ALG_OPEN_SYSTEM;
2879 eAuthMode = AUTH_MODE_AUTO_SWITCH;
2881 rStatus = kalIoctl(prGlueInfo,
2891 if (rStatus != WLAN_STATUS_SUCCESS) {
2892 //printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus);
2896 prGlueInfo->rWpaInfo.u4CipherPairwise =
2897 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
2898 prGlueInfo->rWpaInfo.u4CipherGroup =
2899 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
2901 eEncStatus = ENUM_WEP_ENABLED;
2904 rStatus = kalIoctl(prGlueInfo,
2905 wlanoidSetEncryptionStatus,
2907 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T),
2914 if (rStatus != WLAN_STATUS_SUCCESS) {
2915 //printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus);
2923 } /* wext_set_encode */
2926 /*----------------------------------------------------------------------------*/
2928 * \brief To set power management.
2930 * \param[in] prDev Net device requested.
2931 * \param[in] prIwrInfo NULL.
2932 * \param[in] prPower Pointer to iw_param structure containing tx power setting.
2933 * \param[in] pcExtra NULL.
2935 * \retval 0 Success.
2937 * \note New Power Management Mode is set to driver.
2939 /*----------------------------------------------------------------------------*/
2942 IN struct net_device *prNetDev,
2943 IN struct iw_request_info *prIwrInfo,
2944 IN struct iw_param *prPower,
2949 PARAM_POWER_MODE ePowerMode;
2950 INT_32 i4PowerValue;
2952 P_GLUE_INFO_T prGlueInfo = NULL;
2953 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2954 UINT_32 u4BufLen = 0;
2958 if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
2961 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
2963 //printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n",
2964 // prPower->value, prPower->disabled, prPower->flags);
2966 if(prPower->disabled){
2967 ePowerMode = Param_PowerModeCAM;
2970 i4PowerValue = prPower->value;
2971 #if WIRELESS_EXT < 21
2972 i4PowerValue /= 1000000;
2974 if (i4PowerValue == 0) {
2975 ePowerMode = Param_PowerModeCAM;
2976 } else if (i4PowerValue == 1) {
2977 ePowerMode = Param_PowerModeMAX_PSP;
2978 } else if (i4PowerValue == 2) {
2979 ePowerMode = Param_PowerModeFast_PSP;
2982 DBGLOG(INIT, INFO, ("%s(): unsupported power management mode value = %d.\n",
2991 rStatus = kalIoctl(prGlueInfo,
2992 wlanoidSet802dot11PowerSaveProfile,
3001 if (rStatus != WLAN_STATUS_SUCCESS) {
3002 //printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus);
3008 } /* wext_set_power */
3011 /*----------------------------------------------------------------------------*/
3013 * \brief To get power management.
3015 * \param[in] prDev Net device requested.
3016 * \param[in] prIwrInfo NULL.
3017 * \param[out] prPower Pointer to iw_param structure containing tx power setting.
3018 * \param[in] pcExtra NULL.
3020 * \retval 0 Success.
3022 * \note Power management mode is stored in pTxPow->value.
3024 /*----------------------------------------------------------------------------*/
3027 IN struct net_device *prNetDev,
3028 IN struct iw_request_info *prIwrInfo,
3029 OUT struct iw_param *prPower,
3034 P_GLUE_INFO_T prGlueInfo = NULL;
3035 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3036 UINT_32 u4BufLen = 0;
3037 PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM;
3041 if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
3044 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3047 #if defined(_HIF_SDIO)
3048 rStatus = sdio_io_ctrl(prGlueInfo,
3049 wlanoidQuery802dot11PowerSaveProfile,
3056 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
3057 wlanoidQuery802dot11PowerSaveProfile,
3063 rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
3064 wlanoidQuery802dot11PowerSaveProfile,
3070 if (rStatus != WLAN_STATUS_SUCCESS) {
3075 prPower->disabled = 1;
3077 if (Param_PowerModeCAM == ePowerMode) {
3079 prPower->disabled = 1;
3081 else if (Param_PowerModeMAX_PSP == ePowerMode ) {
3083 prPower->disabled = 0;
3085 else if (Param_PowerModeFast_PSP == ePowerMode ) {
3087 prPower->disabled = 0;
3090 prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
3091 #if WIRELESS_EXT < 21
3092 prPower->value *= 1000000;
3095 //printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n",
3096 // prPower->value, prPower->disabled, prPower->flags);
3099 } /* wext_get_power */
3101 /*----------------------------------------------------------------------------*/
3103 * \brief To set authentication parameters.
3105 * \param[in] prDev Net device requested.
3106 * \param[in] prIwrInfo NULL.
3107 * \param[in] rpAuth Pointer to iw_param structure containing authentication information.
3108 * \param[in] pcExtra Pointer to key string buffer.
3110 * \retval 0 Success.
3111 * \retval -EINVAL Key ID error for WEP.
3112 * \retval -EFAULT Setting parameters to driver fail.
3113 * \retval -EOPNOTSUPP Key size not supported.
3115 * \note Securiry information is stored in pEnc.
3117 /*----------------------------------------------------------------------------*/
3120 IN struct net_device *prNetDev,
3121 IN struct iw_request_info *prIwrInfo,
3122 IN struct iw_param *prAuth,
3126 P_GLUE_INFO_T prGlueInfo = NULL;
3130 if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) {
3133 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3135 /* Save information to glue info and process later when ssid is set. */
3136 switch(prAuth->flags & IW_AUTH_INDEX) {
3137 case IW_AUTH_WPA_VERSION:
3138 #if CFG_SUPPORT_WAPI
3139 if (wlanQueryWapiMode(prGlueInfo->prAdapter)){
3140 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3141 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
3144 prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
3147 prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value;
3151 case IW_AUTH_CIPHER_PAIRWISE:
3152 prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value;
3155 case IW_AUTH_CIPHER_GROUP:
3156 prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value;
3159 case IW_AUTH_KEY_MGMT:
3160 prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value;
3161 #if CFG_SUPPORT_WAPI
3162 if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK ||
3163 prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) {
3165 WLAN_STATUS rStatus;
3167 rStatus = kalIoctl(prGlueInfo,
3176 DBGLOG(INIT, INFO, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value));
3179 if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS)
3180 prGlueInfo->fgWpsActive = TRUE;
3182 prGlueInfo->fgWpsActive = FALSE;
3185 case IW_AUTH_80211_AUTH_ALG:
3186 prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value;
3189 case IW_AUTH_PRIVACY_INVOKED:
3190 prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value;
3192 #if CFG_SUPPORT_802_11W
3194 //printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value);
3195 prGlueInfo->rWpaInfo.u4Mfp = prAuth->value;
3198 #if CFG_SUPPORT_WAPI
3199 case IW_AUTH_WAPI_ENABLED:
3202 WLAN_STATUS rStatus;
3204 rStatus = kalIoctl(prGlueInfo,
3214 DBGLOG(INIT, INFO, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value));
3219 printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags);
3224 } /* wext_set_auth */
3227 /*----------------------------------------------------------------------------*/
3229 * \brief To set encryption cipher and key.
3231 * \param[in] prDev Net device requested.
3232 * \param[in] prIwrInfo NULL.
3233 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
3234 * \param[in] pcExtra Pointer to key string buffer.
3236 * \retval 0 Success.
3237 * \retval -EINVAL Key ID error for WEP.
3238 * \retval -EFAULT Setting parameters to driver fail.
3239 * \retval -EOPNOTSUPP Key size not supported.
3241 * \note Securiry information is stored in pEnc.
3243 /*----------------------------------------------------------------------------*/
3244 #if CFG_SUPPORT_WAPI
3245 UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */
3247 UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */
3251 wext_set_encode_ext (
3252 IN struct net_device *prNetDev,
3253 IN struct iw_request_info *prIwrInfo,
3254 IN struct iw_point *prEnc,
3258 P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf;
3259 P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf;
3262 P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
3264 struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *) pcExtra;
3266 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
3267 ENUM_PARAM_AUTH_MODE_T eAuthMode;
3268 //ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH;
3270 #if CFG_SUPPORT_WAPI
3271 P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
3274 P_GLUE_INFO_T prGlueInfo = NULL;
3275 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3276 UINT_32 u4BufLen = 0;
3280 if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) {
3283 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3285 memset(keyStructBuf, 0, sizeof(keyStructBuf));
3287 #if CFG_SUPPORT_WAPI
3288 if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
3289 if (prEnc->flags & IW_ENCODE_DISABLED) {
3290 //printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n");
3294 prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX);
3295 prWpiKey->ucKeyID --;
3296 if (prWpiKey->ucKeyID > 1) {
3297 /* key id is out of range */
3298 //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID);
3302 if (prIWEncExt->key_len != 32) {
3303 /* key length not valid */
3304 //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len);
3308 //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags);
3310 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3311 prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
3312 prWpiKey->eDirection = ENUM_WPI_RX;
3314 else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3315 prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
3316 prWpiKey->eDirection = ENUM_WPI_RX_TX;
3320 memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2);
3323 memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6);
3325 memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
3326 prWpiKey->u4LenWPIEK = 16;
3328 memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
3329 prWpiKey->u4LenWPICK = 16;
3331 rStatus = kalIoctl(prGlueInfo,
3334 sizeof(PARAM_WPI_KEY_T),
3341 if (rStatus != WLAN_STATUS_SUCCESS) {
3342 //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus);
3350 if ( (prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) {
3351 prRemoveKey->u4Length = sizeof(*prRemoveKey);
3352 memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3354 printk("IW_ENCODE_DISABLED: ID:%d, Addr:[" MACSTR "]\n",
3355 prRemoveKey->KeyIndex, MAC2STR(prRemoveKey->BSSID));
3358 rStatus = kalIoctl(prGlueInfo,
3359 wlanoidSetRemoveKey,
3361 prRemoveKey->u4Length,
3369 if (rStatus != WLAN_STATUS_SUCCESS) {
3370 DBGLOG(INIT, INFO, ("remove key error:%lx\n", rStatus));
3376 //printk ("alg %x\n", prIWEncExt->alg);
3378 switch (prIWEncExt->alg) {
3379 case IW_ENCODE_ALG_NONE:
3381 case IW_ENCODE_ALG_WEP:
3382 /* iwconfig wlan0 key 0123456789 */
3383 /* iwconfig wlan0 key s:abcde */
3384 /* iwconfig wlan0 key 0123456789 [1] */
3385 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3386 /* check key size for WEP */
3387 if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) {
3388 /* prepare PARAM_WEP key structure */
3389 prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
3390 (prEnc->flags & IW_ENCODE_INDEX) -1 : 0;
3391 if (prWepKey->u4KeyIndex > 3) {
3392 /* key id is out of range */
3395 prWepKey->u4KeyIndex |= 0x80000000;
3396 prWepKey->u4Length = 12 + prIWEncExt->key_len;
3397 prWepKey->u4KeyLength = prIWEncExt->key_len;
3398 //kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len);
3399 kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
3402 rStatus = kalIoctl(prGlueInfo,
3412 if (rStatus != WLAN_STATUS_SUCCESS) {
3413 DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus));
3417 /* change to auto switch */
3418 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY |
3419 IW_AUTH_ALG_OPEN_SYSTEM;
3420 eAuthMode = AUTH_MODE_AUTO_SWITCH;
3422 rStatus = kalIoctl(prGlueInfo,
3432 if (rStatus != WLAN_STATUS_SUCCESS) {
3433 DBGLOG(INIT, INFO, ("wlanoidSetAuthMode fail 0x%lx\n", rStatus));
3437 prGlueInfo->rWpaInfo.u4CipherPairwise =
3438 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
3439 prGlueInfo->rWpaInfo.u4CipherGroup =
3440 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40;
3442 eEncStatus = ENUM_WEP_ENABLED;
3445 rStatus = kalIoctl(prGlueInfo,
3446 wlanoidSetEncryptionStatus,
3448 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T),
3455 if (rStatus != WLAN_STATUS_SUCCESS) {
3456 DBGLOG(INIT, INFO, ("wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus));
3461 DBGLOG(INIT, INFO, ("key length %x\n", prIWEncExt->key_len));
3462 DBGLOG(INIT, INFO, ("key error\n"));
3466 case IW_ENCODE_ALG_TKIP:
3467 case IW_ENCODE_ALG_CCMP:
3468 #if CFG_SUPPORT_802_11W
3469 case IW_ENCODE_ALG_AES_CMAC:
3474 prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
3475 (prEnc->flags & IW_ENCODE_INDEX) -1: 0;
3476 #if CFG_SUPPORT_802_11W
3477 if (prKey->u4KeyIndex > 5)
3479 if (prKey->u4KeyIndex > 3)
3482 DBGLOG(INIT, INFO, ("key index error:0x%lx\n", prKey->u4KeyIndex));
3483 /* key id is out of range */
3487 /* bit(31) and bit(30) are shared by pKey and pRemoveKey */
3489 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3490 prKey->u4KeyIndex |= 0x1UL << 31;
3493 /* Pairwise Key Bit(30) */
3494 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3499 prKey->u4KeyIndex |= 0x1UL << 30;
3504 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3505 prKey->u4KeyIndex |= 0x1UL << 29;
3506 memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
3510 memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3512 /* switch tx/rx MIC key for sta */
3513 if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) {
3514 memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16);
3515 memcpy(((PUINT_8)prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8);
3516 memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8);
3519 memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
3522 prKey->u4KeyLength = prIWEncExt->key_len;
3523 prKey->u4Length = ((UINT_32)&(((P_PARAM_KEY_T)0)->aucKeyMaterial)) + prKey->u4KeyLength;
3526 rStatus = kalIoctl(prGlueInfo,
3536 if (rStatus != WLAN_STATUS_SUCCESS) {
3537 DBGLOG(INIT, INFO, ("add key error:%lx\n", rStatus));
3545 } /* wext_set_encode_ext */
3548 /*----------------------------------------------------------------------------*/
3550 * \brief Set country code
3552 * \param[in] prDev Net device requested.
3553 * \param[in] prIwrInfo NULL.
3554 * \param[in] pu4Mode Pointer to new operation mode.
3555 * \param[in] pcExtra NULL.
3557 * \retval 0 For success.
3558 * \retval -EOPNOTSUPP If new mode is not supported.
3560 * \note Device will run in new operation mode if it is valid.
3562 /*----------------------------------------------------------------------------*/
3565 IN struct net_device *prNetDev,
3566 IN struct iwreq *iwr
3569 P_GLUE_INFO_T prGlueInfo;
3570 WLAN_STATUS rStatus;
3572 UINT_8 aucCountry[2];
3576 /* iwr->u.data.pointer should be like "COUNTRY US", "COUNTRY EU"
3579 if (FALSE == GLUE_CHK_PR2(prNetDev, iwr) ||
3580 !iwr->u.data.pointer || iwr->u.data.length < 10) {
3583 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3585 aucCountry[0] = *((PUINT_8)iwr->u.data.pointer + 8);
3586 aucCountry[1] = *((PUINT_8)iwr->u.data.pointer + 9);
3588 rStatus = kalIoctl(prGlueInfo,
3589 wlanoidSetCountryCode,
3601 /*----------------------------------------------------------------------------*/
3603 * \brief ioctl() (Linux Wireless Extensions) routines
3605 * \param[in] prDev Net device requested.
3606 * \param[in] ifr The ifreq structure for seeting the wireless extension.
3607 * \param[in] i4Cmd The wireless extension ioctl command.
3609 * \retval zero On success.
3610 * \retval -EOPNOTSUPP If the cmd is not supported.
3611 * \retval -EFAULT If copy_to_user goes wrong.
3612 * \retval -EINVAL If any value's out of range.
3616 /*----------------------------------------------------------------------------*/
3618 wext_support_ioctl (
3619 IN struct net_device *prDev,
3620 IN struct ifreq *prIfReq,
3624 /* prIfReq is verified in the caller function wlanDoIOCTL() */
3625 struct iwreq *iwr = (struct iwreq*)prIfReq;
3626 struct iw_request_info rIwReqInfo;
3628 char *prExtraBuf = NULL;
3629 UINT_32 u4ExtraSize = 0;
3631 /* prDev is verified in the caller function wlanDoIOCTL() */
3633 printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd);
3635 /* Prepare the call */
3636 rIwReqInfo.cmd = (__u16)i4Cmd;
3637 rIwReqInfo.flags = 0;
3640 case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */
3641 ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL);
3644 /* case SIOCSIWNWID: 0x8B02, deprecated */
3645 /* case SIOCGIWNWID: 0x8B03, deprecated */
3647 case SIOCSIWFREQ: /* 0x8B04, set channel */
3648 ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL);
3651 case SIOCGIWFREQ: /* 0x8B05, get channel */
3652 ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL);
3655 case SIOCSIWMODE: /* 0x8B06, set operation mode */
3656 ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL);
3660 case SIOCGIWMODE: /* 0x8B07, get operation mode */
3661 ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL);
3664 /* case SIOCSIWSENS: 0x8B08, unsupported */
3665 /* case SIOCGIWSENS: 0x8B09, unsupported */
3667 /* case SIOCSIWRANGE: 0x8B0A, unused */
3668 case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */
3669 if (iwr->u.data.pointer != NULL) {
3670 /* Buffer size shoule be large enough */
3671 if (iwr->u.data.length < sizeof(struct iw_range)) {
3676 prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE);
3682 /* reset all fields */
3683 memset(prExtraBuf, 0, sizeof(struct iw_range));
3684 iwr->u.data.length = sizeof(struct iw_range);
3686 ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf);
3687 /* Push up to the caller */
3688 if (copy_to_user(iwr->u.data.pointer,
3690 iwr->u.data.length)) {
3694 kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range));
3702 case SIOCSIWPRIV: /* 0x8B0C, Country */
3703 ret = wext_set_country(prDev, iwr);
3706 /* case SIOCGIWPRIV: 0x8B0D, handled in wlan_do_ioctl() */
3707 /* caes SIOCSIWSTATS: 0x8B0E, unused */
3708 /* case SIOCGIWSTATS:
3709 get statistics, intercepted by wireless_process_ioctl() in wireless.c,
3710 redirected to dev_iwstats(), dev->get_wireless_stats().
3712 /* case SIOCSIWSPY: 0x8B10, unsupported */
3713 /* case SIOCGIWSPY: 0x8B11, unsupported*/
3714 /* case SIOCSIWTHRSPY: 0x8B12, unsupported */
3715 /* case SIOCGIWTHRSPY: 0x8B13, unsupported*/
3717 case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */
3718 if (iwr->u.ap_addr.sa_data[0] == 0 &&
3719 iwr->u.ap_addr.sa_data[1] == 0 &&
3720 iwr->u.ap_addr.sa_data[2] == 0 &&
3721 iwr->u.ap_addr.sa_data[3] == 0 &&
3722 iwr->u.ap_addr.sa_data[4] == 0 &&
3723 iwr->u.ap_addr.sa_data[5] == 0) {
3724 /* WPA Supplicant will set 000000000000 in
3725 ** wpa_driver_wext_deinit(), do nothing here or disassoc again?
3731 ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
3735 case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */
3736 ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL);
3739 case SIOCSIWMLME: /* 0x8B16, request MLME operation */
3740 /* Fixed length structure */
3741 if (iwr->u.data.length != sizeof(struct iw_mlme)) {
3742 DBGLOG(INIT, INFO, ("MLME buffer strange:%d\n", iwr->u.data.length));
3747 if (!iwr->u.data.pointer) {
3752 prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE);
3758 if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) {
3762 ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf);
3765 kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme));
3769 /* case SIOCGIWAPLIST: 0x8B17, deprecated */
3770 case SIOCSIWSCAN: /* 0x8B18, scan request */
3771 if (iwr->u.data.pointer == NULL) {
3772 ret = wext_set_scan(prDev, NULL, NULL, NULL);
3774 #if WIRELESS_EXT > 17
3775 else if (iwr->u.data.length == sizeof(struct iw_scan_req)) {
3776 prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE);
3781 if (copy_from_user(prExtraBuf, ((struct iw_scan_req *) (iwr->u.data.pointer))->essid,
3782 ((struct iw_scan_req *) (iwr->u.data.pointer))->essid_len)) {
3785 ret = wext_set_scan(prDev, NULL, (union iwreq_data *) &(iwr->u.data), prExtraBuf);
3788 kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN);
3797 case SIOCGIWSCAN: /* 0x8B19, get scan results */
3798 if (!iwr->u.data.pointer|| !iwr->u.essid.pointer) {
3803 u4ExtraSize = iwr->u.data.length;
3804 /* allocate the same size of kernel buffer to store scan results. */
3805 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
3811 /* iwr->u.data.length may be updated by wext_get_scan() */
3812 ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf);
3814 if (ret == -E2BIG) {
3815 DBGLOG(INIT, INFO, ("[wifi] wext_get_scan -E2BIG\n"));
3819 /* check updated length is valid */
3820 ASSERT(iwr->u.data.length <= u4ExtraSize);
3821 if (iwr->u.data.length > u4ExtraSize) {
3822 DBGLOG(INIT, INFO, ("Updated result length is larger than allocated (%d > %ld)\n",
3823 iwr->u.data.length, u4ExtraSize));
3824 iwr->u.data.length = u4ExtraSize;
3827 if (copy_to_user(iwr->u.data.pointer,
3829 iwr->u.data.length)) {
3834 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
3842 case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */
3843 if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) {
3847 if (!iwr->u.essid.pointer) {
3852 prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE);
3858 if (copy_from_user(prExtraBuf,
3859 iwr->u.essid.pointer,
3860 iwr->u.essid.length)) {
3864 /* Add trailing '\0' for printk */
3865 //prExtraBuf[iwr->u.essid.length] = 0;
3866 //printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length);
3867 ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
3868 //printk ("set essid %d\n", ret);
3871 kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4);
3877 case SIOCGIWESSID: /* 0x8B1B, get SSID */
3878 if (!iwr->u.essid.pointer) {
3883 if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) {
3884 DBGLOG(INIT, INFO, ("[wifi] iwr->u.essid.length:%d too small\n",
3885 iwr->u.essid.length));
3886 ret = -E2BIG; /* let caller try larger buffer */
3890 prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE);
3896 /* iwr->u.essid.length is updated by wext_get_essid() */
3898 ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf);
3900 if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) {
3905 kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE);
3910 /* case SIOCSIWNICKN: 0x8B1C, not supported */
3911 /* case SIOCGIWNICKN: 0x8B1D, not supported */
3913 case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */
3914 //ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL);
3917 case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */
3918 ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL);
3921 case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */
3922 ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL);
3925 case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */
3926 ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL);
3929 /* case SIOCSIWFRAG: 0x8B24, unsupported */
3930 case SIOCGIWFRAG: /* 0x8B25, get frag threshold */
3931 ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL);
3934 case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */
3935 ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL);
3938 case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */
3939 ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL);
3942 /* case SIOCSIWRETRY: 0x8B28, unsupported */
3943 /* case SIOCGIWRETRY: 0x8B29, unsupported */
3946 case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */
3947 /* Only DISABLED case has NULL pointer and length == 0 */
3948 if (iwr->u.encoding.pointer) {
3949 if (iwr->u.encoding.length > 16) {
3954 u4ExtraSize = iwr->u.encoding.length;
3955 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
3961 if (copy_from_user(prExtraBuf,
3962 iwr->u.encoding.pointer,
3963 iwr->u.encoding.length)) {
3967 else if (iwr->u.encoding.length != 0) {
3973 ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf);
3977 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
3982 case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */
3984 ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL);
3987 case SIOCSIWPOWER: /* 0x8B2C, set power management */
3988 ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL);
3991 case SIOCGIWPOWER: /* 0x8B2D, get power management */
3992 ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL);
3995 #if WIRELESS_EXT > 17
3996 case SIOCSIWGENIE: /* 0x8B30, set gen ie */
3997 if (iwr->u.data.pointer) {
3998 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3999 if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) {
4000 /* Fixed length structure */
4001 #if CFG_SUPPORT_WAPI
4002 if (iwr->u.data.length > 42 /* The max wapi ie buffer */) {
4007 u4ExtraSize = iwr->u.data.length;
4009 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4014 if (copy_from_user(prExtraBuf,
4015 iwr->u.data.pointer,
4016 iwr->u.data.length)) {
4020 WLAN_STATUS rStatus;
4022 #if CFG_SUPPORT_WAPI
4023 rStatus = kalIoctl(prGlueInfo,
4024 wlanoidSetWapiAssocInfo,
4033 if (rStatus != WLAN_STATUS_SUCCESS) {
4034 //printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", rStatus);
4036 #if CFG_SUPPORT_WPS2
4037 PUINT_8 prDesiredIE = NULL;
4038 if (wextSrchDesiredWPSIE(prExtraBuf,
4041 (PUINT_8 *)&prDesiredIE)) {
4042 rStatus = kalIoctl(prGlueInfo,
4043 wlanoidSetWSCAssocInfo,
4045 IE_SIZE(prDesiredIE),
4051 if (rStatus != WLAN_STATUS_SUCCESS) {
4052 //printk(KERN_INFO "[WSC] set WSC assoc info error:%lx\n", rStatus);
4056 #if CFG_SUPPORT_WAPI
4060 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4067 case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */
4072 case SIOCSIWAUTH: /* 0x8B32, set auth mode params */
4073 ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL);
4076 /* case SIOCGIWAUTH: 0x8B33, unused? */
4077 case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */
4078 if (iwr->u.encoding.pointer) {
4079 u4ExtraSize = iwr->u.encoding.length;
4080 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4086 if (copy_from_user(prExtraBuf,
4087 iwr->u.encoding.pointer,
4088 iwr->u.encoding.length)) {
4092 else if (iwr->u.encoding.length != 0) {
4098 ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf);
4102 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4107 /* case SIOCGIWENCODEEXT: 0x8B35, unused? */
4109 case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */
4111 if (iwr->u.data.pointer) {
4112 /* Fixed length structure */
4113 if (iwr->u.data.length != sizeof(struct iw_pmksa)) {
4118 u4ExtraSize = sizeof(struct iw_pmksa);
4119 prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
4125 if (copy_from_user(prExtraBuf,
4126 iwr->u.data.pointer,
4127 sizeof(struct iw_pmksa))) {
4131 switch(((struct iw_pmksa *)prExtraBuf)->cmd) {
4134 printk(KERN_INFO "IW_PMKSA_ADD [" MACSTR "]\n",
4135 MAC2STR(((struct iw_pmksa *)pExtraBuf)->bssid.sa_data));
4138 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4139 WLAN_STATUS rStatus;
4141 P_PARAM_PMKID_T prPmkid;
4143 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
4145 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_ADD\n"));
4150 prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
4151 prPmkid->u4BSSIDInfoCount = 1;
4152 kalMemCopy(prPmkid->arBSSIDInfo->arBSSID,
4153 ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data,
4155 kalMemCopy(prPmkid->arBSSIDInfo->arPMKID,
4156 ((struct iw_pmksa *)prExtraBuf)->pmkid,
4159 rStatus = kalIoctl(prGlueInfo,
4162 sizeof(PARAM_PMKID_T),
4169 if (rStatus != WLAN_STATUS_SUCCESS) {
4170 DBGLOG(INIT, INFO, ("add pmkid error:%lx\n", rStatus));
4172 kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
4175 case IW_PMKSA_REMOVE:
4177 printk(KERN_INFO "IW_PMKSA_REMOVE [" MACSTR "]\n",
4178 MAC2STR(((struct iw_pmksa *)buf)->bssid.sa_data));
4181 case IW_PMKSA_FLUSH:
4183 printk(KERN_INFO "IW_PMKSA_FLUSH\n");
4186 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4187 WLAN_STATUS rStatus;
4189 P_PARAM_PMKID_T prPmkid;
4191 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE);
4193 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
4198 prPmkid->u4Length = 8;
4199 prPmkid->u4BSSIDInfoCount = 0;
4201 rStatus = kalIoctl(prGlueInfo,
4204 sizeof(PARAM_PMKID_T),
4211 if (rStatus != WLAN_STATUS_SUCCESS) {
4212 DBGLOG(INIT, INFO, ("flush pmkid error:%lx\n", rStatus));
4214 kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
4218 DBGLOG(INIT, INFO, ("UNKNOWN iw_pmksa command:%d\n",
4219 ((struct iw_pmksa *)prExtraBuf)->cmd));
4226 kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
4230 else if (iwr->u.data.length != 0) {
4240 /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */
4245 //printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret);
4248 } /* wext_support_ioctl */
4252 /*----------------------------------------------------------------------------*/
4254 * \brief To send an event (RAW socket pacekt) to user process actively.
4256 * \param[in] prGlueInfo Glue layer info.
4257 * \param[in] u4cmd Whcih event command we want to indicate to user process.
4258 * \param[in] pData Data buffer to be indicated.
4259 * \param[in] dataLen Available data size in pData.
4263 * \note Event is indicated to upper layer if cmd is supported and data is valid.
4264 * Using of kernel symbol wireless_send_event(), which is defined in
4265 * <net/iw_handler.h> after WE-14 (2.4.20).
4267 /*----------------------------------------------------------------------------*/
4269 wext_indicate_wext_event (
4270 IN P_GLUE_INFO_T prGlueInfo,
4271 IN unsigned int u4Cmd,
4272 IN unsigned char *pucData,
4273 IN unsigned int u4dataLen
4276 union iwreq_data wrqu;
4277 unsigned char *pucExtraInfo = NULL;
4278 #if WIRELESS_EXT >= 15
4279 unsigned char *pucDesiredIE = NULL;
4280 unsigned char aucExtraInfoBuf[200];
4282 #if WIRELESS_EXT < 18
4286 memset(&wrqu, 0, sizeof(wrqu));
4290 memcpy(&wrqu.power, pucData, u4dataLen);
4293 complete_all(&prGlueInfo->rScanComp);
4298 memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);
4301 memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4305 case IWEVASSOCREQIE:
4306 #if WIRELESS_EXT < 15
4307 /* under WE-15, no suitable Event can be used */
4308 goto skip_indicate_event;
4310 /* do supplicant a favor, parse to the start of WPA/RSN IE */
4311 if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) {
4315 else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
4319 else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) {
4322 #if CFG_SUPPORT_WAPI /* Android+ */
4323 else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) {
4324 //printk("wextSrchDesiredWAPIIE!!\n");
4329 /* no WPA/RSN IE found, skip this event */
4330 goto skip_indicate_event;
4333 #if WIRELESS_EXT < 18
4334 /* under WE-18, only IWEVCUSTOM can be used */
4336 pucExtraInfo = aucExtraInfoBuf;
4337 pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs=");
4338 /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */
4339 /* translate binary string to hex string, requirement of IWEVCUSTOM */
4340 for (i = 0; i < pucDesiredIE[1] + 2 ; ++i) {
4341 pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]);
4343 pucExtraInfo = aucExtraInfoBuf;
4344 wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2;
4346 /* IWEVASSOCREQIE, indicate binary string */
4347 pucExtraInfo = pucDesiredIE;
4348 wrqu.data.length = pucDesiredIE[1] + 2;
4350 #endif /* WIRELESS_EXT < 15 */
4353 case IWEVMICHAELMICFAILURE:
4354 #if WIRELESS_EXT < 15
4355 /* under WE-15, no suitable Event can be used */
4356 goto skip_indicate_event;
4359 P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T)pucData;
4360 /* under WE-18, only IWEVCUSTOM can be used */
4362 pucExtraInfo = aucExtraInfoBuf;
4363 pucExtraInfo += sprintf(pucExtraInfo,
4364 "MLME-MICHAELMICFAILURE.indication ");
4365 pucExtraInfo += sprintf(pucExtraInfo,
4367 (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ?
4368 "groupcast " : "unicast ");
4370 wrqu.data.length = pucExtraInfo - aucExtraInfoBuf;
4371 pucExtraInfo = aucExtraInfoBuf;
4373 #endif /* WIRELESS_EXT < 15 */
4377 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 &&
4378 prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) {
4380 /* only used in WPA2 */
4381 #if WIRELESS_EXT >= 18
4382 P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T)pucData;
4384 struct iw_pmkid_cand rPmkidCand;
4385 pucExtraInfo = aucExtraInfoBuf;
4387 rPmkidCand.flags = prPmkidCand->u4Flags;
4388 rPmkidCand.index = 0;
4389 kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6);
4391 kalMemCopy(pucExtraInfo, (PUINT_8)&rPmkidCand, sizeof(struct iw_pmkid_cand));
4392 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4394 /* pmkid canadidate list is supported after WE-18 */
4395 /* indicate struct iw_pmkid_cand */
4397 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */
4398 goto skip_indicate_event;
4402 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */
4403 goto skip_indicate_event;
4409 pucExtraInfo = aucExtraInfoBuf;
4410 kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T));
4411 wrqu.data.length = sizeof(PTA_IPC_T);
4415 /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */
4416 goto skip_indicate_event;
4419 /* Send event to user space */
4420 wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo);
4422 skip_indicate_event:
4424 } /* wext_indicate_wext_event */
4427 /*----------------------------------------------------------------------------*/
4429 * \brief A method of struct net_device, to get the network interface statistical
4432 * Whenever an application needs to get statistics for the interface, this method
4433 * is called. This happens, for example, when ifconfig or netstat -i is run.
4435 * \param[in] pDev Pointer to struct net_device.
4437 * \return net_device_stats buffer pointer.
4440 /*----------------------------------------------------------------------------*/
4441 struct iw_statistics *
4442 wext_get_wireless_stats (
4443 struct net_device *prDev
4447 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
4448 P_GLUE_INFO_T prGlueInfo = NULL;
4449 struct iw_statistics *pStats = NULL;
4454 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4460 pStats = (struct iw_statistics *) (&(prGlueInfo->rIwStats));
4462 if (!prDev || !netif_carrier_ok(prDev)) {
4463 /* network not connected */
4467 rStatus = kalIoctl(prGlueInfo,
4479 } /* wlan_get_wireless_stats */
4481 /*----------------------------------------------------------------------------*/
4483 * \brief To report the private supported IOCTLs table to user space.
4485 * \param[in] prNetDev Net device requested.
4486 * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
4487 * user space buffer in gl_iwpriv_table.
4489 * \retval 0 For success.
4490 * \retval -E2BIG For user's buffer size is too small.
4491 * \retval -EFAULT For fail.
4494 /*----------------------------------------------------------------------------*/
4497 IN struct net_device *prNetDev,
4498 IN struct ifreq *prIfReq
4501 /* prIfReq is verified in the caller function wlanDoIOCTL() */
4502 struct iwreq *prIwReq = (struct iwreq *)prIfReq;
4503 struct iw_point *prData= (struct iw_point *)&prIwReq->u.data;
4504 UINT_16 u2BufferSize = 0;
4506 u2BufferSize = prData->length;
4508 /* update our private table size */
4509 prData->length = (__u16)sizeof(rIwPrivTable)/sizeof(struct iw_priv_args);
4511 if (u2BufferSize < prData->length) {
4515 if (prData->length) {
4516 if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) {
4522 } /* wext_get_priv */
4524 #endif /* WIRELESS_EXT */