2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 $
6 \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver.
14 * 06 13 2012 yuche.tsai
16 * Update maintrunk driver.
17 * Add support for driver compose assoc request frame.
20 * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl
21 * Adding the template code for set / get band IOCTL (with ICS supplicant_6)..
24 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
25 * Adding the related ioctl / wlan oid function to set the Tx power cfg.
28 * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
29 * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
32 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
33 * 1. eliminaite direct calls to printk in porting layer.
34 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
37 * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
38 * adding the 802.11w related function and define .
40 * 09 23 2011 tsaiyuan.hsu
41 * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state
42 * avoid entering D3 state after deep sleep.
44 * 07 28 2011 chinghwa.yu
45 * [WCXRP00000063] Update BCM CoEx design and settings
46 * Add BWCS cmd and event.
49 * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query the ap address
50 * Remove the netif check while query bssid and ssid
52 * 07 26 2011 chinglan.wang
54 * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection..
56 * 07 18 2011 chinghwa.yu
57 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
58 * Add CMD/Event for RDD and BWCS.
60 * 05 17 2011 eddie.chen
61 * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning
62 * Initilize the vairlabes.
64 * 05 11 2011 jeffrey.chang
65 * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power
66 * modify set_tx_pow ioctl
69 * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring
70 * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of essid storage array.
73 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
74 * improve portability for awareness of early version of linux kernel and wireless extension.
76 * 03 17 2011 chinglan.wang
77 * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
81 * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
82 * Toggle non-standard debug messages to comments.
85 * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get essid
86 * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running.
88 * 02 08 2011 george.huang
89 * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
90 * Support querying power mode OID.
93 * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0
94 * not doing mem alloc. while set ie length already 0
96 * 01 20 2011 eddie.chen
97 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
100 * 01 20 2011 eddie.chen
101 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
104 * 01 20 2011 eddie.chen
105 * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control
106 * Add Oid for sw control debug command
108 * 01 11 2011 chinglan.wang
110 * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish successfully.
111 * Use the WPS function to connect AP, the privacy bit always is set to 1. .
113 * 01 07 2011 cm.chang
114 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
115 * Add a new compiling option to control if MCR read/write is permitted
118 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
119 * separate kalMemAlloc() into virtually-continous and physically-continous types
120 * to ease slab system pressure
123 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
124 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
126 * 12 31 2010 cm.chang
127 * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation
128 * Add some iwpriv commands to support test mode operation
130 * 12 15 2010 george.huang
131 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
132 * Support set PS profile and set WMM-PS related iwpriv.
134 * 12 15 2010 george.huang
135 * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
136 * Allow change PS profile function (throught wext_set_power()).
138 * 12 14 2010 jeffrey.chang
139 * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID
142 * 12 13 2010 chinglan.wang
144 * Add WPS 1.0 feature flag to enable the WPS 1.0 function.
146 * 12 07 2010 cm.chang
147 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
148 * Fix compiling error
150 * 12 07 2010 cm.chang
151 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
152 * 1. Country code is from NVRAM or supplicant
153 * 2. Change band definition in CMD/EVENT.
156 * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1
160 * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921
161 * add the message check code from mt5921.
163 * 10 19 2010 jeffrey.chang
164 * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power saving
165 * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving
167 * 10 18 2010 jeffrey.chang
168 * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
169 * refine the scan ioctl to prevent hanging of Android UI
172 * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
173 * add the scan result with wapi ie.
176 * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
177 * fixed the wapi ie assigned issue.
181 * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function.
183 * 09 21 2010 kevin.huang
184 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
185 * Eliminate Linux Compile Warning
189 * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
193 * Androi/Linux: return current operating channel information
197 * adding the wapi support for integration test.
199 * 08 02 2010 jeffrey.chang
201 * enable remove key ioctl
203 * 08 02 2010 jeffrey.chang
205 * 1) modify tx service thread to avoid busy looping
206 * 2) add spin lock declartion for linux build
208 * 07 28 2010 jeffrey.chang
210 * 1) enable encyption ioctls
211 * 2) temporarily disable remove keys ioctl to prevent TX1 busy
213 * 07 28 2010 jeffrey.chang
215 * 1) remove unused spinlocks
216 * 2) enable encyption ioctls
217 * 3) fix scan ioctl which may cause supplicant to hang
219 * 07 19 2010 jeffrey.chang
221 * add kal api for scanning done
223 * 07 19 2010 jeffrey.chang
225 * for linux driver migration
227 * 07 19 2010 jeffrey.chang
229 * Linux port modification
233 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
235 * 06 06 2010 kevin.huang
236 * [WPD00003832][MT6620 5931] Create driver base
237 * [MT6620 5931] Create driver base
239 * 05 28 2010 jeffrey.chang
240 * [WPD00003826]Initial import for Linux port
241 * remove unused macro and debug messages
243 * 05 14 2010 jeffrey.chang
244 * [WPD00003826]Initial import for Linux port
245 * Add dissassoication support for wpa supplicant
247 * 04 22 2010 jeffrey.chang
248 * [WPD00003826]Initial import for Linux port
250 * 1) modify rx path code for supporting Wi-Fi direct
251 * 2) modify config.h since Linux dont need to consider retaining packet
253 * 04 21 2010 jeffrey.chang
254 * [WPD00003826]Initial import for Linux port
255 * add for private ioctl support
257 * 04 19 2010 jeffrey.chang
258 * [WPD00003826]Initial import for Linux port
259 * Add ioctl of power management
261 * 04 19 2010 jeffrey.chang
262 * [WPD00003826]Initial import for Linux port
263 * remove debug message
265 * 04 14 2010 jeffrey.chang
266 * [WPD00003826]Initial import for Linux port
267 * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
270 * 04 12 2010 jeffrey.chang
271 * [WPD00003826]Initial import for Linux port
272 * remove debug messages for pre-release
275 * [WPD00001943]Create WiFi test driver framework on WinXP
276 * rWlanInfo should be placed at adapter rather than glue due to most operations
277 * * * * * * * * are done in adapter layer.
279 * 04 02 2010 jeffrey.chang
280 * [WPD00003826]Initial import for Linux port
283 * 04 01 2010 jeffrey.chang
284 * [WPD00003826]Initial import for Linux port
285 * enable pmksa cache operation
287 * 03 31 2010 jeffrey.chang
288 * [WPD00003826]Initial import for Linux port
289 * fix ioctl which may cause cmdinfo memory leak
292 * [WPD00003816][MT6620 Wi-Fi] Adding the security support
293 * modify the wapi related code for new driver's design.
295 * 03 30 2010 jeffrey.chang
296 * [WPD00003826]Initial import for Linux port
297 * emulate NDIS Pending OID facility
299 * 03 24 2010 jeffrey.chang
300 * [WPD00003826]Initial import for Linux port
301 * initial import for Linux port
302 ** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090
303 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
304 ** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090
305 ** Remove unused variables
306 ** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090
307 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
308 ** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088
309 ** adding the wapi ioctl support
310 ** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090
311 ** Add Linux SDIO (with mmc core) support.
312 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
313 ** Fix compile warning in Linux.
314 ** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089
315 ** fix compiling warning
316 ** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089
317 ** Add mandatory and private IO control for Linux BWCS
318 ** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088
319 ** fixed the compiling error
320 ** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088
321 ** add the privacy setting from linux supplicant ap selection
322 ** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088
323 ** fixed the compling error
324 ** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088
325 ** rename some variable with pre-fix to avoid the misunderstanding
326 ** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088
327 ** fixed compiling error
328 ** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088
329 ** adjust the code for meet the coding style, and add assert check
330 ** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461
331 ** Update after wlanoidSetPowerMode changed
332 ** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084
334 ** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461
335 ** Add set desired rate in Linux STD IOCTL
336 ** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088
337 ** add pmkid ioctl and indicate
338 ** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461
339 ** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461
340 ** Refine WPS related priv ioctl for unified interface
342 ** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088
343 ** move the configuration code from set essid function,
344 ** remove the non-used code
345 ** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461
347 ** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461
348 ** Add Set Frequency & Channel oid support for Linux
349 ** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461
350 ** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461
351 ** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter
352 ** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425
354 ** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461
356 ** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425
357 ** 1. Fix compiling erros
359 ** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425
360 ** 1. Add WMM-PS setting
361 ** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088
362 ** fixed the compiler error
363 ** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088
365 ** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425
366 ** 1. Update wlanQueryInformation
369 /*******************************************************************************
370 * C O M P I L E R F L A G S
371 ********************************************************************************
374 /*******************************************************************************
375 * E X T E R N A L R E F E R E N C E S
376 ********************************************************************************
382 #include "wlan_oid.h"
385 #include "gl_wext_priv.h"
393 /* compatibility to wireless extensions */
396 /*******************************************************************************
398 ********************************************************************************
400 const long channel_freq
[] = {
401 2412, 2417, 2422, 2427, 2432, 2437, 2442,
402 2447, 2452, 2457, 2462, 2467, 2472, 2484
405 #define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
408 case 1: khz = 2412000; break; \
409 case 2: khz = 2417000; break; \
410 case 3: khz = 2422000; break; \
411 case 4: khz = 2427000; break; \
412 case 5: khz = 2432000; break; \
413 case 6: khz = 2437000; break; \
414 case 7: khz = 2442000; break; \
415 case 8: khz = 2447000; break; \
416 case 9: khz = 2452000; break; \
417 case 10: khz = 2457000; break; \
418 case 11: khz = 2462000; break; \
419 case 12: khz = 2467000; break; \
420 case 13: khz = 2472000; break; \
421 case 14: khz = 2484000; break; \
422 case 36: /* UNII */ khz = 5180000; break; \
423 case 40: /* UNII */ khz = 5200000; break; \
424 case 44: /* UNII */ khz = 5220000; break; \
425 case 48: /* UNII */ khz = 5240000; break; \
426 case 52: /* UNII */ khz = 5260000; break; \
427 case 56: /* UNII */ khz = 5280000; break; \
428 case 60: /* UNII */ khz = 5300000; break; \
429 case 64: /* UNII */ khz = 5320000; break; \
430 case 149: /* UNII */ khz = 5745000; break; \
431 case 153: /* UNII */ khz = 5765000; break; \
432 case 157: /* UNII */ khz = 5785000; break; \
433 case 161: /* UNII */ khz = 5805000; break; \
434 case 165: /* UNII */ khz = 5825000; break; \
435 case 100: /* HiperLAN2 */ khz = 5500000; break; \
436 case 104: /* HiperLAN2 */ khz = 5520000; break; \
437 case 108: /* HiperLAN2 */ khz = 5540000; break; \
438 case 112: /* HiperLAN2 */ khz = 5560000; break; \
439 case 116: /* HiperLAN2 */ khz = 5580000; break; \
440 case 120: /* HiperLAN2 */ khz = 5600000; break; \
441 case 124: /* HiperLAN2 */ khz = 5620000; break; \
442 case 128: /* HiperLAN2 */ khz = 5640000; break; \
443 case 132: /* HiperLAN2 */ khz = 5660000; break; \
444 case 136: /* HiperLAN2 */ khz = 5680000; break; \
445 case 140: /* HiperLAN2 */ khz = 5700000; break; \
446 case 34: /* Japan MMAC */ khz = 5170000; break; \
447 case 38: /* Japan MMAC */ khz = 5190000; break; \
448 case 42: /* Japan MMAC */ khz = 5210000; break; \
449 case 46: /* Japan MMAC */ khz = 5230000; break; \
450 case 184: /* Japan */ khz = 4920000; break; \
451 case 188: /* Japan */ khz = 4940000; break; \
452 case 192: /* Japan */ khz = 4960000; break; \
453 case 196: /* Japan */ khz = 4980000; break; \
454 case 208: /* Japan, means J08 */ khz = 5040000; break; \
455 case 212: /* Japan, means J12 */ khz = 5060000; break; \
456 case 216: /* Japan, means J16 */ khz = 5080000; break; \
457 default: khz = 2412000; break; \
462 #define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0]))
464 #define MAX_SSID_LEN 32
467 /*******************************************************************************
469 ********************************************************************************
472 /*******************************************************************************
473 * P U B L I C D A T A
474 ********************************************************************************
476 /* NOTE: name in iwpriv_args only have 16 bytes */
477 static const struct iw_priv_args rIwPrivTable
[] = {
478 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, ""},
479 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
480 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, 0, ""},
481 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, ""},
482 {IOCTL_SET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, ""},
484 {IOCTL_GET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
485 {IOCTL_GET_INT
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, ""},
487 {IOCTL_SET_INTS
, IW_PRIV_TYPE_INT
| 4, 0, ""},
488 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_INT
| 50, ""},
489 {IOCTL_GET_INT
, 0, IW_PRIV_TYPE_CHAR
| 16, ""},
491 {IOCTL_SET_STRING
, IW_PRIV_TYPE_CHAR
| 256, 0, ""},
493 /* added for set_oid and get_oid */
494 {IOCTL_SET_STRUCT
, 256, 0, ""},
495 {IOCTL_GET_STRUCT
, 0, 256, ""},
497 /* sub-ioctl definitions */
499 {PRIV_CMD_REG_DOMAIN
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_reg_domain" },
500 {PRIV_CMD_REG_DOMAIN
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_reg_domain" },
503 #if CFG_TCP_IP_CHKSUM_OFFLOAD
504 {PRIV_CMD_CSUM_OFFLOAD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_tcp_csum" },
505 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
507 {PRIV_CMD_POWER_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_power_mode" },
508 {PRIV_CMD_POWER_MODE
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_power_mode" },
510 {PRIV_CMD_WMM_PS
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3, 0, "set_wmm_ps" },
512 {PRIV_CMD_TEST_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_test_mode" },
513 {PRIV_CMD_TEST_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_test_cmd" },
514 {PRIV_CMD_TEST_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_test_result" },
515 #if CFG_SUPPORT_PRIV_MCR_RW
516 {PRIV_CMD_ACCESS_MCR
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_mcr" },
517 {PRIV_CMD_ACCESS_MCR
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_mcr" },
519 {PRIV_CMD_SW_CTRL
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_sw_ctrl" },
520 {PRIV_CMD_SW_CTRL
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_sw_ctrl" },
522 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
523 {PRIV_CUSTOM_BWCS_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_bwcs"},
524 /* GET STRUCT sub-ioctls commands */
525 {PRIV_CUSTOM_BWCS_CMD
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_bwcs"},
528 /* SET STRUCT sub-ioctls commands */
529 {PRIV_CMD_OID
, 256, 0, "set_oid"},
530 /* GET STRUCT sub-ioctls commands */
531 {PRIV_CMD_OID
, 0, 256, "get_oid"},
533 {PRIV_CMD_BAND_CONFIG
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "set_band" },
534 {PRIV_CMD_BAND_CONFIG
, 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_band" },
536 {PRIV_CMD_SET_TX_POWER
, IW_PRIV_TYPE_INT
| 4, 0, "set_txpower" },
537 {PRIV_CMD_GET_CH_LIST
, 0, IW_PRIV_TYPE_INT
| 50, "get_ch_list" },
538 {PRIV_CMD_DUMP_MEM
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "get_mem" },
540 #if CFG_ENABLE_WIFI_DIRECT
541 {PRIV_CMD_P2P_MODE
, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "set_p2p_mode" },
543 {PRIV_CMD_GET_BUILD_DATE_CODE
, 0, IW_PRIV_TYPE_CHAR
| 16, "get_date_code" },
544 {PRIV_CMD_GET_DEBUG_CODE
, 0, IW_PRIV_TYPE_CHAR
| 16, "get_dbg_code" },
545 /* handle any command with many input parameters */
546 {PRIV_CMD_OTHER
, IW_PRIV_TYPE_CHAR
| 256, 0, "set_str_cmd"},
550 static const iw_handler rIwPrivHandler
[] = {
551 [IOCTL_SET_INT
- SIOCIWFIRSTPRIV
] = priv_set_int
,
552 [IOCTL_GET_INT
- SIOCIWFIRSTPRIV
] = priv_get_int
,
553 [IOCTL_SET_ADDRESS
- SIOCIWFIRSTPRIV
] = NULL
,
554 [IOCTL_GET_ADDRESS
- SIOCIWFIRSTPRIV
] = NULL
,
555 [IOCTL_SET_STR
- SIOCIWFIRSTPRIV
] = NULL
,
556 [IOCTL_GET_STR
- SIOCIWFIRSTPRIV
] = NULL
,
557 [IOCTL_SET_KEY
- SIOCIWFIRSTPRIV
] = NULL
,
558 [IOCTL_GET_KEY
- SIOCIWFIRSTPRIV
] = NULL
,
559 [IOCTL_SET_STRUCT
- SIOCIWFIRSTPRIV
] = priv_set_struct
,
560 [IOCTL_GET_STRUCT
- SIOCIWFIRSTPRIV
] = priv_get_struct
,
561 [IOCTL_SET_STRUCT_FOR_EM
- SIOCIWFIRSTPRIV
] = priv_set_struct
,
562 [IOCTL_SET_INTS
- SIOCIWFIRSTPRIV
] = priv_set_ints
,
563 [IOCTL_GET_INTS
- SIOCIWFIRSTPRIV
] = priv_get_ints
,
564 [IOCTL_SET_STRING
- SIOCIWFIRSTPRIV
] = priv_set_string
,
567 const struct iw_handler_def wext_handler_def
= {
569 .num_private
= (__u16
)sizeof(rIwPrivHandler
)/sizeof(iw_handler
),
570 .num_private_args
= (__u16
)sizeof(rIwPrivTable
)/sizeof(struct iw_priv_args
),
571 .standard
= (iw_handler
*) NULL
,
572 .private = rIwPrivHandler
,
573 .private_args
= rIwPrivTable
,
574 .get_wireless_stats
= wext_get_wireless_stats
,
577 /*******************************************************************************
578 * P R I V A T E D A T A
579 ********************************************************************************
582 /*******************************************************************************
584 ********************************************************************************
587 /*******************************************************************************
588 * F U N C T I O N D E C L A R A T I O N S
589 ********************************************************************************
591 extern VOID
wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo
);
593 /*******************************************************************************
595 ********************************************************************************
598 /*----------------------------------------------------------------------------*/
600 * \brief Find the desired WPA/RSN Information Element according to desiredElemID.
602 * \param[in] pucIEStart IE starting address.
603 * \param[in] i4TotalIeLen Total length of all the IE.
604 * \param[in] ucDesiredElemId Desired element ID.
605 * \param[out] ppucDesiredIE Pointer to the desired IE.
607 * \retval TRUE Find the desired IE.
608 * \retval FALSE Desired IE not found.
612 /*----------------------------------------------------------------------------*/
614 wextSrchDesiredWPAIE (
615 IN PUINT_8 pucIEStart
,
616 IN INT_32 i4TotalIeLen
,
617 IN UINT_8 ucDesiredElemId
,
618 OUT PUINT_8
*ppucDesiredIE
621 INT_32 i4InfoElemLen
;
624 ASSERT(ppucDesiredIE
);
626 while (i4TotalIeLen
>= 2) {
627 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
629 if (pucIEStart
[0] == ucDesiredElemId
&& i4InfoElemLen
<= i4TotalIeLen
) {
630 if (ucDesiredElemId
!= 0xDD) {
632 *ppucDesiredIE
= &pucIEStart
[0];
636 /* EID == 0xDD, check WPA IE */
637 if (pucIEStart
[1] >= 4) {
638 if (memcmp(&pucIEStart
[2], "\x00\x50\xf2\x01", 4) == 0) {
639 *ppucDesiredIE
= &pucIEStart
[0];
642 } /* check WPA IE length */
643 } /* check EID == 0xDD */
644 } /* check desired EID */
646 /* Select next information element. */
647 i4TotalIeLen
-= i4InfoElemLen
;
648 pucIEStart
+= i4InfoElemLen
;
652 } /* parseSearchDesiredWPAIE */
656 /*----------------------------------------------------------------------------*/
658 * \brief Find the desired WAPI Information Element .
660 * \param[in] pucIEStart IE starting address.
661 * \param[in] i4TotalIeLen Total length of all the IE.
662 * \param[out] ppucDesiredIE Pointer to the desired IE.
664 * \retval TRUE Find the desired IE.
665 * \retval FALSE Desired IE not found.
669 /*----------------------------------------------------------------------------*/
671 wextSrchDesiredWAPIIE (
672 IN PUINT_8 pucIEStart
,
673 IN INT_32 i4TotalIeLen
,
674 OUT PUINT_8
*ppucDesiredIE
677 INT_32 i4InfoElemLen
;
680 ASSERT(ppucDesiredIE
);
682 while (i4TotalIeLen
>= 2) {
683 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
685 if (pucIEStart
[0] == ELEM_ID_WAPI
&& i4InfoElemLen
<= i4TotalIeLen
) {
686 *ppucDesiredIE
= &pucIEStart
[0];
688 } /* check desired EID */
690 /* Select next information element. */
691 i4TotalIeLen
-= i4InfoElemLen
;
692 pucIEStart
+= i4InfoElemLen
;
696 } /* wextSrchDesiredWAPIIE */
700 #if CFG_SUPPORT_HOTSPOT_2_0
701 /*----------------------------------------------------------------------------*/
703 * \brief Check if exist the desired HS2.0 Information Element according to desiredElemID.
705 * \param[in] pucIEStart IE starting address.
706 * \param[in] i4TotalIeLen Total length of all the IE.
707 * \param[in] ucDesiredElemId Desired element ID.
708 * \param[out] ppucDesiredIE Pointer to the desired IE.
710 * \retval TRUE Find the desired IE.
711 * \retval FALSE Desired IE not found.
715 /*----------------------------------------------------------------------------*/
717 wextIsDesiredHS20IE (
719 IN INT_32 i4TotalIeLen
722 INT_32 i4InfoElemLen
;
726 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
728 if (pucCurIE
[0] == ELEM_ID_VENDOR
&& i4InfoElemLen
<= i4TotalIeLen
) {
729 if ((pucCurIE
[1] >= ELEM_MIN_LEN_HS20_INDICATION
)) {
730 if (memcmp(&pucCurIE
[2], "\x50\x6f\x9a\x10", 4) == 0) {
734 } /* check desired EID */
737 } /* wextIsDesiredHS20IE */
740 /*----------------------------------------------------------------------------*/
742 * \brief Check if exist the desired interworking Information Element according to desiredElemID.
744 * \param[in] pucIEStart IE starting address.
745 * \param[in] i4TotalIeLen Total length of all the IE.
746 * \param[in] ucDesiredElemId Desired element ID.
747 * \param[out] ppucDesiredIE Pointer to the desired IE.
749 * \retval TRUE Find the desired IE.
750 * \retval FALSE Desired IE not found.
754 /*----------------------------------------------------------------------------*/
756 wextIsDesiredInterworkingIE (
758 IN INT_32 i4TotalIeLen
761 INT_32 i4InfoElemLen
;
765 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
767 if (pucCurIE
[0] == ELEM_ID_INTERWORKING
&& i4InfoElemLen
<= i4TotalIeLen
) {
768 switch(pucCurIE
[1]) {
769 case IW_IE_LENGTH_ANO
:
770 case IW_IE_LENGTH_ANO_HESSID
:
771 case IW_IE_LENGTH_ANO_VENUE
:
772 case IW_IE_LENGTH_ANO_VENUE_HESSID
:
779 } /* check desired EID */
782 } /* wextIsDesiredInterworkingIE */
785 /*----------------------------------------------------------------------------*/
787 * \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID.
789 * \param[in] pucIEStart IE starting address.
790 * \param[in] i4TotalIeLen Total length of all the IE.
791 * \param[in] ucDesiredElemId Desired element ID.
792 * \param[out] ppucDesiredIE Pointer to the desired IE.
794 * \retval TRUE Find the desired IE.
795 * \retval FALSE Desired IE not found.
799 /*----------------------------------------------------------------------------*/
801 wextIsDesiredAdvProtocolIE (
803 IN INT_32 i4TotalIeLen
806 INT_32 i4InfoElemLen
;
810 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
812 if (pucCurIE
[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL
&& i4InfoElemLen
<= i4TotalIeLen
) {
814 } /* check desired EID */
817 } /* wextIsDesiredAdvProtocolIE */
820 /*----------------------------------------------------------------------------*/
822 * \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID.
824 * \param[in] pucIEStart IE starting address.
825 * \param[in] i4TotalIeLen Total length of all the IE.
826 * \param[in] ucDesiredElemId Desired element ID.
827 * \param[out] ppucDesiredIE Pointer to the desired IE.
829 * \retval TRUE Find the desired IE.
830 * \retval FALSE Desired IE not found.
834 /*----------------------------------------------------------------------------*/
836 wextIsDesiredRoamingConsortiumIE (
838 IN INT_32 i4TotalIeLen
841 INT_32 i4InfoElemLen
;
845 i4InfoElemLen
= (INT_32
) pucCurIE
[1] + 2;
847 if (pucCurIE
[0] == ELEM_ID_ROAMING_CONSORTIUM
&& i4InfoElemLen
<= i4TotalIeLen
) {
849 } /* check desired EID */
852 } /* wextIsDesiredRoamingConsortiumIE */
855 /*----------------------------------------------------------------------------*/
857 * \brief Find the desired HS2.0 Information Element according to desiredElemID.
859 * \param[in] pucIEStart IE starting address.
860 * \param[in] i4TotalIeLen Total length of all the IE.
861 * \param[in] ucDesiredElemId Desired element ID.
862 * \param[out] ppucDesiredIE Pointer to the desired IE.
864 * \retval TRUE Find the desired IE.
865 * \retval FALSE Desired IE not found.
869 /*----------------------------------------------------------------------------*/
871 wextSrchDesiredHS20IE (
872 IN PUINT_8 pucIEStart
,
873 IN INT_32 i4TotalIeLen
,
874 OUT PUINT_8
*ppucDesiredIE
)
876 INT_32 i4InfoElemLen
;
879 ASSERT(ppucDesiredIE
);
881 while (i4TotalIeLen
>= 2) {
882 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
884 if (pucIEStart
[0] == ELEM_ID_VENDOR
&& i4InfoElemLen
<= i4TotalIeLen
) {
885 if ((pucIEStart
[1] >= ELEM_MIN_LEN_HS20_INDICATION
)) {
886 if (memcmp(&pucIEStart
[2], "\x50\x6f\x9a\x10", 4) == 0) {
887 *ppucDesiredIE
= &pucIEStart
[0];
891 } /* check desired EID */
893 /* Select next information element. */
894 i4TotalIeLen
-= i4InfoElemLen
;
895 pucIEStart
+= i4InfoElemLen
;
899 } /* wextSrchDesiredHS20IE */
902 /*----------------------------------------------------------------------------*/
904 * \brief Find the desired interworking Information Element according to desiredElemID.
906 * \param[in] pucIEStart IE starting address.
907 * \param[in] i4TotalIeLen Total length of all the IE.
908 * \param[in] ucDesiredElemId Desired element ID.
909 * \param[out] ppucDesiredIE Pointer to the desired IE.
911 * \retval TRUE Find the desired IE.
912 * \retval FALSE Desired IE not found.
916 /*----------------------------------------------------------------------------*/
918 wextSrchDesiredInterworkingIE (
919 IN PUINT_8 pucIEStart
,
920 IN INT_32 i4TotalIeLen
,
921 OUT PUINT_8
*ppucDesiredIE
)
923 INT_32 i4InfoElemLen
;
926 ASSERT(ppucDesiredIE
);
928 while (i4TotalIeLen
>= 2) {
929 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
931 if (pucIEStart
[0] == ELEM_ID_INTERWORKING
&& i4InfoElemLen
<= i4TotalIeLen
) {
932 *ppucDesiredIE
= &pucIEStart
[0];
934 } /* check desired EID */
936 /* Select next information element. */
937 i4TotalIeLen
-= i4InfoElemLen
;
938 pucIEStart
+= i4InfoElemLen
;
942 } /* wextSrchDesiredInterworkingIE */
944 /*----------------------------------------------------------------------------*/
946 * \brief Find the desired Adv Protocol Information Element according to desiredElemID.
948 * \param[in] pucIEStart IE starting address.
949 * \param[in] i4TotalIeLen Total length of all the IE.
950 * \param[in] ucDesiredElemId Desired element ID.
951 * \param[out] ppucDesiredIE Pointer to the desired IE.
953 * \retval TRUE Find the desired IE.
954 * \retval FALSE Desired IE not found.
958 /*----------------------------------------------------------------------------*/
960 wextSrchDesiredAdvProtocolIE (
961 IN PUINT_8 pucIEStart
,
962 IN INT_32 i4TotalIeLen
,
963 OUT PUINT_8
*ppucDesiredIE
)
965 INT_32 i4InfoElemLen
;
968 ASSERT(ppucDesiredIE
);
970 while (i4TotalIeLen
>= 2) {
971 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
973 if (pucIEStart
[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL
&& i4InfoElemLen
<= i4TotalIeLen
) {
974 *ppucDesiredIE
= &pucIEStart
[0];
976 } /* check desired EID */
978 /* Select next information element. */
979 i4TotalIeLen
-= i4InfoElemLen
;
980 pucIEStart
+= i4InfoElemLen
;
984 } /* wextSrchDesiredAdvProtocolIE */
986 /*----------------------------------------------------------------------------*/
988 * \brief Find the desired Roaming Consortium Information Element according to desiredElemID.
990 * \param[in] pucIEStart IE starting address.
991 * \param[in] i4TotalIeLen Total length of all the IE.
992 * \param[in] ucDesiredElemId Desired element ID.
993 * \param[out] ppucDesiredIE Pointer to the desired IE.
995 * \retval TRUE Find the desired IE.
996 * \retval FALSE Desired IE not found.
1000 /*----------------------------------------------------------------------------*/
1002 wextSrchDesiredRoamingConsortiumIE (
1003 IN PUINT_8 pucIEStart
,
1004 IN INT_32 i4TotalIeLen
,
1005 OUT PUINT_8
*ppucDesiredIE
)
1007 INT_32 i4InfoElemLen
;
1010 ASSERT(ppucDesiredIE
);
1012 while (i4TotalIeLen
>= 2) {
1013 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1015 if (pucIEStart
[0] == ELEM_ID_ROAMING_CONSORTIUM
&& i4InfoElemLen
<= i4TotalIeLen
) {
1016 *ppucDesiredIE
= &pucIEStart
[0];
1018 } /* check desired EID */
1020 /* Select next information element. */
1021 i4TotalIeLen
-= i4InfoElemLen
;
1022 pucIEStart
+= i4InfoElemLen
;
1026 } /* wextSrchDesiredRoamingConsortiumIE */
1031 /*----------------------------------------------------------------------------*/
1033 * \brief Find the desired WPS Information Element according to desiredElemID.
1035 * \param[in] pucIEStart IE starting address.
1036 * \param[in] i4TotalIeLen Total length of all the IE.
1037 * \param[in] ucDesiredElemId Desired element ID.
1038 * \param[out] ppucDesiredIE Pointer to the desired IE.
1040 * \retval TRUE Find the desired IE.
1041 * \retval FALSE Desired IE not found.
1045 /*----------------------------------------------------------------------------*/
1047 wextSrchDesiredWPSIE (
1048 IN PUINT_8 pucIEStart
,
1049 IN INT_32 i4TotalIeLen
,
1050 IN UINT_8 ucDesiredElemId
,
1051 OUT PUINT_8
*ppucDesiredIE
)
1053 INT_32 i4InfoElemLen
;
1056 ASSERT(ppucDesiredIE
);
1058 while (i4TotalIeLen
>= 2) {
1059 i4InfoElemLen
= (INT_32
) pucIEStart
[1] + 2;
1061 if (pucIEStart
[0] == ucDesiredElemId
&& i4InfoElemLen
<= i4TotalIeLen
) {
1062 if (ucDesiredElemId
!= 0xDD) {
1064 *ppucDesiredIE
= &pucIEStart
[0];
1068 /* EID == 0xDD, check WPS IE */
1069 if (pucIEStart
[1] >= 4) {
1070 if (memcmp(&pucIEStart
[2], "\x00\x50\xf2\x04", 4) == 0) {
1071 *ppucDesiredIE
= &pucIEStart
[0];
1074 } /* check WPS IE length */
1075 } /* check EID == 0xDD */
1076 } /* check desired EID */
1078 /* Select next information element. */
1079 i4TotalIeLen
-= i4InfoElemLen
;
1080 pucIEStart
+= i4InfoElemLen
;
1084 } /* parseSearchDesiredWPSIE */
1088 /*----------------------------------------------------------------------------*/
1090 * \brief Get the name of the protocol used on the air.
1092 * \param[in] prDev Net device requested.
1093 * \param[in] prIwrInfo NULL.
1094 * \param[out] pcName Buffer to store protocol name string
1095 * \param[in] pcExtra NULL.
1097 * \retval 0 For success.
1099 * \note If netif_carrier_ok, protocol name is returned;
1100 * otherwise, "disconnected" is returned.
1102 /*----------------------------------------------------------------------------*/
1105 IN
struct net_device
*prNetDev
,
1106 IN
struct iw_request_info
*prIwrInfo
,
1111 ENUM_PARAM_NETWORK_TYPE_T eNetWorkType
;
1113 P_GLUE_INFO_T prGlueInfo
= NULL
;
1114 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1115 UINT_32 u4BufLen
= 0;
1119 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcName
)) {
1122 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1124 if (netif_carrier_ok(prNetDev
)) {
1126 rStatus
= kalIoctl(prGlueInfo
,
1127 wlanoidQueryNetworkTypeInUse
,
1129 sizeof(eNetWorkType
),
1136 switch(eNetWorkType
) {
1137 case PARAM_NETWORK_TYPE_DS
:
1138 strcpy(pcName
, "IEEE 802.11b");
1140 case PARAM_NETWORK_TYPE_OFDM24
:
1141 strcpy(pcName
, "IEEE 802.11bgn");
1143 case PARAM_NETWORK_TYPE_AUTOMODE
:
1144 case PARAM_NETWORK_TYPE_OFDM5
:
1145 strcpy(pcName
, "IEEE 802.11abgn");
1147 case PARAM_NETWORK_TYPE_FH
:
1149 strcpy(pcName
, "IEEE 802.11");
1154 strcpy(pcName
, "Disconnected");
1158 } /* wext_get_name */
1160 /*----------------------------------------------------------------------------*/
1162 * \brief To set the operating channel in the wireless device.
1164 * \param[in] prDev Net device requested.
1165 * \param[in] prIwrInfo NULL
1166 * \param[in] prFreq Buffer to store frequency information
1167 * \param[in] pcExtra NULL
1169 * \retval 0 For success.
1170 * \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS.
1171 * \retval -EINVAL Invalid channel frequency.
1173 * \note If infrastructure mode is IBSS, new channel frequency is set to device.
1174 * The range of channel number depends on different regulatory domain.
1176 /*----------------------------------------------------------------------------*/
1179 IN
struct net_device
*prNetDev
,
1180 IN
struct iw_request_info
*prIwReqInfo
,
1181 IN
struct iw_freq
*prIwFreq
,
1187 UINT_32 u4ChnlFreq
; /* Store channel or frequency information */
1189 P_GLUE_INFO_T prGlueInfo
= NULL
;
1190 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1191 UINT_32 u4BufLen
= 0;
1195 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prIwFreq
)) {
1198 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1201 printk("set m:%d, e:%d, i:%d, flags:%d\n",
1202 prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags);
1205 /* If setting by frequency, convert to a channel */
1206 if ((prIwFreq
->e
== 1) &&
1207 (prIwFreq
->m
>= (int) 2.412e8
) &&
1208 (prIwFreq
->m
<= (int) 2.484e8
)) {
1210 /* Change to KHz format */
1211 u4ChnlFreq
= (UINT_32
)(prIwFreq
->m
/ (KILO
/ 10));
1213 rStatus
= kalIoctl(prGlueInfo
,
1214 wlanoidSetFrequency
,
1222 if (WLAN_STATUS_SUCCESS
!= rStatus
) {
1226 /* Setting by channel number */
1227 else if ((prIwFreq
->m
> KILO
) || (prIwFreq
->e
> 0)) {
1231 /* Change to channel number format */
1232 u4ChnlFreq
= (UINT_32
)prIwFreq
->m
;
1234 rStatus
= kalIoctl(prGlueInfo
,
1246 if (WLAN_STATUS_SUCCESS
!= rStatus
) {
1255 } /* wext_set_freq */
1258 /*----------------------------------------------------------------------------*/
1260 * \brief To get the operating channel in the wireless device.
1262 * \param[in] prDev Net device requested.
1263 * \param[in] prIwrInfo NULL.
1264 * \param[out] prFreq Buffer to store frequency information.
1265 * \param[in] pcExtra NULL.
1267 * \retval 0 If netif_carrier_ok.
1268 * \retval -ENOTCONN Otherwise
1270 * \note If netif_carrier_ok, channel frequency information is stored in pFreq.
1272 /*----------------------------------------------------------------------------*/
1275 IN
struct net_device
*prNetDev
,
1276 IN
struct iw_request_info
*prIwrInfo
,
1277 OUT
struct iw_freq
*prIwFreq
,
1281 UINT_32 u4Channel
= 0;
1284 P_GLUE_INFO_T prGlueInfo
= NULL
;
1285 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1286 UINT_32 u4BufLen
= 0;
1290 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prIwFreq
)) {
1293 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1295 /* GeorgeKuo: TODO skip checking in IBSS mode */
1296 if (!netif_carrier_ok(prNetDev
)) {
1300 rStatus
= kalIoctl(prGlueInfo
,
1301 wlanoidQueryFrequency
,
1310 prIwFreq
->m
= (int) u4Channel
; /* freq in KHz */
1315 } /* wext_get_freq */
1318 /*----------------------------------------------------------------------------*/
1320 * \brief To set operating mode.
1322 * \param[in] prDev Net device requested.
1323 * \param[in] prIwrInfo NULL.
1324 * \param[in] pu4Mode Pointer to new operation mode.
1325 * \param[in] pcExtra NULL.
1327 * \retval 0 For success.
1328 * \retval -EOPNOTSUPP If new mode is not supported.
1330 * \note Device will run in new operation mode if it is valid.
1332 /*----------------------------------------------------------------------------*/
1335 IN
struct net_device
*prNetDev
,
1336 IN
struct iw_request_info
*prIwReqInfo
,
1337 IN
unsigned int *pu4Mode
,
1341 ENUM_PARAM_OP_MODE_T eOpMode
;
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
, pu4Mode
)) {
1352 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1356 eOpMode
= NET_TYPE_AUTO_SWITCH
;
1360 eOpMode
= NET_TYPE_IBSS
;
1364 eOpMode
= NET_TYPE_INFRA
;
1368 DBGLOG(INIT
, INFO
, ("%s(): Set UNSUPPORTED Mode = %d.\n", __FUNCTION__
, *pu4Mode
));
1372 //printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode);
1374 rStatus
= kalIoctl(prGlueInfo
,
1375 wlanoidSetInfrastructureMode
,
1385 /* after set operation mode, key table are cleared */
1387 /* reset wpa info */
1388 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
1389 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= 0;
1390 prGlueInfo
->rWpaInfo
.u4CipherGroup
= IW_AUTH_CIPHER_NONE
;
1391 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= IW_AUTH_CIPHER_NONE
;
1392 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
1393 #if CFG_SUPPORT_802_11W
1394 prGlueInfo
->rWpaInfo
.u4Mfp
= IW_AUTH_MFP_DISABLED
;
1398 } /* wext_set_mode */
1400 /*----------------------------------------------------------------------------*/
1402 * \brief To get operating mode.
1404 * \param[in] prNetDev Net device requested.
1405 * \param[in] prIwReqInfo NULL.
1406 * \param[out] pu4Mode Buffer to store operating mode information.
1407 * \param[in] pcExtra NULL.
1409 * \retval 0 If data is valid.
1410 * \retval -EINVAL Otherwise.
1412 * \note If netif_carrier_ok, operating mode information is stored in pu4Mode.
1414 /*----------------------------------------------------------------------------*/
1417 IN
struct net_device
*prNetDev
,
1418 IN
struct iw_request_info
*prIwReqInfo
,
1419 OUT
unsigned int *pu4Mode
,
1423 ENUM_PARAM_OP_MODE_T eOpMode
;
1425 P_GLUE_INFO_T prGlueInfo
= NULL
;
1426 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1427 UINT_32 u4BufLen
= 0;
1431 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pu4Mode
)) {
1434 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1436 rStatus
= kalIoctl(prGlueInfo
,
1437 wlanoidQueryInfrastructureMode
,
1450 *pu4Mode
= IW_MODE_ADHOC
;
1453 case NET_TYPE_INFRA
:
1454 *pu4Mode
= IW_MODE_INFRA
;
1457 case NET_TYPE_AUTO_SWITCH
:
1458 *pu4Mode
= IW_MODE_AUTO
;
1462 DBGLOG(INIT
, INFO
, ("%s(): Get UNKNOWN Mode.\n", __FUNCTION__
));
1467 } /* wext_get_mode */
1469 /*----------------------------------------------------------------------------*/
1471 * \brief To get the valid range for each configurable STA setting value.
1473 * \param[in] prDev Net device requested.
1474 * \param[in] prIwrInfo NULL.
1475 * \param[in] prData Pointer to iw_point structure, not used.
1476 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1477 * function, wext_support_ioctl() or ioctl_standard_call() in
1480 * \retval 0 If data is valid.
1482 * \note The extra buffer (pcExtra) is filled with information from driver.
1484 /*----------------------------------------------------------------------------*/
1487 IN
struct net_device
*prNetDev
,
1488 IN
struct iw_request_info
*prIwrInfo
,
1489 IN
struct iw_point
*prData
,
1493 struct iw_range
*prRange
= NULL
;
1494 PARAM_RATES_EX aucSuppRate
= {0}; /* data buffers */
1497 P_GLUE_INFO_T prGlueInfo
= NULL
;
1498 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1499 UINT_32 u4BufLen
= 0;
1503 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcExtra
)) {
1506 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1508 prRange
= (struct iw_range
*) pcExtra
;
1510 memset(prRange
, 0, sizeof(*prRange
));
1511 prRange
->throughput
= 20000000; /* 20Mbps */
1512 prRange
->min_nwid
= 0; /* not used */
1513 prRange
->max_nwid
= 0; /* not used */
1515 /* scan_capa not implemented */
1517 /* event_capa[6]: kernel + driver capabilities */
1518 prRange
->event_capa
[0] = (IW_EVENT_CAPA_K_0
1519 | IW_EVENT_CAPA_MASK(SIOCGIWAP
)
1520 | IW_EVENT_CAPA_MASK(SIOCGIWSCAN
)
1521 /* can't display meaningful string in iwlist
1522 | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW)
1523 | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)
1524 | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE)
1525 | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND)
1528 prRange
->event_capa
[1] = IW_EVENT_CAPA_K_1
;
1530 /* report 2.4G channel and frequency only */
1531 prRange
->num_channels
= (__u16
) NUM_CHANNELS
;
1532 prRange
->num_frequency
= (__u8
) NUM_CHANNELS
;
1533 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
1534 /* iwlib takes this number as channel number */
1535 prRange
->freq
[i
].i
= i
+ 1;
1536 prRange
->freq
[i
].m
= channel_freq
[i
];
1537 prRange
->freq
[i
].e
= 6; /* Values in table in MHz */
1542 wlanoidQuerySupportedRates
,
1544 sizeof(aucSuppRate
),
1553 for (i
= 0; i
< IW_MAX_BITRATES
&& i
< PARAM_MAX_LEN_RATES_EX
; i
++) {
1554 if (aucSuppRate
[i
] == 0) {
1557 prRange
->bitrate
[i
] = (aucSuppRate
[i
] & 0x7F) * 500000; /* 0.5Mbps */
1559 prRange
->num_bitrates
= i
;
1561 prRange
->min_rts
= 0;
1562 prRange
->max_rts
= 2347;
1563 prRange
->min_frag
= 256;
1564 prRange
->max_frag
= 2346;
1566 prRange
->min_pmp
= 0; /* power management by driver */
1567 prRange
->max_pmp
= 0; /* power management by driver */
1568 prRange
->min_pmt
= 0; /* power management by driver */
1569 prRange
->max_pmt
= 0; /* power management by driver */
1570 prRange
->pmp_flags
= IW_POWER_RELATIVE
; /* pm default flag */
1571 prRange
->pmt_flags
= IW_POWER_ON
; /* pm timeout flag */
1572 prRange
->pm_capa
= IW_POWER_ON
; /* power management by driver */
1574 prRange
->encoding_size
[0] = 5; /* wep40 */
1575 prRange
->encoding_size
[1] = 16; /* tkip */
1576 prRange
->encoding_size
[2] = 16; /* ckip */
1577 prRange
->encoding_size
[3] = 16; /* ccmp */
1578 prRange
->encoding_size
[4] = 13; /* wep104 */
1579 prRange
->encoding_size
[5] = 16; /* wep128 */
1580 prRange
->num_encoding_sizes
= 6;
1581 prRange
->max_encoding_tokens
= 6; /* token? */
1583 #if WIRELESS_EXT < 17
1584 prRange
->txpower_capa
= 0x0002; /* IW_TXPOW_RELATIVE */
1586 prRange
->txpower_capa
= IW_TXPOW_RELATIVE
;
1588 prRange
->num_txpower
= 5;
1589 prRange
->txpower
[0] = 0; /* minimum */
1590 prRange
->txpower
[1] = 25; /* 25% */
1591 prRange
->txpower
[2] = 50; /* 50% */
1592 prRange
->txpower
[3] = 100; /* 100% */
1594 prRange
->we_version_compiled
= WIRELESS_EXT
;
1595 prRange
->we_version_source
= WIRELESS_EXT
;
1597 prRange
->retry_capa
= IW_RETRY_LIMIT
;
1598 prRange
->retry_flags
= IW_RETRY_LIMIT
;
1599 prRange
->min_retry
= 7;
1600 prRange
->max_retry
= 7;
1601 prRange
->r_time_flags
= IW_RETRY_ON
;
1602 prRange
->min_r_time
= 0;
1603 prRange
->max_r_time
= 0;
1605 /* signal strength and link quality */
1606 /* Just define range here, reporting value moved to wext_get_stats() */
1607 prRange
->sensitivity
= -83; /* fixed value */
1608 prRange
->max_qual
.qual
= 100; /* max 100% */
1609 prRange
->max_qual
.level
= (__u8
)(0x100 - 0); /* max 0 dbm */
1610 prRange
->max_qual
.noise
= (__u8
)(0x100 - 0); /* max 0 dbm */
1613 #if WIRELESS_EXT > 17
1614 prRange
->enc_capa
= IW_ENC_CAPA_WPA
|
1616 IW_ENC_CAPA_CIPHER_TKIP
|
1617 IW_ENC_CAPA_CIPHER_CCMP
;
1620 /* min_pms; Minimal PM saving */
1621 /* max_pms; Maximal PM saving */
1622 /* pms_flags; How to decode max/min PM saving */
1624 /* modul_capa; IW_MODUL_* bit field */
1625 /* bitrate_capa; Types of bitrates supported */
1628 } /* wext_get_range */
1631 /*----------------------------------------------------------------------------*/
1633 * \brief To set BSSID of AP to connect.
1635 * \param[in] prDev Net device requested.
1636 * \param[in] prIwrInfo NULL.
1637 * \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID.
1638 * \param[in] pcExtra NULL.
1640 * \retval 0 For success.
1642 * \note Desired AP's BSSID is set to driver.
1644 /*----------------------------------------------------------------------------*/
1647 IN
struct net_device
*prDev
,
1648 IN
struct iw_request_info
*prIwrInfo
,
1649 IN
struct sockaddr
*prAddr
,
1657 /*----------------------------------------------------------------------------*/
1659 * \brief To get AP MAC address.
1661 * \param[in] prDev Net device requested.
1662 * \param[in] prIwrInfo NULL.
1663 * \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID.
1664 * \param[in] pcExtra NULL.
1666 * \retval 0 If netif_carrier_ok.
1667 * \retval -ENOTCONN Otherwise.
1669 * \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data.
1671 /*----------------------------------------------------------------------------*/
1674 IN
struct net_device
*prNetDev
,
1675 IN
struct iw_request_info
*prIwrInfo
,
1676 OUT
struct sockaddr
*prAddr
,
1680 P_GLUE_INFO_T prGlueInfo
= NULL
;
1681 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1682 UINT_32 u4BufLen
= 0;
1686 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prAddr
)) {
1689 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1691 //if (!netif_carrier_ok(prNetDev)) {
1692 // return -ENOTCONN;
1695 if(prGlueInfo
->eParamMediaStateIndicated
== PARAM_MEDIA_STATE_DISCONNECTED
){
1696 memset(prAddr
, 0, 6);
1700 rStatus
= kalIoctl(prGlueInfo
,
1713 /*----------------------------------------------------------------------------*/
1715 * \brief To set mlme operation request.
1717 * \param[in] prDev Net device requested.
1718 * \param[in] prIwrInfo NULL.
1719 * \param[in] prData Pointer of iw_point header.
1720 * \param[in] pcExtra Pointer to iw_mlme structure mlme request information.
1722 * \retval 0 For success.
1723 * \retval -EOPNOTSUPP unsupported IW_MLME_ command.
1724 * \retval -EINVAL Set MLME Fail, different bssid.
1726 * \note Driver will start mlme operation if valid.
1728 /*----------------------------------------------------------------------------*/
1731 IN
struct net_device
*prNetDev
,
1732 IN
struct iw_request_info
*prIwrInfo
,
1733 IN
struct iw_point
*prData
,
1737 struct iw_mlme
*prMlme
= NULL
;
1740 P_GLUE_INFO_T prGlueInfo
= NULL
;
1741 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1742 UINT_32 u4BufLen
= 0;
1746 if (FALSE
== GLUE_CHK_PR2(prNetDev
, pcExtra
)) {
1749 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1751 prMlme
= (struct iw_mlme
*)pcExtra
;
1752 if (prMlme
->cmd
== IW_MLME_DEAUTH
|| prMlme
->cmd
== IW_MLME_DISASSOC
) {
1753 if (!netif_carrier_ok(prNetDev
)) {
1754 DBGLOG(INIT
, INFO
, ("[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"));
1758 rStatus
= kalIoctl(prGlueInfo
,
1759 wlanoidSetDisassociate
,
1770 DBGLOG(INIT
, INFO
, ("[wifi] unsupported IW_MLME_ command :%d\n", prMlme
->cmd
));
1773 } /* wext_set_mlme */
1775 /*----------------------------------------------------------------------------*/
1777 * \brief To issue scan request.
1779 * \param[in] prDev Net device requested.
1780 * \param[in] prIwrInfo NULL.
1781 * \param[in] prData NULL.
1782 * \param[in] pcExtra NULL.
1784 * \retval 0 For success.
1785 * \retval -EFAULT Tx power is off.
1787 * \note Device will start scanning.
1789 /*----------------------------------------------------------------------------*/
1791 wext_set_scan(IN
struct net_device
*prNetDev
,
1792 IN
struct iw_request_info
*prIwrInfo
, IN
struct iw_scan_req
*prIwScanReq
, IN
char *pcExtra
)
1794 P_GLUE_INFO_T prGlueInfo
= NULL
;
1795 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1796 UINT_32 u4BufLen
= 0;
1800 if (FALSE
== GLUE_CHK_DEV(prNetDev
)) {
1803 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1805 #if WIRELESS_EXT > 17
1808 essid_len
= prIwScanReq
->essid_len
;
1811 init_completion(&prGlueInfo
->rScanComp
);
1813 // TODO: parse flags and issue different scan requests?
1815 rStatus
= kalIoctl(prGlueInfo
,
1816 wlanoidSetBssidListScan
,
1825 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ);
1826 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
1830 } /* wext_set_scan */
1833 /*----------------------------------------------------------------------------*/
1835 * \brief To write the ie to buffer
1838 /*----------------------------------------------------------------------------*/
1839 static inline int snprintf_hex(char *buf
, size_t buf_size
, const u8
*data
,
1843 char *pos
= buf
, *end
= buf
+ buf_size
;
1849 for (i
= 0; i
< len
; i
++) {
1850 ret
= snprintf(pos
, end
- pos
, "%02x",
1852 if (ret
< 0 || ret
>= end
- pos
) {
1863 /*----------------------------------------------------------------------------*/
1865 * \brief To get scan results, transform results from driver's format to WE's.
1867 * \param[in] prDev Net device requested.
1868 * \param[in] prIwrInfo NULL.
1869 * \param[out] prData Pointer to iw_point structure, pData->length is the size of
1870 * pcExtra buffer before used, and is updated after filling scan
1872 * \param[out] pcExtra Pointer to buffer which is allocated by caller of this
1873 * function, wext_support_ioctl() or ioctl_standard_call() in
1876 * \retval 0 For success.
1877 * \retval -ENOMEM If dynamic memory allocation fail.
1878 * \retval -E2BIG Invalid length.
1880 * \note Scan results is filled into pcExtra buffer, data size is updated in
1883 /*----------------------------------------------------------------------------*/
1886 IN
struct net_device
*prNetDev
,
1887 IN
struct iw_request_info
*prIwrInfo
,
1888 IN OUT
struct iw_point
*prData
,
1894 P_PARAM_BSSID_LIST_EX_T prList
= NULL
;
1895 P_PARAM_BSSID_EX_T prBss
= NULL
;
1896 P_PARAM_VARIABLE_IE_T prDesiredIE
= NULL
;
1897 struct iw_event iwEvent
; /* local iw_event buffer */
1899 /* write pointer of extra buffer */
1901 /* pointer to the end of last full entry in extra buffer */
1902 char *pcValidEntryEnd
= NULL
;
1903 char *pcEnd
= NULL
; /* end of extra buffer */
1905 UINT_32 u4AllocBufLen
= 0;
1907 /* arrange rate information */
1908 UINT_32 u4HighestRate
= 0;
1909 char aucRatesBuf
[64];
1915 P_GLUE_INFO_T prGlueInfo
= NULL
;
1916 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
1917 UINT_32 u4BufLen
= 0;
1922 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prData
, pcExtra
)) {
1925 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
1927 /* Initialize local variables */
1929 pcValidEntryEnd
= pcExtra
;
1930 pcEnd
= pcExtra
+ prData
->length
; /* end of extra buffer */
1932 /* Allocate another query buffer with the same size of extra buffer */
1933 u4AllocBufLen
= prData
->length
;
1934 prList
= kalMemAlloc(u4AllocBufLen
, VIR_MEM_TYPE
);
1935 if (prList
== NULL
) {
1936 DBGLOG(INIT
, INFO
, ("[wifi] no memory for scan list:%d\n", prData
->length
));
1940 prList
->u4NumberOfItems
= 0;
1942 /* wait scan done */
1943 //printk ("wait for scan results\n");
1944 //wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ);
1946 rStatus
= kalIoctl(prGlueInfo
,
1947 wlanoidQueryBssidList
,
1956 if (rStatus
== WLAN_STATUS_INVALID_LENGTH
) {
1957 /* Buffer length is not large enough. */
1958 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
1960 #if WIRELESS_EXT >= 17
1961 /* This feature is supported in WE-17 or above, limited by iwlist.
1962 ** Return -E2BIG and iwlist will request again with a larger buffer.
1965 /* Update length to give application a hint on result length */
1966 prData
->length
= (__u16
)u4BufLen
;
1969 /* Realloc a larger query buffer here, but don't write too much to extra
1970 ** buffer when filling it later.
1972 kalMemFree(prList
, VIR_MEM_TYPE
, u4AllocBufLen
);
1974 u4AllocBufLen
= u4BufLen
;
1975 prList
= kalMemAlloc(u4AllocBufLen
, VIR_MEM_TYPE
);
1976 if (prList
== NULL
) {
1977 DBGLOG(INIT
, INFO
, ("[wifi] no memory for larger scan list :%u\n", u4BufLen
));
1981 prList
->NumberOfItems
= 0;
1983 rStatus
= kalIoctl(prGlueInfo
,
1984 wlanoidQueryBssidList
,
1993 if (rStatus
== WLAN_STATUS_INVALID_LENGTH
) {
1994 DBGLOG(INIT
, INFO
, ("[wifi] larger buf:%u result:%u\n", u4AllocBufLen
, u4BufLen
));
1996 prData
->length
= (__u16
)u4BufLen
;
1999 #endif /* WIRELESS_EXT >= 17 */
2004 if (prList
->u4NumberOfItems
> CFG_MAX_NUM_BSS_LIST
) {
2005 DBGLOG(INIT
, INFO
, ("[wifi] strange scan result count:%u\n",
2006 prList
->u4NumberOfItems
));
2010 /* Copy required data from pList to pcExtra */
2011 prBss
= &prList
->arBssid
[0]; /* set to the first entry */
2012 for (i
= 0; i
< prList
->u4NumberOfItems
; ++i
) {
2014 iwEvent
.cmd
= SIOCGIWAP
;
2015 iwEvent
.len
= IW_EV_ADDR_LEN
;
2016 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2018 iwEvent
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
2019 memcpy(iwEvent
.u
.ap_addr
.sa_data
, prBss
->arMacAddress
, ETH_ALEN
);
2020 memcpy(pcCur
, &iwEvent
, IW_EV_ADDR_LEN
);
2021 pcCur
+= IW_EV_ADDR_LEN
;
2024 iwEvent
.cmd
= SIOCGIWESSID
;
2025 /* Modification to user space pointer(essid.pointer) is not needed. */
2026 iwEvent
.u
.essid
.length
= (__u16
)prBss
->rSsid
.u4SsidLen
;
2027 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.essid
.length
;
2029 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2031 iwEvent
.u
.essid
.flags
= 1;
2032 iwEvent
.u
.essid
.pointer
= NULL
;
2034 #if WIRELESS_EXT <= 18
2035 memcpy(pcCur
, &iwEvent
, iwEvent
.len
);
2037 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2038 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2039 &iwEvent
.u
.data
.length
,
2040 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2042 memcpy(pcCur
+ IW_EV_POINT_LEN
, prBss
->rSsid
.aucSsid
, iwEvent
.u
.essid
.length
);
2043 pcCur
+= iwEvent
.len
;
2045 iwEvent
.cmd
= SIOCGIWFREQ
;
2046 iwEvent
.len
= IW_EV_FREQ_LEN
;
2047 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2049 iwEvent
.u
.freq
.m
= prBss
->rConfiguration
.u4DSConfig
;
2050 iwEvent
.u
.freq
.e
= 3; /* (in KHz) */
2051 iwEvent
.u
.freq
.i
= 0;
2052 memcpy(pcCur
, &iwEvent
, IW_EV_FREQ_LEN
);
2053 pcCur
+= IW_EV_FREQ_LEN
;
2055 /* Operation Mode */
2056 iwEvent
.cmd
= SIOCGIWMODE
;
2057 iwEvent
.len
= IW_EV_UINT_LEN
;
2058 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2060 if (prBss
->eOpMode
== NET_TYPE_IBSS
) {
2061 iwEvent
.u
.mode
= IW_MODE_ADHOC
;
2063 else if (prBss
->eOpMode
== NET_TYPE_INFRA
) {
2064 iwEvent
.u
.mode
= IW_MODE_INFRA
;
2067 iwEvent
.u
.mode
= IW_MODE_AUTO
;
2069 memcpy(pcCur
, &iwEvent
, IW_EV_UINT_LEN
);
2070 pcCur
+= IW_EV_UINT_LEN
;
2073 iwEvent
.cmd
= IWEVQUAL
;
2074 iwEvent
.len
= IW_EV_QUAL_LEN
;
2075 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2077 iwEvent
.u
.qual
.qual
= 0; /* Quality not available now */
2078 /* -100 < Rssi < -10, normalized by adding 0x100 */
2079 iwEvent
.u
.qual
.level
= 0x100 + prBss
->rRssi
;
2080 iwEvent
.u
.qual
.noise
= 0; /* Noise not available now */
2081 iwEvent
.u
.qual
.updated
= IW_QUAL_QUAL_INVALID
| IW_QUAL_LEVEL_UPDATED \
2082 | IW_QUAL_NOISE_INVALID
;
2083 memcpy(pcCur
, &iwEvent
, IW_EV_QUAL_LEN
);
2084 pcCur
+= IW_EV_QUAL_LEN
;
2087 iwEvent
.cmd
= SIOCGIWENCODE
;
2088 iwEvent
.len
= IW_EV_POINT_LEN
;
2089 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2091 iwEvent
.u
.data
.pointer
= NULL
;
2092 iwEvent
.u
.data
.flags
= 0;
2093 iwEvent
.u
.data
.length
= 0;
2094 if(!prBss
->u4Privacy
) {
2095 iwEvent
.u
.data
.flags
|= IW_ENCODE_DISABLED
;
2097 #if WIRELESS_EXT <= 18
2098 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2100 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2101 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2102 &iwEvent
.u
.data
.length
,
2103 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2105 pcCur
+= IW_EV_POINT_LEN
;
2107 /* rearrange rate information */
2108 u4BufIndex
= sprintf(aucRatesBuf
, "Rates (Mb/s):");
2110 for (j
= 0; j
< PARAM_MAX_LEN_RATES_EX
; ++j
) {
2111 UINT_8 curRate
= prBss
->rSupportedRates
[j
] & 0x7F;
2116 if (curRate
> u4HighestRate
) {
2117 u4HighestRate
= curRate
;
2120 if (curRate
== RATE_5_5M
) {
2121 u4BufIndex
+= sprintf(aucRatesBuf
+ u4BufIndex
, " 5.5");
2124 u4BufIndex
+= sprintf(aucRatesBuf
+ u4BufIndex
, " %d", curRate
/ 2);
2127 if (u4BufIndex
> sizeof(aucRatesBuf
)) {
2128 //printk("rate info too long\n");
2133 /* Report Highest Rates */
2134 iwEvent
.cmd
= SIOCGIWRATE
;
2135 iwEvent
.len
= IW_EV_PARAM_LEN
;
2136 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2138 iwEvent
.u
.bitrate
.value
= u4HighestRate
* 500000;
2139 iwEvent
.u
.bitrate
.fixed
= 0;
2140 iwEvent
.u
.bitrate
.disabled
= 0;
2141 iwEvent
.u
.bitrate
.flags
= 0;
2142 memcpy(pcCur
, &iwEvent
, iwEvent
.len
);
2143 pcCur
+= iwEvent
.len
;
2145 #if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */
2146 /* Report Residual Rates */
2147 iwEvent
.cmd
= IWEVCUSTOM
;
2148 iwEvent
.u
.data
.length
= u4BufIndex
;
2149 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2150 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2152 iwEvent
.u
.data
.flags
= 0;
2153 #if WIRELESS_EXT <= 18
2154 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2156 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2157 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2158 &iwEvent
.u
.data
.length
,
2159 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2161 memcpy(pcCur
+ IW_EV_POINT_LEN
, aucRatesBuf
, u4BufIndex
);
2162 pcCur
+= iwEvent
.len
;
2163 #endif /* WIRELESS_EXT >= 15 */
2166 if (wextSrchDesiredWPAIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2167 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2169 (PUINT_8
*)&prDesiredIE
)) {
2170 iwEvent
.cmd
= IWEVGENIE
;
2171 iwEvent
.u
.data
.flags
= 1;
2172 iwEvent
.u
.data
.length
= 2 + (__u16
)prDesiredIE
->ucLength
;
2173 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2174 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2176 #if WIRELESS_EXT <= 18
2177 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2179 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2180 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2181 &iwEvent
.u
.data
.length
,
2182 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2184 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2185 pcCur
+= iwEvent
.len
;
2188 #if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */
2189 if (wextSrchDesiredWPSIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2190 prBss
->u4IELength
- sizeof(PARAM_FIXED_IEs
),
2192 (PUINT_8
*)&prDesiredIE
)) {
2193 iwEvent
.cmd
= IWEVGENIE
;
2194 iwEvent
.u
.data
.flags
= 1;
2195 iwEvent
.u
.data
.length
= 2 + (__u16
)prDesiredIE
->ucLength
;
2196 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2197 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2199 #if WIRELESS_EXT <= 18
2200 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2202 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2203 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2204 &iwEvent
.u
.data
.length
,
2205 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2207 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2208 pcCur
+= iwEvent
.len
;
2213 /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */
2214 /* pBss->IEs starts from timestamp */
2215 if (wextSrchDesiredWPAIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2216 prBss
->u4IELength
-sizeof(PARAM_FIXED_IEs
),
2218 (PUINT_8
*)&prDesiredIE
)) {
2220 iwEvent
.cmd
= IWEVGENIE
;
2221 iwEvent
.u
.data
.flags
= 1;
2222 iwEvent
.u
.data
.length
= 2 + (__u16
)prDesiredIE
->ucLength
;
2223 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2224 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2226 #if WIRELESS_EXT <= 18
2227 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2229 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2230 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2231 &iwEvent
.u
.data
.length
,
2232 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2234 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2235 pcCur
+= iwEvent
.len
;
2238 #if CFG_SUPPORT_WAPI /* Android+ */
2239 if (wextSrchDesiredWAPIIE(&prBss
->aucIEs
[sizeof(PARAM_FIXED_IEs
)],
2240 prBss
->u4IELength
-sizeof(PARAM_FIXED_IEs
),
2241 (PUINT_8
*)&prDesiredIE
)) {
2244 iwEvent
.cmd
= IWEVGENIE
;
2245 iwEvent
.u
.data
.flags
= 1;
2246 iwEvent
.u
.data
.length
= 2 + (__u16
)prDesiredIE
->ucLength
;
2247 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2248 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2250 #if WIRELESS_EXT <= 18
2251 memcpy(pcCur
, &iwEvent
, IW_EV_POINT_LEN
);
2253 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2254 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2255 &iwEvent
.u
.data
.length
,
2256 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2258 memcpy(pcCur
+ IW_EV_POINT_LEN
, prDesiredIE
, 2 + prDesiredIE
->ucLength
);
2259 pcCur
+= iwEvent
.len
;
2261 iwEvent
.cmd
= IWEVCUSTOM
;
2262 iwEvent
.u
.data
.length
= (2 + prDesiredIE
->ucLength
) * 2 + 8 /* wapi_ie= */;
2263 iwEvent
.len
= IW_EV_POINT_LEN
+ iwEvent
.u
.data
.length
;
2264 if ((pcCur
+ iwEvent
.len
) > pcEnd
)
2266 iwEvent
.u
.data
.flags
= 1;
2268 memcpy(pcCur
, &iwEvent
, IW_EV_LCP_LEN
);
2269 memcpy(pcCur
+ IW_EV_LCP_LEN
,
2270 &iwEvent
.u
.data
.length
,
2271 sizeof(struct iw_point
) - IW_EV_POINT_OFF
);
2273 pcCur
+= (IW_EV_POINT_LEN
);
2275 pcCur
+= sprintf(pcCur
, "wapi_ie=");
2277 snprintf_hex(pcCur
, pcEnd
- pcCur
, (UINT_8
*)prDesiredIE
, prDesiredIE
->ucLength
+ 2);
2279 pcCur
+= (2 + prDesiredIE
->ucLength
) * 2 /* iwEvent.len */;
2283 /* Complete an entry. Update end of valid entry */
2284 pcValidEntryEnd
= pcCur
;
2285 /* Extract next bss */
2286 prBss
= (P_PARAM_BSSID_EX_T
)((char *)prBss
+ prBss
->u4Length
);
2289 /* Update valid data length for caller function and upper layer
2292 prData
->length
= (pcValidEntryEnd
- pcExtra
);
2293 //printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen);
2295 //kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
2298 /* free local query buffer */
2300 kalMemFree(prList
, VIR_MEM_TYPE
, u4AllocBufLen
);
2304 } /* wext_get_scan */
2306 /*----------------------------------------------------------------------------*/
2308 * \brief To set desired network name ESSID.
2310 * \param[in] prDev Net device requested.
2311 * \param[in] prIwrInfo NULL.
2312 * \param[in] prEssid Pointer of iw_point header.
2313 * \param[in] pcExtra Pointer to buffer srtoring essid string.
2315 * \retval 0 If netif_carrier_ok.
2316 * \retval -E2BIG Essid string length is too big.
2317 * \retval -EINVAL pcExtra is null pointer.
2318 * \retval -EFAULT Driver fail to set new essid.
2320 * \note If string lengh is ok, device will try connecting to the new network.
2322 /*----------------------------------------------------------------------------*/
2325 IN
struct net_device
*prNetDev
,
2326 IN
struct iw_request_info
*prIwrInfo
,
2327 IN
struct iw_point
*prEssid
,
2331 PARAM_SSID_T rNewSsid
;
2333 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
2334 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
2336 P_GLUE_INFO_T prGlueInfo
= NULL
;
2337 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2338 UINT_32 u4BufLen
= 0;
2343 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEssid
, pcExtra
)) {
2346 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2348 if (prEssid
->length
> IW_ESSID_MAX_SIZE
) {
2354 if (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_DISABLED
) {
2355 eAuthMode
= (prGlueInfo
->rWpaInfo
.u4AuthAlg
== IW_AUTH_ALG_OPEN_SYSTEM
) ?
2356 AUTH_MODE_OPEN
: AUTH_MODE_AUTO_SWITCH
;
2357 //printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n",
2358 // (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared");
2362 switch(prGlueInfo
->rWpaInfo
.u4KeyMgmt
) {
2363 case IW_AUTH_KEY_MGMT_802_1X
:
2365 (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA
) ?
2366 AUTH_MODE_WPA
: AUTH_MODE_WPA2
;
2367 //printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n",
2368 // (eAuthMode == AUTH_MODE_WPA) ? "" : "2");
2370 case IW_AUTH_KEY_MGMT_PSK
:
2372 (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA
) ?
2373 AUTH_MODE_WPA_PSK
: AUTH_MODE_WPA2_PSK
;
2374 //printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n",
2375 // (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2");
2377 #if CFG_SUPPORT_WAPI /* Android+ */
2378 case IW_AUTH_KEY_MGMT_WAPI_PSK
:
2380 case IW_AUTH_KEY_MGMT_WAPI_CERT
:
2384 //#if defined (IW_AUTH_KEY_MGMT_WPA_NONE)
2385 // case IW_AUTH_KEY_MGMT_WPA_NONE:
2386 // eAuthMode = AUTH_MODE_WPA_NONE;
2387 // //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n");
2390 #if CFG_SUPPORT_802_11W
2391 case IW_AUTH_KEY_MGMT_802_1X_SHA256
:
2392 eAuthMode
= AUTH_MODE_WPA2
;
2394 case IW_AUTH_KEY_MGMT_PSK_SHA256
:
2395 eAuthMode
= AUTH_MODE_WPA2_PSK
;
2399 //printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n",
2400 // prGlueInfo->rWpaInfo.u4KeyMgmt);
2401 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
2407 rStatus
= kalIoctl(prGlueInfo
,
2417 /* set encryption status */
2418 cipher
= prGlueInfo
->rWpaInfo
.u4CipherGroup
|
2419 prGlueInfo
->rWpaInfo
.u4CipherPairwise
;
2420 if (cipher
& IW_AUTH_CIPHER_CCMP
) {
2421 //printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n");
2422 eEncStatus
= ENUM_ENCRYPTION3_ENABLED
;
2424 else if (cipher
& IW_AUTH_CIPHER_TKIP
) {
2425 //printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n");
2426 eEncStatus
= ENUM_ENCRYPTION2_ENABLED
;
2428 else if (cipher
& (IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
)) {
2429 //printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n");
2430 eEncStatus
= ENUM_ENCRYPTION1_ENABLED
;
2432 else if (cipher
& IW_AUTH_CIPHER_NONE
){
2433 //printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n");
2434 if (prGlueInfo
->rWpaInfo
.fgPrivacyInvoke
)
2435 eEncStatus
= ENUM_ENCRYPTION1_ENABLED
;
2437 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
2440 //printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n");
2441 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
2444 rStatus
= kalIoctl(prGlueInfo
,
2445 wlanoidSetEncryptionStatus
,
2454 #if WIRELESS_EXT < 21
2455 /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before
2456 ** 2.6.19. Cut the trailing '\0'.
2458 rNewSsid
.u4SsidLen
= (prEssid
->length
) ? prEssid
->length
- 1 : 0;
2460 rNewSsid
.u4SsidLen
= prEssid
->length
;
2462 kalMemCopy(rNewSsid
.aucSsid
, pcExtra
, rNewSsid
.u4SsidLen
);
2465 rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0';
2466 printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid);
2469 if (kalIoctl(prGlueInfo
,
2472 sizeof(PARAM_SSID_T
),
2477 &u4BufLen
) != WLAN_STATUS_SUCCESS
) {
2478 //printk(KERN_WARNING "Fail to set ssid\n");
2484 } /* wext_set_essid */
2486 /*----------------------------------------------------------------------------*/
2488 * \brief To get current network name ESSID.
2490 * \param[in] prDev Net device requested.
2491 * \param[in] prIwrInfo NULL.
2492 * \param[in] prEssid Pointer to iw_point structure containing essid information.
2493 * \param[out] pcExtra Pointer to buffer srtoring essid string.
2495 * \retval 0 If netif_carrier_ok.
2496 * \retval -ENOTCONN Otherwise.
2498 * \note If netif_carrier_ok, network essid is stored in pcExtra.
2500 /*----------------------------------------------------------------------------*/
2501 //static PARAM_SSID_T ssid;
2504 IN
struct net_device
*prNetDev
,
2505 IN
struct iw_request_info
*prIwrInfo
,
2506 IN
struct iw_point
*prEssid
,
2510 //PARAM_SSID_T ssid;
2512 P_PARAM_SSID_T prSsid
;
2513 P_GLUE_INFO_T prGlueInfo
= NULL
;
2514 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2515 UINT_32 u4BufLen
= 0;
2521 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEssid
, pcExtra
)) {
2524 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2526 //if (!netif_carrier_ok(prNetDev)) {
2527 // return -ENOTCONN;
2530 prSsid
= kalMemAlloc(sizeof(PARAM_SSID_T
), VIR_MEM_TYPE
);
2536 rStatus
= kalIoctl(prGlueInfo
,
2539 sizeof(PARAM_SSID_T
),
2546 if ((rStatus
== WLAN_STATUS_SUCCESS
) && (prSsid
->u4SsidLen
<= MAX_SSID_LEN
)) {
2547 kalMemCopy(pcExtra
, prSsid
->aucSsid
, prSsid
->u4SsidLen
);
2548 prEssid
->length
= prSsid
->u4SsidLen
;
2552 kalMemFree(prSsid
, VIR_MEM_TYPE
, sizeof(PARAM_SSID_T
));
2555 } /* wext_get_essid */
2560 /*----------------------------------------------------------------------------*/
2562 * \brief To set tx desired bit rate. Three cases here
2563 * iwconfig wlan0 auto -> Set to origianl supported rate set.
2564 * iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate.
2565 * iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps
2567 * \param[in] prNetDev Pointer to the net_device handler.
2568 * \param[in] prIwReqInfo Pointer to the Request Info.
2569 * \param[in] prRate Pointer to the Rate Parameter.
2570 * \param[in] pcExtra Pointer to the extra buffer.
2572 * \retval 0 Update desired rate.
2573 * \retval -EINVAL Wrong parameter
2575 /*----------------------------------------------------------------------------*/
2578 IN
struct net_device
*prNetDev
,
2579 IN
struct iw_request_info
*prIwReqInfo
,
2580 IN
struct iw_param
*prRate
,
2584 PARAM_RATES_EX aucSuppRate
= {0};
2585 PARAM_RATES_EX aucNewRate
= {0};
2586 UINT_32 u4NewRateLen
= 0;
2589 P_GLUE_INFO_T prGlueInfo
= NULL
;
2590 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2591 UINT_32 u4BufLen
= 0;
2595 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRate
)) {
2598 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2601 printk("value = %d, fixed = %d, disable = %d, flags = %d\n",
2602 prRate->value, prRate->fixed, prRate->disabled, prRate->flags);
2605 rStatus
= wlanQueryInformation(
2606 prGlueInfo
->prAdapter
,
2607 wlanoidQuerySupportedRates
,
2609 sizeof(aucSuppRate
),
2613 if (prRate
->value
< 0) {
2614 if (prRate
->fixed
== 0) {
2615 /* iwconfig wlan0 rate auto */
2617 /* set full supported rate to device */
2618 /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */
2619 rStatus
= wlanSetInformation(
2620 prGlueInfo
->prAdapter
,
2621 wlanoidSetDesiredRates
,
2623 sizeof(aucSuppRate
),
2628 /* iwconfig wlan0 rate fixed */
2630 /* fix rate to what? DO NOTHING */
2636 aucNewRate
[0] = prRate
->value
/ 500000; /* In unit of 500k */
2638 for (i
= 0; i
< PARAM_MAX_LEN_RATES_EX
; i
++) {
2639 /* check the given value is supported */
2640 if (aucSuppRate
[i
] == 0) {
2644 if (aucNewRate
[0] == aucSuppRate
[i
]) {
2650 if (u4NewRateLen
== 0) {
2651 /* the given value is not supported */
2652 /* return error or use given rate as upper bound? */
2656 if (prRate
->fixed
== 0) {
2657 /* add all rates lower than desired rate */
2658 for (i
= 0; i
< PARAM_MAX_LEN_RATES_EX
; ++i
) {
2659 if (aucSuppRate
[i
] == 0) {
2663 if (aucSuppRate
[i
] < aucNewRate
[0]) {
2664 aucNewRate
[u4NewRateLen
++] = aucSuppRate
[i
];
2669 rStatus
= wlanSetInformation(
2670 prGlueInfo
->prAdapter
,
2671 wlanoidSetDesiredRates
,
2676 } /* wext_set_rate */
2680 /*----------------------------------------------------------------------------*/
2682 * \brief To get current tx bit rate.
2684 * \param[in] prDev Net device requested.
2685 * \param[in] prIwrInfo NULL.
2686 * \param[out] prRate Pointer to iw_param structure to store current tx rate.
2687 * \param[in] pcExtra NULL.
2689 * \retval 0 If netif_carrier_ok.
2690 * \retval -ENOTCONN Otherwise.
2692 * \note If netif_carrier_ok, current tx rate is stored in pRate.
2694 /*----------------------------------------------------------------------------*/
2697 IN
struct net_device
*prNetDev
,
2698 IN
struct iw_request_info
*prIwrInfo
,
2699 OUT
struct iw_param
*prRate
,
2703 P_GLUE_INFO_T prGlueInfo
= NULL
;
2704 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2705 UINT_32 u4BufLen
= 0;
2710 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRate
)) {
2713 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2715 if (!netif_carrier_ok(prNetDev
)) {
2720 rStatus
= kalIoctl(prGlueInfo
,
2721 wlanoidQueryLinkSpeed
,
2730 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
2734 prRate
->value
= u4Rate
* 100; /* u4Rate is in unit of 100bps */
2738 } /* wext_get_rate */
2741 /*----------------------------------------------------------------------------*/
2743 * \brief To set RTS/CTS theshold.
2745 * \param[in] prDev Net device requested.
2746 * \param[in] prIwrInfo NULL.
2747 * \param[in] prRts Pointer to iw_param structure containing rts threshold.
2748 * \param[in] pcExtra NULL.
2750 * \retval 0 For success.
2751 * \retval -EINVAL Given value is out of range.
2753 * \note If given value is valid, device will follow the new setting.
2755 /*----------------------------------------------------------------------------*/
2758 IN
struct net_device
*prNetDev
,
2759 IN
struct iw_request_info
*prIwrInfo
,
2760 IN
struct iw_param
*prRts
,
2764 PARAM_RTS_THRESHOLD u4RtsThresh
;
2766 P_GLUE_INFO_T prGlueInfo
= NULL
;
2767 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2768 UINT_32 u4BufLen
= 0;
2772 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRts
)) {
2775 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2777 if (prRts
->disabled
== 1) {
2780 else if (prRts
->value
< 0 || prRts
->value
> 2347) {
2784 u4RtsThresh
= (PARAM_RTS_THRESHOLD
)prRts
->value
;
2787 rStatus
= kalIoctl(prGlueInfo
,
2788 wlanoidSetRtsThreshold
,
2790 sizeof(u4RtsThresh
),
2799 prRts
->value
= (typeof(prRts
->value
))u4RtsThresh
;
2800 prRts
->disabled
= (prRts
->value
> 2347) ? 1 : 0;
2804 } /* wext_set_rts */
2806 /*----------------------------------------------------------------------------*/
2808 * \brief To get RTS/CTS theshold.
2810 * \param[in] prDev Net device requested.
2811 * \param[in] prIwrInfo NULL.
2812 * \param[out] prRts Pointer to iw_param structure containing rts threshold.
2813 * \param[in] pcExtra NULL.
2815 * \retval 0 Success.
2817 * \note RTS threshold is stored in pRts.
2819 /*----------------------------------------------------------------------------*/
2822 IN
struct net_device
*prNetDev
,
2823 IN
struct iw_request_info
*prIwrInfo
,
2824 OUT
struct iw_param
*prRts
,
2828 PARAM_RTS_THRESHOLD u4RtsThresh
;
2830 P_GLUE_INFO_T prGlueInfo
= NULL
;
2831 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2832 UINT_32 u4BufLen
= 0;
2836 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prRts
)) {
2839 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2841 rStatus
= kalIoctl(prGlueInfo
,
2842 wlanoidQueryRtsThreshold
,
2844 sizeof(u4RtsThresh
),
2853 prRts
->value
= (typeof(prRts
->value
))u4RtsThresh
;
2854 prRts
->disabled
= (prRts
->value
> 2347 || prRts
->value
< 0) ? 1 : 0;
2858 } /* wext_get_rts */
2860 /*----------------------------------------------------------------------------*/
2862 * \brief To get fragmentation threshold.
2864 * \param[in] prDev Net device requested.
2865 * \param[in] prIwrInfo NULL.
2866 * \param[out] prFrag Pointer to iw_param structure containing frag threshold.
2867 * \param[in] pcExtra NULL.
2869 * \retval 0 Success.
2871 * \note RTS threshold is stored in pFrag. Fragmentation is disabled.
2873 /*----------------------------------------------------------------------------*/
2876 IN
struct net_device
*prNetDev
,
2877 IN
struct iw_request_info
*prIwrInfo
,
2878 OUT
struct iw_param
*prFrag
,
2884 prFrag
->value
= 2346;
2886 prFrag
->disabled
= 1;
2888 } /* wext_get_frag */
2891 /*----------------------------------------------------------------------------*/
2893 * \brief To set TX power, or enable/disable the radio.
2895 * \param[in] prDev Net device requested.
2896 * \param[in] prIwrInfo NULL.
2897 * \param[in] prTxPow Pointer to iw_param structure containing tx power setting.
2898 * \param[in] pcExtra NULL.
2900 * \retval 0 Success.
2902 * \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used
2903 * to enable/disable the radio.
2905 /*----------------------------------------------------------------------------*/
2909 IN
struct net_device
*prNetDev
,
2910 IN
struct iw_request_info
*prIwrInfo
,
2911 IN
struct iw_param
*prTxPow
,
2916 //PARAM_DEVICE_POWER_STATE ePowerState;
2917 ENUM_ACPI_STATE_T ePowerState
;
2919 P_GLUE_INFO_T prGlueInfo
= NULL
;
2920 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
2921 UINT_32 u4BufLen
= 0;
2925 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prTxPow
)) {
2928 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
2930 if(prTxPow
->disabled
){
2931 /* <1> disconnect */
2932 rStatus
= kalIoctl(prGlueInfo
,
2933 wlanoidSetDisassociate
,
2941 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
2942 DBGLOG(INIT
, INFO
, ("######set disassoc failed\n"));
2944 DBGLOG(INIT
, INFO
, ("######set assoc ok\n"));
2947 /* <2> mark to power state flag*/
2948 ePowerState
= ACPI_STATE_D0
;
2949 DBGLOG(INIT
, INFO
, ("set to acpi d3(0)\n"));
2950 wlanSetAcpiState(prGlueInfo
->prAdapter
, ePowerState
);
2954 ePowerState
= ACPI_STATE_D0
;
2955 DBGLOG(INIT
, INFO
, ("set to acpi d0\n"));
2956 wlanSetAcpiState(prGlueInfo
->prAdapter
, ePowerState
);
2959 prGlueInfo
->ePowerState
= ePowerState
;
2962 } /* wext_set_txpow */
2967 /*----------------------------------------------------------------------------*/
2969 * \brief To get TX power.
2971 * \param[in] prDev Net device requested.
2972 * \param[in] prIwrInfo NULL.
2973 * \param[out] prTxPow Pointer to iw_param structure containing tx power setting.
2974 * \param[in] pcExtra NULL.
2976 * \retval 0 Success.
2978 * \note Tx power is stored in pTxPow.
2980 /*----------------------------------------------------------------------------*/
2983 IN
struct net_device
*prNetDev
,
2984 IN
struct iw_request_info
*prIwrInfo
,
2985 OUT
struct iw_param
*prTxPow
,
2989 //PARAM_DEVICE_POWER_STATE ePowerState;
2991 P_GLUE_INFO_T prGlueInfo
= NULL
;
2995 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prTxPow
)) {
2998 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3000 /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not
3001 * current state. Use GLUE_INFO_T to store state.
3003 //ePowerState = prGlueInfo->ePowerState;
3005 /* TxPow parameters: Fixed at relative 100% */
3006 #if WIRELESS_EXT < 17
3007 prTxPow
->flags
= 0x0002; /* IW_TXPOW_RELATIVE */
3009 prTxPow
->flags
= IW_TXPOW_RELATIVE
;
3011 prTxPow
->value
= 100;
3013 //prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE;
3014 prTxPow
->disabled
= TRUE
;
3017 } /* wext_get_txpow */
3020 /*----------------------------------------------------------------------------*/
3022 * \brief To get encryption cipher and key.
3024 * \param[in] prDev Net device requested.
3025 * \param[in] prIwrInfo NULL.
3026 * \param[out] prEnc Pointer to iw_point structure containing securiry information.
3027 * \param[in] pcExtra Buffer to store key content.
3029 * \retval 0 Success.
3031 * \note Securiry information is stored in pEnc except key content.
3033 /*----------------------------------------------------------------------------*/
3036 IN
struct net_device
*prNetDev
,
3037 IN
struct iw_request_info
*prIwrInfo
,
3038 OUT
struct iw_point
*prEnc
,
3043 //ENUM_ENCRYPTION_STATUS_T eEncMode;
3044 ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode
;
3046 P_GLUE_INFO_T prGlueInfo
= NULL
;
3047 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3048 UINT_32 u4BufLen
= 0;
3052 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prEnc
)) {
3055 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3058 rStatus
= kalIoctl(prGlueInfo
,
3059 wlanoidQueryEncryptionStatus
,
3071 case ENUM_WEP_DISABLED
:
3072 prEnc
->flags
= IW_ENCODE_DISABLED
;
3074 case ENUM_WEP_ENABLED
:
3075 prEnc
->flags
= IW_ENCODE_ENABLED
;
3077 case ENUM_WEP_KEY_ABSENT
:
3078 prEnc
->flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
3081 prEnc
->flags
= IW_ENCODE_ENABLED
;
3085 /* Cipher, Key Content, Key ID can't be queried */
3086 prEnc
->flags
|= IW_ENCODE_NOKEY
;
3089 } /* wext_get_encode */
3093 /*----------------------------------------------------------------------------*/
3095 * \brief To set encryption cipher and key.
3097 * \param[in] prDev Net device requested.
3098 * \param[in] prIwrInfo NULL.
3099 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
3100 * \param[in] pcExtra Pointer to key string buffer.
3102 * \retval 0 Success.
3103 * \retval -EINVAL Key ID error for WEP.
3104 * \retval -EFAULT Setting parameters to driver fail.
3105 * \retval -EOPNOTSUPP Key size not supported.
3107 * \note Securiry information is stored in pEnc.
3109 /*----------------------------------------------------------------------------*/
3110 static UINT_8 wepBuf
[48];
3114 IN
struct net_device
*prNetDev
,
3115 IN
struct iw_request_info
*prIwrInfo
,
3116 IN
struct iw_point
*prEnc
,
3121 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
3122 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
3123 //UINT_8 wepBuf[48];
3124 P_PARAM_WEP_T prWepKey
= (P_PARAM_WEP_T
) wepBuf
;
3126 P_GLUE_INFO_T prGlueInfo
= NULL
;
3127 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3128 UINT_32 u4BufLen
= 0;
3133 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEnc
, pcExtra
)) {
3136 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3138 /* reset to default mode */
3139 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
3140 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= 0;
3141 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= IW_AUTH_CIPHER_NONE
;
3142 prGlueInfo
->rWpaInfo
.u4CipherGroup
= IW_AUTH_CIPHER_NONE
;
3143 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
3144 #if CFG_SUPPORT_802_11W
3145 prGlueInfo
->rWpaInfo
.u4Mfp
= IW_AUTH_MFP_DISABLED
;
3148 /* iwconfig wlan0 key off */
3149 if ( (prEnc
->flags
& IW_ENCODE_MODE
) == IW_ENCODE_DISABLED
) {
3150 eAuthMode
= AUTH_MODE_OPEN
;
3152 rStatus
= kalIoctl(prGlueInfo
,
3162 eEncStatus
= ENUM_ENCRYPTION_DISABLED
;
3164 rStatus
= kalIoctl(prGlueInfo
,
3165 wlanoidSetEncryptionStatus
,
3177 /* iwconfig wlan0 key 0123456789 */
3178 /* iwconfig wlan0 key s:abcde */
3179 /* iwconfig wlan0 key 0123456789 [1] */
3180 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3181 /* check key size for WEP */
3182 if (prEnc
->length
== 5 || prEnc
->length
== 13 || prEnc
->length
== 16) {
3183 /* prepare PARAM_WEP key structure */
3184 prWepKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3185 (prEnc
->flags
& IW_ENCODE_INDEX
) -1 : 0;
3186 if (prWepKey
->u4KeyIndex
> 3) {
3187 /* key id is out of range */
3190 prWepKey
->u4KeyIndex
|= 0x80000000;
3191 prWepKey
->u4Length
= 12 + prEnc
->length
;
3192 prWepKey
->u4KeyLength
= prEnc
->length
;
3193 kalMemCopy(prWepKey
->aucKeyMaterial
, pcExtra
, prEnc
->length
);
3196 rStatus
= kalIoctl(prGlueInfo
,
3206 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3207 DBGLOG(INIT
, INFO
, ("wlanoidSetAddWep fail 0x%x\n", rStatus
));
3211 /* change to auto switch */
3212 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_SHARED_KEY
|
3213 IW_AUTH_ALG_OPEN_SYSTEM
;
3214 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
3216 rStatus
= kalIoctl(prGlueInfo
,
3226 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3227 //printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus);
3231 prGlueInfo
->rWpaInfo
.u4CipherPairwise
=
3232 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3233 prGlueInfo
->rWpaInfo
.u4CipherGroup
=
3234 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3236 eEncStatus
= ENUM_WEP_ENABLED
;
3239 rStatus
= kalIoctl(prGlueInfo
,
3240 wlanoidSetEncryptionStatus
,
3242 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T
),
3249 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3250 //printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus);
3258 } /* wext_set_encode */
3261 /*----------------------------------------------------------------------------*/
3263 * \brief To set power management.
3265 * \param[in] prDev Net device requested.
3266 * \param[in] prIwrInfo NULL.
3267 * \param[in] prPower Pointer to iw_param structure containing tx power setting.
3268 * \param[in] pcExtra NULL.
3270 * \retval 0 Success.
3272 * \note New Power Management Mode is set to driver.
3274 /*----------------------------------------------------------------------------*/
3277 IN
struct net_device
*prNetDev
,
3278 IN
struct iw_request_info
*prIwrInfo
,
3279 IN
struct iw_param
*prPower
,
3285 PARAM_POWER_MODE ePowerMode
;
3286 INT_32 i4PowerValue
;
3288 P_GLUE_INFO_T prGlueInfo
= NULL
;
3289 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3290 UINT_32 u4BufLen
= 0;
3294 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prPower
)) {
3297 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3299 //printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n",
3300 // prPower->value, prPower->disabled, prPower->flags);
3302 if(prPower
->disabled
){
3303 ePowerMode
= Param_PowerModeCAM
;
3306 i4PowerValue
= prPower
->value
;
3307 #if WIRELESS_EXT < 21
3308 i4PowerValue
/= 1000000;
3310 if (i4PowerValue
== 0) {
3311 ePowerMode
= Param_PowerModeCAM
;
3312 } else if (i4PowerValue
== 1) {
3313 ePowerMode
= Param_PowerModeMAX_PSP
;
3314 } else if (i4PowerValue
== 2) {
3315 ePowerMode
= Param_PowerModeFast_PSP
;
3318 DBGLOG(INIT
, INFO
, ("%s(): unsupported power management mode value = %d.\n",
3327 rStatus
= kalIoctl(prGlueInfo
,
3328 wlanoidSet802dot11PowerSaveProfile
,
3337 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3338 //printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus);
3344 } /* wext_set_power */
3347 /*----------------------------------------------------------------------------*/
3349 * \brief To get power management.
3351 * \param[in] prDev Net device requested.
3352 * \param[in] prIwrInfo NULL.
3353 * \param[out] prPower Pointer to iw_param structure containing tx power setting.
3354 * \param[in] pcExtra NULL.
3356 * \retval 0 Success.
3358 * \note Power management mode is stored in pTxPow->value.
3360 /*----------------------------------------------------------------------------*/
3363 IN
struct net_device
*prNetDev
,
3364 IN
struct iw_request_info
*prIwrInfo
,
3365 OUT
struct iw_param
*prPower
,
3370 P_GLUE_INFO_T prGlueInfo
= NULL
;
3371 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3372 UINT_32 u4BufLen
= 0;
3373 PARAM_POWER_MODE ePowerMode
= Param_PowerModeCAM
;
3377 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prPower
)) {
3380 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3383 #if defined(_HIF_SDIO)
3384 rStatus
= sdio_io_ctrl(prGlueInfo
,
3385 wlanoidQuery802dot11PowerSaveProfile
,
3392 rStatus
= wlanQueryInformation(prGlueInfo
->prAdapter
,
3393 wlanoidQuery802dot11PowerSaveProfile
,
3399 rStatus
= wlanQueryInformation(prGlueInfo
->prAdapter
,
3400 wlanoidQuery802dot11PowerSaveProfile
,
3406 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3411 prPower
->disabled
= 1;
3413 if (Param_PowerModeCAM
== ePowerMode
) {
3415 prPower
->disabled
= 1;
3417 else if (Param_PowerModeMAX_PSP
== ePowerMode
) {
3419 prPower
->disabled
= 0;
3421 else if (Param_PowerModeFast_PSP
== ePowerMode
) {
3423 prPower
->disabled
= 0;
3426 prPower
->flags
= IW_POWER_PERIOD
| IW_POWER_RELATIVE
;
3427 #if WIRELESS_EXT < 21
3428 prPower
->value
*= 1000000;
3431 //printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n",
3432 // prPower->value, prPower->disabled, prPower->flags);
3435 } /* wext_get_power */
3437 /*----------------------------------------------------------------------------*/
3439 * \brief To set authentication parameters.
3441 * \param[in] prDev Net device requested.
3442 * \param[in] prIwrInfo NULL.
3443 * \param[in] rpAuth Pointer to iw_param structure containing authentication information.
3444 * \param[in] pcExtra Pointer to key string buffer.
3446 * \retval 0 Success.
3447 * \retval -EINVAL Key ID error for WEP.
3448 * \retval -EFAULT Setting parameters to driver fail.
3449 * \retval -EOPNOTSUPP Key size not supported.
3451 * \note Securiry information is stored in pEnc.
3453 /*----------------------------------------------------------------------------*/
3456 IN
struct net_device
*prNetDev
,
3457 IN
struct iw_request_info
*prIwrInfo
,
3458 IN
struct iw_param
*prAuth
,
3462 P_GLUE_INFO_T prGlueInfo
= NULL
;
3466 if (FALSE
== GLUE_CHK_PR2(prNetDev
, prAuth
)) {
3469 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3471 /* Save information to glue info and process later when ssid is set. */
3472 switch(prAuth
->flags
& IW_AUTH_INDEX
) {
3473 case IW_AUTH_WPA_VERSION
:
3474 #if CFG_SUPPORT_WAPI
3475 if (wlanQueryWapiMode(prGlueInfo
->prAdapter
)){
3476 prGlueInfo
->rWpaInfo
.u4WpaVersion
= IW_AUTH_WPA_VERSION_DISABLED
;
3477 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_OPEN_SYSTEM
;
3480 prGlueInfo
->rWpaInfo
.u4WpaVersion
= prAuth
->value
;
3483 prGlueInfo
->rWpaInfo
.u4WpaVersion
= prAuth
->value
;
3487 case IW_AUTH_CIPHER_PAIRWISE
:
3488 prGlueInfo
->rWpaInfo
.u4CipherPairwise
= prAuth
->value
;
3491 case IW_AUTH_CIPHER_GROUP
:
3492 prGlueInfo
->rWpaInfo
.u4CipherGroup
= prAuth
->value
;
3495 case IW_AUTH_KEY_MGMT
:
3496 prGlueInfo
->rWpaInfo
.u4KeyMgmt
= prAuth
->value
;
3497 #if CFG_SUPPORT_WAPI
3498 if (prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WAPI_PSK
||
3499 prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WAPI_CERT
) {
3501 WLAN_STATUS rStatus
;
3503 rStatus
= kalIoctl(prGlueInfo
,
3512 DBGLOG(INIT
, INFO
, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth
->value
));
3515 if (prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_WPS
)
3516 prGlueInfo
->fgWpsActive
= TRUE
;
3518 prGlueInfo
->fgWpsActive
= FALSE
;
3521 case IW_AUTH_80211_AUTH_ALG
:
3522 prGlueInfo
->rWpaInfo
.u4AuthAlg
= prAuth
->value
;
3525 case IW_AUTH_PRIVACY_INVOKED
:
3526 prGlueInfo
->rWpaInfo
.fgPrivacyInvoke
= prAuth
->value
;
3528 #if CFG_SUPPORT_802_11W
3530 //printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value);
3531 prGlueInfo
->rWpaInfo
.u4Mfp
= prAuth
->value
;
3534 #if CFG_SUPPORT_WAPI
3535 case IW_AUTH_WAPI_ENABLED
:
3538 WLAN_STATUS rStatus
;
3540 rStatus
= kalIoctl(prGlueInfo
,
3550 DBGLOG(INIT
, INFO
, ("IW_AUTH_WAPI_ENABLED :%d\n", prAuth
->value
));
3555 printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags);
3560 } /* wext_set_auth */
3563 /*----------------------------------------------------------------------------*/
3565 * \brief To set encryption cipher and key.
3567 * \param[in] prDev Net device requested.
3568 * \param[in] prIwrInfo NULL.
3569 * \param[in] prEnc Pointer to iw_point structure containing securiry information.
3570 * \param[in] pcExtra Pointer to key string buffer.
3572 * \retval 0 Success.
3573 * \retval -EINVAL Key ID error for WEP.
3574 * \retval -EFAULT Setting parameters to driver fail.
3575 * \retval -EOPNOTSUPP Key size not supported.
3577 * \note Securiry information is stored in pEnc.
3579 /*----------------------------------------------------------------------------*/
3580 #if CFG_SUPPORT_WAPI
3581 UINT_8 keyStructBuf
[320]; /* add/remove key shared buffer */
3583 UINT_8 keyStructBuf
[100]; /* add/remove key shared buffer */
3587 wext_set_encode_ext (
3588 IN
struct net_device
*prNetDev
,
3589 IN
struct iw_request_info
*prIwrInfo
,
3590 IN
struct iw_point
*prEnc
,
3594 P_PARAM_REMOVE_KEY_T prRemoveKey
= (P_PARAM_REMOVE_KEY_T
) keyStructBuf
;
3595 P_PARAM_KEY_T prKey
= (P_PARAM_KEY_T
) keyStructBuf
;
3598 P_PARAM_WEP_T prWepKey
= (P_PARAM_WEP_T
) wepBuf
;
3600 struct iw_encode_ext
*prIWEncExt
= (struct iw_encode_ext
*) pcExtra
;
3602 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus
;
3603 ENUM_PARAM_AUTH_MODE_T eAuthMode
;
3604 //ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH;
3606 #if CFG_SUPPORT_WAPI
3607 P_PARAM_WPI_KEY_T prWpiKey
= (P_PARAM_WPI_KEY_T
) keyStructBuf
;
3610 P_GLUE_INFO_T prGlueInfo
= NULL
;
3611 WLAN_STATUS rStatus
= WLAN_STATUS_SUCCESS
;
3612 UINT_32 u4BufLen
= 0;
3616 if (FALSE
== GLUE_CHK_PR3(prNetDev
, prEnc
, pcExtra
)) {
3619 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3621 memset(keyStructBuf
, 0, sizeof(keyStructBuf
));
3623 #if CFG_SUPPORT_WAPI
3624 if (prIWEncExt
->alg
== IW_ENCODE_ALG_SMS4
) {
3625 if (prEnc
->flags
& IW_ENCODE_DISABLED
) {
3626 //printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n");
3630 prWpiKey
->ucKeyID
= (prEnc
->flags
& IW_ENCODE_INDEX
);
3631 prWpiKey
->ucKeyID
--;
3632 if (prWpiKey
->ucKeyID
> 1) {
3633 /* key id is out of range */
3634 //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID);
3638 if (prIWEncExt
->key_len
!= 32) {
3639 /* key length not valid */
3640 //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len);
3644 //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags);
3646 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
3647 prWpiKey
->eKeyType
= ENUM_WPI_GROUP_KEY
;
3648 prWpiKey
->eDirection
= ENUM_WPI_RX
;
3650 else if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
3651 prWpiKey
->eKeyType
= ENUM_WPI_PAIRWISE_KEY
;
3652 prWpiKey
->eDirection
= ENUM_WPI_RX_TX
;
3658 for(i
=0; i
<IW_ENCODE_SEQ_MAX_SIZE
; i
++)
3659 prWpiKey
->aucPN
[i
] = prIWEncExt
->tx_seq
[i
];
3660 for(i
=0; i
<IW_ENCODE_SEQ_MAX_SIZE
; i
++)
3661 prWpiKey
->aucPN
[IW_ENCODE_SEQ_MAX_SIZE
+i
] = prIWEncExt
->rx_seq
[i
];
3665 memcpy(prWpiKey
->aucAddrIndex
, prIWEncExt
->addr
.sa_data
, 6);
3667 memcpy(prWpiKey
->aucWPIEK
, prIWEncExt
->key
, 16);
3668 prWpiKey
->u4LenWPIEK
= 16;
3670 memcpy(prWpiKey
->aucWPICK
, &prIWEncExt
->key
[16], 16);
3671 prWpiKey
->u4LenWPICK
= 16;
3673 rStatus
= kalIoctl(prGlueInfo
,
3676 sizeof(PARAM_WPI_KEY_T
),
3683 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3684 //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus);
3692 if ( (prEnc
->flags
& IW_ENCODE_MODE
) == IW_ENCODE_DISABLED
) {
3693 prRemoveKey
->u4Length
= sizeof(*prRemoveKey
);
3694 memcpy(prRemoveKey
->arBSSID
, prIWEncExt
->addr
.sa_data
, 6);
3696 printk("IW_ENCODE_DISABLED: ID:%d, Addr:[" MACSTR "]\n",
3697 prRemoveKey->KeyIndex, MAC2STR(prRemoveKey->BSSID));
3700 rStatus
= kalIoctl(prGlueInfo
,
3701 wlanoidSetRemoveKey
,
3703 prRemoveKey
->u4Length
,
3711 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3712 DBGLOG(INIT
, INFO
, ("remove key error:%x\n", rStatus
));
3718 //printk ("alg %x\n", prIWEncExt->alg);
3720 switch (prIWEncExt
->alg
) {
3721 case IW_ENCODE_ALG_NONE
:
3723 case IW_ENCODE_ALG_WEP
:
3724 /* iwconfig wlan0 key 0123456789 */
3725 /* iwconfig wlan0 key s:abcde */
3726 /* iwconfig wlan0 key 0123456789 [1] */
3727 /* iwconfig wlan0 key 01234567890123456789012345 [1] */
3728 /* check key size for WEP */
3729 if (prIWEncExt
->key_len
== 5 || prIWEncExt
->key_len
== 13 || prIWEncExt
->key_len
== 16) {
3730 /* prepare PARAM_WEP key structure */
3731 prWepKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3732 (prEnc
->flags
& IW_ENCODE_INDEX
) -1 : 0;
3733 if (prWepKey
->u4KeyIndex
> 3) {
3734 /* key id is out of range */
3737 prWepKey
->u4KeyIndex
|= 0x80000000;
3738 prWepKey
->u4Length
= 12 + prIWEncExt
->key_len
;
3739 prWepKey
->u4KeyLength
= prIWEncExt
->key_len
;
3740 //kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len);
3741 kalMemCopy(prWepKey
->aucKeyMaterial
, prIWEncExt
->key
, prIWEncExt
->key_len
);
3744 rStatus
= kalIoctl(prGlueInfo
,
3754 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3755 DBGLOG(INIT
, INFO
, ("wlanoidSetAddWep fail 0x%x\n", rStatus
));
3759 /* change to auto switch */
3760 prGlueInfo
->rWpaInfo
.u4AuthAlg
= IW_AUTH_ALG_SHARED_KEY
|
3761 IW_AUTH_ALG_OPEN_SYSTEM
;
3762 eAuthMode
= AUTH_MODE_AUTO_SWITCH
;
3764 rStatus
= kalIoctl(prGlueInfo
,
3774 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3775 DBGLOG(INIT
, INFO
, ("wlanoidSetAuthMode fail 0x%x\n", rStatus
));
3779 prGlueInfo
->rWpaInfo
.u4CipherPairwise
=
3780 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3781 prGlueInfo
->rWpaInfo
.u4CipherGroup
=
3782 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_WEP40
;
3784 eEncStatus
= ENUM_WEP_ENABLED
;
3787 rStatus
= kalIoctl(prGlueInfo
,
3788 wlanoidSetEncryptionStatus
,
3790 sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T
),
3797 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3798 DBGLOG(INIT
, INFO
, ("wlanoidSetEncryptionStatus fail 0x%x\n", rStatus
));
3803 DBGLOG(INIT
, INFO
, ("key length %x\n", prIWEncExt
->key_len
));
3804 DBGLOG(INIT
, INFO
, ("key error\n"));
3808 case IW_ENCODE_ALG_TKIP
:
3809 case IW_ENCODE_ALG_CCMP
:
3810 #if CFG_SUPPORT_802_11W
3811 case IW_ENCODE_ALG_AES_CMAC
:
3816 prKey
->u4KeyIndex
= (prEnc
->flags
& IW_ENCODE_INDEX
) ?
3817 (prEnc
->flags
& IW_ENCODE_INDEX
) -1: 0;
3818 #if CFG_SUPPORT_802_11W
3819 if (prKey
->u4KeyIndex
> 5)
3821 if (prKey
->u4KeyIndex
> 3)
3824 DBGLOG(INIT
, INFO
, ("key index error:0x%x\n", prKey
->u4KeyIndex
));
3825 /* key id is out of range */
3829 /* bit(31) and bit(30) are shared by pKey and pRemoveKey */
3831 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
3832 prKey
->u4KeyIndex
|= 0x1UL
<< 31;
3835 /* Pairwise Key Bit(30) */
3836 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
3841 prKey
->u4KeyIndex
|= 0x1UL
<< 30;
3846 if (prIWEncExt
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
3847 prKey
->u4KeyIndex
|= 0x1UL
<< 29;
3848 memcpy(&prKey
->rKeyRSC
, prIWEncExt
->rx_seq
, IW_ENCODE_SEQ_MAX_SIZE
);
3852 memcpy(prKey
->arBSSID
, prIWEncExt
->addr
.sa_data
, 6);
3854 /* switch tx/rx MIC key for sta */
3855 if (prIWEncExt
->alg
== IW_ENCODE_ALG_TKIP
&& prIWEncExt
->key_len
== 32) {
3856 memcpy(prKey
->aucKeyMaterial
, prIWEncExt
->key
, 16);
3857 memcpy(((PUINT_8
)prKey
->aucKeyMaterial
) + 16, prIWEncExt
->key
+ 24, 8);
3858 memcpy((prKey
->aucKeyMaterial
) + 24, prIWEncExt
->key
+ 16, 8);
3861 memcpy(prKey
->aucKeyMaterial
, prIWEncExt
->key
, prIWEncExt
->key_len
);
3864 prKey
->u4KeyLength
= prIWEncExt
->key_len
;
3865 prKey
->u4Length
= ((ULONG
)&(((P_PARAM_KEY_T
)0)->aucKeyMaterial
)) + prKey
->u4KeyLength
;
3868 rStatus
= kalIoctl(prGlueInfo
,
3878 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
3879 DBGLOG(INIT
, INFO
, ("add key error:%x\n", rStatus
));
3887 } /* wext_set_encode_ext */
3890 /*----------------------------------------------------------------------------*/
3892 * \brief Set country code
3894 * \param[in] prDev Net device requested.
3895 * \param[in] prIwrInfo NULL.
3896 * \param[in] pu4Mode Pointer to new operation mode.
3897 * \param[in] pcExtra NULL.
3899 * \retval 0 For success.
3900 * \retval -EOPNOTSUPP If new mode is not supported.
3902 * \note Device will run in new operation mode if it is valid.
3904 /*----------------------------------------------------------------------------*/
3907 IN
struct net_device
*prNetDev
,
3908 IN
struct iwreq
*iwr
3911 P_GLUE_INFO_T prGlueInfo
;
3912 WLAN_STATUS rStatus
;
3914 UINT_8 aucCountry
[2];
3918 /* iwr->u.data.pointer should be like "COUNTRY US", "COUNTRY EU"
3921 if (FALSE
== GLUE_CHK_PR2(prNetDev
, iwr
) ||
3922 !iwr
->u
.data
.pointer
|| iwr
->u
.data
.length
< 10) {
3925 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prNetDev
));
3927 aucCountry
[0] = *((PUINT_8
)iwr
->u
.data
.pointer
+ 8);
3928 aucCountry
[1] = *((PUINT_8
)iwr
->u
.data
.pointer
+ 9);
3930 rStatus
= kalIoctl(prGlueInfo
,
3931 wlanoidSetCountryCode
,
3939 wlanUpdateChannelTable(prGlueInfo
);
3943 /*----------------------------------------------------------------------------*/
3945 * \brief ioctl() (Linux Wireless Extensions) routines
3947 * \param[in] prDev Net device requested.
3948 * \param[in] ifr The ifreq structure for seeting the wireless extension.
3949 * \param[in] i4Cmd The wireless extension ioctl command.
3951 * \retval zero On success.
3952 * \retval -EOPNOTSUPP If the cmd is not supported.
3953 * \retval -EFAULT If copy_to_user goes wrong.
3954 * \retval -EINVAL If any value's out of range.
3958 /*----------------------------------------------------------------------------*/
3960 wext_support_ioctl (
3961 IN
struct net_device
*prDev
,
3962 IN
struct ifreq
*prIfReq
,
3966 /* prIfReq is verified in the caller function wlanDoIOCTL() */
3967 struct iwreq
*iwr
= (struct iwreq
*)prIfReq
;
3968 struct iw_request_info rIwReqInfo
;
3970 char *prExtraBuf
= NULL
;
3971 UINT_32 u4ExtraSize
= 0;
3972 struct iw_scan_req
* prIwScanReq
= NULL
;
3974 /* prDev is verified in the caller function wlanDoIOCTL() */
3976 //printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd);
3978 /* Prepare the call */
3979 rIwReqInfo
.cmd
= (__u16
)i4Cmd
;
3980 rIwReqInfo
.flags
= 0;
3983 case SIOCGIWNAME
: /* 0x8B01, get wireless protocol name */
3984 ret
= wext_get_name(prDev
, &rIwReqInfo
, (char *)&iwr
->u
.name
, NULL
);
3987 /* case SIOCSIWNWID: 0x8B02, deprecated */
3988 /* case SIOCGIWNWID: 0x8B03, deprecated */
3990 case SIOCSIWFREQ
: /* 0x8B04, set channel */
3991 ret
= wext_set_freq(prDev
, NULL
, &iwr
->u
.freq
, NULL
);
3994 case SIOCGIWFREQ
: /* 0x8B05, get channel */
3995 ret
= wext_get_freq(prDev
, NULL
, &iwr
->u
.freq
, NULL
);
3998 case SIOCSIWMODE
: /* 0x8B06, set operation mode */
3999 ret
= wext_set_mode(prDev
, NULL
, &iwr
->u
.mode
, NULL
);
4003 case SIOCGIWMODE
: /* 0x8B07, get operation mode */
4004 ret
= wext_get_mode(prDev
, NULL
, &iwr
->u
.mode
, NULL
);
4007 /* case SIOCSIWSENS: 0x8B08, unsupported */
4008 /* case SIOCGIWSENS: 0x8B09, unsupported */
4010 /* case SIOCSIWRANGE: 0x8B0A, unused */
4011 case SIOCGIWRANGE
: /* 0x8B0B, get range of parameters */
4012 if (iwr
->u
.data
.pointer
!= NULL
) {
4013 /* Buffer size shoule be large enough */
4014 if (iwr
->u
.data
.length
< sizeof(struct iw_range
)) {
4019 prExtraBuf
= kalMemAlloc(sizeof(struct iw_range
), VIR_MEM_TYPE
);
4025 /* reset all fields */
4026 memset(prExtraBuf
, 0, sizeof(struct iw_range
));
4027 iwr
->u
.data
.length
= sizeof(struct iw_range
);
4029 ret
= wext_get_range(prDev
, NULL
, &iwr
->u
.data
, prExtraBuf
);
4030 /* Push up to the caller */
4031 if (copy_to_user(iwr
->u
.data
.pointer
,
4033 iwr
->u
.data
.length
)) {
4037 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, sizeof(struct iw_range
));
4045 case SIOCSIWPRIV
: /* 0x8B0C, Country */
4046 ret
= wext_set_country(prDev
, iwr
);
4049 /* case SIOCGIWPRIV: 0x8B0D, handled in wlan_do_ioctl() */
4050 /* caes SIOCSIWSTATS: 0x8B0E, unused */
4051 /* case SIOCGIWSTATS:
4052 get statistics, intercepted by wireless_process_ioctl() in wireless.c,
4053 redirected to dev_iwstats(), dev->get_wireless_stats().
4055 /* case SIOCSIWSPY: 0x8B10, unsupported */
4056 /* case SIOCGIWSPY: 0x8B11, unsupported*/
4057 /* case SIOCSIWTHRSPY: 0x8B12, unsupported */
4058 /* case SIOCGIWTHRSPY: 0x8B13, unsupported*/
4060 case SIOCSIWAP
: /* 0x8B14, set access point MAC addresses (BSSID) */
4061 if (iwr
->u
.ap_addr
.sa_data
[0] == 0 &&
4062 iwr
->u
.ap_addr
.sa_data
[1] == 0 &&
4063 iwr
->u
.ap_addr
.sa_data
[2] == 0 &&
4064 iwr
->u
.ap_addr
.sa_data
[3] == 0 &&
4065 iwr
->u
.ap_addr
.sa_data
[4] == 0 &&
4066 iwr
->u
.ap_addr
.sa_data
[5] == 0) {
4067 /* WPA Supplicant will set 000000000000 in
4068 ** wpa_driver_wext_deinit(), do nothing here or disassoc again?
4074 ret
= wext_set_ap(prDev
, NULL
, &iwr
->u
.ap_addr
, NULL
);
4078 case SIOCGIWAP
: /* 0x8B15, get access point MAC addresses (BSSID) */
4079 ret
= wext_get_ap(prDev
, NULL
, &iwr
->u
.ap_addr
, NULL
);
4082 case SIOCSIWMLME
: /* 0x8B16, request MLME operation */
4083 /* Fixed length structure */
4084 if (iwr
->u
.data
.length
!= sizeof(struct iw_mlme
)) {
4085 DBGLOG(INIT
, INFO
, ("MLME buffer strange:%d\n", iwr
->u
.data
.length
));
4090 if (!iwr
->u
.data
.pointer
) {
4095 prExtraBuf
= kalMemAlloc(sizeof(struct iw_mlme
), VIR_MEM_TYPE
);
4101 if (copy_from_user(prExtraBuf
, iwr
->u
.data
.pointer
, sizeof(struct iw_mlme
))) {
4105 ret
= wext_set_mlme(prDev
, NULL
, &(iwr
->u
.data
), prExtraBuf
);
4108 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, sizeof(struct iw_mlme
));
4112 /* case SIOCGIWAPLIST: 0x8B17, deprecated */
4113 case SIOCSIWSCAN
: /* 0x8B18, scan request */
4114 if (iwr
->u
.data
.pointer
== NULL
) {
4115 ret
= wext_set_scan(prDev
, NULL
, NULL
, NULL
);
4117 #if WIRELESS_EXT > 17
4118 else if (iwr
->u
.data
.length
== sizeof(struct iw_scan_req
)) {
4119 prIwScanReq
= kalMemAlloc(iwr
->u
.data
.length
, VIR_MEM_TYPE
);
4125 if (copy_from_user(prIwScanReq
, iwr
->u
.data
.pointer
, iwr
->u
.data
.length
)) {
4128 if (prIwScanReq
->essid_len
> IW_ESSID_MAX_SIZE
)
4129 prIwScanReq
->essid_len
= IW_ESSID_MAX_SIZE
;
4130 ret
= wext_set_scan(prDev
, NULL
, prIwScanReq
, &(prIwScanReq
->essid
[0]));
4133 kalMemFree(prIwScanReq
, VIR_MEM_TYPE
, iwr
->u
.data
.length
);
4142 case SIOCGIWSCAN
: /* 0x8B19, get scan results */
4143 if (!iwr
->u
.data
.pointer
|| !iwr
->u
.essid
.pointer
) {
4148 u4ExtraSize
= iwr
->u
.data
.length
;
4149 /* allocate the same size of kernel buffer to store scan results. */
4150 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4156 /* iwr->u.data.length may be updated by wext_get_scan() */
4157 ret
= wext_get_scan(prDev
, NULL
, &iwr
->u
.data
, prExtraBuf
);
4159 if (ret
== -E2BIG
) {
4160 DBGLOG(INIT
, INFO
, ("[wifi] wext_get_scan -E2BIG\n"));
4164 /* check updated length is valid */
4165 ASSERT(iwr
->u
.data
.length
<= u4ExtraSize
);
4166 if (iwr
->u
.data
.length
> u4ExtraSize
) {
4167 DBGLOG(INIT
, INFO
, ("Updated result length is larger than allocated (%d > %u)\n",
4168 iwr
->u
.data
.length
, u4ExtraSize
));
4169 iwr
->u
.data
.length
= u4ExtraSize
;
4172 if (copy_to_user(iwr
->u
.data
.pointer
,
4174 iwr
->u
.data
.length
)) {
4179 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4187 case SIOCSIWESSID
: /* 0x8B1A, set SSID (network name) */
4188 if (iwr
->u
.essid
.length
> IW_ESSID_MAX_SIZE
) {
4192 if (!iwr
->u
.essid
.pointer
) {
4197 prExtraBuf
= kalMemAlloc(IW_ESSID_MAX_SIZE
+ 4, VIR_MEM_TYPE
);
4203 if (copy_from_user(prExtraBuf
,
4204 iwr
->u
.essid
.pointer
,
4205 iwr
->u
.essid
.length
)) {
4209 /* Add trailing '\0' for printk */
4210 //prExtraBuf[iwr->u.essid.length] = 0;
4211 //printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length);
4212 ret
= wext_set_essid(prDev
, NULL
, &iwr
->u
.essid
, prExtraBuf
);
4213 //printk ("set essid %d\n", ret);
4216 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, IW_ESSID_MAX_SIZE
+ 4);
4222 case SIOCGIWESSID
: /* 0x8B1B, get SSID */
4223 if (!iwr
->u
.essid
.pointer
) {
4228 if (iwr
->u
.essid
.length
< IW_ESSID_MAX_SIZE
) {
4229 DBGLOG(INIT
, INFO
, ("[wifi] iwr->u.essid.length:%d too small\n",
4230 iwr
->u
.essid
.length
));
4231 ret
= -E2BIG
; /* let caller try larger buffer */
4235 prExtraBuf
= kalMemAlloc(IW_ESSID_MAX_SIZE
, VIR_MEM_TYPE
);
4241 /* iwr->u.essid.length is updated by wext_get_essid() */
4243 ret
= wext_get_essid(prDev
, NULL
, &iwr
->u
.essid
, prExtraBuf
);
4245 if (copy_to_user(iwr
->u
.essid
.pointer
, prExtraBuf
, iwr
->u
.essid
.length
)) {
4250 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, IW_ESSID_MAX_SIZE
);
4255 /* case SIOCSIWNICKN: 0x8B1C, not supported */
4256 /* case SIOCGIWNICKN: 0x8B1D, not supported */
4258 case SIOCSIWRATE
: /* 0x8B20, set default bit rate (bps) */
4259 //ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL);
4262 case SIOCGIWRATE
: /* 0x8B21, get current bit rate (bps) */
4263 ret
= wext_get_rate(prDev
, NULL
, &iwr
->u
.bitrate
, NULL
);
4266 case SIOCSIWRTS
: /* 0x8B22, set rts/cts threshold */
4267 ret
= wext_set_rts(prDev
, NULL
, &iwr
->u
.rts
, NULL
);
4270 case SIOCGIWRTS
: /* 0x8B23, get rts/cts threshold */
4271 ret
= wext_get_rts(prDev
, NULL
, &iwr
->u
.rts
, NULL
);
4274 /* case SIOCSIWFRAG: 0x8B24, unsupported */
4275 case SIOCGIWFRAG
: /* 0x8B25, get frag threshold */
4276 ret
= wext_get_frag(prDev
, NULL
, &iwr
->u
.frag
, NULL
);
4279 case SIOCSIWTXPOW
: /* 0x8B26, set relative tx power (in %) */
4280 ret
= wext_set_txpow(prDev
, NULL
, &iwr
->u
.txpower
, NULL
);
4283 case SIOCGIWTXPOW
: /* 0x8B27, get relative tx power (in %) */
4284 ret
= wext_get_txpow(prDev
, NULL
, &iwr
->u
.txpower
, NULL
);
4287 /* case SIOCSIWRETRY: 0x8B28, unsupported */
4288 /* case SIOCGIWRETRY: 0x8B29, unsupported */
4291 case SIOCSIWENCODE
: /* 0x8B2A, set encoding token & mode */
4292 /* Only DISABLED case has NULL pointer and length == 0 */
4293 if (iwr
->u
.encoding
.pointer
) {
4294 if (iwr
->u
.encoding
.length
> 16) {
4299 u4ExtraSize
= iwr
->u
.encoding
.length
;
4300 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4306 if (copy_from_user(prExtraBuf
,
4307 iwr
->u
.encoding
.pointer
,
4308 iwr
->u
.encoding
.length
)) {
4312 else if (iwr
->u
.encoding
.length
!= 0) {
4318 ret
= wext_set_encode(prDev
, NULL
, &iwr
->u
.encoding
, prExtraBuf
);
4322 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4327 case SIOCGIWENCODE
: /* 0x8B2B, get encoding token & mode */
4329 ret
= wext_get_encode(prDev
, NULL
, &iwr
->u
.encoding
, NULL
);
4332 case SIOCSIWPOWER
: /* 0x8B2C, set power management */
4333 ret
= wext_set_power(prDev
, NULL
, &iwr
->u
.power
, NULL
);
4336 case SIOCGIWPOWER
: /* 0x8B2D, get power management */
4337 ret
= wext_get_power(prDev
, NULL
, &iwr
->u
.power
, NULL
);
4340 #if WIRELESS_EXT > 17
4341 case SIOCSIWGENIE
: /* 0x8B30, set gen ie */
4342 if (iwr
->u
.data
.pointer
) {
4343 P_GLUE_INFO_T prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4344 if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) {
4345 /* Fixed length structure */
4346 #if CFG_SUPPORT_WAPI
4347 if (iwr
->u
.data
.length
> 42 /* The max wapi ie buffer */) {
4352 u4ExtraSize
= iwr
->u
.data
.length
;
4354 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4359 if (copy_from_user(prExtraBuf
,
4360 iwr
->u
.data
.pointer
,
4361 iwr
->u
.data
.length
)) {
4365 WLAN_STATUS rStatus
;
4367 #if CFG_SUPPORT_WAPI
4368 rStatus
= kalIoctl(prGlueInfo
,
4369 wlanoidSetWapiAssocInfo
,
4378 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4379 //printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", rStatus);
4381 #if CFG_SUPPORT_WPS2
4382 PUINT_8 prDesiredIE
= NULL
;
4383 if (wextSrchDesiredWPSIE(prExtraBuf
,
4386 (PUINT_8
*)&prDesiredIE
)) {
4387 rStatus
= kalIoctl(prGlueInfo
,
4388 wlanoidSetWSCAssocInfo
,
4390 IE_SIZE(prDesiredIE
),
4396 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4397 //printk(KERN_INFO "[WSC] set WSC assoc info error:%lx\n", rStatus);
4401 #if CFG_SUPPORT_WAPI
4405 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4412 case SIOCGIWGENIE
: /* 0x8B31, get gen ie, unused */
4417 case SIOCSIWAUTH
: /* 0x8B32, set auth mode params */
4418 ret
= wext_set_auth(prDev
, NULL
, &iwr
->u
.param
, NULL
);
4421 /* case SIOCGIWAUTH: 0x8B33, unused? */
4422 case SIOCSIWENCODEEXT
: /* 0x8B34, set extended encoding token & mode */
4423 if (iwr
->u
.encoding
.pointer
) {
4424 u4ExtraSize
= iwr
->u
.encoding
.length
;
4425 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4431 if (copy_from_user(prExtraBuf
,
4432 iwr
->u
.encoding
.pointer
,
4433 iwr
->u
.encoding
.length
)) {
4437 else if (iwr
->u
.encoding
.length
!= 0) {
4443 ret
= wext_set_encode_ext(prDev
, NULL
, &iwr
->u
.encoding
, prExtraBuf
);
4447 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4452 /* case SIOCGIWENCODEEXT: 0x8B35, unused? */
4454 case SIOCSIWPMKSA
: /* 0x8B36, pmksa cache operation */
4456 if (iwr
->u
.data
.pointer
) {
4457 /* Fixed length structure */
4458 if (iwr
->u
.data
.length
!= sizeof(struct iw_pmksa
)) {
4463 u4ExtraSize
= sizeof(struct iw_pmksa
);
4464 prExtraBuf
= kalMemAlloc(u4ExtraSize
, VIR_MEM_TYPE
);
4470 if (copy_from_user(prExtraBuf
,
4471 iwr
->u
.data
.pointer
,
4472 sizeof(struct iw_pmksa
))) {
4476 switch(((struct iw_pmksa
*)prExtraBuf
)->cmd
) {
4479 printk(KERN_INFO "IW_PMKSA_ADD [" MACSTR "]\n",
4480 MAC2STR(((struct iw_pmksa *)pExtraBuf)->bssid.sa_data));
4483 P_GLUE_INFO_T prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4484 WLAN_STATUS rStatus
;
4486 P_PARAM_PMKID_T prPmkid
;
4488 prPmkid
=(P_PARAM_PMKID_T
)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T
), VIR_MEM_TYPE
);
4490 DBGLOG(INIT
, INFO
, ("Can not alloc memory for IW_PMKSA_ADD\n"));
4495 prPmkid
->u4Length
= 8 + sizeof(PARAM_BSSID_INFO_T
);
4496 prPmkid
->u4BSSIDInfoCount
= 1;
4497 kalMemCopy(prPmkid
->arBSSIDInfo
->arBSSID
,
4498 ((struct iw_pmksa
*)prExtraBuf
)->bssid
.sa_data
,
4500 kalMemCopy(prPmkid
->arBSSIDInfo
->arPMKID
,
4501 ((struct iw_pmksa
*)prExtraBuf
)->pmkid
,
4504 rStatus
= kalIoctl(prGlueInfo
,
4507 sizeof(PARAM_PMKID_T
),
4514 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4515 DBGLOG(INIT
, INFO
, ("add pmkid error:%x\n", rStatus
));
4517 kalMemFree(prPmkid
, VIR_MEM_TYPE
, 8 + sizeof(PARAM_BSSID_INFO_T
));
4520 case IW_PMKSA_REMOVE
:
4522 printk(KERN_INFO "IW_PMKSA_REMOVE [" MACSTR "]\n",
4523 MAC2STR(((struct iw_pmksa *)buf)->bssid.sa_data));
4526 case IW_PMKSA_FLUSH
:
4528 printk(KERN_INFO "IW_PMKSA_FLUSH\n");
4531 P_GLUE_INFO_T prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4532 WLAN_STATUS rStatus
;
4534 P_PARAM_PMKID_T prPmkid
;
4536 prPmkid
=(P_PARAM_PMKID_T
)kalMemAlloc(8, VIR_MEM_TYPE
);
4538 DBGLOG(INIT
, INFO
, ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
4543 prPmkid
->u4Length
= 8;
4544 prPmkid
->u4BSSIDInfoCount
= 0;
4546 rStatus
= kalIoctl(prGlueInfo
,
4549 sizeof(PARAM_PMKID_T
),
4556 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
4557 DBGLOG(INIT
, INFO
, ("flush pmkid error:%x\n", rStatus
));
4559 kalMemFree(prPmkid
, VIR_MEM_TYPE
, 8);
4563 DBGLOG(INIT
, INFO
, ("UNKNOWN iw_pmksa command:%d\n",
4564 ((struct iw_pmksa
*)prExtraBuf
)->cmd
));
4571 kalMemFree(prExtraBuf
, VIR_MEM_TYPE
, u4ExtraSize
);
4575 else if (iwr
->u
.data
.length
!= 0) {
4585 /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */
4590 //printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret);
4593 } /* wext_support_ioctl */
4597 /*----------------------------------------------------------------------------*/
4599 * \brief To send an event (RAW socket pacekt) to user process actively.
4601 * \param[in] prGlueInfo Glue layer info.
4602 * \param[in] u4cmd Whcih event command we want to indicate to user process.
4603 * \param[in] pData Data buffer to be indicated.
4604 * \param[in] dataLen Available data size in pData.
4608 * \note Event is indicated to upper layer if cmd is supported and data is valid.
4609 * Using of kernel symbol wireless_send_event(), which is defined in
4610 * <net/iw_handler.h> after WE-14 (2.4.20).
4612 /*----------------------------------------------------------------------------*/
4614 wext_indicate_wext_event (
4615 IN P_GLUE_INFO_T prGlueInfo
,
4616 IN
unsigned int u4Cmd
,
4617 IN
unsigned char *pucData
,
4618 IN
unsigned int u4dataLen
4621 union iwreq_data wrqu
;
4622 unsigned char *pucExtraInfo
= NULL
;
4623 #if WIRELESS_EXT >= 15
4624 unsigned char *pucDesiredIE
= NULL
;
4625 unsigned char aucExtraInfoBuf
[200];
4627 #if WIRELESS_EXT < 18
4631 memset(&wrqu
, 0, sizeof(wrqu
));
4635 memcpy(&wrqu
.power
, pucData
, u4dataLen
);
4638 complete_all(&prGlueInfo
->rScanComp
);
4643 memcpy(&wrqu
.ap_addr
.sa_data
, pucData
, ETH_ALEN
);
4646 memset(&wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
4650 case IWEVASSOCREQIE
:
4651 #if WIRELESS_EXT < 15
4652 /* under WE-15, no suitable Event can be used */
4653 goto skip_indicate_event
;
4655 /* do supplicant a favor, parse to the start of WPA/RSN IE */
4656 if (wextSrchDesiredWPAIE(pucData
, u4dataLen
, 0x30, &pucDesiredIE
)) {
4660 else if (wextSrchDesiredWPSIE(pucData
, u4dataLen
, 0xDD, &pucDesiredIE
)) {
4664 else if (wextSrchDesiredWPAIE(pucData
, u4dataLen
, 0xDD, &pucDesiredIE
)) {
4667 #if CFG_SUPPORT_WAPI /* Android+ */
4668 else if (wextSrchDesiredWAPIIE(pucData
, u4dataLen
, &pucDesiredIE
)) {
4669 //printk("wextSrchDesiredWAPIIE!!\n");
4674 /* no WPA/RSN IE found, skip this event */
4675 goto skip_indicate_event
;
4678 #if WIRELESS_EXT < 18
4679 /* under WE-18, only IWEVCUSTOM can be used */
4681 pucExtraInfo
= aucExtraInfoBuf
;
4682 pucExtraInfo
+= sprintf(pucExtraInfo
, "ASSOCINFO(ReqIEs=");
4683 /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */
4684 /* translate binary string to hex string, requirement of IWEVCUSTOM */
4685 for (i
= 0; i
< pucDesiredIE
[1] + 2 ; ++i
) {
4686 pucExtraInfo
+= sprintf(pucExtraInfo
, "%02x", pucDesiredIE
[i
]);
4688 pucExtraInfo
= aucExtraInfoBuf
;
4689 wrqu
.data
.length
= 17 + (pucDesiredIE
[1] + 2) * 2;
4691 /* IWEVASSOCREQIE, indicate binary string */
4692 pucExtraInfo
= pucDesiredIE
;
4693 wrqu
.data
.length
= pucDesiredIE
[1] + 2;
4695 #endif /* WIRELESS_EXT < 15 */
4698 case IWEVMICHAELMICFAILURE
:
4699 #if WIRELESS_EXT < 15
4700 /* under WE-15, no suitable Event can be used */
4701 goto skip_indicate_event
;
4704 P_PARAM_AUTH_REQUEST_T pAuthReq
= (P_PARAM_AUTH_REQUEST_T
)pucData
;
4705 /* under WE-18, only IWEVCUSTOM can be used */
4707 pucExtraInfo
= aucExtraInfoBuf
;
4708 pucExtraInfo
+= sprintf(pucExtraInfo
,
4709 "MLME-MICHAELMICFAILURE.indication ");
4710 pucExtraInfo
+= sprintf(pucExtraInfo
,
4712 (pAuthReq
->u4Flags
== PARAM_AUTH_REQUEST_GROUP_ERROR
) ?
4713 "groupcast " : "unicast ");
4715 wrqu
.data
.length
= pucExtraInfo
- aucExtraInfoBuf
;
4716 pucExtraInfo
= aucExtraInfoBuf
;
4718 #endif /* WIRELESS_EXT < 15 */
4722 if (prGlueInfo
->rWpaInfo
.u4WpaVersion
== IW_AUTH_WPA_VERSION_WPA2
&&
4723 prGlueInfo
->rWpaInfo
.u4KeyMgmt
== IW_AUTH_KEY_MGMT_802_1X
) {
4725 /* only used in WPA2 */
4726 #if WIRELESS_EXT >= 18
4727 P_PARAM_PMKID_CANDIDATE_T prPmkidCand
= (P_PARAM_PMKID_CANDIDATE_T
)pucData
;
4729 struct iw_pmkid_cand rPmkidCand
;
4730 pucExtraInfo
= aucExtraInfoBuf
;
4732 rPmkidCand
.flags
= prPmkidCand
->u4Flags
;
4733 rPmkidCand
.index
= 0;
4734 kalMemCopy(rPmkidCand
.bssid
.sa_data
, prPmkidCand
->arBSSID
, 6);
4736 kalMemCopy(pucExtraInfo
, (PUINT_8
)&rPmkidCand
, sizeof(struct iw_pmkid_cand
));
4737 wrqu
.data
.length
= sizeof(struct iw_pmkid_cand
);
4739 /* pmkid canadidate list is supported after WE-18 */
4740 /* indicate struct iw_pmkid_cand */
4742 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */
4743 goto skip_indicate_event
;
4747 /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */
4748 goto skip_indicate_event
;
4754 pucExtraInfo
= aucExtraInfoBuf
;
4755 kalMemCopy(pucExtraInfo
, pucData
, sizeof(PTA_IPC_T
));
4756 wrqu
.data
.length
= sizeof(PTA_IPC_T
);
4760 /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */
4761 goto skip_indicate_event
;
4764 /* Send event to user space */
4765 wireless_send_event(prGlueInfo
->prDevHandler
, u4Cmd
, &wrqu
, pucExtraInfo
);
4767 skip_indicate_event
:
4769 } /* wext_indicate_wext_event */
4772 /*----------------------------------------------------------------------------*/
4774 * \brief A method of struct net_device, to get the network interface statistical
4777 * Whenever an application needs to get statistics for the interface, this method
4778 * is called. This happens, for example, when ifconfig or netstat -i is run.
4780 * \param[in] pDev Pointer to struct net_device.
4782 * \return net_device_stats buffer pointer.
4785 /*----------------------------------------------------------------------------*/
4786 struct iw_statistics
*
4787 wext_get_wireless_stats (
4788 struct net_device
*prDev
4792 WLAN_STATUS rStatus
= WLAN_STATUS_FAILURE
;
4793 P_GLUE_INFO_T prGlueInfo
= NULL
;
4794 struct iw_statistics
*pStats
= NULL
;
4799 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
4805 pStats
= (struct iw_statistics
*) (&(prGlueInfo
->rIwStats
));
4807 if (!prDev
|| !netif_carrier_ok(prDev
)) {
4808 /* network not connected */
4812 rStatus
= kalIoctl(prGlueInfo
,
4824 } /* wlan_get_wireless_stats */
4826 /*----------------------------------------------------------------------------*/
4828 * \brief To report the private supported IOCTLs table to user space.
4830 * \param[in] prNetDev Net device requested.
4831 * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
4832 * user space buffer in gl_iwpriv_table.
4834 * \retval 0 For success.
4835 * \retval -E2BIG For user's buffer size is too small.
4836 * \retval -EFAULT For fail.
4839 /*----------------------------------------------------------------------------*/
4842 IN
struct net_device
*prNetDev
,
4843 IN
struct ifreq
*prIfReq
4846 /* prIfReq is verified in the caller function wlanDoIOCTL() */
4847 struct iwreq
*prIwReq
= (struct iwreq
*)prIfReq
;
4848 struct iw_point
*prData
= (struct iw_point
*)&prIwReq
->u
.data
;
4849 UINT_16 u2BufferSize
= 0;
4851 u2BufferSize
= prData
->length
;
4853 /* update our private table size */
4854 prData
->length
= (__u16
)sizeof(rIwPrivTable
)/sizeof(struct iw_priv_args
);
4856 if (u2BufferSize
< prData
->length
) {
4860 if (prData
->length
) {
4861 if (copy_to_user(prData
->pointer
, rIwPrivTable
, sizeof(rIwPrivTable
))) {
4867 } /* wext_get_priv */
4869 #endif /* WIRELESS_EXT */