2 * ---------------------------------------------------------------------------
6 * Handlers for ioctls from iwconfig.
7 * These provide the control plane operations.
9 * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
11 * Refer to LICENSE.txt included with this source code for details on
14 * ---------------------------------------------------------------------------
16 #include <linux/types.h>
17 #include <linux/etherdevice.h>
18 #include <linux/if_arp.h>
19 #include <asm/uaccess.h>
20 #include <linux/ctype.h>
21 #include "unifi_priv.h"
22 #include <linux/rtnetlink.h>
24 #define CHECK_INITED(_priv) \
26 if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
27 unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \
32 /* Workaround for the wpa_supplicant hanging issue - disabled on Android */
34 #define CSR_WIFI_WEXT_HANG_WORKAROUND
37 #ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
38 # define UF_RTNL_LOCK() rtnl_lock()
39 # define UF_RTNL_UNLOCK() rtnl_unlock()
41 # define UF_RTNL_LOCK()
42 # define UF_RTNL_UNLOCK()
47 * ---------------------------------------------------------------------------
49 * ---------------------------------------------------------------------------
53 * ---------------------------------------------------------------------------
54 * wext_freq_to_channel
57 * These functions convert between channel number and frequency.
60 * ch Channel number, as defined in 802.11 specs
61 * m, e Mantissa and exponent as provided by wireless extension.
64 * channel or frequency (in MHz) value
65 * ---------------------------------------------------------------------------
68 wext_freq_to_channel(int m
, int e
)
83 return ((mhz
- 5000) / 5);
91 return ((mhz
- 2407) / 5);
95 } /* wext_freq_to_channel() */
98 channel_to_mhz(int ch
, int dot11a
)
101 if (ch
== 0) return 0;
102 if (ch
> 200) return 0;
106 return (5000 + (5 * ch
));
114 if ((ch
< 14) && (ch
> 0)) {
115 return (2407 + (5 * ch
));
120 #ifdef CSR_SUPPORT_WEXT_AP
121 void uf_sme_wext_ap_set_defaults(unifi_priv_t
*priv
)
123 memcpy(priv
->ap_config
.ssid
.ssid
,"defaultssid",sizeof("defaultssid"));
125 priv
->ap_config
.ssid
.length
= 8;
126 priv
->ap_config
.channel
= 6;
127 priv
->ap_config
.if_index
= 1;
128 priv
->ap_config
.credentials
.authType
= 0;
129 priv
->ap_config
.max_connections
=8;
131 priv
->group_sec_config
.apGroupkeyTimeout
= 0;
132 priv
->group_sec_config
.apStrictGtkRekey
= 0;
133 priv
->group_sec_config
.apGmkTimeout
= 0;
134 priv
->group_sec_config
.apResponseTimeout
= 100; /* Default*/
135 priv
->group_sec_config
.apRetransLimit
= 3; /* Default*/
136 /* Set default params even if they may not be used*/
139 priv
->ap_mac_config
.preamble
= CSR_WIFI_SME_USE_LONG_PREAMBLE
;
140 priv
->ap_mac_config
.shortSlotTimeEnabled
= FALSE
;
141 priv
->ap_mac_config
.ctsProtectionType
=CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC
;
143 priv
->ap_mac_config
.wmmEnabled
= TRUE
;
144 priv
->ap_mac_config
.wmmApParams
[0].cwMin
=4;
145 priv
->ap_mac_config
.wmmApParams
[0].cwMax
=10;
146 priv
->ap_mac_config
.wmmApParams
[0].aifs
=3;
147 priv
->ap_mac_config
.wmmApParams
[0].txopLimit
=0;
148 priv
->ap_mac_config
.wmmApParams
[0].admissionControlMandatory
=FALSE
;
149 priv
->ap_mac_config
.wmmApParams
[1].cwMin
=4;
150 priv
->ap_mac_config
.wmmApParams
[1].cwMax
=10;
151 priv
->ap_mac_config
.wmmApParams
[1].aifs
=7;
152 priv
->ap_mac_config
.wmmApParams
[1].txopLimit
=0;
153 priv
->ap_mac_config
.wmmApParams
[1].admissionControlMandatory
=FALSE
;
154 priv
->ap_mac_config
.wmmApParams
[2].cwMin
=3;
155 priv
->ap_mac_config
.wmmApParams
[2].cwMax
=4;
156 priv
->ap_mac_config
.wmmApParams
[2].aifs
=1;
157 priv
->ap_mac_config
.wmmApParams
[2].txopLimit
=94;
158 priv
->ap_mac_config
.wmmApParams
[2].admissionControlMandatory
=FALSE
;
159 priv
->ap_mac_config
.wmmApParams
[3].cwMin
=2;
160 priv
->ap_mac_config
.wmmApParams
[3].cwMax
=3;
161 priv
->ap_mac_config
.wmmApParams
[3].aifs
=1;
162 priv
->ap_mac_config
.wmmApParams
[3].txopLimit
=47;
163 priv
->ap_mac_config
.wmmApParams
[3].admissionControlMandatory
=FALSE
;
165 priv
->ap_mac_config
.wmmApBcParams
[0].cwMin
=4;
166 priv
->ap_mac_config
.wmmApBcParams
[0].cwMax
=10;
167 priv
->ap_mac_config
.wmmApBcParams
[0].aifs
=3;
168 priv
->ap_mac_config
.wmmApBcParams
[0].txopLimit
=0;
169 priv
->ap_mac_config
.wmmApBcParams
[0].admissionControlMandatory
=FALSE
;
170 priv
->ap_mac_config
.wmmApBcParams
[1].cwMin
=4;
171 priv
->ap_mac_config
.wmmApBcParams
[1].cwMax
=10;
172 priv
->ap_mac_config
.wmmApBcParams
[1].aifs
=7;
173 priv
->ap_mac_config
.wmmApBcParams
[1].txopLimit
=0;
174 priv
->ap_mac_config
.wmmApBcParams
[1].admissionControlMandatory
=FALSE
;
175 priv
->ap_mac_config
.wmmApBcParams
[2].cwMin
=3;
176 priv
->ap_mac_config
.wmmApBcParams
[2].cwMax
=4;
177 priv
->ap_mac_config
.wmmApBcParams
[2].aifs
=2;
178 priv
->ap_mac_config
.wmmApBcParams
[2].txopLimit
=94;
179 priv
->ap_mac_config
.wmmApBcParams
[2].admissionControlMandatory
=FALSE
;
180 priv
->ap_mac_config
.wmmApBcParams
[3].cwMin
=2;
181 priv
->ap_mac_config
.wmmApBcParams
[3].cwMax
=3;
182 priv
->ap_mac_config
.wmmApBcParams
[3].aifs
=2;
183 priv
->ap_mac_config
.wmmApBcParams
[3].txopLimit
=47;
184 priv
->ap_mac_config
.wmmApBcParams
[3].admissionControlMandatory
=FALSE
;
186 priv
->ap_mac_config
.accessType
=CSR_WIFI_AP_ACCESS_TYPE_NONE
;
187 priv
->ap_mac_config
.macAddressListCount
=0;
188 priv
->ap_mac_config
.macAddressList
=NULL
;
190 priv
->ap_mac_config
.apHtParams
.rxStbc
=1;
191 priv
->ap_mac_config
.apHtParams
.rifsModeAllowed
=TRUE
;
192 priv
->ap_mac_config
.apHtParams
.greenfieldSupported
=FALSE
;
193 priv
->ap_mac_config
.apHtParams
.shortGi20MHz
=TRUE
;
194 priv
->ap_mac_config
.apHtParams
.htProtection
=0;
195 priv
->ap_mac_config
.apHtParams
.dualCtsProtection
=FALSE
;
197 priv
->ap_mac_config
.phySupportedBitmap
=
198 (CSR_WIFI_SME_AP_PHY_SUPPORT_B
|CSR_WIFI_SME_AP_PHY_SUPPORT_G
|CSR_WIFI_SME_AP_PHY_SUPPORT_N
);
199 priv
->ap_mac_config
.beaconInterval
= 100;
200 priv
->ap_mac_config
.dtimPeriod
=3;
201 priv
->ap_mac_config
.maxListenInterval
=0x00ff;/* Set it to a large value
202 to enable different types of
203 devices to join us */
204 priv
->ap_mac_config
.supportedRatesCount
=
205 uf_configure_supported_rates(priv
->ap_mac_config
.supportedRates
,priv
->ap_mac_config
.phySupportedBitmap
);
209 * ---------------------------------------------------------------------------
210 * uf_sme_wext_set_defaults
212 * Set up power-on defaults for driver config.
214 * Note: The SME Management API *cannot* be used in this function.
217 * priv Pointer to device private context struct
221 * ---------------------------------------------------------------------------
224 uf_sme_wext_set_defaults(unifi_priv_t
*priv
)
226 memset(&priv
->connection_config
, 0, sizeof(CsrWifiSmeConnectionConfig
));
228 priv
->connection_config
.bssType
= CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE
;
229 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
230 priv
->connection_config
.encryptionModeMask
= CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE
;
231 priv
->connection_config
.privacyMode
= CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
;
232 priv
->connection_config
.wmmQosInfo
= 0xFF;
233 priv
->connection_config
.ifIndex
= CSR_WIFI_SME_RADIO_IF_BOTH
;
234 priv
->connection_config
.adhocJoinOnly
= FALSE
;
235 priv
->connection_config
.adhocChannel
= 6;
237 priv
->wep_tx_key_index
= 0;
239 priv
->wext_wireless_stats
.qual
.qual
= 0;
240 priv
->wext_wireless_stats
.qual
.level
= 0;
241 priv
->wext_wireless_stats
.qual
.noise
= 0;
242 priv
->wext_wireless_stats
.qual
.updated
= 0x70;
243 #ifdef CSR_SUPPORT_WEXT_AP
244 /* Initialize the default configuration for AP */
245 uf_sme_wext_ap_set_defaults(priv
);
249 } /* uf_sme_wext_set_defaults() */
253 * ---------------------------------------------------------------------------
255 * ---------------------------------------------------------------------------
259 * ---------------------------------------------------------------------------
260 * unifi_giwname - handler for SIOCGIWNAME
261 * unifi_siwfreq - handler for SIOCSIWFREQ
262 * unifi_giwfreq - handler for SIOCGIWFREQ
263 * unifi_siwmode - handler for SIOCSIWMODE
264 * unifi_giwmode - handler for SIOCGIWMODE
265 * unifi_giwrange - handler for SIOCGIWRANGE
266 * unifi_siwap - handler for SIOCSIWAP
267 * unifi_giwap - handler for SIOCGIWAP
268 * unifi_siwscan - handler for SIOCSIWSCAN
269 * unifi_giwscan - handler for SIOCGIWSCAN
270 * unifi_siwessid - handler for SIOCSIWESSID
271 * unifi_giwessid - handler for SIOCGIWESSID
272 * unifi_siwencode - handler for SIOCSIWENCODE
273 * unifi_giwencode - handler for SIOCGIWENCODE
275 * Handler functions for IW extensions.
276 * These are registered via the unifi_iw_handler_def struct below
277 * and called by the generic IW driver support code.
278 * See include/net/iw_handler.h.
285 * ---------------------------------------------------------------------------
288 iwprivsdefs(struct net_device
*dev
, struct iw_request_info
*info
,
289 union iwreq_data
*wrqu
, char *extra
)
292 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
293 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
294 CsrWifiSmeMibConfig mibConfig
;
295 CsrWifiSmePowerConfig powerConfig
;
297 unifi_trace(priv
, UDBG1
, "iwprivs80211defaults: reload defaults\n");
299 uf_sme_wext_set_defaults(priv
);
301 /* Get, modify and set the MIB data */
302 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
304 unifi_error(priv
, "iwprivs80211defaults: Get CsrWifiSmeMibConfigValue failed.\n");
307 mibConfig
.dot11RtsThreshold
= 2347;
308 mibConfig
.dot11FragmentationThreshold
= 2346;
309 r
= sme_mgt_mib_config_set(priv
, &mibConfig
);
311 unifi_error(priv
, "iwprivs80211defaults: Set CsrWifiSmeMibConfigValue failed.\n");
315 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW
;
316 powerConfig
.listenIntervalTu
= 100;
317 powerConfig
.rxDtims
= 1;
319 r
= sme_mgt_power_config_set(priv
, &powerConfig
);
321 unifi_error(priv
, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n");
326 } /* iwprivsdefs() */
329 iwprivs80211ps(struct net_device
*dev
, struct iw_request_info
*info
,
330 union iwreq_data
*wrqu
, char *extra
)
333 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
334 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
336 int ps_mode
= (int)(*extra
);
337 CsrWifiSmePowerConfig powerConfig
;
339 unifi_trace(priv
, UDBG1
, "iwprivs80211ps: power save mode = %d\n", ps_mode
);
341 r
= sme_mgt_power_config_get(priv
, &powerConfig
);
343 unifi_error(priv
, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n");
348 case CSR_PMM_ACTIVE_MODE
:
349 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW
;
351 case CSR_PMM_POWER_SAVE
:
352 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH
;
354 case CSR_PMM_FAST_POWER_SAVE
:
355 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_MED
;
358 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO
;
362 r
= sme_mgt_power_config_set(priv
, &powerConfig
);
364 unifi_error(priv
, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n");
371 iwprivg80211ps(struct net_device
*dev
, struct iw_request_info
*info
,
372 union iwreq_data
*wrqu
, char *extra
)
374 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
375 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
377 CsrWifiSmePowerConfig powerConfig
;
380 r
= sme_mgt_power_config_get(priv
, &powerConfig
);
382 unifi_error(priv
, "iwprivg80211ps: Get 802.11 power mode failed.\n");
386 switch (powerConfig
.powerSaveLevel
) {
387 case CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW
:
388 snprintf(extra
, IWPRIV_POWER_SAVE_MAX_STRING
,
389 "Power save mode: %d (Active)",
390 powerConfig
.powerSaveLevel
);
392 case CSR_WIFI_SME_POWER_SAVE_LEVEL_MED
:
393 snprintf(extra
, IWPRIV_POWER_SAVE_MAX_STRING
,
394 "Power save mode: %d (Fast)",
395 powerConfig
.powerSaveLevel
);
397 case CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH
:
398 snprintf(extra
, IWPRIV_POWER_SAVE_MAX_STRING
,
399 "Power save mode: %d (Full)",
400 powerConfig
.powerSaveLevel
);
402 case CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO
:
403 snprintf(extra
, IWPRIV_POWER_SAVE_MAX_STRING
,
404 "Power save mode: %d (Auto)",
405 powerConfig
.powerSaveLevel
);
408 snprintf(extra
, IWPRIV_POWER_SAVE_MAX_STRING
,
409 "Power save mode: %d (Unknown)",
410 powerConfig
.powerSaveLevel
);
414 wrqu
->data
.length
= strlen(extra
) + 1;
420 iwprivssmedebug(struct net_device
*dev
, struct iw_request_info
*info
,
421 union iwreq_data
*wrqu
, char *extra
)
423 /* No longer supported on the API */
424 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
425 unifi_debug_buf_dump();
431 #ifdef CSR_SUPPORT_WEXT_AP
432 #define PARAM_TYPE_INT 0
433 #define PARAM_TYPE_STRING 1
434 #define CSR_WIFI_MAX_SSID_LEN 32
435 #define CSR_WIFI_MAX_SEC_LEN 16
436 #define CSR_WIFI_MAX_KEY_LEN 65
438 static int hex_look_up(char x
)
442 if(x
>= 'a' && x
<= 'f')
447 static int power (int a
, int b
)
456 static int decode_parameter_from_string(unifi_priv_t
* priv
, char **str_ptr
,
457 const char *token
, int param_type
,
458 void *dst
, int param_max_len
)
462 u8
*param_str_begin
,*param_str_end
;
463 u8
*orig_str
= *str_ptr
;
465 if (!strncmp(*str_ptr
, token
, strlen(token
))) {
466 strsep(str_ptr
, "=,");
467 param_str_begin
= *str_ptr
;
468 strsep(str_ptr
, "=,");
469 if (*str_ptr
== NULL
) {
470 param_str_len
= strlen(param_str_begin
);
472 param_str_end
= *str_ptr
-1;
473 param_str_len
= param_str_end
- param_str_begin
;
475 unifi_trace(priv
,UDBG2
,"'token:%s', len:%d, ", token
, param_str_len
);
476 if (param_str_len
> param_max_len
) {
477 unifi_notice(priv
,"extracted param len:%d is > MAX:%d\n",param_str_len
, param_max_len
);
478 param_str_len
= param_max_len
;
480 switch (param_type
) {
483 u32
*pdst_int
= dst
,num
=0;
485 if (param_str_len
> sizeof(int_str
)) {
486 param_str_len
= sizeof(int_str
);
488 memcpy(int_str
, param_str_begin
, param_str_len
);
489 for(i
= param_str_len
; i
>0;i
--) {
490 if(int_str
[i
-1] >= '0' && int_str
[i
-1] <='9') {
491 num
+= ((int_str
[i
-1]-'0')*power(10,j
));
494 unifi_error(priv
,"decode_parameter_from_string:not a number %c\n",(int_str
[i
-1]));
499 unifi_trace(priv
,UDBG2
,"decode_parameter_from_string:decoded int = %d\n",*pdst_int
);
503 memcpy(dst
, param_str_begin
, param_str_len
);
504 *((char *)dst
+ param_str_len
) = 0;
505 unifi_trace(priv
,UDBG2
,"decode_parameter_from_string:decoded string = %s\n",(char *)dst
);
509 unifi_error(priv
,"decode_parameter_from_string: Token:%s not found in %s \n",token
,orig_str
);
514 static int store_ap_advanced_config_from_string(unifi_priv_t
*priv
, char *param_str
)
516 char * str_ptr
=param_str
;
519 CsrWifiSmeApMacConfig
* ap_mac_config
= &priv
->ap_mac_config
;
522 ret
= decode_parameter_from_string(priv
, &str_ptr
, "BI=",
523 PARAM_TYPE_INT
, &tmp_var
, 5);
525 unifi_error(priv
,"store_ap_advanced_config_from_string: BI not found\n");
528 ap_mac_config
->beaconInterval
= tmp_var
;
529 ret
= decode_parameter_from_string(priv
, &str_ptr
, "DTIM_PER=",
530 PARAM_TYPE_INT
, &tmp_var
, 5);
532 unifi_error(priv
,"store_ap_advanced_config_from_string: DTIM_PER not found\n");
535 ap_mac_config
->dtimPeriod
= tmp_var
;
536 ret
= decode_parameter_from_string(priv
, &str_ptr
, "WMM=",
537 PARAM_TYPE_INT
, &tmp_var
, 5);
539 unifi_error(priv
,"store_ap_advanced_config_from_string: WMM not found\n");
542 ap_mac_config
->wmmEnabled
= tmp_var
;
543 ret
= decode_parameter_from_string(priv
, &str_ptr
, "PHY=",
544 PARAM_TYPE_STRING
, phy_mode
, 5);
546 unifi_error(priv
,"store_ap_advanced_config_from_string: PHY not found\n");
548 if(strstr(phy_mode
,"b")){
549 ap_mac_config
->phySupportedBitmap
= CSR_WIFI_SME_AP_PHY_SUPPORT_B
;
551 if(strstr(phy_mode
,"g")) {
552 ap_mac_config
->phySupportedBitmap
|= CSR_WIFI_SME_AP_PHY_SUPPORT_G
;
554 if(strstr(phy_mode
,"n")) {
555 ap_mac_config
->phySupportedBitmap
|= CSR_WIFI_SME_AP_PHY_SUPPORT_N
;
557 ap_mac_config
->supportedRatesCount
=
558 uf_configure_supported_rates(ap_mac_config
->supportedRates
, ap_mac_config
->phySupportedBitmap
);
563 static int store_ap_config_from_string( unifi_priv_t
* priv
,char *param_str
)
566 char *str_ptr
= param_str
;
568 char sec
[CSR_WIFI_MAX_SEC_LEN
];
569 char key
[CSR_WIFI_MAX_KEY_LEN
];
571 CsrWifiSmeApConfig_t
*ap_config
= &priv
->ap_config
;
572 CsrWifiSmeApMacConfig
* ap_mac_config
= &priv
->ap_mac_config
;
573 memset(sub_cmd
, 0, sizeof(sub_cmd
));
574 if(!strstr(param_str
,"END")) {
575 unifi_error(priv
,"store_ap_config_from_string:Invalid config string:%s\n",param_str
);
578 if (decode_parameter_from_string(priv
,&str_ptr
, "ASCII_CMD=",
579 PARAM_TYPE_STRING
, sub_cmd
, 6) != 0) {
582 if (strncmp(sub_cmd
, "AP_CFG", 6)) {
584 if(!strncmp(sub_cmd
,"ADVCFG", 6)) {
585 return store_ap_advanced_config_from_string(priv
, str_ptr
);
587 unifi_error(priv
,"store_ap_config_from_string: sub_cmd:%s != 'AP_CFG or ADVCFG'!\n", sub_cmd
);
590 memset(ap_config
, 0, sizeof(CsrWifiSmeApConfig_t
));
591 ret
= decode_parameter_from_string(priv
,&str_ptr
, "SSID=",
592 PARAM_TYPE_STRING
, ap_config
->ssid
.ssid
,
593 CSR_WIFI_MAX_SSID_LEN
);
595 unifi_error(priv
,"store_ap_config_from_string: SSID not found\n");
598 ap_config
->ssid
.length
= strlen(ap_config
->ssid
.ssid
);
600 ret
= decode_parameter_from_string(priv
, &str_ptr
, "SEC=",
601 PARAM_TYPE_STRING
, sec
, CSR_WIFI_MAX_SEC_LEN
);
603 unifi_error(priv
,"store_ap_config_from_string: SEC not found\n");
606 ret
= decode_parameter_from_string(priv
,&str_ptr
, "KEY=",
607 PARAM_TYPE_STRING
, key
, CSR_WIFI_MAX_KEY_LEN
);
608 if(!strcasecmp(sec
,"open")) {
609 unifi_trace(priv
,UDBG2
,"store_ap_config_from_string: security open");
610 ap_config
->credentials
.authType
= CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM
;
612 unifi_notice(priv
,"store_ap_config_from_string: KEY not found:fine with Open\n");
615 else if(!strcasecmp(sec
,"wpa2-psk")) {
617 CsrWifiNmeApAuthPers
*pers
=
618 ((CsrWifiNmeApAuthPers
*)&(ap_config
->credentials
.nmeAuthType
.authTypePersonal
));
619 u8
*psk
= pers
->authPers_credentials
.psk
.psk
;
621 unifi_trace(priv
,UDBG2
,"store_ap_config_from_string: security WPA2");
623 unifi_error(priv
,"store_ap_config_from_string: KEY not found for WPA2\n");
626 ap_config
->credentials
.authType
= CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL
;
627 pers
->authSupport
= CSR_WIFI_SME_RSN_AUTH_WPA2PSK
;
628 pers
->rsnCapabilities
=0;
629 pers
->wapiCapabilities
=0;
630 pers
->pskOrPassphrase
=CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK
;
631 pers
->authPers_credentials
.psk
.encryptionMode
=
632 (CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP
|CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP
) ;
634 psk
[i
] = (16*hex_look_up(key
[j
]))+hex_look_up(key
[j
+1]);
639 unifi_notice(priv
,"store_ap_config_from_string: Unknown security: Assuming Open");
640 ap_config
->credentials
.authType
= CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM
;
643 /* Get the decoded value in a temp int variable to ensure that other fields within the struct
644 which are of type other than int are not over written */
645 ret
= decode_parameter_from_string(priv
,&str_ptr
, "CHANNEL=", PARAM_TYPE_INT
, &tmp_var
, 5);
648 ap_config
->channel
= tmp_var
;
649 ret
= decode_parameter_from_string(priv
,&str_ptr
, "PREAMBLE=", PARAM_TYPE_INT
, &tmp_var
, 5);
652 ap_mac_config
->preamble
= tmp_var
;
653 ret
= decode_parameter_from_string(priv
,&str_ptr
, "MAX_SCB=", PARAM_TYPE_INT
, &tmp_var
, 5);
654 ap_config
->max_connections
= tmp_var
;
659 iwprivsapstart(struct net_device
*dev
, struct iw_request_info
*info
,
660 union iwreq_data
*wrqu
, char *extra
)
662 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
663 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
666 unifi_trace(priv
, UDBG1
, "iwprivsapstart\n" );
667 r
= sme_ap_start(priv
,interfacePriv
->InterfaceTag
,&priv
->ap_config
);
669 unifi_error(priv
,"iwprivsapstart AP START failed : %d\n",-r
);
675 iwprivsapconfig(struct net_device
*dev
, struct iw_request_info
*info
,
676 union iwreq_data
*wrqu
, char *extra
)
678 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
679 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
680 char *cfg_str
= NULL
;
683 unifi_trace(priv
, UDBG1
, "iwprivsapconfig\n" );
684 if (wrqu
->data
.length
!= 0) {
686 if (!(cfg_str
= kmalloc(wrqu
->data
.length
+1, GFP_KERNEL
)))
690 if (copy_from_user(cfg_str
, wrqu
->data
.pointer
, wrqu
->data
.length
)) {
694 cfg_str
[wrqu
->data
.length
] = 0;
695 unifi_trace(priv
,UDBG2
,"length:%d\n",wrqu
->data
.length
);
696 unifi_trace(priv
,UDBG2
,"AP configuration string:%s\n",cfg_str
);
698 if ((r
= store_ap_config_from_string(priv
,str
))) {
699 unifi_error(priv
, "iwprivsapconfig:Failed to decode the string %d\n",r
);
705 unifi_error(priv
,"iwprivsapconfig argument length = 0 \n");
708 r
= sme_ap_config(priv
, &priv
->ap_mac_config
, &priv
->group_sec_config
);
710 unifi_error(priv
,"iwprivsapstop AP Config failed : %d\n",-r
);
711 } else if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
712 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
713 unifi_trace(priv
, UDBG1
, "iwprivsapconfig: Starting the AP");
714 r
= sme_ap_start(priv
,interfacePriv
->InterfaceTag
,&priv
->ap_config
);
716 unifi_error(priv
,"iwprivsapstart AP START failed : %d\n",-r
);
724 iwprivsapstop(struct net_device
*dev
, struct iw_request_info
*info
,
725 union iwreq_data
*wrqu
, char *extra
)
727 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
728 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
730 u16 interface_tag
= interfacePriv
->InterfaceTag
;
732 unifi_trace(priv
, UDBG1
, "iwprivsapstop\n" );
733 r
= sme_ap_stop(priv
,interface_tag
);
735 unifi_error(priv
,"iwprivsapstop AP STOP failed : %d\n",-r
);
742 iwprivsapfwreload(struct net_device
*dev
, struct iw_request_info
*info
,
743 union iwreq_data
*wrqu
, char *extra
)
745 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
746 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
748 unifi_trace(priv
, UDBG1
, "iwprivsapfwreload\n" );
753 iwprivsstackstart(struct net_device
*dev
, struct iw_request_info
*info
,
754 union iwreq_data
*wrqu
, char *extra
)
756 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
757 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
758 unifi_trace(priv
, UDBG1
, "iwprivsstackstart\n" );
763 iwprivsstackstop(struct net_device
*dev
, struct iw_request_info
*info
,
764 union iwreq_data
*wrqu
, char *extra
)
766 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
767 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
769 u16 interface_tag
= interfacePriv
->InterfaceTag
;
771 unifi_trace(priv
, UDBG1
, "iwprivsstackstop\n" );
773 switch(interfacePriv
->interfaceMode
) {
774 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
775 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
776 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
777 r
= sme_mgt_disconnect(priv
);
779 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
780 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
781 r
= sme_ap_stop(priv
,interface_tag
);
788 unifi_error(priv
,"iwprivsstackstop Stack stop failed : %d\n",-r
);
792 #endif /* ANDROID_BUILD */
793 #endif /* CSR_SUPPORT_WEXT_AP */
795 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
797 iwprivsconfwapi(struct net_device
*dev
, struct iw_request_info
*info
,
798 union iwreq_data
*wrqu
, char *extra
)
801 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
802 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
805 unifi_trace(priv
, UDBG1
, "iwprivsconfwapi\n" );
807 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
808 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
809 unifi_error(priv
, "iwprivsconfwapi: not permitted in Mode %d\n",
810 interfacePriv
->interfaceMode
);
814 enable
= *(u8
*)(extra
);
817 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
818 priv
->connection_config
.authModeMask
|= (CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK
| CSR_WIFI_SME_AUTH_MODE_WAPI_WAI
);
819 priv
->connection_config
.encryptionModeMask
|=
820 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4
;
822 priv
->connection_config
.authModeMask
&= ~(CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK
| CSR_WIFI_SME_AUTH_MODE_WAPI_WAI
);
823 priv
->connection_config
.encryptionModeMask
&=
824 ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4
);
832 iwprivswpikey(struct net_device
*dev
, struct iw_request_info
*info
,
833 union iwreq_data
*wrqu
, char *extra
)
837 unifiio_wapi_key_t inKey
;
838 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
839 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
842 unifi_trace(priv
, UDBG1
, "iwprivswpikey\n" );
844 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
845 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
846 unifi_error(priv
, "iwprivswpikey: not permitted in Mode %d\n",
847 interfacePriv
->interfaceMode
);
851 inKey
= *(unifiio_wapi_key_t
*)(extra
);
853 if (inKey
.unicastKey
) {
854 key
.keyType
= CSR_WIFI_SME_KEY_TYPE_PAIRWISE
;
856 key
.keyType
= CSR_WIFI_SME_KEY_TYPE_GROUP
;
859 key
.keyIndex
= inKey
.keyIndex
;
861 /* memcpy(key.keyRsc, inKey.keyRsc, 16); */
862 for (i
= 0; i
< 16; i
+= 2)
864 key
.keyRsc
[i
/2] = inKey
.keyRsc
[i
+1] << 8 | inKey
.keyRsc
[i
];
867 memcpy(key
.address
.a
, inKey
.address
, 6);
869 memcpy(key
.key
, inKey
.key
, 32);
870 key
.authenticator
= 0;
873 unifi_trace(priv
, UDBG1
, "keyType = %d, keyIndex = %d, wepTxKey = %d, keyRsc = %x:%x, auth = %d, address = %x:%x, "
874 "keylength = %d, key = %x:%x\n", key
.keyType
, key
.keyIndex
, key
.wepTxKey
,
875 key
.keyRsc
[0], key
.keyRsc
[7], key
.authenticator
,
876 key
.address
.a
[0], key
.address
.a
[5], key
.keyLength
, key
.key
[0],
879 r
= sme_mgt_key(priv
, &key
, CSR_WIFI_SME_LIST_ACTION_ADD
);
881 unifi_error(priv
, "SETKEYS request was rejected with result %d\n", r
);
882 return convert_sme_error(r
);
892 unifi_giwname(struct net_device
*dev
, struct iw_request_info
*info
,
893 union iwreq_data
*wrqu
, char *extra
)
895 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
896 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
897 char *name
= wrqu
->name
;
898 unifi_trace(priv
, UDBG2
, "unifi_giwname\n");
900 if (priv
->if_index
== CSR_INDEX_5G
) {
901 strcpy(name
, "IEEE 802.11-a");
903 strcpy(name
, "IEEE 802.11-bgn");
906 } /* unifi_giwname() */
910 unifi_siwfreq(struct net_device
*dev
, struct iw_request_info
*info
,
911 union iwreq_data
*wrqu
, char *extra
)
913 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
914 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
915 struct iw_freq
*freq
= (struct iw_freq
*)wrqu
;
918 unifi_trace(priv
, UDBG2
, "unifi_siwfreq\n");
920 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
921 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
922 unifi_error(priv
, "unifi_siwfreq: not permitted in Mode %d\n",
923 interfacePriv
->interfaceMode
);
929 * Channel is stored in the connection configuration,
930 * and set later when ask for a connection.
932 if ((freq
->e
== 0) && (freq
->m
<= 1000)) {
933 priv
->connection_config
.adhocChannel
= freq
->m
;
935 priv
->connection_config
.adhocChannel
= wext_freq_to_channel(freq
->m
, freq
->e
);
940 } /* unifi_siwfreq() */
944 unifi_giwfreq(struct net_device
*dev
, struct iw_request_info
*info
,
945 union iwreq_data
*wrqu
, char *extra
)
947 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
948 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
949 struct iw_freq
*freq
= (struct iw_freq
*)wrqu
;
951 CsrWifiSmeConnectionInfo connectionInfo
;
954 unifi_trace(priv
, UDBG2
, "unifi_giwfreq\n");
957 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
958 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
959 unifi_error(priv
, "unifi_giwfreq: not permitted in Mode %d\n",
960 interfacePriv
->interfaceMode
);
966 err
= sme_mgt_connection_info_get(priv
, &connectionInfo
);
969 freq
->m
= channel_to_mhz(connectionInfo
.channelNumber
,
970 (connectionInfo
.networkType80211
== CSR_WIFI_SME_RADIO_IF_GHZ_5_0
));
974 return convert_sme_error(err
);
975 } /* unifi_giwfreq() */
979 unifi_siwmode(struct net_device
*dev
, struct iw_request_info
*info
,
980 union iwreq_data
*wrqu
, char *extra
)
982 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
983 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
986 unifi_trace(priv
, UDBG2
, "unifi_siwmode\n");
988 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
989 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
990 unifi_error(priv
, "unifi_siwmode: not permitted in Mode %d\n",
991 interfacePriv
->interfaceMode
);
998 priv
->connection_config
.bssType
= CSR_WIFI_SME_BSS_TYPE_ADHOC
;
1001 priv
->connection_config
.bssType
= CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE
;
1004 priv
->connection_config
.bssType
= CSR_WIFI_SME_BSS_TYPE_ANY_BSS
;
1007 unifi_notice(priv
, "Unknown IW MODE value.\n");
1010 /* Clear the SSID and BSSID configuration */
1011 priv
->connection_config
.ssid
.length
= 0;
1012 memset(priv
->connection_config
.bssid
.a
, 0xFF, ETH_ALEN
);
1016 } /* unifi_siwmode() */
1021 unifi_giwmode(struct net_device
*dev
, struct iw_request_info
*info
,
1022 union iwreq_data
*wrqu
, char *extra
)
1025 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1026 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1027 CsrWifiSmeConnectionConfig connectionConfig
;
1030 unifi_trace(priv
, UDBG2
, "unifi_giwmode\n");
1033 unifi_trace(priv
, UDBG2
, "unifi_giwmode: Exisitng mode = 0x%x\n",
1034 interfacePriv
->interfaceMode
);
1035 switch(interfacePriv
->interfaceMode
) {
1036 case CSR_WIFI_ROUTER_CTRL_MODE_STA
:
1037 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI
:
1038 wrqu
->mode
= IW_MODE_INFRA
;
1040 case CSR_WIFI_ROUTER_CTRL_MODE_AP
:
1041 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
:
1042 wrqu
->mode
= IW_MODE_MASTER
;
1044 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS
:
1045 wrqu
->mode
= IW_MODE_ADHOC
;
1047 case CSR_WIFI_ROUTER_CTRL_MODE_P2P
:
1048 case CSR_WIFI_ROUTER_CTRL_MODE_NONE
:
1050 r
= sme_mgt_connection_config_get(priv
, &connectionConfig
);
1053 switch(connectionConfig
.bssType
) {
1054 case CSR_WIFI_SME_BSS_TYPE_ADHOC
:
1055 wrqu
->mode
= IW_MODE_ADHOC
;
1057 case CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE
:
1058 wrqu
->mode
= IW_MODE_INFRA
;
1061 wrqu
->mode
= IW_MODE_AUTO
;
1062 unifi_notice(priv
, "Unknown IW MODE value.\n");
1067 wrqu
->mode
= IW_MODE_AUTO
;
1068 unifi_notice(priv
, "Unknown IW MODE value.\n");
1071 unifi_trace(priv
, UDBG4
, "unifi_giwmode: mode = 0x%x\n", wrqu
->mode
);
1074 } /* unifi_giwmode() */
1079 unifi_giwrange(struct net_device
*dev
, struct iw_request_info
*info
,
1080 union iwreq_data
*wrqu
, char *extra
)
1082 struct iw_point
*dwrq
= &wrqu
->data
;
1083 struct iw_range
*range
= (struct iw_range
*) extra
;
1086 unifi_trace(NULL
, UDBG2
, "unifi_giwrange\n");
1088 dwrq
->length
= sizeof(struct iw_range
);
1089 memset(range
, 0, sizeof(*range
));
1090 range
->min_nwid
= 0x0000;
1091 range
->max_nwid
= 0x0000;
1094 * Don't report the frequency/channel table, then the channel
1095 * number returned elsewhere will be printed as a channel number.
1098 /* Ranges of values reported in quality structs */
1099 range
->max_qual
.qual
= 40; /* Max expected qual value */
1100 range
->max_qual
.level
= -120; /* Noise floor in dBm */
1101 range
->max_qual
.noise
= -120; /* Noise floor in dBm */
1104 /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
1106 #if WIRELESS_EXT > 15
1107 range
->bitrate
[i
++] = 2 * 500000;
1108 range
->bitrate
[i
++] = 4 * 500000;
1109 range
->bitrate
[i
++] = 11 * 500000;
1110 range
->bitrate
[i
++] = 22 * 500000;
1111 range
->bitrate
[i
++] = 12 * 500000;
1112 range
->bitrate
[i
++] = 18 * 500000;
1113 range
->bitrate
[i
++] = 24 * 500000;
1114 range
->bitrate
[i
++] = 36 * 500000;
1115 range
->bitrate
[i
++] = 48 * 500000;
1116 range
->bitrate
[i
++] = 72 * 500000;
1117 range
->bitrate
[i
++] = 96 * 500000;
1118 range
->bitrate
[i
++] = 108 * 500000;
1120 range
->bitrate
[i
++] = 2 * 500000;
1121 range
->bitrate
[i
++] = 4 * 500000;
1122 range
->bitrate
[i
++] = 11 * 500000;
1123 range
->bitrate
[i
++] = 22 * 500000;
1124 range
->bitrate
[i
++] = 24 * 500000;
1125 range
->bitrate
[i
++] = 48 * 500000;
1126 range
->bitrate
[i
++] = 96 * 500000;
1127 range
->bitrate
[i
++] = 108 * 500000;
1128 #endif /* WIRELESS_EXT < 16 */
1129 range
->num_bitrates
= i
;
1131 range
->max_encoding_tokens
= NUM_WEPKEYS
;
1132 range
->num_encoding_sizes
= 2;
1133 range
->encoding_size
[0] = 5;
1134 range
->encoding_size
[1] = 13;
1136 range
->we_version_source
= 20;
1137 range
->we_version_compiled
= WIRELESS_EXT
;
1139 /* Number of channels available in h/w */
1140 range
->num_channels
= 14;
1141 /* Number of entries in freq[] array */
1142 range
->num_frequency
= 14;
1143 for (i
= 0; (i
< range
->num_frequency
) && (i
< IW_MAX_FREQUENCIES
); i
++) {
1145 range
->freq
[i
].i
= chan
;
1146 range
->freq
[i
].m
= channel_to_mhz(chan
, 0);
1147 range
->freq
[i
].e
= 6;
1149 if ((i
+3) < IW_MAX_FREQUENCIES
) {
1150 range
->freq
[i
].i
= 36;
1151 range
->freq
[i
].m
= channel_to_mhz(36, 1);
1152 range
->freq
[i
].e
= 6;
1153 range
->freq
[i
+1].i
= 40;
1154 range
->freq
[i
+1].m
= channel_to_mhz(40, 1);
1155 range
->freq
[i
+1].e
= 6;
1156 range
->freq
[i
+2].i
= 44;
1157 range
->freq
[i
+2].m
= channel_to_mhz(44, 1);
1158 range
->freq
[i
+2].e
= 6;
1159 range
->freq
[i
+3].i
= 48;
1160 range
->freq
[i
+3].m
= channel_to_mhz(48, 1);
1161 range
->freq
[i
+3].e
= 6;
1164 #if WIRELESS_EXT > 16
1165 /* Event capability (kernel + driver) */
1166 range
->event_capa
[0] = (IW_EVENT_CAPA_K_0
|
1167 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY
) |
1168 IW_EVENT_CAPA_MASK(SIOCGIWAP
) |
1169 IW_EVENT_CAPA_MASK(SIOCGIWSCAN
));
1170 range
->event_capa
[1] = IW_EVENT_CAPA_K_1
;
1171 range
->event_capa
[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP
) |
1172 IW_EVENT_CAPA_MASK(IWEVCUSTOM
) |
1173 IW_EVENT_CAPA_MASK(IWEVREGISTERED
) |
1174 IW_EVENT_CAPA_MASK(IWEVEXPIRED
));
1175 #endif /* WIRELESS_EXT > 16 */
1177 #if WIRELESS_EXT > 17
1178 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
1179 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
1180 #endif /* WIRELESS_EXT > 17 */
1184 } /* unifi_giwrange() */
1188 unifi_siwap(struct net_device
*dev
, struct iw_request_info
*info
,
1189 union iwreq_data
*wrqu
, char *extra
)
1191 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1192 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1194 const unsigned char zero_bssid
[ETH_ALEN
] = {0x00, 0x00, 0x00,
1201 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1202 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1203 unifi_error(priv
, "unifi_siwap: not permitted in Mode %d\n",
1204 interfacePriv
->interfaceMode
);
1209 if (wrqu
->ap_addr
.sa_family
!= ARPHRD_ETHER
) {
1213 unifi_trace(priv
, UDBG1
, "unifi_siwap: asked for %pM\n",
1214 wrqu
->ap_addr
.sa_data
);
1216 if (!memcmp(wrqu
->ap_addr
.sa_data
, zero_bssid
, ETH_ALEN
)) {
1217 priv
->ignore_bssid_join
= FALSE
;
1218 err
= sme_mgt_disconnect(priv
);
1220 unifi_trace(priv
, UDBG4
, "unifi_siwap: Disconnect failed, status %d\n", err
);
1225 if (priv
->ignore_bssid_join
) {
1226 unifi_trace(priv
, UDBG4
, "unifi_siwap: ignoring second join\n");
1227 priv
->ignore_bssid_join
= FALSE
;
1229 memcpy(priv
->connection_config
.bssid
.a
, wrqu
->ap_addr
.sa_data
, ETH_ALEN
);
1230 unifi_trace(priv
, UDBG1
, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n",
1231 priv
->connection_config
.bssid
.a
[0],
1232 priv
->connection_config
.bssid
.a
[1],
1233 priv
->connection_config
.bssid
.a
[2],
1234 priv
->connection_config
.bssid
.a
[3],
1235 priv
->connection_config
.bssid
.a
[4],
1236 priv
->connection_config
.bssid
.a
[5]);
1237 err
= sme_mgt_connect(priv
);
1239 unifi_error(priv
, "unifi_siwap: Join failed, status %d\n", err
);
1241 return convert_sme_error(err
);
1247 } /* unifi_siwap() */
1251 unifi_giwap(struct net_device
*dev
, struct iw_request_info
*info
,
1252 union iwreq_data
*wrqu
, char *extra
)
1254 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1255 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1256 CsrWifiSmeConnectionInfo connectionInfo
;
1263 unifi_trace(priv
, UDBG2
, "unifi_giwap\n");
1265 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1266 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1267 unifi_error(priv
, "iwprivswpikey: not permitted in Mode %d\n",
1268 interfacePriv
->interfaceMode
);
1273 r
= sme_mgt_connection_info_get(priv
, &connectionInfo
);
1277 bssid
= connectionInfo
.bssid
.a
;
1278 wrqu
->ap_addr
.sa_family
= ARPHRD_ETHER
;
1279 unifi_trace(priv
, UDBG4
, "unifi_giwap: BSSID = %pM\n", bssid
);
1281 memcpy(wrqu
->ap_addr
.sa_data
, bssid
, ETH_ALEN
);
1283 memset(wrqu
->ap_addr
.sa_data
, 0, ETH_ALEN
);
1288 } /* unifi_giwap() */
1292 unifi_siwscan(struct net_device
*dev
, struct iw_request_info
*info
,
1293 union iwreq_data
*wrqu
, char *extra
)
1295 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1296 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1299 CsrWifiSsid scan_ssid
;
1300 unsigned char *channel_list
= NULL
;
1302 #if WIRELESS_EXT > 17
1303 struct iw_point
*data
= &wrqu
->data
;
1304 struct iw_scan_req
*req
= (struct iw_scan_req
*) extra
;
1311 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1312 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1313 unifi_error(priv
, "unifi_siwscan: not permitted in Mode %d\n",
1314 interfacePriv
->interfaceMode
);
1319 scantype
= UNIFI_SCAN_ACTIVE
;
1321 #if WIRELESS_EXT > 17
1322 /* Providing a valid channel list will force an active scan */
1324 if ((req
->num_channels
> 0) && (req
->num_channels
< IW_MAX_FREQUENCIES
)) {
1325 channel_list
= kmalloc(req
->num_channels
, GFP_KERNEL
);
1328 for (i
= 0; i
< req
->num_channels
; i
++) {
1329 /* Convert frequency to channel number */
1330 int ch
= wext_freq_to_channel(req
->channel_list
[i
].m
,
1331 req
->channel_list
[i
].e
);
1333 channel_list
[chans_good
++] = ch
;
1336 unifi_trace(priv
, UDBG1
,
1337 "SIWSCAN: Scanning %d channels\n", chans_good
);
1339 /* Fall back to scanning all */
1340 unifi_error(priv
, "SIWSCAN: Can't alloc channel_list (%d)\n",
1346 if (req
&& (data
->flags
& IW_SCAN_THIS_ESSID
)) {
1347 memcpy(scan_ssid
.ssid
, req
->essid
, req
->essid_len
);
1348 scan_ssid
.length
= req
->essid_len
;
1349 unifi_trace(priv
, UDBG1
,
1350 "SIWSCAN: Scanning for %.*s\n",
1351 scan_ssid
.length
, scan_ssid
.ssid
);
1355 unifi_trace(priv
, UDBG1
, "SIWSCAN: Scanning for all APs\n");
1356 scan_ssid
.length
= 0;
1359 r
= sme_mgt_scan_full(priv
, &scan_ssid
, chans_good
, channel_list
);
1361 unifi_error(priv
, "SIWSCAN: Scan returned error %d\n", r
);
1363 unifi_trace(priv
, UDBG1
, "SIWSCAN: Scan done\n");
1364 wext_send_scan_results_event(priv
);
1368 kfree(channel_list
);
1374 } /* unifi_siwscan() */
1377 static const unsigned char *
1378 unifi_find_info_element(int id
, const unsigned char *info
, int len
)
1380 const unsigned char *ie
= info
;
1388 /* Return if we find a match */
1399 } /* unifi_find_info_element() */
1403 * Translate scan data returned from the card to a card independent
1404 * format that the Wireless Tools will understand - Jean II
1407 unifi_translate_scan(struct net_device
*dev
,
1408 struct iw_request_info
*info
,
1409 char *current_ev
, char *end_buf
,
1410 CsrWifiSmeScanResult
*scan_data
,
1413 struct iw_event iwe
; /* Temporary buffer */
1414 unsigned char *info_elems
;
1416 const unsigned char *elem
;
1418 int signal
, noise
, snr
;
1419 char *start_buf
= current_ev
;
1420 char *current_val
; /* For rates */
1423 info_elems
= scan_data
->informationElements
;
1424 info_elem_len
= scan_data
->informationElementsLength
;
1426 if (!scan_data
->informationElementsLength
|| !scan_data
->informationElements
) {
1427 unifi_error(NULL
, "*** NULL SCAN IEs ***\n");
1431 /* get capinfo bits */
1432 capabilities
= scan_data
->capabilityInformation
;
1434 unifi_trace(NULL
, UDBG5
, "Capabilities: 0x%x\n", capabilities
);
1436 /* First entry *MUST* be the AP MAC address */
1437 memset(&iwe
, 0, sizeof(iwe
));
1438 iwe
.cmd
= SIOCGIWAP
;
1439 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1440 memcpy(iwe
.u
.ap_addr
.sa_data
, scan_data
->bssid
.a
, ETH_ALEN
);
1441 iwe
.len
= IW_EV_ADDR_LEN
;
1442 r
= uf_iwe_stream_add_event(info
, start_buf
, end_buf
, &iwe
, IW_EV_ADDR_LEN
);
1448 /* Other entries will be displayed in the order we give them */
1451 /* find SSID in Info Elems */
1452 elem
= unifi_find_info_element(IE_SSID_ID
, info_elems
, info_elem_len
);
1454 int e_len
= elem
[1];
1455 const unsigned char *e_ptr
= elem
+ 2;
1456 unsigned char buf
[33];
1458 memset(&iwe
, 0, sizeof(iwe
));
1459 iwe
.cmd
= SIOCGIWESSID
;
1460 iwe
.u
.essid
.length
= e_len
;
1461 if (iwe
.u
.essid
.length
> 32) {
1462 iwe
.u
.essid
.length
= 32;
1464 iwe
.u
.essid
.flags
= scan_index
;
1465 memcpy(buf
, e_ptr
, iwe
.u
.essid
.length
);
1466 buf
[iwe
.u
.essid
.length
] = '\0';
1467 r
= uf_iwe_stream_add_point(info
, start_buf
, end_buf
, &iwe
, buf
);
1476 memset(&iwe
, 0, sizeof(iwe
));
1477 iwe
.cmd
= SIOCGIWMODE
;
1478 if (scan_data
->bssType
== CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE
) {
1479 iwe
.u
.mode
= IW_MODE_INFRA
;
1481 iwe
.u
.mode
= IW_MODE_ADHOC
;
1483 iwe
.len
= IW_EV_UINT_LEN
;
1484 r
= uf_iwe_stream_add_event(info
, start_buf
, end_buf
, &iwe
, IW_EV_UINT_LEN
);
1490 /* Add frequency. iwlist will convert to channel using table given in giwrange */
1491 memset(&iwe
, 0, sizeof(iwe
));
1492 iwe
.cmd
= SIOCGIWFREQ
;
1493 iwe
.u
.freq
.m
= scan_data
->channelFrequency
;
1495 r
= uf_iwe_stream_add_event(info
, start_buf
, end_buf
, &iwe
, IW_EV_FREQ_LEN
);
1502 /* Add quality statistics */
1505 * level and noise below are mapped into an unsigned 8 bit number,
1506 * ranging from [-192; 63]. The way this is achieved is simply to
1507 * add 0x100 onto the number if it is negative,
1508 * once clipped to the correct range.
1510 signal
= scan_data
->rssi
; /* This value is in dBm */
1511 /* Clip range of snr */
1512 snr
= (scan_data
->snr
> 0) ? scan_data
->snr
: 0; /* In dB relative, from 0 - 255 */
1513 snr
= (snr
< 255) ? snr
: 255;
1514 noise
= signal
- snr
;
1516 /* Clip range of signal */
1517 signal
= (signal
< 63) ? signal
: 63;
1518 signal
= (signal
> -192) ? signal
: -192;
1520 /* Clip range of noise */
1521 noise
= (noise
< 63) ? noise
: 63;
1522 noise
= (noise
> -192) ? noise
: -192;
1525 signal
= ( signal
< 0 ) ? signal
+ 0x100 : signal
;
1526 noise
= ( noise
< 0 ) ? noise
+ 0x100 : noise
;
1528 iwe
.u
.qual
.level
= (u8
)signal
; /* -192 : 63 */
1529 iwe
.u
.qual
.noise
= (u8
)noise
; /* -192 : 63 */
1530 iwe
.u
.qual
.qual
= snr
; /* 0 : 255 */
1531 iwe
.u
.qual
.updated
= 0;
1532 #if WIRELESS_EXT > 16
1533 iwe
.u
.qual
.updated
|= IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_UPDATED
|
1534 IW_QUAL_QUAL_UPDATED
;
1535 #if WIRELESS_EXT > 18
1536 iwe
.u
.qual
.updated
|= IW_QUAL_DBM
;
1539 r
= uf_iwe_stream_add_event(info
, start_buf
, end_buf
, &iwe
, IW_EV_QUAL_LEN
);
1545 /* Add encryption capability */
1546 iwe
.cmd
= SIOCGIWENCODE
;
1547 if (capabilities
& SIG_CAP_PRIVACY
) {
1548 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
1550 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
1552 iwe
.u
.data
.length
= 0;
1553 iwe
.len
= IW_EV_POINT_LEN
+ iwe
.u
.data
.length
;
1554 r
= uf_iwe_stream_add_point(info
, start_buf
, end_buf
, &iwe
, "");
1562 * Rate : stuffing multiple values in a single event require a bit
1563 * more of magic - Jean II
1565 current_val
= start_buf
+ IW_EV_LCP_LEN
;
1567 iwe
.cmd
= SIOCGIWRATE
;
1568 /* Those two flags are ignored... */
1569 iwe
.u
.bitrate
.fixed
= iwe
.u
.bitrate
.disabled
= 0;
1571 elem
= unifi_find_info_element(IE_SUPPORTED_RATES_ID
,
1572 info_elems
, info_elem_len
);
1574 int e_len
= elem
[1];
1575 const unsigned char *e_ptr
= elem
+ 2;
1578 * Count how many rates we have.
1579 * Zero marks the end of the list, if the list is not truncated.
1582 for (i
= 0; i
< e_len
; i
++) {
1583 if (e_ptr
[i
] == 0) {
1586 /* Bit rate given in 500 kb/s units (+ 0x80) */
1587 iwe
.u
.bitrate
.value
= ((e_ptr
[i
] & 0x7f) * 500000);
1588 /* Add new value to event */
1589 r
= uf_iwe_stream_add_value(info
, start_buf
, current_val
, end_buf
, &iwe
, IW_EV_PARAM_LEN
);
1597 elem
= unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID
,
1598 info_elems
, info_elem_len
);
1600 int e_len
= elem
[1];
1601 const unsigned char *e_ptr
= elem
+ 2;
1604 * Count how many rates we have.
1605 * Zero marks the end of the list, if the list is not truncated.
1608 for (i
= 0; i
< e_len
; i
++) {
1609 if (e_ptr
[i
] == 0) {
1612 /* Bit rate given in 500 kb/s units (+ 0x80) */
1613 iwe
.u
.bitrate
.value
= ((e_ptr
[i
] & 0x7f) * 500000);
1614 /* Add new value to event */
1615 r
= uf_iwe_stream_add_value(info
, start_buf
, current_val
, end_buf
, &iwe
, IW_EV_PARAM_LEN
);
1622 /* Check if we added any rates event */
1623 if ((current_val
- start_buf
) > IW_EV_LCP_LEN
) {
1624 start_buf
= current_val
;
1628 #if WIRELESS_EXT > 17
1629 memset(&iwe
, 0, sizeof(iwe
));
1630 iwe
.cmd
= IWEVGENIE
;
1631 iwe
.u
.data
.length
= info_elem_len
;
1633 r
= uf_iwe_stream_add_point(info
, start_buf
, end_buf
, &iwe
, info_elems
);
1639 #endif /* WE > 17 */
1641 return (start_buf
- current_ev
);
1642 } /* unifi_translate_scan() */
1647 unifi_giwscan(struct net_device
*dev
, struct iw_request_info
*info
,
1648 union iwreq_data
*wrqu
, char *extra
)
1650 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1651 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1652 struct iw_point
*dwrq
= &wrqu
->data
;
1657 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1658 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1659 unifi_error(priv
, "unifi_giwscan: not permitted in Mode %d\n",
1660 interfacePriv
->interfaceMode
);
1665 unifi_trace(priv
, UDBG1
,
1666 "unifi_giwscan: buffer (%d bytes) \n",
1669 r
= sme_mgt_scan_results_get_async(priv
, info
, extra
, dwrq
->length
);
1672 unifi_trace(priv
, UDBG1
,
1673 "unifi_giwscan: buffer (%d bytes) not big enough.\n",
1682 } /* unifi_giwscan() */
1686 * ---------------------------------------------------------------------------
1689 * Request to join a network or start and AdHoc.
1692 * dev Pointer to network device struct.
1693 * info Pointer to broken-out ioctl request.
1694 * data Pointer to argument data.
1695 * essid Pointer to string giving name of network to join
1699 * 0 on success and everything complete
1700 * -EINPROGRESS to have the higher level call the commit method.
1701 * ---------------------------------------------------------------------------
1704 unifi_siwessid(struct net_device
*dev
, struct iw_request_info
*info
,
1705 struct iw_point
*data
, char *essid
)
1707 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1708 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1715 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1716 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1717 unifi_error(priv
, "unifi_siwessid: not permitted in Mode %d\n",
1718 interfacePriv
->interfaceMode
);
1724 if (data
->flags
& 1) {
1727 if (len
> UNIFI_MAX_SSID_LEN
) {
1728 len
= UNIFI_MAX_SSID_LEN
;
1734 char essid_str
[UNIFI_MAX_SSID_LEN
+1];
1737 for (i
= 0; i
< len
; i
++) {
1738 essid_str
[i
] = (isprint(essid
[i
]) ? essid
[i
] : '?');
1740 essid_str
[i
] = '\0';
1742 unifi_trace(priv
, UDBG1
, "unifi_siwessid: asked for '%*s' (%d)\n", len
, essid_str
, len
);
1743 unifi_trace(priv
, UDBG2
, " with authModeMask = %d", priv
->connection_config
.authModeMask
);
1747 memset(priv
->connection_config
.bssid
.a
, 0xFF, ETH_ALEN
);
1749 if (essid
[len
- 1] == 0) {
1753 memcpy(priv
->connection_config
.ssid
.ssid
, essid
, len
);
1754 priv
->connection_config
.ssid
.length
= len
;
1757 priv
->connection_config
.ssid
.length
= 0;
1761 err
= sme_mgt_connect(priv
);
1764 unifi_error(priv
, "unifi_siwessid: Join failed, status %d\n", err
);
1766 return convert_sme_error(err
);
1771 } /* unifi_siwessid() */
1775 unifi_giwessid(struct net_device
*dev
, struct iw_request_info
*info
,
1776 union iwreq_data
*wrqu
, char *essid
)
1778 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1779 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1780 struct iw_point
*data
= &wrqu
->essid
;
1781 CsrWifiSmeConnectionInfo connectionInfo
;
1785 unifi_trace(priv
, UDBG2
, "unifi_giwessid\n");
1788 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
1789 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
1790 unifi_error(priv
, "unifi_giwessid: not permitted in Mode %d\n",
1791 interfacePriv
->interfaceMode
);
1796 r
= sme_mgt_connection_info_get(priv
, &connectionInfo
);
1800 data
->length
= connectionInfo
.ssid
.length
;
1802 connectionInfo
.ssid
.ssid
,
1804 data
->flags
= 1; /* active */
1806 unifi_trace(priv
, UDBG2
, "unifi_giwessid: %.*s\n",
1807 data
->length
, essid
);
1813 } /* unifi_giwessid() */
1817 unifi_siwrate(struct net_device
*dev
, struct iw_request_info
*info
,
1818 union iwreq_data
*wrqu
, char *extra
)
1820 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1821 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1822 struct iw_param
*args
= &wrqu
->bitrate
;
1823 CsrWifiSmeMibConfig mibConfig
;
1829 unifi_trace(priv
, UDBG2
, "unifi_siwrate\n");
1832 * If args->fixed == 0, value is max rate or -1 for best
1833 * If args->fixed == 1, value is rate to set or -1 for best
1834 * args->disabled and args->flags are not used in SIOCSIWRATE
1837 /* Get, modify and set the MIB data */
1839 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
1842 unifi_error(priv
, "unifi_siwrate: Get CsrWifiSmeMibConfigValue failed.\n");
1846 /* Default to auto rate algorithm */
1847 /* in 500Kbit/s, 0 means auto */
1848 mibConfig
.unifiFixTxDataRate
= 0;
1850 if (args
->value
!= -1) {
1851 mibConfig
.unifiFixTxDataRate
= args
->value
/ 500000;
1854 /* 1 means rate is a maximum, 2 means rate is a set value */
1855 if (args
->fixed
== 1) {
1856 mibConfig
.unifiFixMaxTxDataRate
= 0;
1858 mibConfig
.unifiFixMaxTxDataRate
= 1;
1861 r
= sme_mgt_mib_config_set(priv
, &mibConfig
);
1864 unifi_error(priv
, "unifi_siwrate: Set CsrWifiSmeMibConfigValue failed.\n");
1871 } /* unifi_siwrate() */
1876 unifi_giwrate(struct net_device
*dev
, struct iw_request_info
*info
,
1877 union iwreq_data
*wrqu
, char *extra
)
1879 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1880 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1881 struct iw_param
*args
= &wrqu
->bitrate
;
1884 CsrWifiSmeMibConfig mibConfig
;
1885 CsrWifiSmeConnectionStats connectionStats
;
1888 unifi_trace(priv
, UDBG2
, "unifi_giwrate\n");
1894 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
1897 unifi_error(priv
, "unifi_giwrate: Get CsrWifiSmeMibConfigValue failed.\n");
1901 bitrate
= mibConfig
.unifiFixTxDataRate
;
1902 flag
= mibConfig
.unifiFixMaxTxDataRate
;
1904 /* Used the value returned by the SME if MIB returns 0 */
1907 r
= sme_mgt_connection_stats_get(priv
, &connectionStats
);
1909 /* Ignore errors, we may be disconnected */
1911 bitrate
= connectionStats
.unifiTxDataRate
;
1915 args
->value
= bitrate
* 500000;
1916 args
->fixed
= !flag
;
1921 } /* unifi_giwrate() */
1925 unifi_siwrts(struct net_device
*dev
, struct iw_request_info
*info
,
1926 union iwreq_data
*wrqu
, char *extra
)
1928 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1929 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1930 int val
= wrqu
->rts
.value
;
1932 CsrWifiSmeMibConfig mibConfig
;
1934 unifi_trace(priv
, UDBG2
, "unifi_siwrts\n");
1937 if (wrqu
->rts
.disabled
) {
1941 if ( (val
< 0) || (val
> 2347) )
1946 /* Get, modify and set the MIB data */
1948 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
1951 unifi_error(priv
, "unifi_siwrts: Get CsrWifiSmeMibConfigValue failed.\n");
1954 mibConfig
.dot11RtsThreshold
= val
;
1956 r
= sme_mgt_mib_config_set(priv
, &mibConfig
);
1959 unifi_error(priv
, "unifi_siwrts: Set CsrWifiSmeMibConfigValue failed.\n");
1968 unifi_giwrts(struct net_device
*dev
, struct iw_request_info
*info
,
1969 union iwreq_data
*wrqu
, char *extra
)
1971 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
1972 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
1975 CsrWifiSmeMibConfig mibConfig
;
1977 unifi_trace(priv
, UDBG2
, "unifi_giwrts\n");
1981 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
1984 unifi_error(priv
, "unifi_giwrts: Get CsrWifiSmeMibConfigValue failed.\n");
1988 rts_thresh
= mibConfig
.dot11RtsThreshold
;
1989 if (rts_thresh
> 2347) {
1993 wrqu
->rts
.value
= rts_thresh
;
1994 wrqu
->rts
.disabled
= (rts_thresh
== 2347);
1995 wrqu
->rts
.fixed
= 1;
2002 unifi_siwfrag(struct net_device
*dev
, struct iw_request_info
*info
,
2003 union iwreq_data
*wrqu
, char *extra
)
2005 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2006 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2007 int val
= wrqu
->frag
.value
;
2009 CsrWifiSmeMibConfig mibConfig
;
2011 unifi_trace(priv
, UDBG2
, "unifi_siwfrag\n");
2014 if (wrqu
->frag
.disabled
)
2017 if ( (val
< 256) || (val
> 2347) )
2020 /* Get, modify and set the MIB data */
2022 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
2025 unifi_error(priv
, "unifi_siwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
2028 /* Fragmentation Threashold must be even */
2029 mibConfig
.dot11FragmentationThreshold
= (val
& ~0x1);
2031 r
= sme_mgt_mib_config_set(priv
, &mibConfig
);
2034 unifi_error(priv
, "unifi_siwfrag: Set CsrWifiSmeMibConfigValue failed.\n");
2043 unifi_giwfrag(struct net_device
*dev
, struct iw_request_info
*info
,
2044 union iwreq_data
*wrqu
, char *extra
)
2046 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2047 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2050 CsrWifiSmeMibConfig mibConfig
;
2052 unifi_trace(priv
, UDBG2
, "unifi_giwfrag\n");
2056 r
= sme_mgt_mib_config_get(priv
, &mibConfig
);
2059 unifi_error(priv
, "unifi_giwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
2063 frag_thresh
= mibConfig
.dot11FragmentationThreshold
;
2065 /* Build the return structure */
2066 wrqu
->frag
.value
= frag_thresh
;
2067 wrqu
->frag
.disabled
= (frag_thresh
>= 2346);
2068 wrqu
->frag
.fixed
= 1;
2075 unifi_siwencode(struct net_device
*dev
, struct iw_request_info
*info
,
2076 union iwreq_data
*wrqu
, char *extra
)
2078 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2079 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2080 struct iw_point
*erq
= &wrqu
->encoding
;
2084 CsrWifiSmeKey sme_key
;
2087 unifi_trace(priv
, UDBG2
, "unifi_siwencode\n");
2091 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2092 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2093 unifi_error(priv
, "unifi_siwencode: not permitted in Mode %d\n",
2094 interfacePriv
->interfaceMode
);
2100 * Key index is encoded in the flags.
2101 * 0 - use current default,
2102 * 1-4 - if a key value is given set that key
2103 * if not use that key
2105 index
= (erq
->flags
& IW_ENCODE_INDEX
); /* key number, 1-4 */
2106 if ((index
< 0) || (index
> 4)) {
2107 unifi_error(priv
, "unifi_siwencode: Request to set an invalid key (index:%d)", index
);
2112 * Basic checking: do we have a key to set ?
2113 * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
2114 * but older versions rely on sending a key id 1-4.
2116 if (erq
->length
> 0) {
2118 /* Check the size of the key */
2119 if ((erq
->length
> LARGE_KEY_SIZE
) || (erq
->length
< SMALL_KEY_SIZE
)) {
2120 unifi_error(priv
, "unifi_siwencode: Request to set an invalid key (length:%d)",
2125 /* Check the index (none (i.e. 0) means use current) */
2126 if ((index
< 1) || (index
> 4)) {
2127 /* If we do not have a previous key, use 1 as default */
2128 if (!priv
->wep_tx_key_index
) {
2129 priv
->wep_tx_key_index
= 1;
2131 index
= priv
->wep_tx_key_index
;
2134 /* If we didn't have a key and a valid index is set, we want to remember it*/
2135 if (!priv
->wep_tx_key_index
) {
2136 priv
->wep_tx_key_index
= index
;
2139 unifi_trace(priv
, UDBG1
, "Tx key Index is %d\n", priv
->wep_tx_key_index
);
2143 /* Check if the key is not marked as invalid */
2144 if ((erq
->flags
& IW_ENCODE_NOKEY
) == 0) {
2146 unifi_trace(priv
, UDBG1
, "New %s key (len=%d, index=%d)\n",
2147 (priv
->wep_tx_key_index
== index
) ? "tx" : "",
2148 erq
->length
, index
);
2150 sme_key
.wepTxKey
= (priv
->wep_tx_key_index
== index
);
2151 if (priv
->wep_tx_key_index
== index
) {
2152 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_PAIRWISE
;
2154 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_GROUP
;
2156 /* Key index is zero based in SME but 1 based in wext */
2157 sme_key
.keyIndex
= (index
- 1);
2158 sme_key
.keyLength
= erq
->length
;
2159 sme_key
.authenticator
= 0;
2160 memset(sme_key
.address
.a
, 0xFF, ETH_ALEN
);
2161 memcpy(sme_key
.key
, extra
, erq
->length
);
2164 rc
= sme_mgt_key(priv
, &sme_key
, CSR_WIFI_SME_LIST_ACTION_ADD
);
2167 unifi_error(priv
, "unifi_siwencode: Set key failed (%d)", rc
);
2168 return convert_sme_error(rc
);
2171 /* Store the key to be reported by the SIOCGIWENCODE handler */
2172 priv
->wep_keys
[index
- 1].len
= erq
->length
;
2173 memcpy(priv
->wep_keys
[index
- 1].key
, extra
, erq
->length
);
2177 * No additional key data, so it must be a request to change the
2181 unifi_trace(priv
, UDBG1
, "Tx key Index is %d\n", index
- 1);
2183 /* Store the index to be reported by the SIOCGIWENCODE handler */
2184 priv
->wep_tx_key_index
= index
;
2186 sme_key
.wepTxKey
= 1;
2187 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_PAIRWISE
;
2189 /* Key index is zero based in SME but 1 based in wext */
2190 sme_key
.keyIndex
= (index
- 1);
2191 sme_key
.keyLength
= 0;
2192 sme_key
.authenticator
= 0;
2194 rc
= sme_mgt_key(priv
, &sme_key
, CSR_WIFI_SME_LIST_ACTION_ADD
);
2197 unifi_error(priv
, "unifi_siwencode: Set key failed (%d)", rc
);
2198 return convert_sme_error(rc
);
2201 /* Turn on encryption */
2206 /* Read the flags */
2207 if (erq
->flags
& IW_ENCODE_DISABLED
) {
2208 /* disable encryption */
2209 unifi_trace(priv
, UDBG1
, "disable WEP encryption\n");
2212 priv
->wep_tx_key_index
= 0;
2214 unifi_trace(priv
, UDBG1
, "IW_ENCODE_DISABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2215 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
2218 if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
2219 /* Use shared key auth */
2220 unifi_trace(priv
, UDBG1
, "IW_ENCODE_RESTRICTED: CSR_WIFI_SME_AUTH_MODE_80211_SHARED\n");
2221 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_SHARED
;
2223 /* Turn on encryption */
2226 if (erq
->flags
& IW_ENCODE_OPEN
) {
2227 unifi_trace(priv
, UDBG1
, "IW_ENCODE_OPEN: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2228 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
2231 /* Commit the changes to flags if needed */
2232 if (privacy
!= -1) {
2233 priv
->connection_config
.privacyMode
= privacy
? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED
: CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
;
2234 priv
->connection_config
.encryptionModeMask
= privacy
? (CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40
|
2235 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104
|
2236 CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40
|
2237 CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104
) :
2238 CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE
;
2242 return convert_sme_error(rc
);
2244 } /* unifi_siwencode() */
2249 unifi_giwencode(struct net_device
*dev
, struct iw_request_info
*info
,
2250 union iwreq_data
*wrqu
, char *extra
)
2252 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2253 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2254 struct iw_point
*erq
= &wrqu
->encoding
;
2256 unifi_trace(priv
, UDBG2
, "unifi_giwencode\n");
2260 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2261 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2262 unifi_error(priv
, "unifi_giwencode: not permitted in Mode %d\n",
2263 interfacePriv
->interfaceMode
);
2268 if (priv
->connection_config
.authModeMask
== CSR_WIFI_SME_AUTH_MODE_80211_SHARED
) {
2269 erq
->flags
= IW_ENCODE_RESTRICTED
;
2272 if (priv
->connection_config
.privacyMode
== CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
) {
2273 erq
->flags
= IW_ENCODE_DISABLED
;
2275 erq
->flags
= IW_ENCODE_OPEN
;
2281 if (erq
->flags
!= IW_ENCODE_DISABLED
) {
2282 int index
= priv
->wep_tx_key_index
;
2284 if ((index
> 0) && (index
<= NUM_WEPKEYS
)) {
2285 erq
->flags
|= (index
& IW_ENCODE_INDEX
);
2286 erq
->length
= priv
->wep_keys
[index
- 1].len
;
2287 memcpy(extra
, priv
->wep_keys
[index
- 1].key
, erq
->length
);
2289 unifi_notice(priv
, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n",
2295 } /* unifi_giwencode() */
2299 unifi_siwpower(struct net_device
*dev
, struct iw_request_info
*info
,
2300 union iwreq_data
*wrqu
, char *extra
)
2302 struct iw_param
*args
= &wrqu
->power
;
2303 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2304 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2305 int listen_interval
, wake_for_dtim
;
2307 CsrWifiSmePowerConfig powerConfig
;
2309 unifi_trace(priv
, UDBG2
, "unifi_siwpower\n");
2313 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2314 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2315 unifi_error(priv
, "unifi_siwpower: not permitted in Mode %d\n",
2316 interfacePriv
->interfaceMode
);
2321 r
= sme_mgt_power_config_get(priv
, &powerConfig
);
2324 unifi_error(priv
, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n");
2328 listen_interval
= -1;
2330 if (args
->disabled
) {
2331 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW
;
2335 powerConfig
.powerSaveLevel
= CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH
;
2337 switch (args
->flags
& IW_POWER_TYPE
) {
2341 case IW_POWER_PERIOD
:
2342 listen_interval
= args
->value
/ 1000;
2348 switch (args
->flags
& IW_POWER_MODE
) {
2352 case IW_POWER_UNICAST_R
:
2353 /* not interested in broadcast packets */
2356 case IW_POWER_ALL_R
:
2357 /* yes, we are interested in broadcast packets */
2365 if (listen_interval
> 0) {
2366 powerConfig
.listenIntervalTu
= listen_interval
;
2367 unifi_trace(priv
, UDBG4
, "unifi_siwpower: new Listen Interval = %d.\n",
2368 powerConfig
.listenIntervalTu
);
2371 if (wake_for_dtim
>= 0) {
2372 powerConfig
.rxDtims
= wake_for_dtim
;
2375 r
= sme_mgt_power_config_set(priv
, &powerConfig
);
2378 unifi_error(priv
, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n");
2383 } /* unifi_siwpower() */
2387 unifi_giwpower(struct net_device
*dev
, struct iw_request_info
*info
,
2388 union iwreq_data
*wrqu
, char *extra
)
2390 struct iw_param
*args
= &wrqu
->power
;
2391 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2392 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2393 CsrWifiSmePowerConfig powerConfig
;
2396 unifi_trace(priv
, UDBG2
, "unifi_giwpower\n");
2400 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2401 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2402 unifi_error(priv
, "unifi_giwpower: not permitted in Mode %d\n",
2403 interfacePriv
->interfaceMode
);
2410 r
= sme_mgt_power_config_get(priv
, &powerConfig
);
2413 unifi_error(priv
, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n");
2417 unifi_trace(priv
, UDBG4
, "unifi_giwpower: mode=%d\n",
2418 powerConfig
.powerSaveLevel
);
2420 args
->disabled
= (powerConfig
.powerSaveLevel
== CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW
);
2421 if (args
->disabled
) {
2426 args
->value
= powerConfig
.listenIntervalTu
* 1000;
2427 args
->flags
|= IW_POWER_PERIOD
;
2429 if (powerConfig
.rxDtims
) {
2430 args
->flags
|= IW_POWER_ALL_R
;
2432 args
->flags
|= IW_POWER_UNICAST_R
;
2436 } /* unifi_giwpower() */
2440 * ---------------------------------------------------------------------------
2441 * unifi_siwcommit - handler for SIOCSIWCOMMIT
2443 * Apply all the parameters that have been set.
2444 * In practice this means:
2446 * - join a network or start an AdHoc
2447 * - authenticate and associate.
2454 * ---------------------------------------------------------------------------
2457 unifi_siwcommit(struct net_device
*dev
, struct iw_request_info
*info
,
2458 union iwreq_data
*wrqu
, char *extra
)
2461 } /* unifi_siwcommit() */
2466 unifi_siwmlme(struct net_device
*dev
, struct iw_request_info
*info
,
2467 union iwreq_data
*wrqu
, char *extra
)
2469 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2470 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2471 struct iw_mlme
*mlme
= (struct iw_mlme
*)extra
;
2474 unifi_trace(priv
, UDBG2
, "unifi_siwmlme\n");
2477 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2478 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2479 unifi_error(priv
, "unifi_siwmlme: not permitted in Mode %d\n",
2480 interfacePriv
->interfaceMode
);
2485 switch (mlme
->cmd
) {
2486 case IW_MLME_DEAUTH
:
2487 case IW_MLME_DISASSOC
:
2489 sme_mgt_disconnect(priv
);
2493 func_exit_r(-EOPNOTSUPP
);
2499 } /* unifi_siwmlme() */
2503 * ---------------------------------------------------------------------------
2507 * WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
2508 * Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
2510 * The host program (e.g. wpa_supplicant) uses this call to set the
2511 * additional IEs to accompany the next (Associate?) request.
2520 * This ioctl uses struct iw_point and data buffer that includes IE id
2521 * and len fields. More than one IE may be included in the
2522 * request. Setting the generic IE to empty buffer (len=0) removes the
2523 * generic IE from the driver.
2524 * ---------------------------------------------------------------------------
2527 unifi_siwgenie(struct net_device
*dev
, struct iw_request_info
*info
,
2528 union iwreq_data
*wrqu
, char *extra
)
2530 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2531 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2535 unifi_trace(priv
, UDBG2
, "unifi_siwgenie\n");
2537 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2538 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2539 unifi_error(priv
, "unifi_siwgenie: not permitted in Mode %d\n",
2540 interfacePriv
->interfaceMode
);
2545 if ( priv
->connection_config
.mlmeAssociateReqInformationElements
) {
2546 kfree( priv
->connection_config
.mlmeAssociateReqInformationElements
);
2548 priv
->connection_config
.mlmeAssociateReqInformationElementsLength
= 0;
2549 priv
->connection_config
.mlmeAssociateReqInformationElements
= NULL
;
2551 len
= wrqu
->data
.length
;
2557 priv
->connection_config
.mlmeAssociateReqInformationElements
= kmalloc(len
, GFP_KERNEL
);
2558 if (priv
->connection_config
.mlmeAssociateReqInformationElements
== NULL
) {
2563 priv
->connection_config
.mlmeAssociateReqInformationElementsLength
= len
;
2564 memcpy( priv
->connection_config
.mlmeAssociateReqInformationElements
, extra
, len
);
2568 } /* unifi_siwgenie() */
2572 unifi_giwgenie(struct net_device
*dev
, struct iw_request_info
*info
,
2573 union iwreq_data
*wrqu
, char *extra
)
2575 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2576 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2580 unifi_trace(priv
, UDBG2
, "unifi_giwgenie\n");
2582 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2583 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2584 unifi_error(priv
, "unifi_giwgenie: not permitted in Mode %d\n",
2585 interfacePriv
->interfaceMode
);
2590 len
= priv
->connection_config
.mlmeAssociateReqInformationElementsLength
;
2593 wrqu
->data
.length
= 0;
2597 if (wrqu
->data
.length
< len
) {
2601 wrqu
->data
.length
= len
;
2602 memcpy(extra
, priv
->connection_config
.mlmeAssociateReqInformationElements
, len
);
2606 } /* unifi_giwgenie() */
2610 * ---------------------------------------------------------------------------
2614 * Handlers for SIOCSIWAUTH, SIOCGIWAUTH
2615 * Set/get various authentication parameters.
2622 * ---------------------------------------------------------------------------
2625 _unifi_siwauth(struct net_device
*dev
, struct iw_request_info
*info
,
2626 union iwreq_data
*wrqu
, char *extra
)
2628 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2629 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2630 CsrWifiSmeAuthModeMask new_auth
;
2633 unifi_trace(priv
, UDBG2
, "unifi_siwauth\n");
2635 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2636 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2637 unifi_error(priv
, "unifi_siwauth: not permitted in Mode %d\n",
2638 interfacePriv
->interfaceMode
);
2644 * This ioctl is safe to call even when UniFi is powered off.
2645 * wpa_supplicant calls it to test whether we support WPA.
2648 switch (wrqu
->param
.flags
& IW_AUTH_INDEX
) {
2650 case IW_AUTH_WPA_ENABLED
:
2651 unifi_trace(priv
, UDBG1
, "IW_AUTH_WPA_ENABLED: %d\n", wrqu
->param
.value
);
2653 if (wrqu
->param
.value
== 0) {
2654 unifi_trace(priv
, UDBG5
, "IW_AUTH_WPA_ENABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2655 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
2659 case IW_AUTH_PRIVACY_INVOKED
:
2660 unifi_trace(priv
, UDBG1
, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu
->param
.value
);
2662 priv
->connection_config
.privacyMode
= wrqu
->param
.value
? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED
: CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
;
2663 if (wrqu
->param
.value
== CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
)
2665 priv
->connection_config
.encryptionModeMask
= CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE
;
2669 case IW_AUTH_80211_AUTH_ALG
:
2671 IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
2672 IW_AUTH_ALG_SHARED_KEY 0x00000002
2673 IW_AUTH_ALG_LEAP 0x00000004
2676 if (wrqu
->param
.value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
2677 unifi_trace(priv
, UDBG1
, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu
->param
.value
);
2678 new_auth
|= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
2680 if (wrqu
->param
.value
& IW_AUTH_ALG_SHARED_KEY
) {
2681 unifi_trace(priv
, UDBG1
, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu
->param
.value
);
2682 new_auth
|= CSR_WIFI_SME_AUTH_MODE_80211_SHARED
;
2684 if (wrqu
->param
.value
& IW_AUTH_ALG_LEAP
) {
2685 /* Initial exchanges using open-system to set EAP */
2686 unifi_trace(priv
, UDBG1
, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu
->param
.value
);
2687 new_auth
|= CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X
;
2689 if (new_auth
== 0) {
2690 unifi_trace(priv
, UDBG1
, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
2694 priv
->connection_config
.authModeMask
= new_auth
;
2698 case IW_AUTH_WPA_VERSION
:
2699 unifi_trace(priv
, UDBG1
, "IW_AUTH_WPA_VERSION: %d\n", wrqu
->param
.value
);
2700 priv
->ignore_bssid_join
= TRUE
;
2702 IW_AUTH_WPA_VERSION_DISABLED 0x00000001
2703 IW_AUTH_WPA_VERSION_WPA 0x00000002
2704 IW_AUTH_WPA_VERSION_WPA2 0x00000004
2707 if (!(wrqu
->param
.value
& IW_AUTH_WPA_VERSION_DISABLED
)) {
2709 priv
->connection_config
.authModeMask
= CSR_WIFI_SME_AUTH_MODE_80211_OPEN
;
2711 if (wrqu
->param
.value
& IW_AUTH_WPA_VERSION_WPA
) {
2712 unifi_trace(priv
, UDBG4
, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n");
2713 priv
->connection_config
.authModeMask
|= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA
| CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK
);
2715 if (wrqu
->param
.value
& IW_AUTH_WPA_VERSION_WPA2
) {
2716 unifi_trace(priv
, UDBG4
, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n");
2717 priv
->connection_config
.authModeMask
|= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2
| CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK
);
2722 case IW_AUTH_CIPHER_PAIRWISE
:
2723 unifi_trace(priv
, UDBG1
, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu
->param
.value
);
2726 IW_AUTH_CIPHER_NONE 0x00000001
2727 IW_AUTH_CIPHER_WEP40 0x00000002
2728 IW_AUTH_CIPHER_TKIP 0x00000004
2729 IW_AUTH_CIPHER_CCMP 0x00000008
2730 IW_AUTH_CIPHER_WEP104 0x00000010
2733 priv
->connection_config
.encryptionModeMask
= CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE
;
2735 if (wrqu
->param
.value
& IW_AUTH_CIPHER_WEP40
) {
2736 priv
->connection_config
.encryptionModeMask
|=
2737 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40
;
2739 if (wrqu
->param
.value
& IW_AUTH_CIPHER_WEP104
) {
2740 priv
->connection_config
.encryptionModeMask
|=
2741 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104
;
2743 if (wrqu
->param
.value
& IW_AUTH_CIPHER_TKIP
) {
2744 priv
->connection_config
.encryptionModeMask
|=
2745 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP
;
2747 if (wrqu
->param
.value
& IW_AUTH_CIPHER_CCMP
) {
2748 priv
->connection_config
.encryptionModeMask
|=
2749 CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP
| CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP
;
2754 case IW_AUTH_CIPHER_GROUP
:
2755 unifi_trace(priv
, UDBG1
, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu
->param
.value
);
2757 * Use the WPA version and the group cipher suite to set the permitted
2758 * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
2759 * in the probe responses from the desired BSS(ID)
2762 priv
->connection_config
.encryptionModeMask
&= ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40
|
2763 CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104
|
2764 CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP
|
2765 CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP
);
2766 if (wrqu
->param
.value
& IW_AUTH_CIPHER_WEP40
) {
2767 priv
->connection_config
.encryptionModeMask
|= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40
;
2769 if (wrqu
->param
.value
& IW_AUTH_CIPHER_WEP104
) {
2770 priv
->connection_config
.encryptionModeMask
|= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104
;
2772 if (wrqu
->param
.value
& IW_AUTH_CIPHER_TKIP
) {
2773 priv
->connection_config
.encryptionModeMask
|= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP
;
2775 if (wrqu
->param
.value
& IW_AUTH_CIPHER_CCMP
) {
2776 priv
->connection_config
.encryptionModeMask
|= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP
;
2781 case IW_AUTH_KEY_MGMT
:
2782 unifi_trace(priv
, UDBG1
, "IW_AUTH_KEY_MGMT: %d\n", wrqu
->param
.value
);
2784 IW_AUTH_KEY_MGMT_802_1X 1
2785 IW_AUTH_KEY_MGMT_PSK 2
2787 if (priv
->connection_config
.authModeMask
& (CSR_WIFI_SME_AUTH_MODE_8021X_WPA
| CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK
)) {
2788 /* Check for explicitly set mode. */
2789 if (wrqu
->param
.value
== IW_AUTH_KEY_MGMT_802_1X
) {
2790 priv
->connection_config
.authModeMask
&= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK
;
2792 if (wrqu
->param
.value
== IW_AUTH_KEY_MGMT_PSK
) {
2793 priv
->connection_config
.authModeMask
&= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA
;
2795 unifi_trace(priv
, UDBG5
, "IW_AUTH_KEY_MGMT: WPA: %d\n",
2796 priv
->connection_config
.authModeMask
);
2798 if (priv
->connection_config
.authModeMask
& (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2
| CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK
)) {
2799 /* Check for explicitly set mode. */
2800 if (wrqu
->param
.value
== IW_AUTH_KEY_MGMT_802_1X
) {
2801 priv
->connection_config
.authModeMask
&= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK
;
2803 if (wrqu
->param
.value
== IW_AUTH_KEY_MGMT_PSK
) {
2804 priv
->connection_config
.authModeMask
&= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2
;
2806 unifi_trace(priv
, UDBG5
, "IW_AUTH_KEY_MGMT: WPA2: %d\n",
2807 priv
->connection_config
.authModeMask
);
2811 case IW_AUTH_TKIP_COUNTERMEASURES
:
2813 * Set to true at the start of the 60 second backup-off period
2814 * following 2 MichaelMIC failures within 60s.
2816 unifi_trace(priv
, UDBG1
, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu
->param
.value
);
2819 case IW_AUTH_DROP_UNENCRYPTED
:
2821 * Set to true on init.
2822 * Set to false just before associate if encryption will not be
2825 * Note this is not the same as the 802.1X controlled port
2827 unifi_trace(priv
, UDBG1
, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu
->param
.value
);
2830 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
2832 * This is set by wpa_supplicant to allow unencrypted EAPOL messages
2833 * even if pairwise keys are set when not using WPA. IEEE 802.1X
2834 * specifies that these frames are not encrypted, but WPA encrypts
2835 * them when pairwise keys are in use.
2836 * I think the UniFi f/w handles this decision for us.
2838 unifi_trace(priv
, UDBG1
, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu
->param
.value
);
2841 case IW_AUTH_ROAMING_CONTROL
:
2842 unifi_trace(priv
, UDBG1
, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu
->param
.value
);
2846 unifi_trace(priv
, UDBG1
, "Unsupported auth param %d to 0x%X\n",
2847 wrqu
->param
.flags
& IW_AUTH_INDEX
,
2852 unifi_trace(priv
, UDBG2
, "authModeMask = %d", priv
->connection_config
.authModeMask
);
2856 } /* _unifi_siwauth() */
2860 unifi_siwauth(struct net_device
*dev
, struct iw_request_info
*info
,
2861 union iwreq_data
*wrqu
, char *extra
)
2866 err
= _unifi_siwauth(dev
, info
, wrqu
, extra
);
2870 } /* unifi_siwauth() */
2874 unifi_giwauth(struct net_device
*dev
, struct iw_request_info
*info
,
2875 union iwreq_data
*wrqu
, char *extra
)
2877 unifi_trace(NULL
, UDBG2
, "unifi_giwauth\n");
2879 } /* unifi_giwauth() */
2882 * ---------------------------------------------------------------------------
2883 * unifi_siwencodeext
2884 * unifi_giwencodeext
2886 * Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
2887 * encoding token & mode
2896 * For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
2897 * This flag means "use this key to encode transmissions"; we just
2898 * assume only one key will be set and that is the one to use.
2899 * ---------------------------------------------------------------------------
2902 _unifi_siwencodeext(struct net_device
*dev
, struct iw_request_info
*info
,
2903 union iwreq_data
*wrqu
, char *extra
)
2905 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
2906 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
2907 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
2909 unsigned char *keydata
;
2910 unsigned char tkip_key
[32];
2912 unsigned char *a
= (unsigned char *)ext
->addr
.sa_data
;
2913 CsrWifiSmeKey sme_key
;
2914 CsrWifiSmeKeyType key_type
;
2920 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
2921 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
2922 unifi_error(priv
, "unifi_siwencodeext: not permitted in Mode %d\n",
2923 interfacePriv
->interfaceMode
);
2928 unifi_trace(priv
, UDBG1
, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n",
2929 wrqu
->encoding
.flags
, ext
->alg
, ext
->ext_flags
,
2930 ext
->key_len
, (wrqu
->encoding
.flags
& IW_ENCODE_INDEX
));
2931 unifi_trace(priv
, UDBG3
, " addr=%pM\n", a
);
2933 if ((ext
->key_len
== 0) && (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
)) {
2934 /* This means use a different key (given by key_idx) for Tx. */
2936 unifi_trace(priv
, UDBG1
, KERN_ERR
"unifi_siwencodeext: NYI should change tx key id here!!\n");
2940 memset(&sme_key
, 0, sizeof(sme_key
));
2942 keydata
= (unsigned char *)(ext
+ 1);
2943 keyid
= (wrqu
->encoding
.flags
& IW_ENCODE_INDEX
);
2946 * Check for request to delete keys for an address.
2948 /* Pick out request for no privacy. */
2949 if (ext
->alg
== IW_ENCODE_ALG_NONE
) {
2951 unifi_trace(priv
, UDBG1
, "Deleting %s key %d\n",
2952 (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) ? "GROUP" : "PAIRWISE",
2955 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
2956 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_GROUP
;
2958 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_PAIRWISE
;
2960 sme_key
.keyIndex
= (keyid
- 1);
2961 sme_key
.keyLength
= 0;
2962 sme_key
.authenticator
= 0;
2963 memcpy(sme_key
.address
.a
, a
, ETH_ALEN
);
2965 r
= sme_mgt_key(priv
, &sme_key
, CSR_WIFI_SME_LIST_ACTION_REMOVE
);
2968 unifi_error(priv
, "Delete key request was rejected with result %d\n", r
);
2969 return convert_sme_error(r
);
2976 * Request is to set a key, not delete
2979 /* Pick out WEP and use set_wep_key(). */
2980 if (ext
->alg
== IW_ENCODE_ALG_WEP
) {
2981 /* WEP-40, WEP-104 */
2983 /* Check for valid key length */
2984 if (!((ext
->key_len
== 5) || (ext
->key_len
== 13))) {
2985 unifi_trace(priv
, UDBG1
, KERN_ERR
"Invalid length for WEP key: %d\n", ext
->key_len
);
2989 unifi_trace(priv
, UDBG1
, "Setting WEP key %d tx:%d\n",
2990 keyid
, ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
);
2992 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
2993 sme_key
.wepTxKey
= TRUE
;
2994 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_PAIRWISE
;
2996 sme_key
.wepTxKey
= FALSE
;
2997 sme_key
.keyType
= CSR_WIFI_SME_KEY_TYPE_GROUP
;
2999 sme_key
.keyIndex
= (keyid
- 1);
3000 sme_key
.keyLength
= ext
->key_len
;
3001 sme_key
.authenticator
= 0;
3002 memset(sme_key
.address
.a
, 0xFF, ETH_ALEN
);
3003 memcpy(sme_key
.key
, keydata
, ext
->key_len
);
3005 r
= sme_mgt_key(priv
, &sme_key
, CSR_WIFI_SME_LIST_ACTION_ADD
);
3008 unifi_error(priv
, "siwencodeext: Set key failed (%d)", r
);
3009 return convert_sme_error(r
);
3017 * If we reach here, we are dealing with a WPA/WPA2 key
3020 if (ext
->key_len
> 32) {
3025 * TKIP keys from wpa_supplicant need swapping.
3026 * What about other supplicants (when they come along)?
3028 if ((ext
->alg
== IW_ENCODE_ALG_TKIP
) && (ext
->key_len
== 32)) {
3029 memcpy(tkip_key
, keydata
, 16);
3030 memcpy(tkip_key
+ 16, keydata
+ 24, 8);
3031 memcpy(tkip_key
+ 24, keydata
+ 16, 8);
3035 key_type
= (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) ?
3036 CSR_WIFI_SME_KEY_TYPE_GROUP
: /* Group Key */
3037 CSR_WIFI_SME_KEY_TYPE_PAIRWISE
; /* Pairwise Key */
3039 sme_key
.keyType
= key_type
;
3040 sme_key
.keyIndex
= (keyid
- 1);
3041 sme_key
.keyLength
= ext
->key_len
;
3042 sme_key
.authenticator
= 0;
3043 memcpy(sme_key
.address
.a
, ext
->addr
.sa_data
, ETH_ALEN
);
3044 if (ext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
3046 unifi_trace(priv
, UDBG5
, "RSC first 6 bytes = %02X:%02X:%02X:%02X:%02X:%02X\n",
3047 ext
->rx_seq
[0], ext
->rx_seq
[1], ext
->rx_seq
[2], ext
->rx_seq
[3], ext
->rx_seq
[4], ext
->rx_seq
[5]);
3049 /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */
3050 sme_key
.keyRsc
[0] = ext
->rx_seq
[1] << 8 | ext
->rx_seq
[0];
3051 sme_key
.keyRsc
[1] = ext
->rx_seq
[3] << 8 | ext
->rx_seq
[2];
3052 sme_key
.keyRsc
[2] = ext
->rx_seq
[5] << 8 | ext
->rx_seq
[4];
3053 sme_key
.keyRsc
[3] = ext
->rx_seq
[7] << 8 | ext
->rx_seq
[6];
3057 memcpy(sme_key
.key
, keydata
, ext
->key_len
);
3059 r
= sme_mgt_key(priv
, &sme_key
, CSR_WIFI_SME_LIST_ACTION_ADD
);
3062 unifi_error(priv
, "SETKEYS request was rejected with result %d\n", r
);
3063 return convert_sme_error(r
);
3068 } /* _unifi_siwencodeext() */
3072 unifi_siwencodeext(struct net_device
*dev
, struct iw_request_info
*info
,
3073 union iwreq_data
*wrqu
, char *extra
)
3077 err
= _unifi_siwencodeext(dev
, info
, wrqu
, extra
);
3080 } /* unifi_siwencodeext() */
3084 unifi_giwencodeext(struct net_device
*dev
, struct iw_request_info
*info
,
3085 union iwreq_data
*wrqu
, char *extra
)
3088 } /* unifi_giwencodeext() */
3092 * ---------------------------------------------------------------------------
3095 * SIOCSIWPMKSA - PMKSA cache operation
3096 * The caller passes a pmksa structure:
3097 * - cmd one of ADD, REMOVE, FLUSH
3098 * - bssid MAC address
3099 * - pmkid ID string (16 bytes)
3108 * This is not needed since we provide a siwgenie method.
3109 * ---------------------------------------------------------------------------
3111 #define UNIFI_PMKID_KEY_SIZE 16
3113 unifi_siwpmksa(struct net_device
*dev
, struct iw_request_info
*info
,
3114 union iwreq_data
*wrqu
, char *extra
)
3116 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
3117 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
3118 struct iw_pmksa
*pmksa
= (struct iw_pmksa
*)extra
;
3120 CsrWifiSmePmkidList pmkid_list
;
3121 CsrWifiSmePmkid pmkid
;
3122 CsrWifiSmeListAction action
;
3126 if(interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_AP
||
3127 interfacePriv
->interfaceMode
== CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
) {
3128 unifi_error(priv
, "unifi_siwpmksa: not permitted in Mode %d\n",
3129 interfacePriv
->interfaceMode
);
3134 unifi_trace(priv
, UDBG1
, "SIWPMKSA: cmd %d, %pM\n", pmksa
->cmd
,
3135 pmksa
->bssid
.sa_data
);
3137 pmkid_list
.pmkids
= NULL
;
3138 switch (pmksa
->cmd
) {
3140 pmkid_list
.pmkids
= &pmkid
;
3141 action
= CSR_WIFI_SME_LIST_ACTION_ADD
;
3142 pmkid_list
.pmkidsCount
= 1;
3143 memcpy(pmkid
.bssid
.a
, pmksa
->bssid
.sa_data
, ETH_ALEN
);
3144 memcpy(pmkid
.pmkid
, pmksa
->pmkid
, UNIFI_PMKID_KEY_SIZE
);
3146 case IW_PMKSA_REMOVE
:
3147 pmkid_list
.pmkids
= &pmkid
;
3148 action
= CSR_WIFI_SME_LIST_ACTION_REMOVE
;
3149 pmkid_list
.pmkidsCount
= 1;
3150 memcpy(pmkid
.bssid
.a
, pmksa
->bssid
.sa_data
, ETH_ALEN
);
3151 memcpy(pmkid
.pmkid
, pmksa
->pmkid
, UNIFI_PMKID_KEY_SIZE
);
3153 case IW_PMKSA_FLUSH
:
3154 /* Replace current PMKID's with an empty list */
3155 pmkid_list
.pmkidsCount
= 0;
3156 action
= CSR_WIFI_SME_LIST_ACTION_FLUSH
;
3159 unifi_notice(priv
, "SIWPMKSA: Unknown command (0x%x)\n", pmksa
->cmd
);
3163 /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */
3165 r
= sme_mgt_pmkid(priv
, action
, &pmkid_list
);
3168 unifi_error(priv
, "SIWPMKSA: Set PMKID's Failed.\n");
3173 } /* unifi_siwpmksa() */
3177 * ---------------------------------------------------------------------------
3178 * unifi_get_wireless_stats
3180 * get_wireless_stats method for Linux wireless extensions.
3183 * dev Pointer to associated netdevice.
3186 * Pointer to iw_statistics struct.
3187 * ---------------------------------------------------------------------------
3189 struct iw_statistics
*
3190 unifi_get_wireless_stats(struct net_device
*dev
)
3192 netInterface_priv_t
*interfacePriv
= (netInterface_priv_t
*)netdev_priv(dev
);
3193 unifi_priv_t
*priv
= interfacePriv
->privPtr
;
3195 if (priv
->init_progress
!= UNIFI_INIT_COMPLETED
) {
3199 return &priv
->wext_wireless_stats
;
3200 } /* unifi_get_wireless_stats() */
3204 * Structures to export the Wireless Handlers
3207 static const struct iw_priv_args unifi_private_args
[] = {
3208 /*{ cmd, set_args, get_args, name } */
3209 { SIOCIWS80211POWERSAVEPRIV
, IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
3210 IW_PRIV_TYPE_NONE
, "iwprivs80211ps" },
3211 { SIOCIWG80211POWERSAVEPRIV
, IW_PRIV_TYPE_NONE
,
3212 IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
| IWPRIV_POWER_SAVE_MAX_STRING
, "iwprivg80211ps" },
3213 { SIOCIWS80211RELOADDEFAULTSPRIV
, IW_PRIV_TYPE_NONE
,
3214 IW_PRIV_TYPE_NONE
, "iwprivsdefs" },
3215 { SIOCIWSSMEDEBUGPRIV
, IW_PRIV_TYPE_CHAR
| IWPRIV_SME_DEBUG_MAX_STRING
, IW_PRIV_TYPE_NONE
, "iwprivssmedebug" },
3216 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3217 { SIOCIWSCONFWAPIPRIV
, IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
3218 IW_PRIV_TYPE_NONE
, "iwprivsconfwapi" },
3219 { SIOCIWSWAPIKEYPRIV
, IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| sizeof(unifiio_wapi_key_t
),
3220 IW_PRIV_TYPE_NONE
, "iwprivswpikey" },
3222 #ifdef CSR_SUPPORT_WEXT_AP
3223 { SIOCIWSAPCFGPRIV
, IW_PRIV_TYPE_CHAR
| 256, IW_PRIV_TYPE_NONE
, "AP_SET_CFG" },
3224 { SIOCIWSAPSTARTPRIV
, 0,IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
|IWPRIV_SME_MAX_STRING
,"AP_BSS_START" },
3225 { SIOCIWSAPSTOPPRIV
, IW_PRIV_TYPE_CHAR
|IW_PRIV_SIZE_FIXED
|0,
3226 IW_PRIV_TYPE_CHAR
|IW_PRIV_SIZE_FIXED
|0, "AP_BSS_STOP" },
3227 #ifdef ANDROID_BUILD
3228 { SIOCIWSFWRELOADPRIV
, IW_PRIV_TYPE_CHAR
|256,
3229 IW_PRIV_TYPE_CHAR
|IW_PRIV_SIZE_FIXED
|0, "WL_FW_RELOAD" },
3230 { SIOCIWSSTACKSTART
, 0,
3231 IW_PRIV_TYPE_CHAR
|IW_PRIV_SIZE_FIXED
|IWPRIV_SME_MAX_STRING
, "START" },
3232 { SIOCIWSSTACKSTOP
, 0,
3233 IW_PRIV_TYPE_CHAR
|IW_PRIV_SIZE_FIXED
|IWPRIV_SME_MAX_STRING
, "STOP" },
3234 #endif /* ANDROID_BUILD */
3235 #endif /* CSR_SUPPORT_WEXT_AP */
3238 static const iw_handler unifi_handler
[] =
3240 (iw_handler
) unifi_siwcommit
, /* SIOCSIWCOMMIT */
3241 (iw_handler
) unifi_giwname
, /* SIOCGIWNAME */
3242 (iw_handler
) NULL
, /* SIOCSIWNWID */
3243 (iw_handler
) NULL
, /* SIOCGIWNWID */
3244 (iw_handler
) unifi_siwfreq
, /* SIOCSIWFREQ */
3245 (iw_handler
) unifi_giwfreq
, /* SIOCGIWFREQ */
3246 (iw_handler
) unifi_siwmode
, /* SIOCSIWMODE */
3247 (iw_handler
) unifi_giwmode
, /* SIOCGIWMODE */
3248 (iw_handler
) NULL
, /* SIOCSIWSENS */
3249 (iw_handler
) NULL
, /* SIOCGIWSENS */
3250 (iw_handler
) NULL
, /* SIOCSIWRANGE */
3251 (iw_handler
) unifi_giwrange
, /* SIOCGIWRANGE */
3252 (iw_handler
) NULL
, /* SIOCSIWPRIV */
3253 (iw_handler
) NULL
, /* SIOCGIWPRIV */
3254 (iw_handler
) NULL
, /* SIOCSIWSTATS */
3255 (iw_handler
) NULL
, /* SIOCGIWSTATS */
3256 (iw_handler
) NULL
, /* SIOCSIWSPY */
3257 (iw_handler
) NULL
, /* SIOCGIWSPY */
3258 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
3259 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
3260 (iw_handler
) unifi_siwap
, /* SIOCSIWAP */
3261 (iw_handler
) unifi_giwap
, /* SIOCGIWAP */
3262 #if WIRELESS_EXT > 17
3263 /* WPA : IEEE 802.11 MLME requests */
3264 unifi_siwmlme
, /* SIOCSIWMLME, request MLME operation */
3266 (iw_handler
) NULL
, /* -- hole -- */
3268 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
3269 (iw_handler
) unifi_siwscan
, /* SIOCSIWSCAN */
3270 (iw_handler
) unifi_giwscan
, /* SIOCGIWSCAN */
3271 (iw_handler
) unifi_siwessid
, /* SIOCSIWESSID */
3272 (iw_handler
) unifi_giwessid
, /* SIOCGIWESSID */
3273 (iw_handler
) NULL
, /* SIOCSIWNICKN */
3274 (iw_handler
) NULL
, /* SIOCGIWNICKN */
3275 (iw_handler
) NULL
, /* -- hole -- */
3276 (iw_handler
) NULL
, /* -- hole -- */
3277 unifi_siwrate
, /* SIOCSIWRATE */
3278 unifi_giwrate
, /* SIOCGIWRATE */
3279 unifi_siwrts
, /* SIOCSIWRTS */
3280 unifi_giwrts
, /* SIOCGIWRTS */
3281 unifi_siwfrag
, /* SIOCSIWFRAG */
3282 unifi_giwfrag
, /* SIOCGIWFRAG */
3283 (iw_handler
) NULL
, /* SIOCSIWTXPOW */
3284 (iw_handler
) NULL
, /* SIOCGIWTXPOW */
3285 (iw_handler
) NULL
, /* SIOCSIWRETRY */
3286 (iw_handler
) NULL
, /* SIOCGIWRETRY */
3287 unifi_siwencode
, /* SIOCSIWENCODE */
3288 unifi_giwencode
, /* SIOCGIWENCODE */
3289 unifi_siwpower
, /* SIOCSIWPOWER */
3290 unifi_giwpower
, /* SIOCGIWPOWER */
3291 #if WIRELESS_EXT > 17
3292 (iw_handler
) NULL
, /* -- hole -- */
3293 (iw_handler
) NULL
, /* -- hole -- */
3295 /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
3296 unifi_siwgenie
, /* SIOCSIWGENIE */ /* set generic IE */
3297 unifi_giwgenie
, /* SIOCGIWGENIE */ /* get generic IE */
3299 /* WPA : Authentication mode parameters */
3300 unifi_siwauth
, /* SIOCSIWAUTH */ /* set authentication mode params */
3301 unifi_giwauth
, /* SIOCGIWAUTH */ /* get authentication mode params */
3303 /* WPA : Extended version of encoding configuration */
3304 unifi_siwencodeext
, /* SIOCSIWENCODEEXT */ /* set encoding token & mode */
3305 unifi_giwencodeext
, /* SIOCGIWENCODEEXT */ /* get encoding token & mode */
3307 /* WPA2 : PMKSA cache management */
3308 unifi_siwpmksa
, /* SIOCSIWPMKSA */ /* PMKSA cache operation */
3309 (iw_handler
) NULL
, /* -- hole -- */
3310 #endif /* WIRELESS_EXT > 17 */
3314 static const iw_handler unifi_private_handler
[] =
3316 iwprivs80211ps
, /* SIOCIWFIRSTPRIV */
3317 iwprivg80211ps
, /* SIOCIWFIRSTPRIV + 1 */
3318 iwprivsdefs
, /* SIOCIWFIRSTPRIV + 2 */
3320 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3321 iwprivsconfwapi
, /* SIOCIWFIRSTPRIV + 4 */
3322 (iw_handler
) NULL
, /* SIOCIWFIRSTPRIV + 5 */
3323 iwprivswpikey
, /* SIOCIWFIRSTPRIV + 6 */
3330 iwprivssmedebug
, /* SIOCIWFIRSTPRIV + 8 */
3331 #ifdef CSR_SUPPORT_WEXT_AP
3339 #ifdef ANDROID_BUILD
3351 #endif /* ANDROID_BUILD */
3365 #endif /* CSR_SUPPORT_WEXT_AP */
3368 struct iw_handler_def unifi_iw_handler_def
=
3370 .num_standard
= sizeof(unifi_handler
) / sizeof(iw_handler
),
3371 .num_private
= sizeof(unifi_private_handler
) / sizeof(iw_handler
),
3372 .num_private_args
= sizeof(unifi_private_args
) / sizeof(struct iw_priv_args
),
3373 .standard
= (iw_handler
*) unifi_handler
,
3374 .private = (iw_handler
*) unifi_private_handler
,
3375 .private_args
= (struct iw_priv_args
*) unifi_private_args
,
3376 #if IW_HANDLER_VERSION >= 6
3377 .get_wireless_stats
= unifi_get_wireless_stats
,