2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#5 $
6 \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver.
14 ** 09 17 2012 cm.chang
15 ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
16 ** Duplicate source from MT6620 v2.3 driver branch
17 ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
20 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
24 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
25 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
27 * 06 13 2012 yuche.tsai
29 * Update maintrunk driver.
30 * Add support for driver compose assoc request frame.
33 * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
34 * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
37 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
38 * Adding the related ioctl / wlan oid function to set the Tx power cfg.
41 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
42 * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
45 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
46 * 1. eliminaite direct calls to printk in porting layer.
47 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
50 * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
51 * adding the 802.11w related function and define .
53 * 09 23 2011 tsaiyuan.hsu
54 * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state
55 * avoid entering D3 state after deep sleep.
57 * 07 28 2011 chinghwa.yu
58 * [WCXRP00000063] Update BCM CoEx design and settings
59 * Add BWCS cmd and event.
62 * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query the ap address
63 * Remove the netif check while query bssid and ssid
65 * 07 26 2011 chinglan.wang
67 * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection..
69 * 07 18 2011 chinghwa.yu
70 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
71 * Add CMD/Event for RDD and BWCS.
73 * 05 17 2011 eddie.chen
74 * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
75 * Initilize the vairlabes.
77 * 05 11 2011 jeffrey.chang
78 * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
79 * modify set_tx_pow ioctl
82 * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring
83 * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of essid storage array.
86 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
87 * improve portability for awareness of early version of linux kernel and wireless extension.
89 * 03 17 2011 chinglan.wang
90 * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
94 * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
95 * Toggle non-standard debug messages to comments.
98 * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get essid
99 * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running.
101 * 02 08 2011 george.huang
102 * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
103 * Support querying power mode OID.
106 * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0
107 * not doing mem alloc. while set ie length already 0
109 * 01 20 2011 eddie.chen
110 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
113 * 01 20 2011 eddie.chen
114 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
117 * 01 20 2011 eddie.chen
118 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
119 * Add Oid for sw control debug command
121 * 01 11 2011 chinglan.wang
123 * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish successfully.
124 * Use the WPS function to connect AP, the privacy bit always is set to 1. .
126 * 01 07 2011 cm.chang
127 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
128 * Add a new compiling option to control if MCR read/write is permitted
131 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
132 * separate kalMemAlloc() into virtually-continous and physically-continous types
133 * to ease slab system pressure
136 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
137 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
139 * 12 31 2010 cm.chang
140 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
141 * Add some iwpriv commands to support test mode operation
143 * 12 15 2010 george.huang
144 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
145 * Support set PS profile and set WMM-PS related iwpriv.
147 * 12 15 2010 george.huang
148 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
149 * Allow change PS profile function (throught wext_set_power()).
151 * 12 14 2010 jeffrey.chang
152 * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID
155 * 12 13 2010 chinglan.wang
157 * Add WPS 1.0 feature flag to enable the WPS 1.0 function.
159 * 12 07 2010 cm.chang
160 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
161 * Fix compiling error
163 * 12 07 2010 cm.chang
164 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
165 * 1. Country code is from NVRAM or supplicant
166 * 2. Change band definition in CMD/EVENT.
169 * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1
173 * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
174 * add the message check code from mt5921.
176 * 10 19 2010 jeffrey.chang
177 * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power saving
178 * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving
180 * 10 18 2010 jeffrey.chang
181 * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
182 * refine the scan ioctl to prevent hanging of Android UI
185 * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
186 * add the scan result with wapi ie.
189 * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
190 * fixed the wapi ie assigned issue.
194 * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function.
196 * 09 21 2010 kevin.huang
197 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
198 * Eliminate Linux Compile Warning
202 * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
206 * Androi/Linux: return current operating channel information
210 * adding the wapi support for integration test.
212 * 08 02 2010 jeffrey.chang
214 * enable remove key ioctl
216 * 08 02 2010 jeffrey.chang
218 * 1) modify tx service thread to avoid busy looping
219 * 2) add spin lock declartion for linux build
221 * 07 28 2010 jeffrey.chang
223 * 1) enable encyption ioctls
224 * 2) temporarily disable remove keys ioctl to prevent TX1 busy
226 * 07 28 2010 jeffrey.chang
228 * 1) remove unused spinlocks
229 * 2) enable encyption ioctls
230 * 3) fix scan ioctl which may cause supplicant to hang
232 * 07 19 2010 jeffrey.chang
234 * add kal api for scanning done
236 * 07 19 2010 jeffrey.chang
238 * for linux driver migration
240 * 07 19 2010 jeffrey.chang
242 * Linux port modification
246 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
248 * 06 06 2010 kevin.huang
249 * [WPD00003832][MT6620 5931] Create driver base
250 * [MT6620 5931] Create driver base
252 * 05 28 2010 jeffrey.chang
253 * [WPD00003826]Initial import for Linux port
254 * remove unused macro and debug messages
256 * 05 14 2010 jeffrey.chang
257 * [WPD00003826]Initial import for Linux port
258 * Add dissassoication support for wpa supplicant
260 * 04 22 2010 jeffrey.chang
261 * [WPD00003826]Initial import for Linux port
263 * 1) modify rx path code for supporting Wi-Fi direct
264 * 2) modify config.h since Linux dont need to consider retaining packet
266 * 04 21 2010 jeffrey.chang
267 * [WPD00003826]Initial import for Linux port
268 * add for private ioctl support
270 * 04 19 2010 jeffrey.chang
271 * [WPD00003826]Initial import for Linux port
272 * Add ioctl of power management
274 * 04 19 2010 jeffrey.chang
275 * [WPD00003826]Initial import for Linux port
276 * remove debug message
278 * 04 14 2010 jeffrey.chang
279 * [WPD00003826]Initial import for Linux port
280 * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
283 * 04 12 2010 jeffrey.chang
284 * [WPD00003826]Initial import for Linux port
285 * remove debug messages for pre-release
288 * [WPD00001943]Create WiFi test driver framework on WinXP
289 * rWlanInfo should be placed at adapter rather than glue due to most operations
290 * * * * * * * * are done in adapter layer.
292 * 04 02 2010 jeffrey.chang
293 * [WPD00003826]Initial import for Linux port
296 * 04 01 2010 jeffrey.chang
297 * [WPD00003826]Initial import for Linux port
298 * enable pmksa cache operation
300 * 03 31 2010 jeffrey.chang
301 * [WPD00003826]Initial import for Linux port
302 * fix ioctl which may cause cmdinfo memory leak
305 * [WPD00003816][MT6620 Wi-Fi] Adding the security support
306 * modify the wapi related code for new driver's design.
308 * 03 30 2010 jeffrey.chang
309 * [WPD00003826]Initial import for Linux port
310 * emulate NDIS Pending OID facility
312 * 03 24 2010 jeffrey.chang
313 * [WPD00003826]Initial import for Linux port
314 * initial import for Linux port
315 ** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090
316 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
317 ** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090
318 ** Remove unused variables
319 ** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090
320 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
321 ** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088
322 ** adding the wapi ioctl support
323 ** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090
324 ** Add Linux SDIO (with mmc core) support.
325 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
326 ** Fix compile warning in Linux.
327 ** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089
328 ** fix compiling warning
329 ** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089
330 ** Add mandatory and private IO control for Linux BWCS
331 ** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088
332 ** fixed the compiling error
333 ** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088
334 ** add the privacy setting from linux supplicant ap selection
335 ** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088
336 ** fixed the compling error
337 ** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088
338 ** rename some variable with pre-fix to avoid the misunderstanding
339 ** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088
340 ** fixed compiling error
341 ** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088
342 ** adjust the code for meet the coding style, and add assert check
343 ** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461
344 ** Update after wlanoidSetPowerMode changed
345 ** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084
347 ** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461
348 ** Add set desired rate in Linux STD IOCTL
349 ** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088
350 ** add pmkid ioctl and indicate
351 ** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461
352 ** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461
353 ** Refine WPS related priv ioctl for unified interface
355 ** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088
356 ** move the configuration code from set essid function,
357 ** remove the non-used code
358 ** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461
360 ** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461
361 ** Add Set Frequency & Channel oid support for Linux
362 ** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461
363 ** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461
364 ** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter
365 ** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425
367 ** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461
369 ** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425
370 ** 1. Fix compiling erros
372 ** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425
373 ** 1. Add WMM-PS setting
374 ** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088
375 ** fixed the compiler error
376 ** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088
378 ** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425
379 ** 1. Update wlanQueryInformation
382 /*******************************************************************************
383 * C O M P I L E R F L A G S
384 ********************************************************************************
387 /*******************************************************************************
388 * E X T E R N A L R E F E R E N C E S
389 ********************************************************************************
395 #include "wlan_oid.h"
398 #include "gl_wext_priv.h"
406 /* compatibility to wireless extensions */
409 /*******************************************************************************
411 ********************************************************************************
413 const long channel_freq
[] = {
414 2412, 2417, 2422, 2427, 2432, 2437, 2442,
415 2447, 2452, 2457, 2462, 2467, 2472, 2484
418 #define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
486 case 149: /* UNII */\
489 case 153: /* UNII */\
492 case 157: /* UNII */\
495 case 161: /* UNII */\
498 case 165: /* UNII */\
501 case 100: /* HiperLAN2 */\
504 case 104: /* HiperLAN2 */\
507 case 108: /* HiperLAN2 */\
510 case 112: /* HiperLAN2 */\
513 case 116: /* HiperLAN2 */\
516 case 120: /* HiperLAN2 */\
519 case 124: /* HiperLAN2 */\
522 case 128: /* HiperLAN2 */\
525 case 132: /* HiperLAN2 */\
528 case 136: /* HiperLAN2 */\
531 case 140: /* HiperLAN2 */\
534 case 34: /* Japan MMAC */\
537 case 38: /* Japan MMAC */\
540 case 42: /* Japan MMAC */\
543 case 46: /* Japan MMAC */\
546 case 184: /* Japan */\
549 case 188: /* Japan */\
552 case 192: /* Japan */\
555 case 196: /* Japan */\
558 case 208: /* Japan, means J08 */\
561 case 212: /* Japan, means J12 */\
564 case 216: /* Japan, means J16 */\
574 #define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0]))
576 #define MAX_SSID_LEN 32
579 /*******************************************************************************
581 ********************************************************************************
584 /*******************************************************************************
585 * P U B L I C D A T A
586 ********************************************************************************
588 /* NOTE: name in iwpriv_args only have 16 bytes */
589 static const struct iw_priv_args rIwPrivTable
[] = {
590 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, ""},
591 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
592 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, 0, ""},
593 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, ""},
594 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, ""},
596 {IOCTL_GET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
597 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
598 {IOCTL_GET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
599 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
601 {IOCTL_SET_INTS
, IW_PRIV_TYPE_INT
| 4, 0, ""},
602 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| 50, ""},
604 /* added for set_oid and get_oid */
605 {IOCTL_SET_STRUCT
, 256, 0, ""},
606 {IOCTL_GET_STRUCT
, 0, 256, ""},
608 {IOCTL_GET_DRIVER
, IW_PRIV_TYPE_CHAR
| 2000, IW_PRIV_TYPE_CHAR
| 2000, "driver"},
610 /* sub-ioctl definitions */
612 {PRIV_CMD_REG_DOMAIN
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_reg_domain"},
613 {PRIV_CMD_REG_DOMAIN
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_reg_domain"},
616 #if CFG_TCP_IP_CHKSUM_OFFLOAD
617 {PRIV_CMD_CSUM_OFFLOAD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_tcp_csum"},
618 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
620 {PRIV_CMD_POWER_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_power_mode"},
621 {PRIV_CMD_POWER_MODE
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_power_mode"},
623 {PRIV_CMD_WMM_PS
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, 0, "set_wmm_ps"},
625 {PRIV_CMD_TEST_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_test_mode"},
626 {PRIV_CMD_TEST_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_test_cmd"},
627 {PRIV_CMD_TEST_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
628 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_test_result"},
629 #if CFG_SUPPORT_PRIV_MCR_RW
630 {PRIV_CMD_ACCESS_MCR
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_mcr"},
631 {PRIV_CMD_ACCESS_MCR
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
632 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_mcr"},
634 {PRIV_CMD_SW_CTRL
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_sw_ctrl"},
635 {PRIV_CMD_SW_CTRL
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
636 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_sw_ctrl"},
638 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
639 {PRIV_CUSTOM_BWCS_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_bwcs"},
640 /* GET STRUCT sub-ioctls commands */
641 {PRIV_CUSTOM_BWCS_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
642 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_bwcs"},
645 /* SET STRUCT sub-ioctls commands */
646 {PRIV_CMD_OID
, 256, 0, "set_oid"},
647 /* GET STRUCT sub-ioctls commands */
648 {PRIV_CMD_OID
, 0, 256, "get_oid"},
650 {PRIV_CMD_BAND_CONFIG
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_band"},
651 {PRIV_CMD_BAND_CONFIG
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_band"},
653 {PRIV_CMD_SET_TX_POWER
, IW_PRIV_TYPE_INT
| 4, 0, "set_txpower"},
654 {PRIV_CMD_GET_CH_LIST
, 0, IW_PRIV_TYPE_INT
| 50, "get_ch_list"},
655 {PRIV_CMD_DUMP_MEM
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
656 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_mem"},
658 #if CFG_ENABLE_WIFI_DIRECT
659 {PRIV_CMD_P2P_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_p2p_mode"},
661 {PRIV_CMD_MET_PROFILING
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_met_prof" },
665 static const iw_handler rIwPrivHandler
[] = {
666 [IOCTL_SET_INT
- SIOCIWFIRSTPRIV
] = priv_set_int
,
667 [IOCTL_GET_INT
- SIOCIWFIRSTPRIV
] = priv_get_int
,
668 [IOCTL_SET_ADDRESS
- SIOCIWFIRSTPRIV
] = NULL
,
669 [IOCTL_GET_ADDRESS
- SIOCIWFIRSTPRIV
] = NULL
,
670 [IOCTL_SET_STR
- SIOCIWFIRSTPRIV
] = NULL
,
671 [IOCTL_GET_STR
- SIOCIWFIRSTPRIV
] = NULL
,
672 [IOCTL_SET_KEY
- SIOCIWFIRSTPRIV
] = NULL
,
673 [IOCTL_GET_KEY
- SIOCIWFIRSTPRIV
] = NULL
,
674 [IOCTL_SET_STRUCT
- SIOCIWFIRSTPRIV
] = priv_set_struct
,
675 [IOCTL_GET_STRUCT
- SIOCIWFIRSTPRIV
] = priv_get_struct
,
676 [IOCTL_SET_STRUCT_FOR_EM
- SIOCIWFIRSTPRIV
] = priv_set_struct
,
677 [IOCTL_SET_INTS
- SIOCIWFIRSTPRIV
] = priv_set_ints
,
678 [IOCTL_GET_INTS
- SIOCIWFIRSTPRIV
] = priv_get_ints
,
679 [IOCTL_GET_DRIVER
- SIOCIWFIRSTPRIV
] = priv_set_driver
682 const struct iw_handler_def wext_handler_def
= {
684 .num_private
= (__u16
) sizeof(rIwPrivHandler
) / sizeof(iw_handler
),
685 .num_private_args
= (__u16
) sizeof(rIwPrivTable
) / sizeof(struct iw_priv_args
),
686 .standard
= (iw_handler
*) NULL
,
687 .private = rIwPrivHandler
,
688 .private_args
= rIwPrivTable
,
689 .get_wireless_stats
= wext_get_wireless_stats
,
692 /*******************************************************************************
693 * P R I V A T E D A T A
694 ********************************************************************************
697 /*******************************************************************************
699 ********************************************************************************
702 /*******************************************************************************
703 * F U N C T I O N D E C L A R A T I O N S
704 ********************************************************************************
706 extern VOID
wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo
);
708 /*******************************************************************************
710 ********************************************************************************
713 wext_support_ioctl_SIOCSIWGENIE(IN P_GLUE_INFO_T prGlueInfo
, IN
char *prExtraBuf
, IN UINT_32 u4ExtraSize
);
716 wext_support_ioctl_SIOCSIWPMKSA_Action(IN
struct net_device
*prDev
, IN
char *prExtraBuf
, IN
int ioMode
, OUT
int *ret
);
719 /*----------------------------------------------------------------------------*/
721 * \brief Find the desired WPA/RSN Information Element according to desiredElemID.
723 * \param[in] pucIEStart IE starting address.
724 * \param[in] i4TotalIeLen Total length of all the IE.
725 * \param[in] ucDesiredElemId Desired element ID.
726 * \param[out] ppucDesiredIE Pointer to the desired IE.
728 * \retval TRUE Find the desired IE.
729 * \retval FALSE Desired IE not found.
733 /*----------------------------------------------------------------------------*/
735 wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart
,
736 IN INT_32 i4TotalIeLen
, IN UINT_8 ucDesiredElemId
, OUT PUINT_8
* ppucDesiredIE
)
738 INT_32 i4InfoElemLen
;
741 ASSERT(ppucDesiredIE
);
743 while (i4TotalIeLen
>= 2) {
744 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
746 if (pucIEStart
[0] == ucDesiredElemId
&& i4InfoElemLen
<= i4TotalIeLen
) {
747 if (ucDesiredElemId
!= 0xDD) {
749 *ppucDesiredIE
= &pucIEStart
[0];
752 /* EID == 0xDD, check WPA IE */
753 if (pucIEStart
[1] >= 4) {
754 if (memcmp(&pucIEStart
[2], "\x00\x50\xf2\x01", 4) == 0) {
755 *ppucDesiredIE
= &pucIEStart
[0];
758 } /* check WPA IE length */
759 } /* check EID == 0xDD */
762 /* check desired EID */
763 /* Select next information element. */
764 i4TotalIeLen
-= i4InfoElemLen
;
765 pucIEStart
+= i4InfoElemLen
;
769 } /* parseSearchDesiredWPAIE */
773 /*----------------------------------------------------------------------------*/
775 * \brief Find the desired WAPI Information Element .
777 * \param[in] pucIEStart IE starting address.
778 * \param[in] i4TotalIeLen Total length of all the IE.
779 * \param[out] ppucDesiredIE Pointer to the desired IE.
781 * \retval TRUE Find the desired IE.
782 * \retval FALSE Desired IE not found.
786 /*----------------------------------------------------------------------------*/
788 wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart
, IN INT_32 i4TotalIeLen
, OUT PUINT_8
* ppucDesiredIE
)
790 INT_32 i4InfoElemLen
;
793 ASSERT(ppucDesiredIE
);
795 while (i4TotalIeLen
>= 2) {
796 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
798 if (pucIEStart
[0] == ELEM_ID_WAPI
&& i4InfoElemLen
<= i4TotalIeLen
) {
799 *ppucDesiredIE
= &pucIEStart
[0];
803 /* check desired EID */
804 /* Select next information element. */
805 i4TotalIeLen
-= i4InfoElemLen
;
806 pucIEStart
+= i4InfoElemLen
;
810 } /* wextSrchDesiredWAPIIE */
813 #if CFG_SUPPORT_PASSPOINT
814 /*----------------------------------------------------------------------------*/
816 * \brief Check if exist the desired HS2.0 Information Element according to desiredElemID.
818 * \param[in] pucIEStart IE starting address.
819 * \param[in] i4TotalIeLen Total length of all the IE.
820 * \param[in] ucDesiredElemId Desired element ID.
821 * \param[out] ppucDesiredIE Pointer to the desired IE.
823 * \retval TRUE Find the desired IE.
824 * \retval FALSE Desired IE not found.
828 /*----------------------------------------------------------------------------*/
829 BOOLEAN
wextIsDesiredHS20IE(IN PUINT_8 pucCurIE
, IN INT_32 i4TotalIeLen
)
831 INT_32 i4InfoElemLen
;
835 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
837 if (pucCurIE
[0] == ELEM_ID_VENDOR
&& i4InfoElemLen
<= i4TotalIeLen
) {
838 if ((pucCurIE
[1] >= ELEM_MIN_LEN_HS20_INDICATION
)) {
839 if (memcmp(&pucCurIE
[2], "\x50\x6f\x9a\x10", 4) == 0) {
844 /* check desired EID */
846 } /* wextIsDesiredHS20IE */
849 /*----------------------------------------------------------------------------*/
851 * \brief Check if exist the desired interworking Information Element according to desiredElemID.
853 * \param[in] pucIEStart IE starting address.
854 * \param[in] i4TotalIeLen Total length of all the IE.
855 * \param[in] ucDesiredElemId Desired element ID.
856 * \param[out] ppucDesiredIE Pointer to the desired IE.
858 * \retval TRUE Find the desired IE.
859 * \retval FALSE Desired IE not found.
863 /*----------------------------------------------------------------------------*/
864 BOOLEAN
wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE
, IN INT_32 i4TotalIeLen
)
866 INT_32 i4InfoElemLen
;
870 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
872 if (pucCurIE
[0] == ELEM_ID_INTERWORKING
&& i4InfoElemLen
<= i4TotalIeLen
) {
873 switch (pucCurIE
[1]) {
874 case IW_IE_LENGTH_ANO
:
875 case IW_IE_LENGTH_ANO_HESSID
:
876 case IW_IE_LENGTH_ANO_VENUE
:
877 case IW_IE_LENGTH_ANO_VENUE_HESSID
:
885 /* check desired EID */
887 } /* wextIsDesiredInterworkingIE */
890 /*----------------------------------------------------------------------------*/
892 * \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID.
894 * \param[in] pucIEStart IE starting address.
895 * \param[in] i4TotalIeLen Total length of all the IE.
896 * \param[in] ucDesiredElemId Desired element ID.
897 * \param[out] ppucDesiredIE Pointer to the desired IE.
899 * \retval TRUE Find the desired IE.
900 * \retval FALSE Desired IE not found.
904 /*----------------------------------------------------------------------------*/
905 BOOLEAN
wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE
, IN INT_32 i4TotalIeLen
)
907 INT_32 i4InfoElemLen
;
911 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
913 if (pucCurIE
[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL
&& i4InfoElemLen
<= i4TotalIeLen
) {
916 /* check desired EID */
918 } /* wextIsDesiredAdvProtocolIE */
921 /*----------------------------------------------------------------------------*/
923 * \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID.
925 * \param[in] pucIEStart IE starting address.
926 * \param[in] i4TotalIeLen Total length of all the IE.
927 * \param[in] ucDesiredElemId Desired element ID.
928 * \param[out] ppucDesiredIE Pointer to the desired IE.
930 * \retval TRUE Find the desired IE.
931 * \retval FALSE Desired IE not found.
935 /*----------------------------------------------------------------------------*/
936 BOOLEAN
wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE
, IN INT_32 i4TotalIeLen
)
938 INT_32 i4InfoElemLen
;
942 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
944 if (pucCurIE
[0] == ELEM_ID_ROAMING_CONSORTIUM
&& i4InfoElemLen
<= i4TotalIeLen
) {
947 /* check desired EID */
949 } /* wextIsDesiredRoamingConsortiumIE */
952 /*----------------------------------------------------------------------------*/
954 * \brief Find the desired HS2.0 Information Element according to desiredElemID.
956 * \param[in] pucIEStart IE starting address.
957 * \param[in] i4TotalIeLen Total length of all the IE.
958 * \param[in] ucDesiredElemId Desired element ID.
959 * \param[out] ppucDesiredIE Pointer to the desired IE.
961 * \retval TRUE Find the desired IE.
962 * \retval FALSE Desired IE not found.
966 /*----------------------------------------------------------------------------*/
968 wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart
, IN INT_32 i4TotalIeLen
, OUT PUINT_8
* ppucDesiredIE
)
970 INT_32 i4InfoElemLen
;
973 ASSERT(ppucDesiredIE
);
975 while (i4TotalIeLen
>= 2) {
976 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
978 if (pucIEStart
[0] == ELEM_ID_VENDOR
&& i4InfoElemLen
<= i4TotalIeLen
) {
979 if ((pucIEStart
[1] >= ELEM_MIN_LEN_HS20_INDICATION
)) {
980 if (memcmp(&pucIEStart
[2], "\x50\x6f\x9a\x10", 4) == 0) {
981 *ppucDesiredIE
= &pucIEStart
[0];
987 /* check desired EID */
988 /* Select next information element. */
989 i4TotalIeLen
-= i4InfoElemLen
;
990 pucIEStart
+= i4InfoElemLen
;
994 } /* wextSrchDesiredHS20IE */
997 /*----------------------------------------------------------------------------*/
999 * \brief Find the desired interworking Information Element according to desiredElemID.
1001 * \param[in] pucIEStart IE starting address.
1002 * \param[in] i4TotalIeLen Total length of all the IE.
1003 * \param[in] ucDesiredElemId Desired element ID.
1004 * \param[out] ppucDesiredIE Pointer to the desired IE.
1006 * \retval TRUE Find the desired IE.
1007 * \retval FALSE Desired IE not found.
1011 /*----------------------------------------------------------------------------*/
1013 wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart
,
1014 IN INT_32 i4TotalIeLen
, OUT PUINT_8
* ppucDesiredIE
)
1016 INT_32 i4InfoElemLen
;
1019 ASSERT(ppucDesiredIE
);
1021 while (i4TotalIeLen
>= 2) {
1022 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1024 if (pucIEStart
[0] == ELEM_ID_INTERWORKING
&& i4InfoElemLen
<= i4TotalIeLen
) {
1025 *ppucDesiredIE
= &pucIEStart
[0];
1029 /* check desired EID */
1030 /* Select next information element. */
1031 i4TotalIeLen
-= i4InfoElemLen
;
1032 pucIEStart
+= i4InfoElemLen
;
1036 } /* wextSrchDesiredInterworkingIE */
1038 /*----------------------------------------------------------------------------*/
1040 * \brief Find the desired Adv Protocol Information Element according to desiredElemID.
1042 * \param[in] pucIEStart IE starting address.
1043 * \param[in] i4TotalIeLen Total length of all the IE.
1044 * \param[in] ucDesiredElemId Desired element ID.
1045 * \param[out] ppucDesiredIE Pointer to the desired IE.
1047 * \retval TRUE Find the desired IE.
1048 * \retval FALSE Desired IE not found.
1052 /*----------------------------------------------------------------------------*/
1054 wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart
,
1055 IN INT_32 i4TotalIeLen
, OUT PUINT_8
* ppucDesiredIE
)
1057 INT_32 i4InfoElemLen
;
1060 ASSERT(ppucDesiredIE
);
1062 while (i4TotalIeLen
>= 2) {
1063 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1065 if (pucIEStart
[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL
1066 && i4InfoElemLen
<= i4TotalIeLen
) {
1067 *ppucDesiredIE
= &pucIEStart
[0];
1071 /* check desired EID */
1072 /* Select next information element. */
1073 i4TotalIeLen
-= i4InfoElemLen
;
1074 pucIEStart
+= i4InfoElemLen
;
1078 } /* wextSrchDesiredAdvProtocolIE */
1080 /*----------------------------------------------------------------------------*/
1082 * \brief Find the desired Roaming Consortium Information Element according to desiredElemID.
1084 * \param[in] pucIEStart IE starting address.
1085 * \param[in] i4TotalIeLen Total length of all the IE.
1086 * \param[in] ucDesiredElemId Desired element ID.
1087 * \param[out] ppucDesiredIE Pointer to the desired IE.
1089 * \retval TRUE Find the desired IE.
1090 * \retval FALSE Desired IE not found.
1094 /*----------------------------------------------------------------------------*/
1096 wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart
,
1097 IN INT_32 i4TotalIeLen
, OUT PUINT_8
* ppucDesiredIE
)
1099 INT_32 i4InfoElemLen
;
1102 ASSERT(ppucDesiredIE
);
1104 while (i4TotalIeLen
>= 2) {
1105 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1107 if (pucIEStart
[0] == ELEM_ID_ROAMING_CONSORTIUM
&& i4InfoElemLen
<= i4TotalIeLen
) {
1108 *ppucDesiredIE
= &pucIEStart
[0];
1112 /* check desired EID */
1113 /* Select next information element. */
1114 i4TotalIeLen
-= i4InfoElemLen
;
1115 pucIEStart
+= i4InfoElemLen
;
1119 } /* wextSrchDesiredRoamingConsortiumIE */
1121 #endif /* CFG_SUPPORT_PASSPOINT */
1124 /*----------------------------------------------------------------------------*/
1126 * \brief Find the desired WPS Information Element according to desiredElemID.
1128 * \param[in] pucIEStart IE starting address.
1129 * \param[in] i4TotalIeLen Total length of all the IE.
1130 * \param[in] ucDesiredElemId Desired element ID.
1131 * \param[out] ppucDesiredIE Pointer to the desired IE.
1133 * \retval TRUE Find the desired IE.
1134 * \retval FALSE Desired IE not found.
1138 /*----------------------------------------------------------------------------*/
1140 wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart
,
1141 IN INT_32 i4TotalIeLen
, IN UINT_8 ucDesiredElemId
, OUT PUINT_8
* ppucDesiredIE
)
1143 INT_32 i4InfoElemLen
;
1146 ASSERT(ppucDesiredIE
);
1148 while (i4TotalIeLen
>= 2) {
1149 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1151 if (pucIEStart
[0] == ucDesiredElemId
&& i4InfoElemLen
<= i4TotalIeLen
) {
1152 if (ucDesiredElemId
!= 0xDD) {
1154 *ppucDesiredIE
= &pucIEStart
[0];
1157 /* EID == 0xDD, check WPS IE */
1158 if (pucIEStart
[1] >= 4) {
1159 if (memcmp(&pucIEStart
[2], "\x00\x50\xf2\x04", 4) == 0) {
1160 *ppucDesiredIE
= &pucIEStart
[0];
1163 } /* check WPS IE length */
1164 } /* check EID == 0xDD */
1167 /* check desired EID */
1168 /* Select next information element. */
1169 i4TotalIeLen
-= i4InfoElemLen
;
1170 pucIEStart
+= i4InfoElemLen
;
1174 } /* parseSearchDesiredWPSIE */
1178 /*----------------------------------------------------------------------------*/
1180 * \brief Get the name of the protocol used on the air.
1182 * \param[in] prDev Net device requested.
1183 * \param[in] prIwrInfo NULL.
1184 * \param[out] pcName Buffer to store protocol name string
1185 * \param[in] pcExtra NULL.
1187 * \retval 0 For success.
1189 * \note If netif_carrier_ok, protocol name is returned;
1190 * otherwise, "disconnected" is returned.
1192 /*----------------------------------------------------------------------------*/
1194 wext_get_name(IN
struct net_device
*prNetDev
,
1195 IN
struct iw_request_info
*prIwrInfo
, OUT
char *pcName
, IN
char *pcExtra
)
1197 ENUM_PARAM_NETWORK_TYPE_T eNetWorkType
;
1199 P_GLUE_INFO_T prGlueInfo
= NULL
;
1200 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1201 UINT_32 u4BufLen
= 0;
1205 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcName
)) {
1208 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1210 if (netif_carrier_ok(prNetDev
)) {
1212 rStatus
= kalIoctl(prGlueInfo
,
1213 wlanoidQueryNetworkTypeInUse
,
1215 sizeof(eNetWorkType
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
1217 switch (eNetWorkType
) {
1218 case PARAM_NETWORK_TYPE_DS
:
1219 strcpy(pcName
, "IEEE 802.11b");
1221 case PARAM_NETWORK_TYPE_OFDM24
:
1222 strcpy(pcName
, "IEEE 802.11bgn");
1224 case PARAM_NETWORK_TYPE_AUTOMODE
:
1225 case PARAM_NETWORK_TYPE_OFDM5
:
1226 strcpy(pcName
, "IEEE 802.11abgn");
1228 case PARAM_NETWORK_TYPE_FH
:
1230 strcpy(pcName
, "IEEE 802.11");
1234 strcpy(pcName
, "Disconnected");
1238 } /* wext_get_name */
1240 /*----------------------------------------------------------------------------*/
1242 * \brief To set the operating channel in the wireless device.
1244 * \param[in] prDev Net device requested.
1245 * \param[in] prIwrInfo NULL
1246 * \param[in] prFreq Buffer to store frequency information
1247 * \param[in] pcExtra NULL
1249 * \retval 0 For success.
1250 * \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS.
1251 * \retval -EINVAL Invalid channel frequency.
1253 * \note If infrastructure mode is IBSS, new channel frequency is set to device.
1254 * The range of channel number depends on different regulatory domain.
1256 /*----------------------------------------------------------------------------*/
1258 wext_set_freq(IN
struct net_device
*prNetDev
,
1259 IN
struct iw_request_info
*prIwReqInfo
, IN
struct iw_freq
*prIwFreq
, IN
char *pcExtra
)
1263 UINT_32 u4ChnlFreq
; /* Store channel or frequency information */
1265 P_GLUE_INFO_T prGlueInfo
= NULL
;
1266 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1267 UINT_32 u4BufLen
= 0;
1271 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prIwFreq
)) {
1274 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1277 printk("set m:%d, e:%d, i:%d, flags:%d\n",
1278 prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags);
1281 /* If setting by frequency, convert to a channel */
1282 if ((prIwFreq
->e
== 1) && (prIwFreq
->m
>= (int)2.412e8
) && (prIwFreq
->m
<= (int)2.484e8
)) {
1284 /* Change to KHz format */
1285 u4ChnlFreq
= (UINT_32
) (prIwFreq
->m
/ (KILO
/ 10));
1287 rStatus
= kalIoctl(prGlueInfo
,
1288 wlanoidSetFrequency
,
1289 &u4ChnlFreq
, sizeof(u4ChnlFreq
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
1291 if (WLAN_STATUS_SUCCESS
!= rStatus
) {
1295 /* Setting by channel number */
1296 else if ((prIwFreq
->m
> KILO
) || (prIwFreq
->e
> 0)) {
1299 /* Change to channel number format */
1300 u4ChnlFreq
= (UINT_32
) prIwFreq
->m
;
1302 rStatus
= kalIoctl(prGlueInfo
,
1304 &u4ChnlFreq
, sizeof(u4ChnlFreq
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
1309 if (WLAN_STATUS_SUCCESS
!= rStatus
) {
1318 } /* wext_set_freq */
1321 /*----------------------------------------------------------------------------*/
1323 * \brief To get the operating channel in the wireless device.
1325 * \param[in] prDev Net device requested.
1326 * \param[in] prIwrInfo NULL.
1327 * \param[out] prFreq Buffer to store frequency information.
1328 * \param[in] pcExtra NULL.
1330 * \retval 0 If netif_carrier_ok.
1331 * \retval -ENOTCONN Otherwise
1333 * \note If netif_carrier_ok, channel frequency information is stored in pFreq.
1335 /*----------------------------------------------------------------------------*/
1337 wext_get_freq(IN
struct net_device
*prNetDev
,
1338 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_freq
*prIwFreq
, IN
char *pcExtra
)
1340 UINT_32 u4Channel
= 0;
1343 P_GLUE_INFO_T prGlueInfo
= NULL
;
1344 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1345 UINT_32 u4BufLen
= 0;
1349 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prIwFreq
)) {
1352 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1354 /* GeorgeKuo: TODO skip checking in IBSS mode */
1355 if (!netif_carrier_ok(prNetDev
)) {
1359 rStatus
= kalIoctl(prGlueInfo
,
1360 wlanoidQueryFrequency
,
1361 &u4Channel
, sizeof(u4Channel
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
1363 prIwFreq
->m
= (int)u4Channel
; /* freq in KHz */
1368 } /* wext_get_freq */
1371 /*----------------------------------------------------------------------------*/
1373 * \brief To set operating mode.
1375 * \param[in] prDev Net device requested.
1376 * \param[in] prIwrInfo NULL.
1377 * \param[in] pu4Mode Pointer to new operation mode.
1378 * \param[in] pcExtra NULL.
1380 * \retval 0 For success.
1381 * \retval -EOPNOTSUPP If new mode is not supported.
1383 * \note Device will run in new operation mode if it is valid.
1385 /*----------------------------------------------------------------------------*/
1387 wext_set_mode(IN
struct net_device
*prNetDev
,
1388 IN
struct iw_request_info
*prIwReqInfo
, IN
unsigned int *pu4Mode
, IN
char *pcExtra
)
1390 ENUM_PARAM_OP_MODE_T eOpMode
;
1392 P_GLUE_INFO_T prGlueInfo
= NULL
;
1393 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1394 UINT_32 u4BufLen
= 0;
1398 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pu4Mode
)) {
1401 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1405 eOpMode
= NET_TYPE_AUTO_SWITCH
;
1409 eOpMode
= NET_TYPE_IBSS
;
1413 eOpMode
= NET_TYPE_INFRA
;
1417 DBGLOG(INIT
, INFO
, ("%s(): Set UNSUPPORTED Mode = %d.\n", __func__
, *pu4Mode
));
1421 /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */
1423 rStatus
= kalIoctl(prGlueInfo
,
1424 wlanoidSetInfrastructureMode
,
1425 &eOpMode
, sizeof(eOpMode
), FALSE
, FALSE
, TRUE
, &u4BufLen
);
1428 /* after set operation mode, key table are cleared */
1430 /* reset wpa info */
1431 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
1432 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= 0;
1433 prGlueInfo
->rWpaInfo
.u4CipherGroup
= IW_AUTH_CIPHER_NONE
;
1434 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= IW_AUTH_CIPHER_NONE
;
1435 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
1436 #if CFG_SUPPORT_802_11W
1437 prGlueInfo
->rWpaInfo
.u4Mfp
= IW_AUTH_MFP_DISABLED
;
1441 } /* wext_set_mode */
1443 /*----------------------------------------------------------------------------*/
1445 * \brief To get operating mode.
1447 * \param[in] prNetDev Net device requested.
1448 * \param[in] prIwReqInfo NULL.
1449 * \param[out] pu4Mode Buffer to store operating mode information.
1450 * \param[in] pcExtra NULL.
1452 * \retval 0 If data is valid.
1453 * \retval -EINVAL Otherwise.
1455 * \note If netif_carrier_ok, operating mode information is stored in pu4Mode.
1457 /*----------------------------------------------------------------------------*/
1459 wext_get_mode(IN
struct net_device
*prNetDev
,
1460 IN
struct iw_request_info
*prIwReqInfo
, OUT
unsigned int *pu4Mode
, IN
char *pcExtra
)
1462 ENUM_PARAM_OP_MODE_T eOpMode
;
1464 P_GLUE_INFO_T prGlueInfo
= NULL
;
1465 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1466 UINT_32 u4BufLen
= 0;
1470 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pu4Mode
)) {
1473 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1475 rStatus
= kalIoctl(prGlueInfo
,
1476 wlanoidQueryInfrastructureMode
,
1477 &eOpMode
, sizeof(eOpMode
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
1483 *pu4Mode
= IW_MODE_ADHOC
;
1486 case NET_TYPE_INFRA
:
1487 *pu4Mode
= IW_MODE_INFRA
;
1490 case NET_TYPE_AUTO_SWITCH
:
1491 *pu4Mode
= IW_MODE_AUTO
;
1495 DBGLOG(INIT
, INFO
, ("%s(): Get UNKNOWN Mode.\n", __func__
));
1500 } /* wext_get_mode */
1502 /*----------------------------------------------------------------------------*/
1504 * \brief To get the valid range for each configurable STA setting value.
1506 * \param[in] prDev Net device requested.
1507 * \param[in] prIwrInfo NULL.
1508 * \param[in] prData Pointer to iw_point structure, not used.
1509 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1510 * function, wext_support_ioctl() or ioctl_standard_call() in
1513 * \retval 0 If data is valid.
1515 * \note The extra buffer (pcExtra) is filled with information from driver.
1517 /*----------------------------------------------------------------------------*/
1519 wext_get_range(IN
struct net_device
*prNetDev
,
1520 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_point
*prData
, OUT
char *pcExtra
)
1522 struct iw_range
*prRange
= NULL
;
1523 PARAM_RATES_EX aucSuppRate
= { 0 }; /* data buffers */
1526 P_GLUE_INFO_T prGlueInfo
= NULL
;
1527 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1528 UINT_32 u4BufLen
= 0;
1532 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcExtra
)) {
1535 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1537 prRange
= (struct iw_range
*)pcExtra
;
1539 memset(prRange
, 0, sizeof(*prRange
));
1540 prRange
->throughput
= 20000000; /* 20Mbps */
1541 prRange
->min_nwid
= 0; /* not used */
1542 prRange
->max_nwid
= 0; /* not used */
1544 /* scan_capa not implemented */
1546 /* event_capa[6]: kernel + driver capabilities */
1547 prRange
->event_capa
[0] = (IW_EVENT_CAPA_K_0
| IW_EVENT_CAPA_MASK(SIOCGIWAP
)
1548 | IW_EVENT_CAPA_MASK(SIOCGIWSCAN
)
1549 /* can't display meaningful string in iwlist
1550 | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW)
1551 | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)
1552 | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE)
1553 | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND)
1556 prRange
->event_capa
[1] = IW_EVENT_CAPA_K_1
;
1558 /* report 2.4G channel and frequency only */
1559 prRange
->num_channels
= (__u16
) NUM_CHANNELS
;
1560 prRange
->num_frequency
= (__u8
) NUM_CHANNELS
;
1561 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
1562 /* iwlib takes this number as channel number */
1563 prRange
->freq
[i
].i
= i
+ 1;
1564 prRange
->freq
[i
].m
= channel_freq
[i
];
1565 prRange
->freq
[i
].e
= 6; /* Values in table in MHz */
1568 rStatus
= kalIoctl(prGlueInfo
,
1569 wlanoidQuerySupportedRates
,
1570 &aucSuppRate
, sizeof(aucSuppRate
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
1574 for (i
= 0; i
< IW_MAX_BITRATES
&& i
< PARAM_MAX_LEN_RATES_EX
; i
++) {
1575 if (aucSuppRate
[i
] == 0) {
1578 prRange
->bitrate
[i
] = (aucSuppRate
[i
] & 0x7F) * 500000; /* 0.5Mbps */
1580 prRange
->num_bitrates
= i
;
1582 prRange
->min_rts
= 0;
1583 prRange
->max_rts
= 2347;
1584 prRange
->min_frag
= 256;
1585 prRange
->max_frag
= 2346;
1587 prRange
->min_pmp
= 0; /* power management by driver */
1588 prRange
->max_pmp
= 0; /* power management by driver */
1589 prRange
->min_pmt
= 0; /* power management by driver */
1590 prRange
->max_pmt
= 0; /* power management by driver */
1591 prRange
->pmp_flags
= IW_POWER_RELATIVE
; /* pm default flag */
1592 prRange
->pmt_flags
= IW_POWER_ON
; /* pm timeout flag */
1593 prRange
->pm_capa
= IW_POWER_ON
; /* power management by driver */
1595 prRange
->encoding_size
[0] = 5; /* wep40 */
1596 prRange
->encoding_size
[1] = 16; /* tkip */
1597 prRange
->encoding_size
[2] = 16; /* ckip */
1598 prRange
->encoding_size
[3] = 16; /* ccmp */
1599 prRange
->encoding_size
[4] = 13; /* wep104 */
1600 prRange
->encoding_size
[5] = 16; /* wep128 */
1601 prRange
->num_encoding_sizes
= 6;
1602 prRange
->max_encoding_tokens
= 6; /* token? */
1604 #if WIRELESS_EXT < 17
1605 prRange
->txpower_capa
= 0x0002; /* IW_TXPOW_RELATIVE */
1607 prRange
->txpower_capa
= IW_TXPOW_RELATIVE
;
1609 prRange
->num_txpower
= 5;
1610 prRange
->txpower
[0] = 0; /* minimum */
1611 prRange
->txpower
[1] = 25; /* 25% */
1612 prRange
->txpower
[2] = 50; /* 50% */
1613 prRange
->txpower
[3] = 100; /* 100% */
1615 prRange
->we_version_compiled
= WIRELESS_EXT
;
1616 prRange
->we_version_source
= WIRELESS_EXT
;
1618 prRange
->retry_capa
= IW_RETRY_LIMIT
;
1619 prRange
->retry_flags
= IW_RETRY_LIMIT
;
1620 prRange
->min_retry
= 7;
1621 prRange
->max_retry
= 7;
1622 prRange
->r_time_flags
= IW_RETRY_ON
;
1623 prRange
->min_r_time
= 0;
1624 prRange
->max_r_time
= 0;
1626 /* signal strength and link quality */
1627 /* Just define range here, reporting value moved to wext_get_stats() */
1628 prRange
->sensitivity
= -83; /* fixed value */
1629 prRange
->max_qual
.qual
= 100; /* max 100% */
1630 prRange
->max_qual
.level
= (__u8
) (0x100 - 0); /* max 0 dbm */
1631 prRange
->max_qual
.noise
= (__u8
) (0x100 - 0); /* max 0 dbm */
1634 #if WIRELESS_EXT > 17
1635 prRange
->enc_capa
= IW_ENC_CAPA_WPA
|
1636 IW_ENC_CAPA_WPA2
| IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
1639 /* min_pms; Minimal PM saving */
1640 /* max_pms; Maximal PM saving */
1641 /* pms_flags; How to decode max/min PM saving */
1643 /* modul_capa; IW_MODUL_* bit field */
1644 /* bitrate_capa; Types of bitrates supported */
1647 } /* wext_get_range */
1650 /*----------------------------------------------------------------------------*/
1652 * \brief To set BSSID of AP to connect.
1654 * \param[in] prDev Net device requested.
1655 * \param[in] prIwrInfo NULL.
1656 * \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID.
1657 * \param[in] pcExtra NULL.
1659 * \retval 0 For success.
1661 * \note Desired AP's BSSID is set to driver.
1663 /*----------------------------------------------------------------------------*/
1665 wext_set_ap(IN
struct net_device
*prDev
,
1666 IN
struct iw_request_info
*prIwrInfo
, IN
struct sockaddr
*prAddr
, IN
char *pcExtra
)
1672 /*----------------------------------------------------------------------------*/
1674 * \brief To get AP MAC address.
1676 * \param[in] prDev Net device requested.
1677 * \param[in] prIwrInfo NULL.
1678 * \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID.
1679 * \param[in] pcExtra NULL.
1681 * \retval 0 If netif_carrier_ok.
1682 * \retval -ENOTCONN Otherwise.
1684 * \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data.
1686 /*----------------------------------------------------------------------------*/
1688 wext_get_ap(IN
struct net_device
*prNetDev
,
1689 IN
struct iw_request_info
*prIwrInfo
, OUT
struct sockaddr
*prAddr
, IN
char *pcExtra
)
1691 P_GLUE_INFO_T prGlueInfo
= NULL
;
1692 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1693 UINT_32 u4BufLen
= 0;
1697 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prAddr
)) {
1700 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1702 /* if (!netif_carrier_ok(prNetDev)) { */
1703 /* return -ENOTCONN; */
1706 if (prGlueInfo
->eParamMediaStateIndicated
== PARAM_MEDIA_STATE_DISCONNECTED
) {
1707 memset(prAddr
, 0, 6);
1711 rStatus
= kalIoctl(prGlueInfo
,
1713 prAddr
->sa_data
, ETH_ALEN
, TRUE
, FALSE
, FALSE
, &u4BufLen
);
1718 /*----------------------------------------------------------------------------*/
1720 * \brief To set mlme operation request.
1722 * \param[in] prDev Net device requested.
1723 * \param[in] prIwrInfo NULL.
1724 * \param[in] prData Pointer of iw_point header.
1725 * \param[in] pcExtra Pointer to iw_mlme structure mlme request information.
1727 * \retval 0 For success.
1728 * \retval -EOPNOTSUPP unsupported IW_MLME_ command.
1729 * \retval -EINVAL Set MLME Fail, different bssid.
1731 * \note Driver will start mlme operation if valid.
1733 /*----------------------------------------------------------------------------*/
1735 wext_set_mlme(IN
struct net_device
*prNetDev
,
1736 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_point
*prData
, IN
char *pcExtra
)
1738 struct iw_mlme
*prMlme
= NULL
;
1741 P_GLUE_INFO_T prGlueInfo
= NULL
;
1742 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1743 UINT_32 u4BufLen
= 0;
1747 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcExtra
)) {
1750 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1752 prMlme
= (struct iw_mlme
*)pcExtra
;
1753 if (prMlme
->cmd
== IW_MLME_DEAUTH
|| prMlme
->cmd
== IW_MLME_DISASSOC
) {
1754 if (!netif_carrier_ok(prNetDev
)) {
1756 ("[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"));
1760 rStatus
= kalIoctl(prGlueInfo
,
1761 wlanoidSetDisassociate
, NULL
, 0, FALSE
, FALSE
, TRUE
, &u4BufLen
);
1764 DBGLOG(INIT
, INFO
, ("[wifi] unsupported IW_MLME_ command :%d\n", prMlme
->cmd
));
1767 } /* wext_set_mlme */
1769 /*----------------------------------------------------------------------------*/
1771 * \brief To issue scan request.
1773 * \param[in] prDev Net device requested.
1774 * \param[in] prIwrInfo NULL.
1775 * \param[in] prData NULL.
1776 * \param[in] pcExtra NULL.
1778 * \retval 0 For success.
1779 * \retval -EFAULT Tx power is off.
1781 * \note Device will start scanning.
1783 /*----------------------------------------------------------------------------*/
1785 wext_set_scan(IN
struct net_device
*prNetDev
,
1786 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_scan_req
*prIwScanReq
, IN
char *pcExtra
)
1788 P_GLUE_INFO_T prGlueInfo
= NULL
;
1789 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1790 UINT_32 u4BufLen
= 0;
1794 if (FALSE
== GLUE_CHK_DEV(prNetDev
)) {
1797 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1799 #if WIRELESS_EXT > 17
1802 essid_len
= prIwScanReq
->essid_len
;
1805 init_completion(&prGlueInfo
->rScanComp
);
1807 /* TODO: parse flags and issue different scan requests? */
1809 rStatus
= kalIoctl(prGlueInfo
,
1810 wlanoidSetBssidListScan
,
1811 pcExtra
, essid_len
, FALSE
, FALSE
, FALSE
, &u4BufLen
);
1813 /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */
1814 /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */
1818 } /* wext_set_scan */
1821 /*----------------------------------------------------------------------------*/
1823 * \brief To write the ie to buffer
1826 /*----------------------------------------------------------------------------*/
1827 static inline int snprintf_hex(char *buf
, size_t buf_size
, const u8
*data
, size_t len
)
1830 char *pos
= buf
, *end
= buf
+ buf_size
;
1836 for (i
= 0; i
< len
; i
++) {
1837 ret
= snprintf(pos
, end
- pos
, "%02x", data
[i
]);
1838 if (ret
< 0 || ret
>= end
- pos
) {
1849 /*----------------------------------------------------------------------------*/
1851 * \brief To get scan results, transform results from driver's format to WE's.
1853 * \param[in] prDev Net device requested.
1854 * \param[in] prIwrInfo NULL.
1855 * \param[out] prData Pointer to iw_point structure, pData->length is the size of
1856 * pcExtra buffer before used, and is updated after filling scan
1858 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1859 * function, wext_support_ioctl() or ioctl_standard_call() in
1862 * \retval 0 For success.
1863 * \retval -ENOMEM If dynamic memory allocation fail.
1864 * \retval -E2BIG Invalid length.
1866 * \note Scan results is filled into pcExtra buffer, data size is updated in
1869 /*----------------------------------------------------------------------------*/
1871 wext_get_scan(IN
struct net_device
*prNetDev
,
1872 IN
struct iw_request_info
*prIwrInfo
,
1873 IN OUT
struct iw_point
*prData
, IN
char *pcExtra
)
1877 P_PARAM_BSSID_LIST_EX_T prList
= NULL
;
1878 P_PARAM_BSSID_EX_T prBss
= NULL
;
1879 P_PARAM_VARIABLE_IE_T prDesiredIE
= NULL
;
1880 struct iw_event iwEvent
; /* local iw_event buffer */
1882 /* write pointer of extra buffer */
1884 /* pointer to the end of last full entry in extra buffer */
1885 char *pcValidEntryEnd
= NULL
;
1886 char *pcEnd
= NULL
; /* end of extra buffer */
1888 UINT_32 u4AllocBufLen
= 0;
1890 /* arrange rate information */
1891 UINT_32 u4HighestRate
= 0;
1892 char aucRatesBuf
[64];
1898 P_GLUE_INFO_T prGlueInfo
= NULL
;
1899 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1900 UINT_32 u4BufLen
= 0;
1905 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prData
, pcExtra
)) {
1908 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1910 /* Initialize local variables */
1912 pcValidEntryEnd
= pcExtra
;
1913 pcEnd
= pcExtra
+ prData
->length
; /* end of extra buffer */
1915 /* Allocate another query buffer with the same size of extra buffer */
1916 u4AllocBufLen
= prData
->length
;
1917 prList
= kalMemAlloc(u4AllocBufLen
, VIR_MEM_TYPE
);
1918 if (prList
== NULL
) {
1919 DBGLOG(INIT
, INFO
, ("[wifi] no memory for scan list:%d\n", prData
->length
));
1923 prList
->u4NumberOfItems
= 0;
1925 /* wait scan done */
1926 /* printk ("wait for scan results\n"); */
1927 /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */
1929 rStatus
= kalIoctl(prGlueInfo
,
1930 wlanoidQueryBssidList
,
1931 prList
, u4AllocBufLen
, TRUE
, FALSE
, FALSE
, &u4BufLen
);
1933 if (rStatus
== WLAN_STATUS_INVALID_LENGTH
) {
1934 /* Buffer length is not large enough. */
1935 /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */
1937 #if WIRELESS_EXT >= 17
1938 /* This feature is supported in WE-17 or above, limited by iwlist.
1939 ** Return -E2BIG and iwlist will request again with a larger buffer.
1942 /* Update length to give application a hint on result length */
1943 prData
->length
= (__u16
) u4BufLen
;
1946 /* Realloc a larger query buffer here, but don't write too much to extra
1947 ** buffer when filling it later.
1949 kalMemFree(prList
, VIR_MEM_TYPE
, u4AllocBufLen
);
1951 u4AllocBufLen
= u4BufLen
;
1952 prList
= kalMemAlloc(u4AllocBufLen
, VIR_MEM_TYPE
);
1953 if (prList
== NULL
) {
1955 ("[wifi] no memory for larger scan list :%ld\n", u4BufLen
));
1959 prList
->NumberOfItems
= 0;
1961 rStatus
= kalIoctl(prGlueInfo
,
1962 wlanoidQueryBssidList
,
1963 prList
, u4AllocBufLen
, TRUE
, FALSE
, FALSE
, &u4BufLen
);
1965 if (rStatus
== WLAN_STATUS_INVALID_LENGTH
) {
1967 ("[wifi] larger buf:%d result:%ld\n", u4AllocBufLen
, u4BufLen
));
1969 prData
->length
= (__u16
) u4BufLen
;
1972 #endif /* WIRELESS_EXT >= 17 */
1977 if (prList
->u4NumberOfItems
> CFG_MAX_NUM_BSS_LIST
) {
1978 DBGLOG(INIT
, INFO
, ("[wifi] strange scan result count:%ld\n",
1979 prList
->u4NumberOfItems
));
1983 /* Copy required data from pList to pcExtra */
1984 prBss
= &prList
->arBssid
[0]; /* set to the first entry */
1985 for (i
= 0; i
< prList
->u4NumberOfItems
; ++i
) {
1987 iwEvent
.cmd
= SIOCGIWAP
;
1988 iwEvent
.len
= IW_EV_ADDR_LEN
;
1989 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
1991 iwEvent
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1992 memcpy(iwEvent
.u
.ap_addr
.sa_data
, prBss
->arMacAddress
, ETH_ALEN
);
1993 memcpy(pcCur
, &iwEvent
, IW_EV_ADDR_LEN
);
1994 pcCur
+= IW_EV_ADDR_LEN
;
1997 iwEvent
.cmd
= SIOCGIWESSID
;
1998 /* Modification to user space pointer(essid.pointer) is not needed. */
1999 iwEvent
.u
.essid
.length
= (__u16
) prBss
->rSsid
.u4SsidLen
;
2000 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.essid
.length
;
2002 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2004 iwEvent
.u
.essid
.flags
= 1;
2005 iwEvent
.u
.essid
.pointer
= NULL
;
2007 #if WIRELESS_EXT <= 18
2008 memcpy(pcCur
, &iwEvent
, iwEvent
.len
);
2010 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2011 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2012 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2014 memcpy(pcCur
+ IW_EV_POINT_LEN
, prBss
->rSsid
.aucSsid
, iwEvent
.u
.essid
.length
);
2015 pcCur
+= iwEvent
.len
;
2017 iwEvent
.cmd
= SIOCGIWFREQ
;
2018 iwEvent
.len
= IW_EV_FREQ_LEN
;
2019 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2021 iwEvent
.u
.freq
.m
= prBss
->rConfiguration
.u4DSConfig
;
2022 iwEvent
.u
.freq
.e
= 3; /* (in KHz) */
2023 iwEvent
.u
.freq
.i
= 0;
2024 memcpy(pcCur
, &iwEvent
, IW_EV_FREQ_LEN
);
2025 pcCur
+= IW_EV_FREQ_LEN
;
2027 /* Operation Mode */
2028 iwEvent
.cmd
= SIOCGIWMODE
;
2029 iwEvent
.len
= IW_EV_UINT_LEN
;
2030 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2032 if (prBss
->eOpMode
== NET_TYPE_IBSS
) {
2033 iwEvent
.u
.mode
= IW_MODE_ADHOC
;
2034 } else if (prBss
->eOpMode
== NET_TYPE_INFRA
) {
2035 iwEvent
.u
.mode
= IW_MODE_INFRA
;
2037 iwEvent
.u
.mode
= IW_MODE_AUTO
;
2039 memcpy(pcCur
, &iwEvent
, IW_EV_UINT_LEN
);
2040 pcCur
+= IW_EV_UINT_LEN
;
2043 iwEvent
.cmd
= IWEVQUAL
;
2044 iwEvent
.len
= IW_EV_QUAL_LEN
;
2045 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2047 iwEvent
.u
.qual
.qual
= 0; /* Quality not available now */
2048 /* -100 < Rssi < -10, normalized by adding 0x100 */
2049 iwEvent
.u
.qual
.level
= 0x100 + prBss
->rRssi
;
2050 iwEvent
.u
.qual
.noise
= 0; /* Noise not available now */
2051 iwEvent
.u
.qual
.updated
= IW_QUAL_QUAL_INVALID
| IW_QUAL_LEVEL_UPDATED
2052 | IW_QUAL_NOISE_INVALID
;
2053 memcpy(pcCur
, &iwEvent
, IW_EV_QUAL_LEN
);
2054 pcCur
+= IW_EV_QUAL_LEN
;
2057 iwEvent
.cmd
= SIOCGIWENCODE
;
2058 iwEvent
.len
= IW_EV_POINT_LEN
;
2059 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2061 iwEvent
.u
.data
.pointer
= NULL
;
2062 iwEvent
.u
.data
.flags
= 0;
2063 iwEvent
.u
.data
.length
= 0;
2064 if (!prBss
->u4Privacy
) {
2065 iwEvent
.u
.data
.flags
|= IW_ENCODE_DISABLED
;
2067 #if WIRELESS_EXT <= 18
2068 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2070 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2071 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2072 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2074 pcCur
+= IW_EV_POINT_LEN
;
2076 /* rearrange rate information */
2077 u4BufIndex
= sprintf(aucRatesBuf
, "Rates (Mb/s):");
2079 for (j
= 0; j
< PARAM_MAX_LEN_RATES_EX
; ++j
) {
2080 UINT_8 curRate
= prBss
->rSupportedRates
[j
] & 0x7F;
2085 if (curRate
> u4HighestRate
) {
2086 u4HighestRate
= curRate
;
2089 if (curRate
== RATE_5_5M
) {
2090 u4BufIndex
+= sprintf(aucRatesBuf
+ u4BufIndex
, " 5.5");
2092 u4BufIndex
+= sprintf(aucRatesBuf
+ u4BufIndex
, " %d", curRate
/ 2);
2095 if (u4BufIndex
> sizeof(aucRatesBuf
)) {
2096 /* printk("rate info too long\n"); */
2101 /* Report Highest Rates */
2102 iwEvent
.cmd
= SIOCGIWRATE
;
2103 iwEvent
.len
= IW_EV_PARAM_LEN
;
2104 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2106 iwEvent
.u
.bitrate
.value
= u4HighestRate
* 500000;
2107 iwEvent
.u
.bitrate
.fixed
= 0;
2108 iwEvent
.u
.bitrate
.disabled
= 0;
2109 iwEvent
.u
.bitrate
.flags
= 0;
2110 memcpy(pcCur
, &iwEvent
, iwEvent
.len
);
2111 pcCur
+= iwEvent
.len
;
2113 #if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */
2114 /* Report Residual Rates */
2115 iwEvent
.cmd
= IWEVCUSTOM
;
2116 iwEvent
.u
.data
.length
= u4BufIndex
;
2117 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2118 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2120 iwEvent
.u
.data
.flags
= 0;
2121 #if WIRELESS_EXT <= 18
2122 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2124 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2125 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2126 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2128 memcpy(pcCur
+ IW_EV_POINT_LEN
, aucRatesBuf
, u4BufIndex
);
2129 pcCur
+= iwEvent
.len
;
2130 #endif /* WIRELESS_EXT >= 15 */
2133 if (wextSrchDesiredWPAIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2134 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2135 0xDD, (PUINT_8
*) &prDesiredIE
)) {
2136 iwEvent
.cmd
= IWEVGENIE
;
2137 iwEvent
.u
.data
.flags
= 1;
2138 iwEvent
.u
.data
.length
= 2 + (__u16
) prDesiredIE
->ucLength
;
2139 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2140 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2142 #if WIRELESS_EXT <= 18
2143 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2145 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2146 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2147 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2149 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2150 pcCur
+= iwEvent
.len
;
2152 #if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */
2153 if (wextSrchDesiredWPSIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2154 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2155 0xDD, (PUINT_8
*) &prDesiredIE
)) {
2156 iwEvent
.cmd
= IWEVGENIE
;
2157 iwEvent
.u
.data
.flags
= 1;
2158 iwEvent
.u
.data
.length
= 2 + (__u16
) prDesiredIE
->ucLength
;
2159 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2160 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2162 #if WIRELESS_EXT <= 18
2163 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2165 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2166 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2167 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2169 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2170 pcCur
+= iwEvent
.len
;
2175 /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */
2176 /* pBss->IEs starts from timestamp */
2177 if (wextSrchDesiredWPAIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2178 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2179 0x30, (PUINT_8
*) &prDesiredIE
)) {
2181 iwEvent
.cmd
= IWEVGENIE
;
2182 iwEvent
.u
.data
.flags
= 1;
2183 iwEvent
.u
.data
.length
= 2 + (__u16
) prDesiredIE
->ucLength
;
2184 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2185 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2187 #if WIRELESS_EXT <= 18
2188 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2190 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2191 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2192 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2194 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2195 pcCur
+= iwEvent
.len
;
2197 #if CFG_SUPPORT_WAPI /* Android+ */
2198 if (wextSrchDesiredWAPIIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2199 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2200 (PUINT_8
*) &prDesiredIE
)) {
2203 iwEvent
.cmd
= IWEVGENIE
;
2204 iwEvent
.u
.data
.flags
= 1;
2205 iwEvent
.u
.data
.length
= 2 + (__u16
) prDesiredIE
->ucLength
;
2206 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2207 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2209 #if WIRELESS_EXT <= 18
2210 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2212 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2213 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2214 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2216 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2217 pcCur
+= iwEvent
.len
;
2219 iwEvent
.cmd
= IWEVCUSTOM
;
2220 iwEvent
.u
.data
.length
= (2 + prDesiredIE
->ucLength
) * 2 + 8 /* wapi_ie= */;
2221 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2222 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2224 iwEvent
.u
.data
.flags
= 1;
2226 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2227 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2228 &iwEvent
.u
.data
.length
, sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2230 pcCur
+= (IW_EV_POINT_LEN
);
2232 pcCur
+= sprintf(pcCur
, "wapi_ie=");
2234 snprintf_hex(pcCur
, pcEnd
- pcCur
, (UINT_8
*) prDesiredIE
,
2235 prDesiredIE
->ucLength
+ 2);
2237 pcCur
+= (2 + prDesiredIE
->ucLength
) * 2 /* iwEvent.len */;
2241 /* Complete an entry. Update end of valid entry */
2242 pcValidEntryEnd
= pcCur
;
2243 /* Extract next bss */
2244 prBss
= (P_PARAM_BSSID_EX_T
) ((char *)prBss
+ prBss
->u4Length
);
2247 /* Update valid data length for caller function and upper layer
2250 prData
->length
= (pcValidEntryEnd
- pcExtra
);
2251 /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */
2253 /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */
2256 /* free local query buffer */
2258 kalMemFree(prList
, VIR_MEM_TYPE
, u4AllocBufLen
);
2262 } /* wext_get_scan */
2264 /*----------------------------------------------------------------------------*/
2266 * \brief To set desired network name ESSID.
2268 * \param[in] prDev Net device requested.
2269 * \param[in] prIwrInfo NULL.
2270 * \param[in] prEssid Pointer of iw_point header.
2271 * \param[in] pcExtra Pointer to buffer srtoring essid string.
2273 * \retval 0 If netif_carrier_ok.
2274 * \retval -E2BIG Essid string length is too big.
2275 * \retval -EINVAL pcExtra is null pointer.
2276 * \retval -EFAULT Driver fail to set new essid.
2278 * \note If string lengh is ok, device will try connecting to the new network.
2280 /*----------------------------------------------------------------------------*/
2282 wext_set_essid(IN
struct net_device
*prNetDev
,
2283 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_point
*prEssid
, IN
char *pcExtra
)
2285 PARAM_SSID_T rNewSsid
;
2287 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
2288 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
2290 P_GLUE_INFO_T prGlueInfo
= NULL
;
2291 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2292 UINT_32 u4BufLen
= 0;
2297 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEssid
, pcExtra
)) {
2300 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2302 if (prEssid
->length
> IW_ESSID_MAX_SIZE
) {
2308 if (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_DISABLED
) {
2309 eAuthMode
= (prGlueInfo
->rWpaInfo
.u4AuthAlg
== IW_AUTH_ALG_OPEN_SYSTEM
) ?
2310 AUTH_MODE_OPEN
: AUTH_MODE_AUTO_SWITCH
;
2311 /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */
2312 /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */
2315 switch (prGlueInfo
->rWpaInfo
.u4KeyMgmt
) {
2316 case IW_AUTH_KEY_MGMT_802_1X
:
2318 (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA
) ?
2319 AUTH_MODE_WPA
: AUTH_MODE_WPA2
;
2320 /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */
2321 /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */
2323 case IW_AUTH_KEY_MGMT_PSK
:
2325 (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA
) ?
2326 AUTH_MODE_WPA_PSK
: AUTH_MODE_WPA2_PSK
;
2327 /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */
2328 /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */
2330 #if CFG_SUPPORT_WAPI /* Android+ */
2331 case IW_AUTH_KEY_MGMT_WAPI_PSK
:
2333 case IW_AUTH_KEY_MGMT_WAPI_CERT
:
2337 /* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */
2338 /* case IW_AUTH_KEY_MGMT_WPA_NONE: */
2339 /* eAuthMode = AUTH_MODE_WPA_NONE; */
2340 /* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */
2343 #if CFG_SUPPORT_802_11W
2344 case IW_AUTH_KEY_MGMT_802_1X_SHA256
:
2345 eAuthMode
= AUTH_MODE_WPA2
;
2347 case IW_AUTH_KEY_MGMT_PSK_SHA256
:
2348 eAuthMode
= AUTH_MODE_WPA2_PSK
;
2352 /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */
2353 /* prGlueInfo->rWpaInfo.u4KeyMgmt); */
2354 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
2360 rStatus
= kalIoctl(prGlueInfo
,
2362 &eAuthMode
, sizeof(eAuthMode
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
2364 /* set encryption status */
2365 cipher
= prGlueInfo
->rWpaInfo
.u4CipherGroup
| prGlueInfo
->rWpaInfo
.u4CipherPairwise
;
2366 if (cipher
& IW_AUTH_CIPHER_CCMP
) {
2367 /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */
2368 eEncStatus
= ENUM_ENCRYPTION3_ENABLED
;
2369 } else if (cipher
& IW_AUTH_CIPHER_TKIP
) {
2370 /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */
2371 eEncStatus
= ENUM_ENCRYPTION2_ENABLED
;
2372 } else if (cipher
& (IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
)) {
2373 /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */
2374 eEncStatus
= ENUM_ENCRYPTION1_ENABLED
;
2375 } else if (cipher
& IW_AUTH_CIPHER_NONE
) {
2376 /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */
2377 if (prGlueInfo
->rWpaInfo
.fgPrivacyInvoke
)
2378 eEncStatus
= ENUM_ENCRYPTION1_ENABLED
;
2380 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
2382 /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */
2383 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
2386 rStatus
= kalIoctl(prGlueInfo
,
2387 wlanoidSetEncryptionStatus
,
2388 &eEncStatus
, sizeof(eEncStatus
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
2390 #if WIRELESS_EXT < 21
2391 /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before
2392 ** 2.6.19. Cut the trailing '\0'.
2394 rNewSsid
.u4SsidLen
= (prEssid
->length
) ? prEssid
->length
- 1 : 0;
2396 rNewSsid
.u4SsidLen
= prEssid
->length
;
2398 kalMemCopy(rNewSsid
.aucSsid
, pcExtra
, rNewSsid
.u4SsidLen
);
2401 rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0';
2402 printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid);
2405 if (kalIoctl(prGlueInfo
,
2408 sizeof(PARAM_SSID_T
), FALSE
, FALSE
, TRUE
, &u4BufLen
) != WLAN_STATUS_SUCCESS
) {
2409 /* printk(KERN_WARNING "Fail to set ssid\n"); */
2415 } /* wext_set_essid */
2417 /*----------------------------------------------------------------------------*/
2419 * \brief To get current network name ESSID.
2421 * \param[in] prDev Net device requested.
2422 * \param[in] prIwrInfo NULL.
2423 * \param[in] prEssid Pointer to iw_point structure containing essid information.
2424 * \param[out] pcExtra Pointer to buffer srtoring essid string.
2426 * \retval 0 If netif_carrier_ok.
2427 * \retval -ENOTCONN Otherwise.
2429 * \note If netif_carrier_ok, network essid is stored in pcExtra.
2431 /*----------------------------------------------------------------------------*/
2432 /* static PARAM_SSID_T ssid; */
2434 wext_get_essid(IN
struct net_device
*prNetDev
,
2435 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_point
*prEssid
, OUT
char *pcExtra
)
2437 /* PARAM_SSID_T ssid; */
2439 P_PARAM_SSID_T prSsid
;
2440 P_GLUE_INFO_T prGlueInfo
= NULL
;
2441 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2442 UINT_32 u4BufLen
= 0;
2448 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEssid
, pcExtra
)) {
2451 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2453 /* if (!netif_carrier_ok(prNetDev)) { */
2454 /* return -ENOTCONN; */
2457 prSsid
= kalMemAlloc(sizeof(PARAM_SSID_T
), VIR_MEM_TYPE
);
2463 rStatus
= kalIoctl(prGlueInfo
,
2465 prSsid
, sizeof(PARAM_SSID_T
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
2467 if ((rStatus
== WLAN_STATUS_SUCCESS
) && (prSsid
->u4SsidLen
<= MAX_SSID_LEN
)) {
2468 kalMemCopy(pcExtra
, prSsid
->aucSsid
, prSsid
->u4SsidLen
);
2469 prEssid
->length
= prSsid
->u4SsidLen
;
2473 kalMemFree(prSsid
, VIR_MEM_TYPE
, sizeof(PARAM_SSID_T
));
2476 } /* wext_get_essid */
2481 /*----------------------------------------------------------------------------*/
2483 * \brief To set tx desired bit rate. Three cases here
2484 * iwconfig wlan0 auto -> Set to origianl supported rate set.
2485 * iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate.
2486 * iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps
2488 * \param[in] prNetDev Pointer to the net_device handler.
2489 * \param[in] prIwReqInfo Pointer to the Request Info.
2490 * \param[in] prRate Pointer to the Rate Parameter.
2491 * \param[in] pcExtra Pointer to the extra buffer.
2493 * \retval 0 Update desired rate.
2494 * \retval -EINVAL Wrong parameter
2496 /*----------------------------------------------------------------------------*/
2498 wext_set_rate(IN
struct net_device
*prNetDev
,
2499 IN
struct iw_request_info
*prIwReqInfo
, IN
struct iw_param
*prRate
, IN
char *pcExtra
)
2501 PARAM_RATES_EX aucSuppRate
= { 0 };
2502 PARAM_RATES_EX aucNewRate
= { 0 };
2503 UINT_32 u4NewRateLen
= 0;
2506 P_GLUE_INFO_T prGlueInfo
= NULL
;
2507 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2508 UINT_32 u4BufLen
= 0;
2512 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRate
)) {
2515 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2518 printk("value = %d, fixed = %d, disable = %d, flags = %d\n",
2519 prRate->value, prRate->fixed, prRate->disabled, prRate->flags);
2522 rStatus
= wlanQueryInformation(prGlueInfo
->prAdapter
,
2523 wlanoidQuerySupportedRates
,
2524 &aucSuppRate
, sizeof(aucSuppRate
), &u4BufLen
);
2527 if (prRate
->value
< 0) {
2528 if (prRate
->fixed
== 0) {
2529 /* iwconfig wlan0 rate auto */
2531 /* set full supported rate to device */
2532 /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */
2533 rStatus
= wlanSetInformation(prGlueInfo
->prAdapter
,
2534 wlanoidSetDesiredRates
,
2535 &aucSuppRate
, sizeof(aucSuppRate
), &u4BufLen
);
2538 /* iwconfig wlan0 rate fixed */
2540 /* fix rate to what? DO NOTHING */
2546 aucNewRate
[0] = prRate
->value
/ 500000; /* In unit of 500k */
2548 for (i
= 0; i
< PARAM_MAX_LEN_RATES_EX
; i
++) {
2549 /* check the given value is supported */
2550 if (aucSuppRate
[i
] == 0) {
2554 if (aucNewRate
[0] == aucSuppRate
[i
]) {
2560 if (u4NewRateLen
== 0) {
2561 /* the given value is not supported */
2562 /* return error or use given rate as upper bound? */
2566 if (prRate
->fixed
== 0) {
2567 /* add all rates lower than desired rate */
2568 for (i
= 0; i
< PARAM_MAX_LEN_RATES_EX
; ++i
) {
2569 if (aucSuppRate
[i
] == 0) {
2573 if (aucSuppRate
[i
] < aucNewRate
[0]) {
2574 aucNewRate
[u4NewRateLen
++] = aucSuppRate
[i
];
2579 rStatus
= wlanSetInformation(prGlueInfo
->prAdapter
,
2580 wlanoidSetDesiredRates
,
2581 &aucNewRate
, sizeof(aucNewRate
), &u4BufLen
);
2583 } /* wext_set_rate */
2587 /*----------------------------------------------------------------------------*/
2589 * \brief To get current tx bit rate.
2591 * \param[in] prDev Net device requested.
2592 * \param[in] prIwrInfo NULL.
2593 * \param[out] prRate Pointer to iw_param structure to store current tx rate.
2594 * \param[in] pcExtra NULL.
2596 * \retval 0 If netif_carrier_ok.
2597 * \retval -ENOTCONN Otherwise.
2599 * \note If netif_carrier_ok, current tx rate is stored in pRate.
2601 /*----------------------------------------------------------------------------*/
2603 wext_get_rate(IN
struct net_device
*prNetDev
,
2604 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_param
*prRate
, IN
char *pcExtra
)
2606 P_GLUE_INFO_T prGlueInfo
= NULL
;
2607 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2608 UINT_32 u4BufLen
= 0;
2613 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRate
)) {
2616 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2618 if (!netif_carrier_ok(prNetDev
)) {
2623 rStatus
= kalIoctl(prGlueInfo
,
2624 wlanoidQueryLinkSpeed
,
2625 &u4Rate
, sizeof(u4Rate
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
2627 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
2631 prRate
->value
= u4Rate
* 100; /* u4Rate is in unit of 100bps */
2635 } /* wext_get_rate */
2638 /*----------------------------------------------------------------------------*/
2640 * \brief To set RTS/CTS theshold.
2642 * \param[in] prDev Net device requested.
2643 * \param[in] prIwrInfo NULL.
2644 * \param[in] prRts Pointer to iw_param structure containing rts threshold.
2645 * \param[in] pcExtra NULL.
2647 * \retval 0 For success.
2648 * \retval -EINVAL Given value is out of range.
2650 * \note If given value is valid, device will follow the new setting.
2652 /*----------------------------------------------------------------------------*/
2654 wext_set_rts(IN
struct net_device
*prNetDev
,
2655 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_param
*prRts
, IN
char *pcExtra
)
2657 PARAM_RTS_THRESHOLD u4RtsThresh
;
2659 P_GLUE_INFO_T prGlueInfo
= NULL
;
2660 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2661 UINT_32 u4BufLen
= 0;
2665 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRts
)) {
2668 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2670 if (prRts
->disabled
== 1) {
2672 } else if (prRts
->value
< 0 || prRts
->value
> 2347) {
2675 u4RtsThresh
= (PARAM_RTS_THRESHOLD
) prRts
->value
;
2678 rStatus
= kalIoctl(prGlueInfo
,
2679 wlanoidSetRtsThreshold
,
2680 &u4RtsThresh
, sizeof(u4RtsThresh
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
2684 prRts
->value
= (typeof(prRts
->value
)) u4RtsThresh
;
2685 prRts
->disabled
= (prRts
->value
> 2347) ? 1 : 0;
2689 } /* wext_set_rts */
2691 /*----------------------------------------------------------------------------*/
2693 * \brief To get RTS/CTS theshold.
2695 * \param[in] prDev Net device requested.
2696 * \param[in] prIwrInfo NULL.
2697 * \param[out] prRts Pointer to iw_param structure containing rts threshold.
2698 * \param[in] pcExtra NULL.
2700 * \retval 0 Success.
2702 * \note RTS threshold is stored in pRts.
2704 /*----------------------------------------------------------------------------*/
2706 wext_get_rts(IN
struct net_device
*prNetDev
,
2707 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_param
*prRts
, IN
char *pcExtra
)
2709 PARAM_RTS_THRESHOLD u4RtsThresh
;
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
, prRts
)) {
2720 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2722 rStatus
= kalIoctl(prGlueInfo
,
2723 wlanoidQueryRtsThreshold
,
2724 &u4RtsThresh
, sizeof(u4RtsThresh
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
2728 prRts
->value
= (typeof(prRts
->value
)) u4RtsThresh
;
2729 prRts
->disabled
= (prRts
->value
> 2347 || prRts
->value
< 0) ? 1 : 0;
2733 } /* wext_get_rts */
2735 /*----------------------------------------------------------------------------*/
2737 * \brief To get fragmentation threshold.
2739 * \param[in] prDev Net device requested.
2740 * \param[in] prIwrInfo NULL.
2741 * \param[out] prFrag Pointer to iw_param structure containing frag threshold.
2742 * \param[in] pcExtra NULL.
2744 * \retval 0 Success.
2746 * \note RTS threshold is stored in pFrag. Fragmentation is disabled.
2748 /*----------------------------------------------------------------------------*/
2750 wext_get_frag(IN
struct net_device
*prNetDev
,
2751 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_param
*prFrag
, IN
char *pcExtra
)
2755 prFrag
->value
= 2346;
2757 prFrag
->disabled
= 1;
2759 } /* wext_get_frag */
2762 /*----------------------------------------------------------------------------*/
2764 * \brief To set TX power, or enable/disable the radio.
2766 * \param[in] prDev Net device requested.
2767 * \param[in] prIwrInfo NULL.
2768 * \param[in] prTxPow Pointer to iw_param structure containing tx power setting.
2769 * \param[in] pcExtra NULL.
2771 * \retval 0 Success.
2773 * \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used
2774 * to enable/disable the radio.
2776 /*----------------------------------------------------------------------------*/
2779 wext_set_txpow(IN
struct net_device
*prNetDev
,
2780 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_param
*prTxPow
, IN
char *pcExtra
)
2783 /* PARAM_DEVICE_POWER_STATE ePowerState; */
2784 ENUM_ACPI_STATE_T ePowerState
;
2786 P_GLUE_INFO_T prGlueInfo
= NULL
;
2787 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2788 UINT_32 u4BufLen
= 0;
2792 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prTxPow
)) {
2795 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2797 if (prTxPow
->disabled
) {
2798 /* <1> disconnect */
2799 rStatus
= kalIoctl(prGlueInfo
,
2800 wlanoidSetDisassociate
, NULL
, 0, FALSE
, FALSE
, TRUE
, &u4BufLen
);
2801 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
2802 DBGLOG(INIT
, INFO
, ("######set disassoc failed\n"));
2804 DBGLOG(INIT
, INFO
, ("######set assoc ok\n"));
2807 /* <2> mark to power state flag */
2808 ePowerState
= ACPI_STATE_D0
;
2809 DBGLOG(INIT
, INFO
, ("set to acpi d3(0)\n"));
2810 wlanSetAcpiState(prGlueInfo
->prAdapter
, ePowerState
);
2813 ePowerState
= ACPI_STATE_D0
;
2814 DBGLOG(INIT
, INFO
, ("set to acpi d0\n"));
2815 wlanSetAcpiState(prGlueInfo
->prAdapter
, ePowerState
);
2818 prGlueInfo
->ePowerState
= ePowerState
;
2821 } /* wext_set_txpow */
2826 /*----------------------------------------------------------------------------*/
2828 * \brief To get TX power.
2830 * \param[in] prDev Net device requested.
2831 * \param[in] prIwrInfo NULL.
2832 * \param[out] prTxPow Pointer to iw_param structure containing tx power setting.
2833 * \param[in] pcExtra NULL.
2835 * \retval 0 Success.
2837 * \note Tx power is stored in pTxPow.
2839 /*----------------------------------------------------------------------------*/
2841 wext_get_txpow(IN
struct net_device
*prNetDev
,
2842 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_param
*prTxPow
, IN
char *pcExtra
)
2844 /* PARAM_DEVICE_POWER_STATE ePowerState; */
2846 P_GLUE_INFO_T prGlueInfo
= NULL
;
2850 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prTxPow
)) {
2853 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2855 /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not
2856 * current state. Use GLUE_INFO_T to store state.
2858 /* ePowerState = prGlueInfo->ePowerState; */
2860 /* TxPow parameters: Fixed at relative 100% */
2861 #if WIRELESS_EXT < 17
2862 prTxPow
->flags
= 0x0002; /* IW_TXPOW_RELATIVE */
2864 prTxPow
->flags
= IW_TXPOW_RELATIVE
;
2866 prTxPow
->value
= 100;
2868 /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */
2869 prTxPow
->disabled
= TRUE
;
2872 } /* wext_get_txpow */
2875 /*----------------------------------------------------------------------------*/
2877 * \brief To get encryption cipher and key.
2879 * \param[in] prDev Net device requested.
2880 * \param[in] prIwrInfo NULL.
2881 * \param[out] prEnc Pointer to iw_point structure containing securiry information.
2882 * \param[in] pcExtra Buffer to store key content.
2884 * \retval 0 Success.
2886 * \note Securiry information is stored in pEnc except key content.
2888 /*----------------------------------------------------------------------------*/
2890 wext_get_encode(IN
struct net_device
*prNetDev
,
2891 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_point
*prEnc
, IN
char *pcExtra
)
2894 /* ENUM_ENCRYPTION_STATUS_T eEncMode; */
2895 ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode
;
2897 P_GLUE_INFO_T prGlueInfo
= NULL
;
2898 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2899 UINT_32 u4BufLen
= 0;
2903 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prEnc
)) {
2906 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2909 rStatus
= kalIoctl(prGlueInfo
,
2910 wlanoidQueryEncryptionStatus
,
2911 &eEncMode
, sizeof(eEncMode
), TRUE
, FALSE
, FALSE
, &u4BufLen
);
2916 case ENUM_WEP_DISABLED
:
2917 prEnc
->flags
= IW_ENCODE_DISABLED
;
2919 case ENUM_WEP_ENABLED
:
2920 prEnc
->flags
= IW_ENCODE_ENABLED
;
2922 case ENUM_WEP_KEY_ABSENT
:
2923 prEnc
->flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
2926 prEnc
->flags
= IW_ENCODE_ENABLED
;
2930 /* Cipher, Key Content, Key ID can't be queried */
2931 prEnc
->flags
|= IW_ENCODE_NOKEY
;
2934 } /* wext_get_encode */
2938 /*----------------------------------------------------------------------------*/
2940 * \brief To set encryption cipher and key.
2942 * \param[in] prDev Net device requested.
2943 * \param[in] prIwrInfo NULL.
2944 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
2945 * \param[in] pcExtra Pointer to key string buffer.
2947 * \retval 0 Success.
2948 * \retval -EINVAL Key ID error for WEP.
2949 * \retval -EFAULT Setting parameters to driver fail.
2950 * \retval -EOPNOTSUPP Key size not supported.
2952 * \note Securiry information is stored in pEnc.
2954 /*----------------------------------------------------------------------------*/
2955 static UINT_8 wepBuf
[48];
2958 wext_set_encode(IN
struct net_device
*prNetDev
,
2959 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_point
*prEnc
, IN
char *pcExtra
)
2962 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
2963 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
2964 /* UINT_8 wepBuf[48]; */
2965 P_PARAM_WEP_T prWepKey
= (P_PARAM_WEP_T
) wepBuf
;
2967 P_GLUE_INFO_T prGlueInfo
= NULL
;
2968 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2969 UINT_32 u4BufLen
= 0;
2974 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEnc
, pcExtra
)) {
2977 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2979 /* reset to default mode */
2980 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
2981 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= 0;
2982 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= IW_AUTH_CIPHER_NONE
;
2983 prGlueInfo
->rWpaInfo
.u4CipherGroup
= IW_AUTH_CIPHER_NONE
;
2984 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
2985 #if CFG_SUPPORT_802_11W
2986 prGlueInfo
->rWpaInfo
.u4Mfp
= IW_AUTH_MFP_DISABLED
;
2989 /* iwconfig wlan0 key off */
2990 if ((prEnc
->flags
& IW_ENCODE_MODE
) == IW_ENCODE_DISABLED
) {
2991 eAuthMode
= AUTH_MODE_OPEN
;
2993 rStatus
= kalIoctl(prGlueInfo
,
2995 &eAuthMode
, sizeof(eAuthMode
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
2997 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
2999 rStatus
= kalIoctl(prGlueInfo
,
3000 wlanoidSetEncryptionStatus
,
3001 &eEncStatus
, sizeof(eEncStatus
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
3006 /* iwconfig wlan0 key 0123456789 */
3007 /* iwconfig wlan0 key s:abcde */
3008 /* iwconfig wlan0 key 0123456789 [1] */
3009 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3010 /* check key size for WEP */
3011 if (prEnc
->length
== 5 || prEnc
->length
== 13 || prEnc
->length
== 16) {
3012 /* prepare PARAM_WEP key structure */
3013 prWepKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3014 (prEnc
->flags
& IW_ENCODE_INDEX
) - 1 : 0;
3015 if (prWepKey
->u4KeyIndex
> 3) {
3016 /* key id is out of range */
3019 prWepKey
->u4KeyIndex
|= 0x80000000;
3020 prWepKey
->u4Length
= 12 + prEnc
->length
;
3021 prWepKey
->u4KeyLength
= prEnc
->length
;
3022 kalMemCopy(prWepKey
->aucKeyMaterial
, pcExtra
, prEnc
->length
);
3025 rStatus
= kalIoctl(prGlueInfo
,
3027 prWepKey
, prWepKey
->u4Length
, FALSE
, FALSE
, TRUE
, &u4BufLen
);
3029 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3030 DBGLOG(INIT
, INFO
, ("wlanoidSetAddWep fail 0x%lx\n", rStatus
));
3034 /* change to auto switch */
3035 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_SHARED_KEY
| IW_AUTH_ALG_OPEN_SYSTEM
;
3036 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
3038 rStatus
= kalIoctl(prGlueInfo
,
3040 &eAuthMode
, sizeof(eAuthMode
), FALSE
, FALSE
, FALSE
, &u4BufLen
);
3042 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3043 /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */
3047 prGlueInfo
->rWpaInfo
.u4CipherPairwise
=
3048 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3049 prGlueInfo
->rWpaInfo
.u4CipherGroup
= IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3051 eEncStatus
= ENUM_WEP_ENABLED
;
3054 rStatus
= kalIoctl(prGlueInfo
,
3055 wlanoidSetEncryptionStatus
,
3057 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T
),
3058 FALSE
, FALSE
, FALSE
, &u4BufLen
);
3060 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3061 /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */
3069 } /* wext_set_encode */
3072 /*----------------------------------------------------------------------------*/
3074 * \brief To set power management.
3076 * \param[in] prDev Net device requested.
3077 * \param[in] prIwrInfo NULL.
3078 * \param[in] prPower Pointer to iw_param structure containing tx power setting.
3079 * \param[in] pcExtra NULL.
3081 * \retval 0 Success.
3083 * \note New Power Management Mode is set to driver.
3085 /*----------------------------------------------------------------------------*/
3087 wext_set_power(IN
struct net_device
*prNetDev
,
3088 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_param
*prPower
, IN
char *pcExtra
)
3091 PARAM_POWER_MODE ePowerMode
;
3092 INT_32 i4PowerValue
;
3094 P_GLUE_INFO_T prGlueInfo
= NULL
;
3095 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3096 UINT_32 u4BufLen
= 0;
3097 PARAM_POWER_MODE_T rPowerMode
;
3101 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prPower
)) {
3104 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3110 if (!prGlueInfo
->prAdapter
->prAisBssInfo
) {
3113 /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */
3114 /* prPower->value, prPower->disabled, prPower->flags); */
3116 if (prPower
->disabled
) {
3117 ePowerMode
= Param_PowerModeCAM
;
3119 i4PowerValue
= prPower
->value
;
3120 #if WIRELESS_EXT < 21
3121 i4PowerValue
/= 1000000;
3123 if (i4PowerValue
== 0) {
3124 ePowerMode
= Param_PowerModeCAM
;
3125 } else if (i4PowerValue
== 1) {
3126 ePowerMode
= Param_PowerModeMAX_PSP
;
3127 } else if (i4PowerValue
== 2) {
3128 ePowerMode
= Param_PowerModeFast_PSP
;
3130 DBGLOG(INIT
, INFO
, ("%s(): unsupported power management mode value = %d.\n",
3131 __func__
, prPower
->value
));
3137 rPowerMode
.ePowerMode
= ePowerMode
;
3138 rPowerMode
.ucBssIdx
= prGlueInfo
->prAdapter
->prAisBssInfo
->ucBssIndex
;
3140 rStatus
= kalIoctl(prGlueInfo
,
3141 wlanoidSet802dot11PowerSaveProfile
,
3142 &rPowerMode
, sizeof(PARAM_POWER_MODE_T
), FALSE
, FALSE
, TRUE
, &u4BufLen
);
3144 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3145 /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */
3150 } /* wext_set_power */
3153 /*----------------------------------------------------------------------------*/
3155 * \brief To get power management.
3157 * \param[in] prDev Net device requested.
3158 * \param[in] prIwrInfo NULL.
3159 * \param[out] prPower Pointer to iw_param structure containing tx power setting.
3160 * \param[in] pcExtra NULL.
3162 * \retval 0 Success.
3164 * \note Power management mode is stored in pTxPow->value.
3166 /*----------------------------------------------------------------------------*/
3168 wext_get_power(IN
struct net_device
*prNetDev
,
3169 IN
struct iw_request_info
*prIwrInfo
, OUT
struct iw_param
*prPower
, IN
char *pcExtra
)
3172 P_GLUE_INFO_T prGlueInfo
= NULL
;
3173 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3174 UINT_32 u4BufLen
= 0;
3175 PARAM_POWER_MODE ePowerMode
= Param_PowerModeCAM
;
3179 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prPower
)) {
3182 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3185 #if defined(_HIF_SDIO)
3186 rStatus
= sdio_io_ctrl(prGlueInfo
,
3187 wlanoidQuery802dot11PowerSaveProfile
,
3188 &ePowerMode
, sizeof(ePowerMode
), TRUE
, TRUE
, &u4BufLen
);
3190 rStatus
= wlanQueryInformation(prGlueInfo
->prAdapter
,
3191 wlanoidQuery802dot11PowerSaveProfile
,
3192 &ePowerMode
, sizeof(ePowerMode
), &u4BufLen
);
3195 rStatus
= wlanQueryInformation(prGlueInfo
->prAdapter
,
3196 wlanoidQuery802dot11PowerSaveProfile
,
3197 &ePowerMode
, sizeof(ePowerMode
), &u4BufLen
);
3200 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3205 prPower
->disabled
= 1;
3207 if (Param_PowerModeCAM
== ePowerMode
) {
3209 prPower
->disabled
= 1;
3210 } else if (Param_PowerModeMAX_PSP
== ePowerMode
) {
3212 prPower
->disabled
= 0;
3213 } else if (Param_PowerModeFast_PSP
== ePowerMode
) {
3215 prPower
->disabled
= 0;
3218 prPower
->flags
= IW_POWER_PERIOD
| IW_POWER_RELATIVE
;
3219 #if WIRELESS_EXT < 21
3220 prPower
->value
*= 1000000;
3223 /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */
3224 /* prPower->value, prPower->disabled, prPower->flags); */
3227 } /* wext_get_power */
3229 /*----------------------------------------------------------------------------*/
3231 * \brief To set authentication parameters.
3233 * \param[in] prDev Net device requested.
3234 * \param[in] prIwrInfo NULL.
3235 * \param[in] rpAuth Pointer to iw_param structure containing authentication information.
3236 * \param[in] pcExtra Pointer to key string buffer.
3238 * \retval 0 Success.
3239 * \retval -EINVAL Key ID error for WEP.
3240 * \retval -EFAULT Setting parameters to driver fail.
3241 * \retval -EOPNOTSUPP Key size not supported.
3243 * \note Securiry information is stored in pEnc.
3245 /*----------------------------------------------------------------------------*/
3247 wext_set_auth(IN
struct net_device
*prNetDev
,
3248 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_param
*prAuth
, IN
char *pcExtra
)
3250 P_GLUE_INFO_T prGlueInfo
= NULL
;
3254 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prAuth
)) {
3257 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3259 /* Save information to glue info and process later when ssid is set. */
3260 switch (prAuth
->flags
& IW_AUTH_INDEX
) {
3261 case IW_AUTH_WPA_VERSION
:
3262 #if CFG_SUPPORT_WAPI
3263 if (wlanQueryWapiMode(prGlueInfo
->prAdapter
)) {
3264 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
3265 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
3267 prGlueInfo
->rWpaInfo
.u4WpaVersion
= prAuth
->value
;
3270 prGlueInfo
->rWpaInfo
.u4WpaVersion
= prAuth
->value
;
3274 case IW_AUTH_CIPHER_PAIRWISE
:
3275 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= prAuth
->value
;
3278 case IW_AUTH_CIPHER_GROUP
:
3279 prGlueInfo
->rWpaInfo
.u4CipherGroup
= prAuth
->value
;
3282 case IW_AUTH_KEY_MGMT
:
3283 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= prAuth
->value
;
3284 #if CFG_SUPPORT_WAPI
3285 if (prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WAPI_PSK
||
3286 prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WAPI_CERT
) {
3288 WLAN_STATUS rStatus
;
3290 rStatus
= kalIoctl(prGlueInfo
,
3293 sizeof(UINT_32
), FALSE
, FALSE
, TRUE
, &u4BufLen
);
3294 DBGLOG(INIT
, INFO
, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth
->value
));
3297 if (prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WPS
)
3298 prGlueInfo
->fgWpsActive
= TRUE
;
3300 prGlueInfo
->fgWpsActive
= FALSE
;
3303 case IW_AUTH_80211_AUTH_ALG
:
3304 prGlueInfo
->rWpaInfo
.u4AuthAlg
= prAuth
->value
;
3307 case IW_AUTH_PRIVACY_INVOKED
:
3308 prGlueInfo
->rWpaInfo
.fgPrivacyInvoke
= prAuth
->value
;
3310 #if CFG_SUPPORT_802_11W
3312 /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */
3313 prGlueInfo
->rWpaInfo
.u4Mfp
= prAuth
->value
;
3316 #if CFG_SUPPORT_WAPI
3317 case IW_AUTH_WAPI_ENABLED
:
3320 WLAN_STATUS rStatus
;
3322 rStatus
= kalIoctl(prGlueInfo
,
3325 sizeof(UINT_32
), FALSE
, FALSE
, TRUE
, &u4BufLen
);
3327 DBGLOG(INIT
, INFO
, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth
->value
));
3332 printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags);
3337 } /* wext_set_auth */
3340 /*----------------------------------------------------------------------------*/
3342 * \brief To set encryption cipher and key.
3344 * \param[in] prDev Net device requested.
3345 * \param[in] prIwrInfo NULL.
3346 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
3347 * \param[in] pcExtra Pointer to key string buffer.
3349 * \retval 0 Success.
3350 * \retval -EINVAL Key ID error for WEP.
3351 * \retval -EFAULT Setting parameters to driver fail.
3352 * \retval -EOPNOTSUPP Key size not supported.
3354 * \note Securiry information is stored in pEnc.
3356 /*----------------------------------------------------------------------------*/
3357 #if CFG_SUPPORT_WAPI
3358 UINT_8 keyStructBuf
[1024]; /* add/remove key shared buffer */
3360 UINT_8 keyStructBuf
[100]; /* add/remove key shared buffer */
3364 wext_set_encode_ext(IN
struct net_device
*prNetDev
,
3365 IN
struct iw_request_info
*prIwrInfo
,
3366 IN
struct iw_point
*prEnc
, IN
char *pcExtra
)
3368 P_PARAM_REMOVE_KEY_T prRemoveKey
= (P_PARAM_REMOVE_KEY_T
) keyStructBuf
;
3369 P_PARAM_KEY_T prKey
= (P_PARAM_KEY_T
) keyStructBuf
;
3372 P_PARAM_WEP_T prWepKey
= (P_PARAM_WEP_T
) wepBuf
;
3374 struct iw_encode_ext
*prIWEncExt
= (struct iw_encode_ext
*)pcExtra
;
3376 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
3377 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
3378 /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */
3380 #if CFG_SUPPORT_WAPI
3381 P_PARAM_WPI_KEY_T prWpiKey
= (P_PARAM_WPI_KEY_T
) keyStructBuf
;
3384 P_GLUE_INFO_T prGlueInfo
= NULL
;
3385 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3386 UINT_32 u4BufLen
= 0;
3390 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEnc
, pcExtra
)) {
3393 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3395 memset(keyStructBuf
, 0, sizeof(keyStructBuf
));
3397 #if CFG_SUPPORT_WAPI
3398 if (prIWEncExt
->alg
== IW_ENCODE_ALG_SMS4
) {
3399 if (prEnc
->flags
& IW_ENCODE_DISABLED
) {
3400 /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */
3404 prWpiKey
->ucKeyID
= (prEnc
->flags
& IW_ENCODE_INDEX
);
3405 prWpiKey
->ucKeyID
--;
3406 if (prWpiKey
->ucKeyID
> 1) {
3407 /* key id is out of range */
3408 /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */
3412 if (prIWEncExt
->key_len
!= 32) {
3413 /* key length not valid */
3414 /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */
3417 /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */
3419 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
3420 prWpiKey
->eKeyType
= ENUM_WPI_GROUP_KEY
;
3421 prWpiKey
->eDirection
= ENUM_WPI_RX
;
3422 } else if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
3423 prWpiKey
->eKeyType
= ENUM_WPI_PAIRWISE_KEY
;
3424 prWpiKey
->eDirection
= ENUM_WPI_RX_TX
;
3428 memcpy(&prWpiKey
->aucPN
[0], &prIWEncExt
->tx_seq
[0], IW_ENCODE_SEQ_MAX_SIZE
* 2);
3431 memcpy(prWpiKey
->aucAddrIndex
, prIWEncExt
->addr
.sa_data
, 6);
3433 memcpy(prWpiKey
->aucWPIEK
, prIWEncExt
->key
, 16);
3434 prWpiKey
->u4LenWPIEK
= 16;
3436 memcpy(prWpiKey
->aucWPICK
, &prIWEncExt
->key
[16], 16);
3437 prWpiKey
->u4LenWPICK
= 16;
3439 rStatus
= kalIoctl(prGlueInfo
,
3442 sizeof(PARAM_WPI_KEY_T
), FALSE
, FALSE
, TRUE
, &u4BufLen
);
3444 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3445 /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */
3452 if ((prEnc
->flags
& IW_ENCODE_MODE
) == IW_ENCODE_DISABLED
) {
3453 prRemoveKey
->u4Length
= sizeof(*prRemoveKey
);
3454 memcpy(prRemoveKey
->arBSSID
, prIWEncExt
->addr
.sa_data
, 6);
3456 printk("IW_ENCODE_DISABLED: ID:%d, Addr:[" MACSTR "]\n",
3457 prRemoveKey->KeyIndex, MAC2STR(prRemoveKey->BSSID));
3460 rStatus
= kalIoctl(prGlueInfo
,
3461 wlanoidSetRemoveKey
,
3463 prRemoveKey
->u4Length
, FALSE
, FALSE
, TRUE
, &u4BufLen
);
3466 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3467 DBGLOG(INIT
, INFO
, ("remove key error:%lx\n", rStatus
));
3472 /* printk ("alg %x\n", prIWEncExt->alg); */
3474 switch (prIWEncExt
->alg
) {
3475 case IW_ENCODE_ALG_NONE
:
3477 case IW_ENCODE_ALG_WEP
:
3478 /* iwconfig wlan0 key 0123456789 */
3479 /* iwconfig wlan0 key s:abcde */
3480 /* iwconfig wlan0 key 0123456789 [1] */
3481 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3482 /* check key size for WEP */
3483 if (prIWEncExt
->key_len
== 5 || prIWEncExt
->key_len
== 13
3484 || prIWEncExt
->key_len
== 16) {
3485 /* prepare PARAM_WEP key structure */
3486 prWepKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3487 (prEnc
->flags
& IW_ENCODE_INDEX
) - 1 : 0;
3488 if (prWepKey
->u4KeyIndex
> 3) {
3489 /* key id is out of range */
3492 prWepKey
->u4KeyIndex
|= 0x80000000;
3493 prWepKey
->u4Length
= 12 + prIWEncExt
->key_len
;
3494 prWepKey
->u4KeyLength
= prIWEncExt
->key_len
;
3495 /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */
3496 kalMemCopy(prWepKey
->aucKeyMaterial
, prIWEncExt
->key
,
3497 prIWEncExt
->key_len
);
3500 rStatus
= kalIoctl(prGlueInfo
,
3504 FALSE
, FALSE
, TRUE
, &u4BufLen
);
3506 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3508 ("wlanoidSetAddWep fail 0x%lx\n", rStatus
));
3512 /* change to auto switch */
3513 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_SHARED_KEY
|
3514 IW_AUTH_ALG_OPEN_SYSTEM
;
3515 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
3517 rStatus
= kalIoctl(prGlueInfo
,
3521 FALSE
, FALSE
, FALSE
, &u4BufLen
);
3523 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3525 ("wlanoidSetAuthMode fail 0x%lx\n", rStatus
));
3529 prGlueInfo
->rWpaInfo
.u4CipherPairwise
=
3530 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3531 prGlueInfo
->rWpaInfo
.u4CipherGroup
=
3532 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3534 eEncStatus
= ENUM_WEP_ENABLED
;
3537 rStatus
= kalIoctl(prGlueInfo
,
3538 wlanoidSetEncryptionStatus
,
3540 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T
),
3541 FALSE
, FALSE
, FALSE
, &u4BufLen
);
3543 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3545 ("wlanoidSetEncryptionStatus fail 0x%lx\n",
3551 DBGLOG(INIT
, INFO
, ("key length %x\n", prIWEncExt
->key_len
));
3552 DBGLOG(INIT
, INFO
, ("key error\n"));
3556 case IW_ENCODE_ALG_TKIP
:
3557 case IW_ENCODE_ALG_CCMP
:
3558 #if CFG_SUPPORT_802_11W
3559 case IW_ENCODE_ALG_AES_CMAC
:
3564 prKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3565 (prEnc
->flags
& IW_ENCODE_INDEX
) - 1 : 0;
3566 #if CFG_SUPPORT_802_11W
3567 if (prKey
->u4KeyIndex
> 5)
3569 if (prKey
->u4KeyIndex
> 3)
3573 ("key index error:0x%lx\n", prKey
->u4KeyIndex
));
3574 /* key id is out of range */
3578 /* bit(31) and bit(30) are shared by pKey and pRemoveKey */
3579 /* Tx Key Bit(31) */
3580 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
3581 prKey
->u4KeyIndex
|= 0x1UL
<< 31;
3584 /* Pairwise Key Bit(30) */
3585 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
3589 prKey
->u4KeyIndex
|= 0x1UL
<< 30;
3594 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
3595 prKey
->u4KeyIndex
|= 0x1UL
<< 29;
3596 memcpy(&prKey
->rKeyRSC
, prIWEncExt
->rx_seq
, IW_ENCODE_SEQ_MAX_SIZE
);
3600 memcpy(prKey
->arBSSID
, prIWEncExt
->addr
.sa_data
, 6);
3602 /* switch tx/rx MIC key for sta */
3603 if (prIWEncExt
->alg
== IW_ENCODE_ALG_TKIP
&& prIWEncExt
->key_len
== 32) {
3604 memcpy(prKey
->aucKeyMaterial
, prIWEncExt
->key
, 16);
3605 memcpy(((PUINT_8
) prKey
->aucKeyMaterial
) + 16, prIWEncExt
->key
+ 24,
3607 memcpy((prKey
->aucKeyMaterial
) + 24, prIWEncExt
->key
+ 16, 8);
3609 memcpy(prKey
->aucKeyMaterial
, prIWEncExt
->key
, prIWEncExt
->key_len
);
3612 prKey
->u4KeyLength
= prIWEncExt
->key_len
;
3614 ((ULONG
) &(((P_PARAM_KEY_T
) 0)->aucKeyMaterial
)) +
3618 rStatus
= kalIoctl(prGlueInfo
,
3620 prKey
, prKey
->u4Length
, FALSE
, FALSE
, TRUE
, &u4BufLen
);
3622 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3623 DBGLOG(INIT
, INFO
, ("add key error:%lx\n", rStatus
));
3631 } /* wext_set_encode_ext */
3634 /*----------------------------------------------------------------------------*/
3636 * \brief Set country code
3638 * \param[in] prDev Net device requested.
3639 * \param[in] prIwrInfo NULL.
3640 * \param[in] pu4Mode Pointer to new operation mode.
3641 * \param[in] pcExtra NULL.
3643 * \retval 0 For success.
3644 * \retval -EOPNOTSUPP If new mode is not supported.
3646 * \note Device will run in new operation mode if it is valid.
3648 /*----------------------------------------------------------------------------*/
3649 static int wext_set_country(IN
struct net_device
*prNetDev
, IN
struct iwreq
*iwr
)
3651 P_GLUE_INFO_T prGlueInfo
;
3652 WLAN_STATUS rStatus
;
3654 UINT_8 aucCountry
[2];
3658 /* iwr->u.data.pointer should be like "COUNTRY US", "COUNTRY EU"
3661 if (FALSE
== GLUE_CHK_PR2(prNetDev
, iwr
) || !iwr
->u
.data
.pointer
|| iwr
->u
.data
.length
< 10) {
3664 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3666 aucCountry
[0] = *((PUINT_8
) iwr
->u
.data
.pointer
+ 8);
3667 aucCountry
[1] = *((PUINT_8
) iwr
->u
.data
.pointer
+ 9);
3669 rStatus
= kalIoctl(prGlueInfo
,
3670 wlanoidSetCountryCode
, &aucCountry
[0], 2, FALSE
, FALSE
, TRUE
, &u4BufLen
);
3671 wlanUpdateChannelTable(prGlueInfo
);
3676 /*----------------------------------------------------------------------------*/
3678 * \brief ioctl() (Linux Wireless Extensions) routines
3680 * \param[in] prDev Net device requested.
3681 * \param[in] ifr The ifreq structure for seeting the wireless extension.
3682 * \param[in] i4Cmd The wireless extension ioctl command.
3684 * \retval zero On success.
3685 * \retval -EOPNOTSUPP If the cmd is not supported.
3686 * \retval -EFAULT If copy_to_user goes wrong.
3687 * \retval -EINVAL If any value's out of range.
3691 /*----------------------------------------------------------------------------*/
3692 int wext_support_ioctl(IN
struct net_device
*prDev
, IN
struct ifreq
*prIfReq
, IN
int i4Cmd
)
3694 /* prIfReq is verified in the caller function wlanDoIOCTL() */
3695 struct iwreq
*iwr
= (struct iwreq
*)prIfReq
;
3696 struct iw_request_info rIwReqInfo
;
3698 char *prExtraBuf
= NULL
;
3699 UINT_32 u4ExtraSize
= 0;
3700 struct iw_scan_req
* prIwScanReq
= NULL
;
3702 /* prDev is verified in the caller function wlanDoIOCTL() */
3704 /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */
3706 /* Prepare the call */
3707 rIwReqInfo
.cmd
= (__u16
) i4Cmd
;
3708 rIwReqInfo
.flags
= 0;
3711 case SIOCGIWNAME
: /* 0x8B01, get wireless protocol name */
3712 ret
= wext_get_name(prDev
, &rIwReqInfo
, (char *)&iwr
->u
.name
, NULL
);
3715 /* case SIOCSIWNWID: 0x8B02, deprecated */
3716 /* case SIOCGIWNWID: 0x8B03, deprecated */
3718 case SIOCSIWFREQ
: /* 0x8B04, set channel */
3719 ret
= wext_set_freq(prDev
, NULL
, &iwr
->u
.freq
, NULL
);
3722 case SIOCGIWFREQ
: /* 0x8B05, get channel */
3723 ret
= wext_get_freq(prDev
, NULL
, &iwr
->u
.freq
, NULL
);
3726 case SIOCSIWMODE
: /* 0x8B06, set operation mode */
3727 ret
= wext_set_mode(prDev
, NULL
, &iwr
->u
.mode
, NULL
);
3731 case SIOCGIWMODE
: /* 0x8B07, get operation mode */
3732 ret
= wext_get_mode(prDev
, NULL
, &iwr
->u
.mode
, NULL
);
3735 /* case SIOCSIWSENS: 0x8B08, unsupported */
3736 /* case SIOCGIWSENS: 0x8B09, unsupported */
3738 /* case SIOCSIWRANGE: 0x8B0A, unused */
3739 case SIOCGIWRANGE
: /* 0x8B0B, get range of parameters */
3740 if (iwr
->u
.data
.pointer
!= NULL
) {
3741 /* Buffer size shoule be large enough */
3742 if (iwr
->u
.data
.length
< sizeof(struct iw_range
)) {
3747 prExtraBuf
= kalMemAlloc(sizeof(struct iw_range
), VIR_MEM_TYPE
);
3753 /* reset all fields */
3754 memset(prExtraBuf
, 0, sizeof(struct iw_range
));
3755 iwr
->u
.data
.length
= sizeof(struct iw_range
);
3757 ret
= wext_get_range(prDev
, NULL
, &iwr
->u
.data
, prExtraBuf
);
3758 /* Push up to the caller */
3759 if (copy_to_user(iwr
->u
.data
.pointer
, prExtraBuf
, iwr
->u
.data
.length
)) {
3763 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, sizeof(struct iw_range
));
3770 case SIOCSIWPRIV
: /* 0x8B0C, Country */
3771 /* TODO: receive the android driver command */
3772 /* COUNTRY PNOFORCE ... */
3773 ret
= wext_set_country(prDev
, iwr
);
3776 /* case SIOCGIWPRIV: 0x8B0D, handled in wlan_do_ioctl() */
3777 /* caes SIOCSIWSTATS: 0x8B0E, unused */
3778 /* case SIOCGIWSTATS:
3779 get statistics, intercepted by wireless_process_ioctl() in wireless.c,
3780 redirected to dev_iwstats(), dev->get_wireless_stats().
3782 /* case SIOCSIWSPY: 0x8B10, unsupported */
3783 /* case SIOCGIWSPY: 0x8B11, unsupported */
3784 /* case SIOCSIWTHRSPY: 0x8B12, unsupported */
3785 /* case SIOCGIWTHRSPY: 0x8B13, unsupported */
3787 case SIOCSIWAP
: /* 0x8B14, set access point MAC addresses (BSSID) */
3788 if (iwr
->u
.ap_addr
.sa_data
[0] == 0 &&
3789 iwr
->u
.ap_addr
.sa_data
[1] == 0 &&
3790 iwr
->u
.ap_addr
.sa_data
[2] == 0 &&
3791 iwr
->u
.ap_addr
.sa_data
[3] == 0 &&
3792 iwr
->u
.ap_addr
.sa_data
[4] == 0 && iwr
->u
.ap_addr
.sa_data
[5] == 0) {
3793 /* WPA Supplicant will set 000000000000 in
3794 ** wpa_driver_wext_deinit(), do nothing here or disassoc again?
3799 ret
= wext_set_ap(prDev
, NULL
, &iwr
->u
.ap_addr
, NULL
);
3803 case SIOCGIWAP
: /* 0x8B15, get access point MAC addresses (BSSID) */
3804 ret
= wext_get_ap(prDev
, NULL
, &iwr
->u
.ap_addr
, NULL
);
3807 case SIOCSIWMLME
: /* 0x8B16, request MLME operation */
3808 /* Fixed length structure */
3809 if (iwr
->u
.data
.length
!= sizeof(struct iw_mlme
)) {
3810 DBGLOG(INIT
, INFO
, ("MLME buffer strange:%d\n", iwr
->u
.data
.length
));
3815 if (!iwr
->u
.data
.pointer
) {
3820 prExtraBuf
= kalMemAlloc(sizeof(struct iw_mlme
), VIR_MEM_TYPE
);
3826 if (copy_from_user(prExtraBuf
, iwr
->u
.data
.pointer
, sizeof(struct iw_mlme
))) {
3829 ret
= wext_set_mlme(prDev
, NULL
, &(iwr
->u
.data
), prExtraBuf
);
3832 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, sizeof(struct iw_mlme
));
3836 /* case SIOCGIWAPLIST: 0x8B17, deprecated */
3837 case SIOCSIWSCAN
: /* 0x8B18, scan request */
3838 if (iwr
->u
.data
.pointer
== NULL
) {
3839 ret
= wext_set_scan(prDev
, NULL
, NULL
, NULL
);
3841 #if WIRELESS_EXT > 17
3842 else if (iwr
->u
.data
.length
== sizeof(struct iw_scan_req
)) {
3843 prIwScanReq
= kalMemAlloc(iwr
->u
.data
.length
, VIR_MEM_TYPE
);
3849 if (copy_from_user(prIwScanReq
, iwr
->u
.data
.pointer
, iwr
->u
.data
.length
)) {
3852 if (prIwScanReq
->essid_len
> IW_ESSID_MAX_SIZE
)
3853 prIwScanReq
->essid_len
= IW_ESSID_MAX_SIZE
;
3854 ret
= wext_set_scan(prDev
, NULL
, prIwScanReq
, &(prIwScanReq
->essid
[0]));
3857 kalMemFree(prIwScanReq
, VIR_MEM_TYPE
, iwr
->u
.data
.length
);
3866 case SIOCGIWSCAN
: /* 0x8B19, get scan results */
3867 if (!iwr
->u
.data
.pointer
|| !iwr
->u
.essid
.pointer
) {
3872 u4ExtraSize
= iwr
->u
.data
.length
;
3873 /* allocate the same size of kernel buffer to store scan results. */
3874 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
3880 /* iwr->u.data.length may be updated by wext_get_scan() */
3881 ret
= wext_get_scan(prDev
, NULL
, &iwr
->u
.data
, prExtraBuf
);
3883 if (ret
== -E2BIG
) {
3884 DBGLOG(INIT
, INFO
, ("[wifi] wext_get_scan -E2BIG\n"));
3887 /* check updated length is valid */
3888 ASSERT(iwr
->u
.data
.length
<= u4ExtraSize
);
3889 if (iwr
->u
.data
.length
> u4ExtraSize
) {
3891 ("Updated result length is larger than allocated (%d > %ld)\n",
3892 iwr
->u
.data
.length
, u4ExtraSize
));
3893 iwr
->u
.data
.length
= u4ExtraSize
;
3896 if (copy_to_user(iwr
->u
.data
.pointer
, prExtraBuf
, iwr
->u
.data
.length
)) {
3901 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
3909 case SIOCSIWESSID
: /* 0x8B1A, set SSID (network name) */
3910 if (iwr
->u
.essid
.length
> IW_ESSID_MAX_SIZE
) {
3914 if (!iwr
->u
.essid
.pointer
) {
3919 prExtraBuf
= kalMemAlloc(IW_ESSID_MAX_SIZE
+ 4, VIR_MEM_TYPE
);
3925 if (copy_from_user(prExtraBuf
, iwr
->u
.essid
.pointer
, iwr
->u
.essid
.length
)) {
3928 /* Add trailing '\0' for printk */
3929 /* prExtraBuf[iwr->u.essid.length] = 0; */
3930 /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */
3931 ret
= wext_set_essid(prDev
, NULL
, &iwr
->u
.essid
, prExtraBuf
);
3932 /* printk ("set essid %d\n", ret); */
3935 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, IW_ESSID_MAX_SIZE
+ 4);
3941 case SIOCGIWESSID
: /* 0x8B1B, get SSID */
3942 if (!iwr
->u
.essid
.pointer
) {
3947 if (iwr
->u
.essid
.length
< IW_ESSID_MAX_SIZE
) {
3948 DBGLOG(INIT
, INFO
, ("[wifi] iwr->u.essid.length:%d too small\n",
3949 iwr
->u
.essid
.length
));
3950 ret
= -E2BIG
; /* let caller try larger buffer */
3954 prExtraBuf
= kalMemAlloc(IW_ESSID_MAX_SIZE
, VIR_MEM_TYPE
);
3960 /* iwr->u.essid.length is updated by wext_get_essid() */
3962 ret
= wext_get_essid(prDev
, NULL
, &iwr
->u
.essid
, prExtraBuf
);
3964 if (copy_to_user(iwr
->u
.essid
.pointer
, prExtraBuf
, iwr
->u
.essid
.length
)) {
3969 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, IW_ESSID_MAX_SIZE
);
3974 /* case SIOCSIWNICKN: 0x8B1C, not supported */
3975 /* case SIOCGIWNICKN: 0x8B1D, not supported */
3977 case SIOCSIWRATE
: /* 0x8B20, set default bit rate (bps) */
3978 /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */
3981 case SIOCGIWRATE
: /* 0x8B21, get current bit rate (bps) */
3982 ret
= wext_get_rate(prDev
, NULL
, &iwr
->u
.bitrate
, NULL
);
3985 case SIOCSIWRTS
: /* 0x8B22, set rts/cts threshold */
3986 ret
= wext_set_rts(prDev
, NULL
, &iwr
->u
.rts
, NULL
);
3989 case SIOCGIWRTS
: /* 0x8B23, get rts/cts threshold */
3990 ret
= wext_get_rts(prDev
, NULL
, &iwr
->u
.rts
, NULL
);
3993 /* case SIOCSIWFRAG: 0x8B24, unsupported */
3994 case SIOCGIWFRAG
: /* 0x8B25, get frag threshold */
3995 ret
= wext_get_frag(prDev
, NULL
, &iwr
->u
.frag
, NULL
);
3998 case SIOCSIWTXPOW
: /* 0x8B26, set relative tx power (in %) */
3999 ret
= wext_set_txpow(prDev
, NULL
, &iwr
->u
.txpower
, NULL
);
4002 case SIOCGIWTXPOW
: /* 0x8B27, get relative tx power (in %) */
4003 ret
= wext_get_txpow(prDev
, NULL
, &iwr
->u
.txpower
, NULL
);
4006 /* case SIOCSIWRETRY: 0x8B28, unsupported */
4007 /* case SIOCGIWRETRY: 0x8B29, unsupported */
4010 case SIOCSIWENCODE
: /* 0x8B2A, set encoding token & mode */
4011 /* Only DISABLED case has NULL pointer and length == 0 */
4012 if (iwr
->u
.encoding
.pointer
) {
4013 if (iwr
->u
.encoding
.length
> 16) {
4018 u4ExtraSize
= iwr
->u
.encoding
.length
;
4019 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4025 if (copy_from_user(prExtraBuf
,
4026 iwr
->u
.encoding
.pointer
, iwr
->u
.encoding
.length
)) {
4029 } else if (iwr
->u
.encoding
.length
!= 0) {
4035 ret
= wext_set_encode(prDev
, NULL
, &iwr
->u
.encoding
, prExtraBuf
);
4039 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4044 case SIOCGIWENCODE
: /* 0x8B2B, get encoding token & mode */
4046 ret
= wext_get_encode(prDev
, NULL
, &iwr
->u
.encoding
, NULL
);
4049 case SIOCSIWPOWER
: /* 0x8B2C, set power management */
4050 ret
= wext_set_power(prDev
, NULL
, &iwr
->u
.power
, NULL
);
4053 case SIOCGIWPOWER
: /* 0x8B2D, get power management */
4054 ret
= wext_get_power(prDev
, NULL
, &iwr
->u
.power
, NULL
);
4057 #if WIRELESS_EXT > 17
4058 case SIOCSIWGENIE
: /* 0x8B30, set gen ie */
4059 if (iwr
->u
.data
.pointer
) {
4060 P_GLUE_INFO_T prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4061 if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) {
4062 /* Fixed length structure */
4063 #if CFG_SUPPORT_WAPI
4064 if (iwr
->u
.data
.length
> 42 /* The max wapi ie buffer */) {
4069 u4ExtraSize
= iwr
->u
.data
.length
;
4071 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4076 if (copy_from_user(prExtraBuf
,
4077 iwr
->u
.data
.pointer
,
4078 iwr
->u
.data
.length
)) {
4081 wext_support_ioctl_SIOCSIWGENIE(prGlueInfo
, prExtraBuf
, u4ExtraSize
);
4083 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4090 case SIOCGIWGENIE
: /* 0x8B31, get gen ie, unused */
4095 case SIOCSIWAUTH
: /* 0x8B32, set auth mode params */
4096 ret
= wext_set_auth(prDev
, NULL
, &iwr
->u
.param
, NULL
);
4099 /* case SIOCGIWAUTH: 0x8B33, unused? */
4100 case SIOCSIWENCODEEXT
: /* 0x8B34, set extended encoding token & mode */
4101 if (iwr
->u
.encoding
.pointer
) {
4102 u4ExtraSize
= iwr
->u
.encoding
.length
;
4103 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4109 if (copy_from_user(prExtraBuf
,
4110 iwr
->u
.encoding
.pointer
, iwr
->u
.encoding
.length
)) {
4113 } else if (iwr
->u
.encoding
.length
!= 0) {
4119 ret
= wext_set_encode_ext(prDev
, NULL
, &iwr
->u
.encoding
, prExtraBuf
);
4123 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4128 /* case SIOCGIWENCODEEXT: 0x8B35, unused? */
4130 case SIOCSIWPMKSA
: /* 0x8B36, pmksa cache operation */
4132 if (iwr
->u
.data
.pointer
) {
4133 /* Fixed length structure */
4134 if (iwr
->u
.data
.length
!= sizeof(struct iw_pmksa
)) {
4139 u4ExtraSize
= sizeof(struct iw_pmksa
);
4140 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4146 if (copy_from_user(prExtraBuf
,
4147 iwr
->u
.data
.pointer
, sizeof(struct iw_pmksa
))) {
4150 switch (((struct iw_pmksa
*)prExtraBuf
)->cmd
) {
4153 printk(KERN_INFO "IW_PMKSA_ADD [" MACSTR "]\n",
4154 MAC2STR(((struct iw_pmksa *)pExtraBuf)->bssid.sa_data));
4157 wext_support_ioctl_SIOCSIWPMKSA_Action(prDev
, prExtraBuf
, IW_PMKSA_ADD
, &ret
);
4160 case IW_PMKSA_REMOVE
:
4162 printk(KERN_INFO "IW_PMKSA_REMOVE [" MACSTR "]\n",
4163 MAC2STR(((struct iw_pmksa *)buf)->bssid.sa_data));
4166 case IW_PMKSA_FLUSH
:
4168 printk(KERN_INFO "IW_PMKSA_FLUSH\n");
4171 wext_support_ioctl_SIOCSIWPMKSA_Action(prDev
, prExtraBuf
, IW_PMKSA_FLUSH
, &ret
);
4175 DBGLOG(INIT
, INFO
, ("UNKNOWN iw_pmksa command:%d\n",
4176 ((struct iw_pmksa
*)prExtraBuf
)->cmd
));
4183 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4186 } else if (iwr
->u
.data
.length
!= 0) {
4196 /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */
4201 /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */
4204 } /* wext_support_ioctl */
4207 wext_support_ioctl_SIOCSIWGENIE(IN P_GLUE_INFO_T prGlueInfo
, IN
char *prExtraBuf
, IN UINT_32 u4ExtraSize
)
4209 WLAN_STATUS rStatus
;
4211 #if CFG_SUPPORT_WAPI
4212 rStatus
= kalIoctl(prGlueInfo
,
4213 wlanoidSetWapiAssocInfo
,
4216 FALSE
, FALSE
, TRUE
, &u4BufLen
);
4217 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4219 #if CFG_SUPPORT_WPS2
4220 PUINT_8 prDesiredIE
= NULL
;
4221 if (wextSrchDesiredWPSIE(prExtraBuf
,
4227 kalIoctl(prGlueInfo
,
4228 wlanoidSetWSCAssocInfo
,
4230 IE_SIZE(prDesiredIE
),
4233 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4234 /* printk(KERN_INFO "[WSC] set WSC assoc info error:%lx\n", rStatus); */
4238 #if CFG_SUPPORT_WAPI
4245 wext_support_ioctl_SIOCSIWPMKSA_Action(IN
struct net_device
*prDev
, IN
char *prExtraBuf
, IN
int ioMode
, OUT
int *ret
)
4247 P_GLUE_INFO_T prGlueInfo
=
4248 *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4249 WLAN_STATUS rStatus
;
4251 P_PARAM_PMKID_T prPmkid
;
4256 (P_PARAM_PMKID_T
) kalMemAlloc(8 +
4258 (PARAM_BSSID_INFO_T
),
4262 ("Can not alloc memory for IW_PMKSA_ADD\n"));
4267 prPmkid
->u4Length
= 8 + sizeof(PARAM_BSSID_INFO_T
);
4268 prPmkid
->u4BSSIDInfoCount
= 1;
4269 kalMemCopy(prPmkid
->arBSSIDInfo
->arBSSID
,
4270 ((struct iw_pmksa
*)prExtraBuf
)->bssid
.
4272 kalMemCopy(prPmkid
->arBSSIDInfo
->arPMKID
,
4273 ((struct iw_pmksa
*)prExtraBuf
)->pmkid
,
4276 rStatus
= kalIoctl(prGlueInfo
,
4279 sizeof(PARAM_PMKID_T
),
4280 FALSE
, FALSE
, TRUE
, &u4BufLen
);
4282 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4284 ("add pmkid error:%lx\n", rStatus
));
4286 kalMemFree(prPmkid
, VIR_MEM_TYPE
,
4287 8 + sizeof(PARAM_BSSID_INFO_T
));
4289 case IW_PMKSA_FLUSH
:
4291 (P_PARAM_PMKID_T
) kalMemAlloc(8, VIR_MEM_TYPE
);
4294 ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
4299 prPmkid
->u4Length
= 8;
4300 prPmkid
->u4BSSIDInfoCount
= 0;
4302 rStatus
= kalIoctl(prGlueInfo
,
4305 sizeof(PARAM_PMKID_T
),
4306 FALSE
, FALSE
, TRUE
, &u4BufLen
);
4308 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4310 ("flush pmkid error:%lx\n",
4313 kalMemFree(prPmkid
, VIR_MEM_TYPE
, 8);
4320 /*----------------------------------------------------------------------------*/
4322 * \brief To send an event (RAW socket pacekt) to user process actively.
4324 * \param[in] prGlueInfo Glue layer info.
4325 * \param[in] u4cmd Whcih event command we want to indicate to user process.
4326 * \param[in] pData Data buffer to be indicated.
4327 * \param[in] dataLen Available data size in pData.
4331 * \note Event is indicated to upper layer if cmd is supported and data is valid.
4332 * Using of kernel symbol wireless_send_event(), which is defined in
4333 * <net/iw_handler.h> after WE-14 (2.4.20).
4335 /*----------------------------------------------------------------------------*/
4337 wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo
,
4338 IN
unsigned int u4Cmd
,
4339 IN
unsigned char *pucData
, IN
unsigned int u4dataLen
)
4341 union iwreq_data wrqu
;
4342 unsigned char *pucExtraInfo
= NULL
;
4343 #if WIRELESS_EXT >= 15
4344 unsigned char *pucDesiredIE
= NULL
;
4345 unsigned char aucExtraInfoBuf
[200];
4347 #if WIRELESS_EXT < 18
4351 memset(&wrqu
, 0, sizeof(wrqu
));
4355 memcpy(&wrqu
.power
, pucData
, u4dataLen
);
4358 complete_all(&prGlueInfo
->rScanComp
);
4363 memcpy(&wrqu
.ap_addr
.sa_data
, pucData
, ETH_ALEN
);
4365 memset(&wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
4369 case IWEVASSOCREQIE
:
4370 #if WIRELESS_EXT < 15
4371 /* under WE-15, no suitable Event can be used */
4372 goto skip_indicate_event
;
4374 /* do supplicant a favor, parse to the start of WPA/RSN IE */
4375 if (wextSrchDesiredWPAIE(pucData
, u4dataLen
, 0x30, &pucDesiredIE
)) {
4379 else if (wextSrchDesiredWPSIE(pucData
, u4dataLen
, 0xDD, &pucDesiredIE
)) {
4383 else if (wextSrchDesiredWPAIE(pucData
, u4dataLen
, 0xDD, &pucDesiredIE
)) {
4386 #if CFG_SUPPORT_WAPI /* Android+ */
4387 else if (wextSrchDesiredWAPIIE(pucData
, u4dataLen
, &pucDesiredIE
)) {
4388 /* printk("wextSrchDesiredWAPIIE!!\n"); */
4393 /* no WPA/RSN IE found, skip this event */
4394 goto skip_indicate_event
;
4397 #if WIRELESS_EXT < 18
4398 /* under WE-18, only IWEVCUSTOM can be used */
4400 pucExtraInfo
= aucExtraInfoBuf
;
4401 pucExtraInfo
+= sprintf(pucExtraInfo
, "ASSOCINFO(ReqIEs=");
4402 /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */
4403 /* translate binary string to hex string, requirement of IWEVCUSTOM */
4404 for (i
= 0; i
< pucDesiredIE
[1] + 2; ++i
) {
4405 pucExtraInfo
+= sprintf(pucExtraInfo
, "%02x", pucDesiredIE
[i
]);
4407 pucExtraInfo
= aucExtraInfoBuf
;
4408 wrqu
.data
.length
= 17 + (pucDesiredIE
[1] + 2) * 2;
4410 /* IWEVASSOCREQIE, indicate binary string */
4411 pucExtraInfo
= pucDesiredIE
;
4412 wrqu
.data
.length
= pucDesiredIE
[1] + 2;
4414 #endif /* WIRELESS_EXT < 15 */
4417 case IWEVMICHAELMICFAILURE
:
4418 #if WIRELESS_EXT < 15
4419 /* under WE-15, no suitable Event can be used */
4420 goto skip_indicate_event
;
4423 P_PARAM_AUTH_REQUEST_T pAuthReq
= (P_PARAM_AUTH_REQUEST_T
) pucData
;
4424 /* under WE-18, only IWEVCUSTOM can be used */
4426 pucExtraInfo
= aucExtraInfoBuf
;
4427 pucExtraInfo
+= sprintf(pucExtraInfo
, "MLME-MICHAELMICFAILURE.indication ");
4428 pucExtraInfo
+= sprintf(pucExtraInfo
,
4430 (pAuthReq
->u4Flags
==
4431 PARAM_AUTH_REQUEST_GROUP_ERROR
) ? "groupcast " :
4434 wrqu
.data
.length
= pucExtraInfo
- aucExtraInfoBuf
;
4435 pucExtraInfo
= aucExtraInfoBuf
;
4437 #endif /* WIRELESS_EXT < 15 */
4441 if (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA2
&&
4442 prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_802_1X
) {
4444 /* only used in WPA2 */
4445 #if WIRELESS_EXT >= 18
4446 P_PARAM_PMKID_CANDIDATE_T prPmkidCand
= (P_PARAM_PMKID_CANDIDATE_T
) pucData
;
4448 struct iw_pmkid_cand rPmkidCand
;
4449 pucExtraInfo
= aucExtraInfoBuf
;
4451 rPmkidCand
.flags
= prPmkidCand
->u4Flags
;
4452 rPmkidCand
.index
= 0;
4453 kalMemCopy(rPmkidCand
.bssid
.sa_data
, prPmkidCand
->arBSSID
, 6);
4455 kalMemCopy(pucExtraInfo
, (PUINT_8
) &rPmkidCand
,
4456 sizeof(struct iw_pmkid_cand
));
4457 wrqu
.data
.length
= sizeof(struct iw_pmkid_cand
);
4459 /* pmkid canadidate list is supported after WE-18 */
4460 /* indicate struct iw_pmkid_cand */
4462 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */
4463 goto skip_indicate_event
;
4466 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */
4467 goto skip_indicate_event
;
4473 pucExtraInfo
= aucExtraInfoBuf
;
4474 kalMemCopy(pucExtraInfo
, pucData
, sizeof(PTA_IPC_T
));
4475 wrqu
.data
.length
= sizeof(PTA_IPC_T
);
4479 /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */
4480 goto skip_indicate_event
;
4483 /* Send event to user space */
4484 wireless_send_event(prGlueInfo
->prDevHandler
, u4Cmd
, &wrqu
, pucExtraInfo
);
4486 skip_indicate_event
:
4488 } /* wext_indicate_wext_event */
4491 /*----------------------------------------------------------------------------*/
4493 * \brief A method of struct net_device, to get the network interface statistical
4496 * Whenever an application needs to get statistics for the interface, this method
4497 * is called. This happens, for example, when ifconfig or netstat -i is run.
4499 * \param[in] pDev Pointer to struct net_device.
4501 * \return net_device_stats buffer pointer.
4504 /*----------------------------------------------------------------------------*/
4505 struct iw_statistics
*wext_get_wireless_stats(struct net_device
*prDev
)
4508 WLAN_STATUS rStatus
= WLAN_STATUS_FAILURE
;
4509 P_GLUE_INFO_T prGlueInfo
= NULL
;
4510 struct iw_statistics
*pStats
= NULL
;
4515 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4521 pStats
= (struct iw_statistics
*)(&(prGlueInfo
->rIwStats
));
4523 if (!prDev
|| !netif_carrier_ok(prDev
)) {
4524 /* network not connected */
4528 rStatus
= kalIoctl(prGlueInfo
,
4529 wlanoidQueryRssi
, &i4Rssi
, sizeof(i4Rssi
), TRUE
, TRUE
, TRUE
, &bufLen
);
4533 } /* wlan_get_wireless_stats */
4535 /*----------------------------------------------------------------------------*/
4537 * \brief To report the private supported IOCTLs table to user space.
4539 * \param[in] prNetDev Net device requested.
4540 * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
4541 * user space buffer in gl_iwpriv_table.
4543 * \retval 0 For success.
4544 * \retval -E2BIG For user's buffer size is too small.
4545 * \retval -EFAULT For fail.
4548 /*----------------------------------------------------------------------------*/
4549 int wext_get_priv(IN
struct net_device
*prNetDev
, IN
struct ifreq
*prIfReq
)
4551 /* prIfReq is verified in the caller function wlanDoIOCTL() */
4552 struct iwreq
*prIwReq
= (struct iwreq
*)prIfReq
;
4553 struct iw_point
*prData
= (struct iw_point
*)&prIwReq
->u
.data
;
4554 UINT_16 u2BufferSize
= 0;
4556 u2BufferSize
= prData
->length
;
4558 /* update our private table size */
4559 prData
->length
= (__u16
) sizeof(rIwPrivTable
) / sizeof(struct iw_priv_args
);
4561 if (u2BufferSize
< prData
->length
) {
4565 if (prData
->length
) {
4566 if (copy_to_user(prData
->pointer
, rIwPrivTable
, sizeof(rIwPrivTable
))) {
4572 } /* wext_get_priv */
4574 #endif /* WIRELESS_EXT */