Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sme_wext.c
Go to the documentation of this file.
1 /*
2  * ---------------------------------------------------------------------------
3  * FILE: sme_wext.c
4  *
5  * PURPOSE:
6  * Handlers for ioctls from iwconfig.
7  * These provide the control plane operations.
8  *
9  * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
10  *
11  * Refer to LICENSE.txt included with this source code for details on
12  * the license terms.
13  *
14  * ---------------------------------------------------------------------------
15  */
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>
23 
24 #define CHECK_INITED(_priv) \
25  do { \
26  if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
27  unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \
28  return -ENODEV; \
29  } \
30  } while (0)
31 
32 /* Workaround for the wpa_supplicant hanging issue - disabled on Android */
33 #ifndef ANDROID_BUILD
34 #define CSR_WIFI_WEXT_HANG_WORKAROUND
35 #endif
36 
37 #ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
38 # define UF_RTNL_LOCK() rtnl_lock()
39 # define UF_RTNL_UNLOCK() rtnl_unlock()
40 #else
41 # define UF_RTNL_LOCK()
42 # define UF_RTNL_UNLOCK()
43 #endif
44 
45 
46 /*
47  * ---------------------------------------------------------------------------
48  * Helper functions
49  * ---------------------------------------------------------------------------
50  */
51 
52 /*
53  * ---------------------------------------------------------------------------
54  * wext_freq_to_channel
55  * channel_to_mhz
56  *
57  * These functions convert between channel number and frequency.
58  *
59  * Arguments:
60  * ch Channel number, as defined in 802.11 specs
61  * m, e Mantissa and exponent as provided by wireless extension.
62  *
63  * Returns:
64  * channel or frequency (in MHz) value
65  * ---------------------------------------------------------------------------
66  */
67 static int
68 wext_freq_to_channel(int m, int e)
69 {
70  int mhz;
71 
72  mhz = m;
73  while (e < 6) {
74  mhz /= 10;
75  e++;
76  }
77  while (e > 6) {
78  mhz *= 10;
79  e--;
80  }
81 
82  if (mhz >= 5000) {
83  return ((mhz - 5000) / 5);
84  }
85 
86  if (mhz == 2482) {
87  return 14;
88  }
89 
90  if (mhz >= 2407) {
91  return ((mhz - 2407) / 5);
92  }
93 
94  return 0;
95 } /* wext_freq_to_channel() */
96 
97 static int
98 channel_to_mhz(int ch, int dot11a)
99 {
100 
101  if (ch == 0) return 0;
102  if (ch > 200) return 0;
103 
104  /* 5G */
105  if (dot11a) {
106  return (5000 + (5 * ch));
107  }
108 
109  /* 2.4G */
110  if (ch == 14) {
111  return 2484;
112  }
113 
114  if ((ch < 14) && (ch > 0)) {
115  return (2407 + (5 * ch));
116  }
117 
118  return 0;
119 }
120 #ifdef CSR_SUPPORT_WEXT_AP
121 void uf_sme_wext_ap_set_defaults(unifi_priv_t *priv)
122 {
123  memcpy(priv->ap_config.ssid.ssid,"defaultssid",sizeof("defaultssid"));
124 
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;
130 
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*/
137  /* Until Here*/
138 
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;
142 
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;
164 
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;
185 
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;
189 
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;
196 
197  priv->ap_mac_config.phySupportedBitmap =
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);
206 }
207 #endif
208 /*
209  * ---------------------------------------------------------------------------
210  * uf_sme_wext_set_defaults
211  *
212  * Set up power-on defaults for driver config.
213  *
214  * Note: The SME Management API *cannot* be used in this function.
215  *
216  * Arguments:
217  * priv Pointer to device private context struct
218  *
219  * Returns:
220  * None.
221  * ---------------------------------------------------------------------------
222  */
223 void
225 {
226  memset(&priv->connection_config, 0, sizeof(CsrWifiSmeConnectionConfig));
227 
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;
236 
237  priv->wep_tx_key_index = 0;
238 
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);
246 #endif
247 
248 
249 } /* uf_sme_wext_set_defaults() */
250 
251 
252 /*
253  * ---------------------------------------------------------------------------
254  * WEXT methods
255  * ---------------------------------------------------------------------------
256  */
257 
258 /*
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
274  *
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.
279  *
280  * Arguments:
281  * None.
282  *
283  * Returns:
284  * None.
285  * ---------------------------------------------------------------------------
286  */
287 static int
288 iwprivsdefs(struct net_device *dev, struct iw_request_info *info,
289  union iwreq_data *wrqu, char *extra)
290 {
291  int r;
293  unifi_priv_t *priv = interfacePriv->privPtr;
294  CsrWifiSmeMibConfig mibConfig;
295  CsrWifiSmePowerConfig powerConfig;
296 
297  unifi_trace(priv, UDBG1, "iwprivs80211defaults: reload defaults\n");
298 
300 
301  /* Get, modify and set the MIB data */
302  r = sme_mgt_mib_config_get(priv, &mibConfig);
303  if (r) {
304  unifi_error(priv, "iwprivs80211defaults: Get CsrWifiSmeMibConfigValue failed.\n");
305  return r;
306  }
307  mibConfig.dot11RtsThreshold = 2347;
308  mibConfig.dot11FragmentationThreshold = 2346;
309  r = sme_mgt_mib_config_set(priv, &mibConfig);
310  if (r) {
311  unifi_error(priv, "iwprivs80211defaults: Set CsrWifiSmeMibConfigValue failed.\n");
312  return r;
313  }
314 
316  powerConfig.listenIntervalTu = 100;
317  powerConfig.rxDtims = 1;
318 
319  r = sme_mgt_power_config_set(priv, &powerConfig);
320  if (r) {
321  unifi_error(priv, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n");
322  return r;
323  }
324 
325  return 0;
326 } /* iwprivsdefs() */
327 
328 static int
329 iwprivs80211ps(struct net_device *dev, struct iw_request_info *info,
330  union iwreq_data *wrqu, char *extra)
331 {
332  int r = 0;
333  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
334  unifi_priv_t *priv = interfacePriv->privPtr;
335 
336  int ps_mode = (int)(*extra);
337  CsrWifiSmePowerConfig powerConfig;
338 
339  unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode);
340 
341  r = sme_mgt_power_config_get(priv, &powerConfig);
342  if (r) {
343  unifi_error(priv, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n");
344  return r;
345  }
346 
347  switch (ps_mode) {
348  case CSR_PMM_ACTIVE_MODE:
350  break;
351  case CSR_PMM_POWER_SAVE:
353  break;
356  break;
357  default:
359  break;
360  }
361 
362  r = sme_mgt_power_config_set(priv, &powerConfig);
363  if (r) {
364  unifi_error(priv, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n");
365  }
366 
367  return r;
368 }
369 
370 static int
371 iwprivg80211ps(struct net_device *dev, struct iw_request_info *info,
372  union iwreq_data *wrqu, char *extra)
373 {
374  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
375  unifi_priv_t *priv = interfacePriv->privPtr;
376 
377  CsrWifiSmePowerConfig powerConfig;
378  int r;
379 
380  r = sme_mgt_power_config_get(priv, &powerConfig);
381  if (r) {
382  unifi_error(priv, "iwprivg80211ps: Get 802.11 power mode failed.\n");
383  return r;
384  }
385 
386  switch (powerConfig.powerSaveLevel) {
389  "Power save mode: %d (Active)",
390  powerConfig.powerSaveLevel);
391  break;
394  "Power save mode: %d (Fast)",
395  powerConfig.powerSaveLevel);
396  break;
399  "Power save mode: %d (Full)",
400  powerConfig.powerSaveLevel);
401  break;
404  "Power save mode: %d (Auto)",
405  powerConfig.powerSaveLevel);
406  break;
407  default:
409  "Power save mode: %d (Unknown)",
410  powerConfig.powerSaveLevel);
411  break;
412  }
413 
414  wrqu->data.length = strlen(extra) + 1;
415 
416  return 0;
417 }
418 
419 static int
420 iwprivssmedebug(struct net_device *dev, struct iw_request_info *info,
421  union iwreq_data *wrqu, char *extra)
422 {
423  /* No longer supported on the API */
424 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
425  unifi_debug_buf_dump();
426 #endif
427 
428  return 0;
429 }
430 
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
437 
438 static int hex_look_up(char x)
439 {
440  if(x>='0' && x<='9')
441  return (x-48);
442  if(x>= 'a' && x <= 'f')
443  return (x-87);
444  return -1;
445 }
446 
447 static int power (int a, int b)
448 {
449  int i;
450  int num =1;
451  for(i=0;i<b;i++)
452  num *=a;
453  return num;
454 }
455 
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)
459 {
460  u8 int_str[7] = "0";
461  u32 param_str_len;
462  u8 *param_str_begin,*param_str_end;
463  u8 *orig_str = *str_ptr;
464 
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);
471  } else {
472  param_str_end = *str_ptr-1;
473  param_str_len = param_str_end - param_str_begin;
474  }
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;
479  }
480  switch (param_type) {
481  case PARAM_TYPE_INT:
482  {
483  u32 *pdst_int = dst,num =0;
484  int i,j=0;
485  if (param_str_len > sizeof(int_str)) {
486  param_str_len = sizeof(int_str);
487  }
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));
492  j++;
493  } else {
494  unifi_error(priv,"decode_parameter_from_string:not a number %c\n",(int_str[i-1]));
495  return -1;
496  }
497  }
498  *pdst_int = num;
499  unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded int = %d\n",*pdst_int);
500  }
501  break;
502  default:
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);
506  break;
507  }
508  } else {
509  unifi_error(priv,"decode_parameter_from_string: Token:%s not found in %s \n",token,orig_str);
510  return -1;
511  }
512  return 0;
513 }
514 static int store_ap_advanced_config_from_string(unifi_priv_t *priv, char *param_str)
515 {
516  char * str_ptr=param_str;
517  int ret = 0,tmp_var;
518  char phy_mode[6];
519  CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config;
520 
521  /* Check for BI */
522  ret = decode_parameter_from_string(priv, &str_ptr, "BI=",
523  PARAM_TYPE_INT, &tmp_var, 5);
524  if(ret) {
525  unifi_error(priv,"store_ap_advanced_config_from_string: BI not found\n");
526  return -1;
527  }
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);
531  if(ret) {
532  unifi_error(priv,"store_ap_advanced_config_from_string: DTIM_PER not found\n");
533  return -1;
534  }
535  ap_mac_config->dtimPeriod = tmp_var;
536  ret = decode_parameter_from_string(priv, &str_ptr, "WMM=",
537  PARAM_TYPE_INT, &tmp_var, 5);
538  if(ret) {
539  unifi_error(priv,"store_ap_advanced_config_from_string: WMM not found\n");
540  return -1;
541  }
542  ap_mac_config->wmmEnabled = tmp_var;
543  ret = decode_parameter_from_string(priv, &str_ptr, "PHY=",
544  PARAM_TYPE_STRING, phy_mode, 5);
545  if(ret) {
546  unifi_error(priv,"store_ap_advanced_config_from_string: PHY not found\n");
547  } else {
548  if(strstr(phy_mode,"b")){
550  }
551  if(strstr(phy_mode,"g")) {
553  }
554  if(strstr(phy_mode,"n")) {
556  }
557  ap_mac_config->supportedRatesCount =
558  uf_configure_supported_rates(ap_mac_config->supportedRates, ap_mac_config->phySupportedBitmap);
559  }
560  return ret;
561 }
562 
563 static int store_ap_config_from_string( unifi_priv_t * priv,char *param_str)
564 
565 {
566  char *str_ptr = param_str;
567  char sub_cmd[16];
568  char sec[CSR_WIFI_MAX_SEC_LEN];
569  char key[CSR_WIFI_MAX_KEY_LEN];
570  int ret = 0,tmp_var;
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);
576  return -1;
577  }
578  if (decode_parameter_from_string(priv,&str_ptr, "ASCII_CMD=",
579  PARAM_TYPE_STRING, sub_cmd, 6) != 0) {
580  return -1;
581  }
582  if (strncmp(sub_cmd, "AP_CFG", 6)) {
583 
584  if(!strncmp(sub_cmd ,"ADVCFG", 6)) {
585  return store_ap_advanced_config_from_string(priv, str_ptr);
586  }
587  unifi_error(priv,"store_ap_config_from_string: sub_cmd:%s != 'AP_CFG or ADVCFG'!\n", sub_cmd);
588  return -1;
589  }
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);
594  if(ret) {
595  unifi_error(priv,"store_ap_config_from_string: SSID not found\n");
596  return -1;
597  }
598  ap_config->ssid.length = strlen(ap_config->ssid.ssid);
599 
600  ret = decode_parameter_from_string(priv, &str_ptr, "SEC=",
601  PARAM_TYPE_STRING, sec, CSR_WIFI_MAX_SEC_LEN);
602  if(ret) {
603  unifi_error(priv,"store_ap_config_from_string: SEC not found\n");
604  return -1;
605  }
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;
611  if(ret) {
612  unifi_notice(priv,"store_ap_config_from_string: KEY not found:fine with Open\n");
613  }
614  }
615  else if(!strcasecmp(sec,"wpa2-psk")) {
616  int i,j=0;
617  CsrWifiNmeApAuthPers *pers =
618  ((CsrWifiNmeApAuthPers *)&(ap_config->credentials.nmeAuthType.authTypePersonal));
619  u8 *psk = pers->authPers_credentials.psk.psk;
620 
621  unifi_trace(priv,UDBG2,"store_ap_config_from_string: security WPA2");
622  if(ret) {
623  unifi_error(priv,"store_ap_config_from_string: KEY not found for WPA2\n");
624  return -1;
625  }
626  ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL;
628  pers->rsnCapabilities =0;
629  pers->wapiCapabilities =0;
633  for(i=0;i<32;i++){
634  psk[i] = (16*hex_look_up(key[j]))+hex_look_up(key[j+1]);
635  j+=2;
636  }
637 
638  } else {
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;
641  return -1;
642  }
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);
646  if(ret)
647  return -1;
648  ap_config->channel = tmp_var;
649  ret = decode_parameter_from_string(priv,&str_ptr, "PREAMBLE=", PARAM_TYPE_INT, &tmp_var, 5);
650  if(ret)
651  return -1;
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;
655  return ret;
656 }
657 
658 static int
659 iwprivsapstart(struct net_device *dev, struct iw_request_info *info,
660  union iwreq_data *wrqu, char *extra)
661 {
662  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
663  unifi_priv_t *priv = interfacePriv->privPtr;
664  int r;
665 
666  unifi_trace(priv, UDBG1, "iwprivsapstart\n" );
667  r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
668  if(r) {
669  unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
670  }
671  return r;
672 }
673 
674 static int
675 iwprivsapconfig(struct net_device *dev, struct iw_request_info *info,
676  union iwreq_data *wrqu, char *extra)
677 {
678  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
679  unifi_priv_t *priv = interfacePriv->privPtr;
680  char *cfg_str = NULL;
681  int r;
682 
683  unifi_trace(priv, UDBG1, "iwprivsapconfig\n" );
684  if (wrqu->data.length != 0) {
685  char *str;
686  if (!(cfg_str = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
687  {
688  return -ENOMEM;
689  }
690  if (copy_from_user(cfg_str, wrqu->data.pointer, wrqu->data.length)) {
691  kfree(cfg_str);
692  return -EFAULT;
693  }
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);
697  str = 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);
700  kfree(cfg_str);
701  return -EIO;
702 
703  }
704  } else {
705  unifi_error(priv,"iwprivsapconfig argument length = 0 \n");
706  return -EIO;
707  }
708  r = sme_ap_config(priv, &priv->ap_mac_config, &priv->group_sec_config);
709  if(r) {
710  unifi_error(priv,"iwprivsapstop AP Config failed : %d\n",-r);
711  } else if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
713  unifi_trace(priv, UDBG1, "iwprivsapconfig: Starting the AP");
714  r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
715  if(r) {
716  unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
717  }
718  }
719  kfree(cfg_str);
720  return r;
721 }
722 
723 static int
724 iwprivsapstop(struct net_device *dev, struct iw_request_info *info,
725  union iwreq_data *wrqu, char *extra)
726 {
727  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
728  unifi_priv_t *priv = interfacePriv->privPtr;
729  int r;
730  u16 interface_tag = interfacePriv->InterfaceTag;
731 
732  unifi_trace(priv, UDBG1, "iwprivsapstop\n" );
733  r = sme_ap_stop(priv,interface_tag);
734  if(r) {
735  unifi_error(priv,"iwprivsapstop AP STOP failed : %d\n",-r);
736  }
737  return r;
738 }
739 
740 #ifdef ANDROID_BUILD
741 static int
742 iwprivsapfwreload(struct net_device *dev, struct iw_request_info *info,
743  union iwreq_data *wrqu, char *extra)
744 {
745  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
746  unifi_priv_t *priv = interfacePriv->privPtr;
747 
748  unifi_trace(priv, UDBG1, "iwprivsapfwreload\n" );
749  return 0;
750 }
751 
752 static int
753 iwprivsstackstart(struct net_device *dev, struct iw_request_info *info,
754  union iwreq_data *wrqu, char *extra)
755 {
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" );
759  return 0;
760 }
761 
762 static int
763 iwprivsstackstop(struct net_device *dev, struct iw_request_info *info,
764  union iwreq_data *wrqu, char *extra)
765 {
766  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
767  unifi_priv_t *priv = interfacePriv->privPtr;
768  int r = 0;
769  u16 interface_tag = interfacePriv->InterfaceTag;
770 
771  unifi_trace(priv, UDBG1, "iwprivsstackstop\n" );
772 
773  switch(interfacePriv->interfaceMode) {
777  r = sme_mgt_disconnect(priv);
778  break;
781  r = sme_ap_stop(priv,interface_tag);
782  break;
783  default :
784  break;
785  }
786 
787  if(r) {
788  unifi_error(priv,"iwprivsstackstop Stack stop failed : %d\n",-r);
789  }
790  return 0;
791 }
792 #endif /* ANDROID_BUILD */
793 #endif /* CSR_SUPPORT_WEXT_AP */
794 
795 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
796 static int
797 iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info,
798  union iwreq_data *wrqu, char *extra)
799 {
800  u8 enable;
801  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
802  unifi_priv_t *priv = interfacePriv->privPtr;
803  func_enter();
804 
805  unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" );
806 
807  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
809  unifi_error(priv, "iwprivsconfwapi: not permitted in Mode %d\n",
810  interfacePriv->interfaceMode);
811  return -EPERM;
812  }
813 
814  enable = *(u8*)(extra);
815 
816  if (enable) {
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 |=
821  } else {
822  priv->connection_config.authModeMask &= ~(CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI);
823  priv->connection_config.encryptionModeMask &=
825  }
826 
827  func_exit();
828  return 0;
829 }
830 
831 static int
832 iwprivswpikey(struct net_device *dev, struct iw_request_info *info,
833  union iwreq_data *wrqu, char *extra)
834 {
835  int r = 0, i;
837  unifiio_wapi_key_t inKey;
838  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
839  unifi_priv_t *priv = interfacePriv->privPtr;
840  func_enter();
841 
842  unifi_trace(priv, UDBG1, "iwprivswpikey\n" );
843 
844  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
846  unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
847  interfacePriv->interfaceMode);
848  return -EPERM;
849  }
850 
851  inKey = *(unifiio_wapi_key_t*)(extra);
852 
853  if (inKey.unicastKey) {
855  } else {
857  }
858 
859  key.keyIndex = inKey.keyIndex;
860 
861  /* memcpy(key.keyRsc, inKey.keyRsc, 16); */
862  for (i = 0; i < 16; i+= 2)
863  {
864  key.keyRsc[i/2] = inKey.keyRsc[i+1] << 8 | inKey.keyRsc[i];
865  }
866 
867  memcpy(key.address.a, inKey.address, 6);
868  key.keyLength = 32;
869  memcpy(key.key, inKey.key, 32);
870  key.authenticator = 0;
871  key.wepTxKey = 0;
872 
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],
877  key.key[15]);
878 
879  r = sme_mgt_key(priv, &key, CSR_WIFI_SME_LIST_ACTION_ADD);
880  if (r) {
881  unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
882  return convert_sme_error(r);
883  }
884 
885  func_exit();
886  return r;
887 }
888 #endif
889 
890 
891 static int
892 unifi_giwname(struct net_device *dev, struct iw_request_info *info,
893  union iwreq_data *wrqu, char *extra)
894 {
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");
899 
900  if (priv->if_index == CSR_INDEX_5G) {
901  strcpy(name, "IEEE 802.11-a");
902  } else {
903  strcpy(name, "IEEE 802.11-bgn");
904  }
905  return 0;
906 } /* unifi_giwname() */
907 
908 
909 static int
910 unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
911  union iwreq_data *wrqu, char *extra)
912 {
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;
916 
917  func_enter();
918  unifi_trace(priv, UDBG2, "unifi_siwfreq\n");
919 
920  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
922  unifi_error(priv, "unifi_siwfreq: not permitted in Mode %d\n",
923  interfacePriv->interfaceMode);
924  return -EPERM;
925  }
926 
927 
928  /*
929  * Channel is stored in the connection configuration,
930  * and set later when ask for a connection.
931  */
932  if ((freq->e == 0) && (freq->m <= 1000)) {
933  priv->connection_config.adhocChannel = freq->m;
934  } else {
935  priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e);
936  }
937 
938  func_exit();
939  return 0;
940 } /* unifi_siwfreq() */
941 
942 
943 static int
944 unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
945  union iwreq_data *wrqu, char *extra)
946 {
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;
950  int err = 0;
951  CsrWifiSmeConnectionInfo connectionInfo;
952 
953  func_enter();
954  unifi_trace(priv, UDBG2, "unifi_giwfreq\n");
955  CHECK_INITED(priv);
956 
957  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
959  unifi_error(priv, "unifi_giwfreq: not permitted in Mode %d\n",
960  interfacePriv->interfaceMode);
961  return -EPERM;
962  }
963 
964 
965  UF_RTNL_UNLOCK();
966  err = sme_mgt_connection_info_get(priv, &connectionInfo);
967  UF_RTNL_LOCK();
968 
969  freq->m = channel_to_mhz(connectionInfo.channelNumber,
970  (connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0));
971  freq->e = 6;
972 
973  func_exit();
974  return convert_sme_error(err);
975 } /* unifi_giwfreq() */
976 
977 
978 static int
979 unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
980  union iwreq_data *wrqu, char *extra)
981 {
982  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
983  unifi_priv_t *priv = interfacePriv->privPtr;
984 
985  func_enter();
986  unifi_trace(priv, UDBG2, "unifi_siwmode\n");
987 
988  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
990  unifi_error(priv, "unifi_siwmode: not permitted in Mode %d\n",
991  interfacePriv->interfaceMode);
992  return -EPERM;
993  }
994 
995 
996  switch(wrqu->mode) {
997  case IW_MODE_ADHOC:
998  priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ADHOC;
999  break;
1000  case IW_MODE_INFRA:
1001  priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE;
1002  break;
1003  case IW_MODE_AUTO:
1004  priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ANY_BSS;
1005  break;
1006  default:
1007  unifi_notice(priv, "Unknown IW MODE value.\n");
1008  }
1009 
1010  /* Clear the SSID and BSSID configuration */
1011  priv->connection_config.ssid.length = 0;
1012  memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
1013 
1014  func_exit();
1015  return 0;
1016 } /* unifi_siwmode() */
1017 
1018 
1019 
1020 static int
1021 unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
1022  union iwreq_data *wrqu, char *extra)
1023 {
1024  int r = 0;
1025  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1026  unifi_priv_t *priv = interfacePriv->privPtr;
1027  CsrWifiSmeConnectionConfig connectionConfig;
1028 
1029  func_enter();
1030  unifi_trace(priv, UDBG2, "unifi_giwmode\n");
1031  CHECK_INITED(priv);
1032 
1033  unifi_trace(priv, UDBG2, "unifi_giwmode: Exisitng mode = 0x%x\n",
1034  interfacePriv->interfaceMode);
1035  switch(interfacePriv->interfaceMode) {
1038  wrqu->mode = IW_MODE_INFRA;
1039  break;
1042  wrqu->mode = IW_MODE_MASTER;
1043  break;
1045  wrqu->mode = IW_MODE_ADHOC;
1046  break;
1049  UF_RTNL_UNLOCK();
1050  r = sme_mgt_connection_config_get(priv, &connectionConfig);
1051  UF_RTNL_LOCK();
1052  if (r == 0) {
1053  switch(connectionConfig.bssType) {
1055  wrqu->mode = IW_MODE_ADHOC;
1056  break;
1058  wrqu->mode = IW_MODE_INFRA;
1059  break;
1060  default:
1061  wrqu->mode = IW_MODE_AUTO;
1062  unifi_notice(priv, "Unknown IW MODE value.\n");
1063  }
1064  }
1065  break;
1066  default:
1067  wrqu->mode = IW_MODE_AUTO;
1068  unifi_notice(priv, "Unknown IW MODE value.\n");
1069 
1070  }
1071  unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode);
1072  func_exit();
1073  return r;
1074 } /* unifi_giwmode() */
1075 
1076 
1077 
1078 static int
1079 unifi_giwrange(struct net_device *dev, struct iw_request_info *info,
1080  union iwreq_data *wrqu, char *extra)
1081 {
1082  struct iw_point *dwrq = &wrqu->data;
1083  struct iw_range *range = (struct iw_range *) extra;
1084  int i;
1085 
1086  unifi_trace(NULL, UDBG2, "unifi_giwrange\n");
1087 
1088  dwrq->length = sizeof(struct iw_range);
1089  memset(range, 0, sizeof(*range));
1090  range->min_nwid = 0x0000;
1091  range->max_nwid = 0x0000;
1092 
1093  /*
1094  * Don't report the frequency/channel table, then the channel
1095  * number returned elsewhere will be printed as a channel number.
1096  */
1097 
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 */
1102 
1103 
1104  /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
1105  i = 0;
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;
1119 #else
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;
1130 
1132  range->num_encoding_sizes = 2;
1133  range->encoding_size[0] = 5;
1134  range->encoding_size[1] = 13;
1135 
1136  range->we_version_source = 20;
1138 
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++) {
1144  int chan = i + 1;
1145  range->freq[i].i = chan;
1146  range->freq[i].m = channel_to_mhz(chan, 0);
1147  range->freq[i].e = 6;
1148  }
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;
1162  }
1163 
1164 #if WIRELESS_EXT > 16
1165  /* Event capability (kernel + driver) */
1166  range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1170  range->event_capa[1] = IW_EVENT_CAPA_K_1;
1171  range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
1175 #endif /* WIRELESS_EXT > 16 */
1176 
1177 #if WIRELESS_EXT > 17
1180 #endif /* WIRELESS_EXT > 17 */
1181 
1182 
1183  return 0;
1184 } /* unifi_giwrange() */
1185 
1186 
1187 static int
1188 unifi_siwap(struct net_device *dev, struct iw_request_info *info,
1189  union iwreq_data *wrqu, char *extra)
1190 {
1191  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1192  unifi_priv_t *priv = interfacePriv->privPtr;
1193  int err = 0;
1194 
1195  func_enter();
1196 
1197  CHECK_INITED(priv);
1198 
1199  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1200  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1201  unifi_error(priv, "unifi_siwap: not permitted in Mode %d\n",
1202  interfacePriv->interfaceMode);
1203  return -EPERM;
1204  }
1205 
1206 
1207  if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) {
1208  return -EINVAL;
1209  }
1210 
1211  unifi_trace(priv, UDBG1, "unifi_siwap: asked for %pM\n",
1212  wrqu->ap_addr.sa_data);
1213 
1214  if (is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
1215  priv->ignore_bssid_join = FALSE;
1216  err = sme_mgt_disconnect(priv);
1217  if (err) {
1218  unifi_trace(priv, UDBG4, "unifi_siwap: Disconnect failed, status %d\n", err);
1219  }
1220  return 0;
1221  }
1222 
1223  if (priv->ignore_bssid_join) {
1224  unifi_trace(priv, UDBG4, "unifi_siwap: ignoring second join\n");
1225  priv->ignore_bssid_join = FALSE;
1226  } else {
1227  memcpy(priv->connection_config.bssid.a, wrqu->ap_addr.sa_data, ETH_ALEN);
1228  unifi_trace(priv, UDBG1, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n",
1229  priv->connection_config.bssid.a[0],
1230  priv->connection_config.bssid.a[1],
1231  priv->connection_config.bssid.a[2],
1232  priv->connection_config.bssid.a[3],
1233  priv->connection_config.bssid.a[4],
1234  priv->connection_config.bssid.a[5]);
1235  err = sme_mgt_connect(priv);
1236  if (err) {
1237  unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err);
1238  func_exit();
1239  return convert_sme_error(err);
1240  }
1241  }
1242  func_exit();
1243 
1244  return 0;
1245 } /* unifi_siwap() */
1246 
1247 
1248 static int
1249 unifi_giwap(struct net_device *dev, struct iw_request_info *info,
1250  union iwreq_data *wrqu, char *extra)
1251 {
1252  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1253  unifi_priv_t *priv = interfacePriv->privPtr;
1254  CsrWifiSmeConnectionInfo connectionInfo;
1255  int r = 0;
1256  u8 *bssid;
1257 
1258  func_enter();
1259 
1260  CHECK_INITED(priv);
1261  unifi_trace(priv, UDBG2, "unifi_giwap\n");
1262 
1263  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1264  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1265  unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
1266  interfacePriv->interfaceMode);
1267  return -EPERM;
1268  }
1269 
1270  UF_RTNL_UNLOCK();
1271  r = sme_mgt_connection_info_get(priv, &connectionInfo);
1272  UF_RTNL_LOCK();
1273 
1274  if (r == 0) {
1275  bssid = connectionInfo.bssid.a;
1276  wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1277  unifi_trace(priv, UDBG4, "unifi_giwap: BSSID = %pM\n", bssid);
1278 
1279  memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
1280  } else {
1281  memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1282  }
1283 
1284  func_exit();
1285  return 0;
1286 } /* unifi_giwap() */
1287 
1288 
1289 static int
1290 unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
1291  union iwreq_data *wrqu, char *extra)
1292 {
1293  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1294  unifi_priv_t *priv = interfacePriv->privPtr;
1295  int scantype;
1296  int r;
1297  CsrWifiSsid scan_ssid;
1298  unsigned char *channel_list = NULL;
1299  int chans_good = 0;
1300 #if WIRELESS_EXT > 17
1301  struct iw_point *data = &wrqu->data;
1302  struct iw_scan_req *req = (struct iw_scan_req *) extra;
1303 #endif
1304 
1305  func_enter();
1306 
1307  CHECK_INITED(priv);
1308 
1309  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1310  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1311  unifi_error(priv, "unifi_siwscan: not permitted in Mode %d\n",
1312  interfacePriv->interfaceMode);
1313  return -EPERM;
1314  }
1315 
1316 
1317  scantype = UNIFI_SCAN_ACTIVE;
1318 
1319 #if WIRELESS_EXT > 17
1320  /* Providing a valid channel list will force an active scan */
1321  if (req) {
1322  if ((req->num_channels > 0) && (req->num_channels < IW_MAX_FREQUENCIES)) {
1323  channel_list = kmalloc(req->num_channels, GFP_KERNEL);
1324  if (channel_list) {
1325  int i;
1326  for (i = 0; i < req->num_channels; i++) {
1327  /* Convert frequency to channel number */
1328  int ch = wext_freq_to_channel(req->channel_list[i].m,
1329  req->channel_list[i].e);
1330  if (ch) {
1331  channel_list[chans_good++] = ch;
1332  }
1333  }
1334  unifi_trace(priv, UDBG1,
1335  "SIWSCAN: Scanning %d channels\n", chans_good);
1336  } else {
1337  /* Fall back to scanning all */
1338  unifi_error(priv, "SIWSCAN: Can't alloc channel_list (%d)\n",
1339  req->num_channels);
1340  }
1341  }
1342  }
1343 
1344  if (req && (data->flags & IW_SCAN_THIS_ESSID)) {
1345  memcpy(scan_ssid.ssid, req->essid, req->essid_len);
1346  scan_ssid.length = req->essid_len;
1347  unifi_trace(priv, UDBG1,
1348  "SIWSCAN: Scanning for %.*s\n",
1349  scan_ssid.length, scan_ssid.ssid);
1350  } else
1351 #endif
1352  {
1353  unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n");
1354  scan_ssid.length = 0;
1355  }
1356 
1357  r = sme_mgt_scan_full(priv, &scan_ssid, chans_good, channel_list);
1358  if (r) {
1359  unifi_error(priv, "SIWSCAN: Scan returned error %d\n", r);
1360  } else {
1361  unifi_trace(priv, UDBG1, "SIWSCAN: Scan done\n");
1363  }
1364 
1365  if (channel_list) {
1366  kfree(channel_list);
1367  }
1368 
1369  func_exit();
1370  return r;
1371 
1372 } /* unifi_siwscan() */
1373 
1374 
1375 static const unsigned char *
1376 unifi_find_info_element(int id, const unsigned char *info, int len)
1377 {
1378  const unsigned char *ie = info;
1379 
1380  while (len > 1)
1381  {
1382  int e_id, e_len;
1383  e_id = ie[0];
1384  e_len = ie[1];
1385 
1386  /* Return if we find a match */
1387  if (e_id == id)
1388  {
1389  return ie;
1390  }
1391 
1392  len -= (e_len + 2);
1393  ie += (e_len + 2);
1394  }
1395 
1396  return NULL;
1397 } /* unifi_find_info_element() */
1398 
1399 
1400 /*
1401  * Translate scan data returned from the card to a card independent
1402  * format that the Wireless Tools will understand - Jean II
1403  */
1404 int
1406  struct iw_request_info *info,
1407  char *current_ev, char *end_buf,
1409  int scan_index)
1410 {
1411  struct iw_event iwe; /* Temporary buffer */
1412  unsigned char *info_elems;
1413  int info_elem_len;
1414  const unsigned char *elem;
1415  u16 capabilities;
1416  int signal, noise, snr;
1417  char *start_buf = current_ev;
1418  char *current_val; /* For rates */
1419  int i, r;
1420 
1421  info_elems = scan_data->informationElements;
1422  info_elem_len = scan_data->informationElementsLength;
1423 
1424  if (!scan_data->informationElementsLength || !scan_data->informationElements) {
1425  unifi_error(NULL, "*** NULL SCAN IEs ***\n");
1426  return -EIO;
1427  }
1428 
1429  /* get capinfo bits */
1430  capabilities = scan_data->capabilityInformation;
1431 
1432  unifi_trace(NULL, UDBG5, "Capabilities: 0x%x\n", capabilities);
1433 
1434  /* First entry *MUST* be the AP MAC address */
1435  memset(&iwe, 0, sizeof(iwe));
1436  iwe.cmd = SIOCGIWAP;
1437  iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1438  memcpy(iwe.u.ap_addr.sa_data, scan_data->bssid.a, ETH_ALEN);
1439  iwe.len = IW_EV_ADDR_LEN;
1440  r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN);
1441  if (r < 0) {
1442  return r;
1443  }
1444  start_buf += r;
1445 
1446  /* Other entries will be displayed in the order we give them */
1447 
1448  /* Add the ESSID */
1449  /* find SSID in Info Elems */
1450  elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len);
1451  if (elem) {
1452  int e_len = elem[1];
1453  const unsigned char *e_ptr = elem + 2;
1454  unsigned char buf[33];
1455 
1456  memset(&iwe, 0, sizeof(iwe));
1457  iwe.cmd = SIOCGIWESSID;
1458  iwe.u.essid.length = e_len;
1459  if (iwe.u.essid.length > 32) {
1460  iwe.u.essid.length = 32;
1461  }
1462  iwe.u.essid.flags = scan_index;
1463  memcpy(buf, e_ptr, iwe.u.essid.length);
1464  buf[iwe.u.essid.length] = '\0';
1465  r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf);
1466  if (r < 0) {
1467  return r;
1468  }
1469  start_buf += r;
1470 
1471  }
1472 
1473  /* Add mode */
1474  memset(&iwe, 0, sizeof(iwe));
1475  iwe.cmd = SIOCGIWMODE;
1476  if (scan_data->bssType == CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE) {
1477  iwe.u.mode = IW_MODE_INFRA;
1478  } else {
1479  iwe.u.mode = IW_MODE_ADHOC;
1480  }
1481  iwe.len = IW_EV_UINT_LEN;
1482  r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN);
1483  if (r < 0) {
1484  return r;
1485  }
1486  start_buf += r;
1487 
1488  /* Add frequency. iwlist will convert to channel using table given in giwrange */
1489  memset(&iwe, 0, sizeof(iwe));
1490  iwe.cmd = SIOCGIWFREQ;
1491  iwe.u.freq.m = scan_data->channelFrequency;
1492  iwe.u.freq.e = 6;
1493  r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN);
1494  if (r < 0) {
1495  return r;
1496  }
1497  start_buf += r;
1498 
1499 
1500  /* Add quality statistics */
1501  iwe.cmd = IWEVQUAL;
1502  /*
1503  * level and noise below are mapped into an unsigned 8 bit number,
1504  * ranging from [-192; 63]. The way this is achieved is simply to
1505  * add 0x100 onto the number if it is negative,
1506  * once clipped to the correct range.
1507  */
1508  signal = scan_data->rssi; /* This value is in dBm */
1509  /* Clip range of snr */
1510  snr = (scan_data->snr > 0) ? scan_data->snr : 0; /* In dB relative, from 0 - 255 */
1511  snr = (snr < 255) ? snr : 255;
1512  noise = signal - snr;
1513 
1514  /* Clip range of signal */
1515  signal = (signal < 63) ? signal : 63;
1516  signal = (signal > -192) ? signal : -192;
1517 
1518  /* Clip range of noise */
1519  noise = (noise < 63) ? noise : 63;
1520  noise = (noise > -192) ? noise : -192;
1521 
1522  /* Make u8 */
1523  signal = ( signal < 0 ) ? signal + 0x100 : signal;
1524  noise = ( noise < 0 ) ? noise + 0x100 : noise;
1525 
1526  iwe.u.qual.level = (u8)signal; /* -192 : 63 */
1527  iwe.u.qual.noise = (u8)noise; /* -192 : 63 */
1528  iwe.u.qual.qual = snr; /* 0 : 255 */
1529  iwe.u.qual.updated = 0;
1530 #if WIRELESS_EXT > 16
1533 #if WIRELESS_EXT > 18
1534  iwe.u.qual.updated |= IW_QUAL_DBM;
1535 #endif
1536 #endif
1537  r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN);
1538  if (r < 0) {
1539  return r;
1540  }
1541  start_buf += r;
1542 
1543  /* Add encryption capability */
1544  iwe.cmd = SIOCGIWENCODE;
1545  if (capabilities & SIG_CAP_PRIVACY) {
1546  iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1547  } else {
1548  iwe.u.data.flags = IW_ENCODE_DISABLED;
1549  }
1550  iwe.u.data.length = 0;
1551  iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1552  r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, "");
1553  if (r < 0) {
1554  return r;
1555  }
1556  start_buf += r;
1557 
1558 
1559  /*
1560  * Rate : stuffing multiple values in a single event require a bit
1561  * more of magic - Jean II
1562  */
1563  current_val = start_buf + IW_EV_LCP_LEN;
1564 
1565  iwe.cmd = SIOCGIWRATE;
1566  /* Those two flags are ignored... */
1567  iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1568 
1570  info_elems, info_elem_len);
1571  if (elem) {
1572  int e_len = elem[1];
1573  const unsigned char *e_ptr = elem + 2;
1574 
1575  /*
1576  * Count how many rates we have.
1577  * Zero marks the end of the list, if the list is not truncated.
1578  */
1579  /* Max 8 values */
1580  for (i = 0; i < e_len; i++) {
1581  if (e_ptr[i] == 0) {
1582  break;
1583  }
1584  /* Bit rate given in 500 kb/s units (+ 0x80) */
1585  iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
1586  /* Add new value to event */
1587  r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
1588  if (r < 0) {
1589  return r;
1590  }
1591  current_val +=r;
1592 
1593  }
1594  }
1596  info_elems, info_elem_len);
1597  if (elem) {
1598  int e_len = elem[1];
1599  const unsigned char *e_ptr = elem + 2;
1600 
1601  /*
1602  * Count how many rates we have.
1603  * Zero marks the end of the list, if the list is not truncated.
1604  */
1605  /* Max 8 values */
1606  for (i = 0; i < e_len; i++) {
1607  if (e_ptr[i] == 0) {
1608  break;
1609  }
1610  /* Bit rate given in 500 kb/s units (+ 0x80) */
1611  iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
1612  /* Add new value to event */
1613  r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
1614  if (r < 0) {
1615  return r;
1616  }
1617  current_val +=r;
1618  }
1619  }
1620  /* Check if we added any rates event */
1621  if ((current_val - start_buf) > IW_EV_LCP_LEN) {
1622  start_buf = current_val;
1623  }
1624 
1625 
1626 #if WIRELESS_EXT > 17
1627  memset(&iwe, 0, sizeof(iwe));
1628  iwe.cmd = IWEVGENIE;
1629  iwe.u.data.length = info_elem_len;
1630 
1631  r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems);
1632  if (r < 0) {
1633  return r;
1634  }
1635 
1636  start_buf += r;
1637 #endif /* WE > 17 */
1638 
1639  return (start_buf - current_ev);
1640 } /* unifi_translate_scan() */
1641 
1642 
1643 
1644 static int
1645 unifi_giwscan(struct net_device *dev, struct iw_request_info *info,
1646  union iwreq_data *wrqu, char *extra)
1647 {
1648  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1649  unifi_priv_t *priv = interfacePriv->privPtr;
1650  struct iw_point *dwrq = &wrqu->data;
1651  int r;
1652 
1653  CHECK_INITED(priv);
1654 
1655  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1656  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1657  unifi_error(priv, "unifi_giwscan: not permitted in Mode %d\n",
1658  interfacePriv->interfaceMode);
1659  return -EPERM;
1660  }
1661 
1662 
1663  unifi_trace(priv, UDBG1,
1664  "unifi_giwscan: buffer (%d bytes) \n",
1665  dwrq->length);
1666  UF_RTNL_UNLOCK();
1667  r = sme_mgt_scan_results_get_async(priv, info, extra, dwrq->length);
1668  UF_RTNL_LOCK();
1669  if (r < 0) {
1670  unifi_trace(priv, UDBG1,
1671  "unifi_giwscan: buffer (%d bytes) not big enough.\n",
1672  dwrq->length);
1673  return r;
1674  }
1675 
1676  dwrq->length = r;
1677  dwrq->flags = 0;
1678 
1679  return 0;
1680 } /* unifi_giwscan() */
1681 
1682 
1683 /*
1684  * ---------------------------------------------------------------------------
1685  * unifi_siwessid
1686  *
1687  * Request to join a network or start and AdHoc.
1688  *
1689  * Arguments:
1690  * dev Pointer to network device struct.
1691  * info Pointer to broken-out ioctl request.
1692  * data Pointer to argument data.
1693  * essid Pointer to string giving name of network to join
1694  * or start
1695  *
1696  * Returns:
1697  * 0 on success and everything complete
1698  * -EINPROGRESS to have the higher level call the commit method.
1699  * ---------------------------------------------------------------------------
1700  */
1701 static int
1702 unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
1703  struct iw_point *data, char *essid)
1704 {
1705  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1706  unifi_priv_t *priv = interfacePriv->privPtr;
1707  int len;
1708  int err = 0;
1709 
1710  func_enter();
1711  CHECK_INITED(priv);
1712 
1713  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1714  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1715  unifi_error(priv, "unifi_siwessid: not permitted in Mode %d\n",
1716  interfacePriv->interfaceMode);
1717  return -EPERM;
1718  }
1719 
1720 
1721  len = 0;
1722  if (data->flags & 1) {
1723  /* Limit length */
1724  len = data->length;
1725  if (len > UNIFI_MAX_SSID_LEN) {
1726  len = UNIFI_MAX_SSID_LEN;
1727  }
1728  }
1729 
1730 #ifdef UNIFI_DEBUG
1731  {
1732  char essid_str[UNIFI_MAX_SSID_LEN+1];
1733  int i;
1734 
1735  for (i = 0; i < len; i++) {
1736  essid_str[i] = (isprint(essid[i]) ? essid[i] : '?');
1737  }
1738  essid_str[i] = '\0';
1739 
1740  unifi_trace(priv, UDBG1, "unifi_siwessid: asked for '%*s' (%d)\n", len, essid_str, len);
1741  unifi_trace(priv, UDBG2, " with authModeMask = %d", priv->connection_config.authModeMask);
1742  }
1743 #endif
1744 
1745  memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
1746  if (len) {
1747  if (essid[len - 1] == 0) {
1748  len --;
1749  }
1750 
1751  memcpy(priv->connection_config.ssid.ssid, essid, len);
1752  priv->connection_config.ssid.length = len;
1753 
1754  } else {
1755  priv->connection_config.ssid.length = 0;
1756  }
1757 
1758  UF_RTNL_UNLOCK();
1759  err = sme_mgt_connect(priv);
1760  UF_RTNL_LOCK();
1761  if (err) {
1762  unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err);
1763  func_exit();
1764  return convert_sme_error(err);
1765  }
1766 
1767  func_exit();
1768  return 0;
1769 } /* unifi_siwessid() */
1770 
1771 
1772 static int
1773 unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
1774  union iwreq_data *wrqu, char *essid)
1775 {
1776  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1777  unifi_priv_t *priv = interfacePriv->privPtr;
1778  struct iw_point *data = &wrqu->essid;
1779  CsrWifiSmeConnectionInfo connectionInfo;
1780  int r = 0;
1781 
1782  func_enter();
1783  unifi_trace(priv, UDBG2, "unifi_giwessid\n");
1784  CHECK_INITED(priv);
1785 
1786  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1787  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1788  unifi_error(priv, "unifi_giwessid: not permitted in Mode %d\n",
1789  interfacePriv->interfaceMode);
1790  return -EPERM;
1791  }
1792 
1793  UF_RTNL_UNLOCK();
1794  r = sme_mgt_connection_info_get(priv, &connectionInfo);
1795  UF_RTNL_LOCK();
1796 
1797  if (r == 0) {
1798  data->length = connectionInfo.ssid.length;
1799  strncpy(essid,
1800  connectionInfo.ssid.ssid,
1801  data->length);
1802  data->flags = 1; /* active */
1803 
1804  unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n",
1805  data->length, essid);
1806  }
1807 
1808  func_exit();
1809 
1810  return 0;
1811 } /* unifi_giwessid() */
1812 
1813 
1814 static int
1815 unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
1816  union iwreq_data *wrqu, char *extra)
1817 {
1818  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1819  unifi_priv_t *priv = interfacePriv->privPtr;
1820  struct iw_param *args = &wrqu->bitrate;
1821  CsrWifiSmeMibConfig mibConfig;
1822  int r;
1823 
1824  func_enter();
1825 
1826  CHECK_INITED(priv);
1827  unifi_trace(priv, UDBG2, "unifi_siwrate\n");
1828 
1829  /*
1830  * If args->fixed == 0, value is max rate or -1 for best
1831  * If args->fixed == 1, value is rate to set or -1 for best
1832  * args->disabled and args->flags are not used in SIOCSIWRATE
1833  */
1834 
1835  /* Get, modify and set the MIB data */
1836  UF_RTNL_UNLOCK();
1837  r = sme_mgt_mib_config_get(priv, &mibConfig);
1838  UF_RTNL_LOCK();
1839  if (r) {
1840  unifi_error(priv, "unifi_siwrate: Get CsrWifiSmeMibConfigValue failed.\n");
1841  return r;
1842  }
1843 
1844  /* Default to auto rate algorithm */
1845  /* in 500Kbit/s, 0 means auto */
1846  mibConfig.unifiFixTxDataRate = 0;
1847 
1848  if (args->value != -1) {
1849  mibConfig.unifiFixTxDataRate = args->value / 500000;
1850  }
1851 
1852  /* 1 means rate is a maximum, 2 means rate is a set value */
1853  if (args->fixed == 1) {
1854  mibConfig.unifiFixMaxTxDataRate = 0;
1855  } else {
1856  mibConfig.unifiFixMaxTxDataRate = 1;
1857  }
1858  UF_RTNL_UNLOCK();
1859  r = sme_mgt_mib_config_set(priv, &mibConfig);
1860  UF_RTNL_LOCK();
1861  if (r) {
1862  unifi_error(priv, "unifi_siwrate: Set CsrWifiSmeMibConfigValue failed.\n");
1863  return r;
1864  }
1865 
1866  func_exit();
1867 
1868  return 0;
1869 } /* unifi_siwrate() */
1870 
1871 
1872 
1873 static int
1874 unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
1875  union iwreq_data *wrqu, char *extra)
1876 {
1877  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1878  unifi_priv_t *priv = interfacePriv->privPtr;
1879  struct iw_param *args = &wrqu->bitrate;
1880  int r;
1881  int bitrate, flag;
1882  CsrWifiSmeMibConfig mibConfig;
1883  CsrWifiSmeConnectionStats connectionStats;
1884 
1885  func_enter();
1886  unifi_trace(priv, UDBG2, "unifi_giwrate\n");
1887  CHECK_INITED(priv);
1888 
1889  flag = 0;
1890  bitrate = 0;
1891  UF_RTNL_UNLOCK();
1892  r = sme_mgt_mib_config_get(priv, &mibConfig);
1893  UF_RTNL_LOCK();
1894  if (r) {
1895  unifi_error(priv, "unifi_giwrate: Get CsrWifiSmeMibConfigValue failed.\n");
1896  return r;
1897  }
1898 
1899  bitrate = mibConfig.unifiFixTxDataRate;
1900  flag = mibConfig.unifiFixMaxTxDataRate;
1901 
1902  /* Used the value returned by the SME if MIB returns 0 */
1903  if (bitrate == 0) {
1904  UF_RTNL_UNLOCK();
1905  r = sme_mgt_connection_stats_get(priv, &connectionStats);
1906  UF_RTNL_LOCK();
1907  /* Ignore errors, we may be disconnected */
1908  if (r == 0) {
1909  bitrate = connectionStats.unifiTxDataRate;
1910  }
1911  }
1912 
1913  args->value = bitrate * 500000;
1914  args->fixed = !flag;
1915 
1916  func_exit();
1917 
1918  return 0;
1919 } /* unifi_giwrate() */
1920 
1921 
1922 static int
1923 unifi_siwrts(struct net_device *dev, struct iw_request_info *info,
1924  union iwreq_data *wrqu, char *extra)
1925 {
1926  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1927  unifi_priv_t *priv = interfacePriv->privPtr;
1928  int val = wrqu->rts.value;
1929  int r = 0;
1930  CsrWifiSmeMibConfig mibConfig;
1931 
1932  unifi_trace(priv, UDBG2, "unifi_siwrts\n");
1933  CHECK_INITED(priv);
1934 
1935  if (wrqu->rts.disabled) {
1936  val = 2347;
1937  }
1938 
1939  if ( (val < 0) || (val > 2347) )
1940  {
1941  return -EINVAL;
1942  }
1943 
1944  /* Get, modify and set the MIB data */
1945  UF_RTNL_UNLOCK();
1946  r = sme_mgt_mib_config_get(priv, &mibConfig);
1947  UF_RTNL_LOCK();
1948  if (r) {
1949  unifi_error(priv, "unifi_siwrts: Get CsrWifiSmeMibConfigValue failed.\n");
1950  return r;
1951  }
1952  mibConfig.dot11RtsThreshold = val;
1953  UF_RTNL_UNLOCK();
1954  r = sme_mgt_mib_config_set(priv, &mibConfig);
1955  UF_RTNL_LOCK();
1956  if (r) {
1957  unifi_error(priv, "unifi_siwrts: Set CsrWifiSmeMibConfigValue failed.\n");
1958  return r;
1959  }
1960 
1961  return 0;
1962 }
1963 
1964 
1965 static int
1966 unifi_giwrts(struct net_device *dev, struct iw_request_info *info,
1967  union iwreq_data *wrqu, char *extra)
1968 {
1969  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
1970  unifi_priv_t *priv = interfacePriv->privPtr;
1971  int r;
1972  int rts_thresh;
1973  CsrWifiSmeMibConfig mibConfig;
1974 
1975  unifi_trace(priv, UDBG2, "unifi_giwrts\n");
1976  CHECK_INITED(priv);
1977 
1978  UF_RTNL_UNLOCK();
1979  r = sme_mgt_mib_config_get(priv, &mibConfig);
1980  UF_RTNL_LOCK();
1981  if (r) {
1982  unifi_error(priv, "unifi_giwrts: Get CsrWifiSmeMibConfigValue failed.\n");
1983  return r;
1984  }
1985 
1986  rts_thresh = mibConfig.dot11RtsThreshold;
1987  if (rts_thresh > 2347) {
1988  rts_thresh = 2347;
1989  }
1990 
1991  wrqu->rts.value = rts_thresh;
1992  wrqu->rts.disabled = (rts_thresh == 2347);
1993  wrqu->rts.fixed = 1;
1994 
1995  return 0;
1996 }
1997 
1998 
1999 static int
2000 unifi_siwfrag(struct net_device *dev, struct iw_request_info *info,
2001  union iwreq_data *wrqu, char *extra)
2002 {
2003  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2004  unifi_priv_t *priv = interfacePriv->privPtr;
2005  int val = wrqu->frag.value;
2006  int r = 0;
2007  CsrWifiSmeMibConfig mibConfig;
2008 
2009  unifi_trace(priv, UDBG2, "unifi_siwfrag\n");
2010  CHECK_INITED(priv);
2011 
2012  if (wrqu->frag.disabled)
2013  val = 2346;
2014 
2015  if ( (val < 256) || (val > 2347) )
2016  return -EINVAL;
2017 
2018  /* Get, modify and set the MIB data */
2019  UF_RTNL_UNLOCK();
2020  r = sme_mgt_mib_config_get(priv, &mibConfig);
2021  UF_RTNL_LOCK();
2022  if (r) {
2023  unifi_error(priv, "unifi_siwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
2024  return r;
2025  }
2026  /* Fragmentation Threashold must be even */
2027  mibConfig.dot11FragmentationThreshold = (val & ~0x1);
2028  UF_RTNL_UNLOCK();
2029  r = sme_mgt_mib_config_set(priv, &mibConfig);
2030  UF_RTNL_LOCK();
2031  if (r) {
2032  unifi_error(priv, "unifi_siwfrag: Set CsrWifiSmeMibConfigValue failed.\n");
2033  return r;
2034  }
2035 
2036  return 0;
2037 }
2038 
2039 
2040 static int
2041 unifi_giwfrag(struct net_device *dev, struct iw_request_info *info,
2042  union iwreq_data *wrqu, char *extra)
2043 {
2044  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2045  unifi_priv_t *priv = interfacePriv->privPtr;
2046  int r;
2047  int frag_thresh;
2048  CsrWifiSmeMibConfig mibConfig;
2049 
2050  unifi_trace(priv, UDBG2, "unifi_giwfrag\n");
2051  CHECK_INITED(priv);
2052 
2053  UF_RTNL_UNLOCK();
2054  r = sme_mgt_mib_config_get(priv, &mibConfig);
2055  UF_RTNL_LOCK();
2056  if (r) {
2057  unifi_error(priv, "unifi_giwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
2058  return r;
2059  }
2060 
2061  frag_thresh = mibConfig.dot11FragmentationThreshold;
2062 
2063  /* Build the return structure */
2064  wrqu->frag.value = frag_thresh;
2065  wrqu->frag.disabled = (frag_thresh >= 2346);
2066  wrqu->frag.fixed = 1;
2067 
2068  return 0;
2069 }
2070 
2071 
2072 static int
2073 unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
2074  union iwreq_data *wrqu, char *extra)
2075 {
2076  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2077  unifi_priv_t *priv = interfacePriv->privPtr;
2078  struct iw_point *erq = &wrqu->encoding;
2079  int index;
2080  int rc = 0;
2081  int privacy = -1;
2082  CsrWifiSmeKey sme_key;
2083 
2084  func_enter();
2085  unifi_trace(priv, UDBG2, "unifi_siwencode\n");
2086 
2087  CHECK_INITED(priv);
2088 
2089  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2090  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2091  unifi_error(priv, "unifi_siwencode: not permitted in Mode %d\n",
2092  interfacePriv->interfaceMode);
2093  return -EPERM;
2094  }
2095 
2096 
2097  /*
2098  * Key index is encoded in the flags.
2099  * 0 - use current default,
2100  * 1-4 - if a key value is given set that key
2101  * if not use that key
2102  */
2103  index = (erq->flags & IW_ENCODE_INDEX); /* key number, 1-4 */
2104  if ((index < 0) || (index > 4)) {
2105  unifi_error(priv, "unifi_siwencode: Request to set an invalid key (index:%d)", index);
2106  return -EINVAL;
2107  }
2108 
2109  /*
2110  * Basic checking: do we have a key to set ?
2111  * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
2112  * but older versions rely on sending a key id 1-4.
2113  */
2114  if (erq->length > 0) {
2115 
2116  /* Check the size of the key */
2117  if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) {
2118  unifi_error(priv, "unifi_siwencode: Request to set an invalid key (length:%d)",
2119  erq->length);
2120  return -EINVAL;
2121  }
2122 
2123  /* Check the index (none (i.e. 0) means use current) */
2124  if ((index < 1) || (index > 4)) {
2125  /* If we do not have a previous key, use 1 as default */
2126  if (!priv->wep_tx_key_index) {
2127  priv->wep_tx_key_index = 1;
2128  }
2129  index = priv->wep_tx_key_index;
2130  }
2131 
2132  /* If we didn't have a key and a valid index is set, we want to remember it*/
2133  if (!priv->wep_tx_key_index) {
2134  priv->wep_tx_key_index = index;
2135  }
2136 
2137  unifi_trace(priv, UDBG1, "Tx key Index is %d\n", priv->wep_tx_key_index);
2138 
2139  privacy = 1;
2140 
2141  /* Check if the key is not marked as invalid */
2142  if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
2143 
2144  unifi_trace(priv, UDBG1, "New %s key (len=%d, index=%d)\n",
2145  (priv->wep_tx_key_index == index) ? "tx" : "",
2146  erq->length, index);
2147 
2148  sme_key.wepTxKey = (priv->wep_tx_key_index == index);
2149  if (priv->wep_tx_key_index == index) {
2151  } else {
2153  }
2154  /* Key index is zero based in SME but 1 based in wext */
2155  sme_key.keyIndex = (index - 1);
2156  sme_key.keyLength = erq->length;
2157  sme_key.authenticator = 0;
2158  memset(sme_key.address.a, 0xFF, ETH_ALEN);
2159  memcpy(sme_key.key, extra, erq->length);
2160 
2161  UF_RTNL_UNLOCK();
2162  rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
2163  UF_RTNL_LOCK();
2164  if (rc) {
2165  unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
2166  return convert_sme_error(rc);
2167  }
2168 
2169  /* Store the key to be reported by the SIOCGIWENCODE handler */
2170  priv->wep_keys[index - 1].len = erq->length;
2171  memcpy(priv->wep_keys[index - 1].key, extra, erq->length);
2172  }
2173  } else {
2174  /*
2175  * No additional key data, so it must be a request to change the
2176  * active key.
2177  */
2178  if (index != 0) {
2179  unifi_trace(priv, UDBG1, "Tx key Index is %d\n", index - 1);
2180 
2181  /* Store the index to be reported by the SIOCGIWENCODE handler */
2182  priv->wep_tx_key_index = index;
2183 
2184  sme_key.wepTxKey = 1;
2186 
2187  /* Key index is zero based in SME but 1 based in wext */
2188  sme_key.keyIndex = (index - 1);
2189  sme_key.keyLength = 0;
2190  sme_key.authenticator = 0;
2191  UF_RTNL_UNLOCK();
2192  rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
2193  UF_RTNL_LOCK();
2194  if (rc) {
2195  unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
2196  return convert_sme_error(rc);
2197  }
2198 
2199  /* Turn on encryption */
2200  privacy = 1;
2201  }
2202  }
2203 
2204  /* Read the flags */
2205  if (erq->flags & IW_ENCODE_DISABLED) {
2206  /* disable encryption */
2207  unifi_trace(priv, UDBG1, "disable WEP encryption\n");
2208  privacy = 0;
2209 
2210  priv->wep_tx_key_index = 0;
2211 
2212  unifi_trace(priv, UDBG1, "IW_ENCODE_DISABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2213  priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
2214  }
2215 
2216  if (erq->flags & IW_ENCODE_RESTRICTED) {
2217  /* Use shared key auth */
2218  unifi_trace(priv, UDBG1, "IW_ENCODE_RESTRICTED: CSR_WIFI_SME_AUTH_MODE_80211_SHARED\n");
2219  priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_SHARED;
2220 
2221  /* Turn on encryption */
2222  privacy = 1;
2223  }
2224  if (erq->flags & IW_ENCODE_OPEN) {
2225  unifi_trace(priv, UDBG1, "IW_ENCODE_OPEN: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2226  priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
2227  }
2228 
2229  /* Commit the changes to flags if needed */
2230  if (privacy != -1) {
2231  priv->connection_config.privacyMode = privacy ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
2232  priv->connection_config.encryptionModeMask = privacy ? (CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 |
2237  }
2238 
2239  func_exit_r(rc);
2240  return convert_sme_error(rc);
2241 
2242 } /* unifi_siwencode() */
2243 
2244 
2245 
2246 static int
2247 unifi_giwencode(struct net_device *dev, struct iw_request_info *info,
2248  union iwreq_data *wrqu, char *extra)
2249 {
2250  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2251  unifi_priv_t *priv = interfacePriv->privPtr;
2252  struct iw_point *erq = &wrqu->encoding;
2253 
2254  unifi_trace(priv, UDBG2, "unifi_giwencode\n");
2255 
2256  CHECK_INITED(priv);
2257 
2258  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2259  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2260  unifi_error(priv, "unifi_giwencode: not permitted in Mode %d\n",
2261  interfacePriv->interfaceMode);
2262  return -EPERM;
2263  }
2264 
2265 
2266  if (priv->connection_config.authModeMask == CSR_WIFI_SME_AUTH_MODE_80211_SHARED) {
2267  erq->flags = IW_ENCODE_RESTRICTED;
2268  }
2269  else {
2270  if (priv->connection_config.privacyMode == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED) {
2271  erq->flags = IW_ENCODE_DISABLED;
2272  } else {
2273  erq->flags = IW_ENCODE_OPEN;
2274  }
2275  }
2276 
2277  erq->length = 0;
2278 
2279  if (erq->flags != IW_ENCODE_DISABLED) {
2280  int index = priv->wep_tx_key_index;
2281 
2282  if ((index > 0) && (index <= NUM_WEPKEYS)) {
2283  erq->flags |= (index & IW_ENCODE_INDEX);
2284  erq->length = priv->wep_keys[index - 1].len;
2285  memcpy(extra, priv->wep_keys[index - 1].key, erq->length);
2286  } else {
2287  unifi_notice(priv, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n",
2288  index);
2289  }
2290  }
2291 
2292  return 0;
2293 } /* unifi_giwencode() */
2294 
2295 
2296 static int
2297 unifi_siwpower(struct net_device *dev, struct iw_request_info *info,
2298  union iwreq_data *wrqu, char *extra)
2299 {
2300  struct iw_param *args = &wrqu->power;
2301  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2302  unifi_priv_t *priv = interfacePriv->privPtr;
2303  int listen_interval, wake_for_dtim;
2304  int r = 0;
2305  CsrWifiSmePowerConfig powerConfig;
2306 
2307  unifi_trace(priv, UDBG2, "unifi_siwpower\n");
2308 
2309  CHECK_INITED(priv);
2310 
2311  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2312  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2313  unifi_error(priv, "unifi_siwpower: not permitted in Mode %d\n",
2314  interfacePriv->interfaceMode);
2315  return -EPERM;
2316  }
2317 
2318  UF_RTNL_UNLOCK();
2319  r = sme_mgt_power_config_get(priv, &powerConfig);
2320  UF_RTNL_LOCK();
2321  if (r) {
2322  unifi_error(priv, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n");
2323  return r;
2324  }
2325 
2326  listen_interval = -1;
2327  wake_for_dtim = -1;
2328  if (args->disabled) {
2330  }
2331  else
2332  {
2334 
2335  switch (args->flags & IW_POWER_TYPE) {
2336  case 0:
2337  /* not specified */
2338  break;
2339  case IW_POWER_PERIOD:
2340  listen_interval = args->value / 1000;
2341  break;
2342  default:
2343  return -EINVAL;
2344  }
2345 
2346  switch (args->flags & IW_POWER_MODE) {
2347  case 0:
2348  /* not specified */
2349  break;
2350  case IW_POWER_UNICAST_R:
2351  /* not interested in broadcast packets */
2352  wake_for_dtim = 0;
2353  break;
2354  case IW_POWER_ALL_R:
2355  /* yes, we are interested in broadcast packets */
2356  wake_for_dtim = 1;
2357  break;
2358  default:
2359  return -EINVAL;
2360  }
2361  }
2362 
2363  if (listen_interval > 0) {
2364  powerConfig.listenIntervalTu = listen_interval;
2365  unifi_trace(priv, UDBG4, "unifi_siwpower: new Listen Interval = %d.\n",
2366  powerConfig.listenIntervalTu);
2367  }
2368 
2369  if (wake_for_dtim >= 0) {
2370  powerConfig.rxDtims = wake_for_dtim;
2371  }
2372  UF_RTNL_UNLOCK();
2373  r = sme_mgt_power_config_set(priv, &powerConfig);
2374  UF_RTNL_LOCK();
2375  if (r) {
2376  unifi_error(priv, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n");
2377  return r;
2378  }
2379 
2380  return 0;
2381 } /* unifi_siwpower() */
2382 
2383 
2384 static int
2385 unifi_giwpower(struct net_device *dev, struct iw_request_info *info,
2386  union iwreq_data *wrqu, char *extra)
2387 {
2388  struct iw_param *args = &wrqu->power;
2389  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2390  unifi_priv_t *priv = interfacePriv->privPtr;
2391  CsrWifiSmePowerConfig powerConfig;
2392  int r;
2393 
2394  unifi_trace(priv, UDBG2, "unifi_giwpower\n");
2395 
2396  CHECK_INITED(priv);
2397 
2398  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2399  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2400  unifi_error(priv, "unifi_giwpower: not permitted in Mode %d\n",
2401  interfacePriv->interfaceMode);
2402  return -EPERM;
2403  }
2404 
2405 
2406  args->flags = 0;
2407  UF_RTNL_UNLOCK();
2408  r = sme_mgt_power_config_get(priv, &powerConfig);
2409  UF_RTNL_LOCK();
2410  if (r) {
2411  unifi_error(priv, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n");
2412  return r;
2413  }
2414 
2415  unifi_trace(priv, UDBG4, "unifi_giwpower: mode=%d\n",
2416  powerConfig.powerSaveLevel);
2417 
2419  if (args->disabled) {
2420  args->flags = 0;
2421  return 0;
2422  }
2423 
2424  args->value = powerConfig.listenIntervalTu * 1000;
2425  args->flags |= IW_POWER_PERIOD;
2426 
2427  if (powerConfig.rxDtims) {
2428  args->flags |= IW_POWER_ALL_R;
2429  } else {
2430  args->flags |= IW_POWER_UNICAST_R;
2431  }
2432 
2433  return 0;
2434 } /* unifi_giwpower() */
2435 
2436 
2437 /*
2438  * ---------------------------------------------------------------------------
2439  * unifi_siwcommit - handler for SIOCSIWCOMMIT
2440  *
2441  * Apply all the parameters that have been set.
2442  * In practice this means:
2443  * - do a scan
2444  * - join a network or start an AdHoc
2445  * - authenticate and associate.
2446  *
2447  * Arguments:
2448  * None.
2449  *
2450  * Returns:
2451  * None.
2452  * ---------------------------------------------------------------------------
2453  */
2454 static int
2455 unifi_siwcommit(struct net_device *dev, struct iw_request_info *info,
2456  union iwreq_data *wrqu, char *extra)
2457 {
2458  return 0;
2459 } /* unifi_siwcommit() */
2460 
2461 
2462 
2463 static int
2464 unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
2465  union iwreq_data *wrqu, char *extra)
2466 {
2467  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2468  unifi_priv_t *priv = interfacePriv->privPtr;
2469  struct iw_mlme *mlme = (struct iw_mlme *)extra;
2470  func_enter();
2471 
2472  unifi_trace(priv, UDBG2, "unifi_siwmlme\n");
2473  CHECK_INITED(priv);
2474 
2475  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2476  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2477  unifi_error(priv, "unifi_siwmlme: not permitted in Mode %d\n",
2478  interfacePriv->interfaceMode);
2479  return -EPERM;
2480  }
2481 
2482 
2483  switch (mlme->cmd) {
2484  case IW_MLME_DEAUTH:
2485  case IW_MLME_DISASSOC:
2486  UF_RTNL_UNLOCK();
2487  sme_mgt_disconnect(priv);
2488  UF_RTNL_LOCK();
2489  break;
2490  default:
2492  return -EOPNOTSUPP;
2493  }
2494 
2495  func_exit();
2496  return 0;
2497 } /* unifi_siwmlme() */
2498 
2499 
2500 /*
2501  * ---------------------------------------------------------------------------
2502  * unifi_siwgenie
2503  * unifi_giwgenie
2504  *
2505  * WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
2506  * Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
2507  *
2508  * The host program (e.g. wpa_supplicant) uses this call to set the
2509  * additional IEs to accompany the next (Associate?) request.
2510  *
2511  * Arguments:
2512  * None.
2513  *
2514  * Returns:
2515  * None.
2516  * Notes:
2517  * From wireless.h:
2518  * This ioctl uses struct iw_point and data buffer that includes IE id
2519  * and len fields. More than one IE may be included in the
2520  * request. Setting the generic IE to empty buffer (len=0) removes the
2521  * generic IE from the driver.
2522  * ---------------------------------------------------------------------------
2523  */
2524 static int
2525 unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
2526  union iwreq_data *wrqu, char *extra)
2527 {
2528  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2529  unifi_priv_t *priv = interfacePriv->privPtr;
2530  int len;
2531 
2532  func_enter();
2533  unifi_trace(priv, UDBG2, "unifi_siwgenie\n");
2534 
2535  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2536  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2537  unifi_error(priv, "unifi_siwgenie: not permitted in Mode %d\n",
2538  interfacePriv->interfaceMode);
2539  return -EPERM;
2540  }
2541 
2542 
2543  if ( priv->connection_config.mlmeAssociateReqInformationElements) {
2544  kfree( priv->connection_config.mlmeAssociateReqInformationElements);
2545  }
2546  priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
2547  priv->connection_config.mlmeAssociateReqInformationElements = NULL;
2548 
2549  len = wrqu->data.length;
2550  if (len == 0) {
2551  func_exit();
2552  return 0;
2553  }
2554 
2555  priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL);
2556  if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) {
2557  func_exit();
2558  return -ENOMEM;
2559  }
2560 
2561  priv->connection_config.mlmeAssociateReqInformationElementsLength = len;
2562  memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len);
2563 
2564  func_exit();
2565  return 0;
2566 } /* unifi_siwgenie() */
2567 
2568 
2569 static int
2570 unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
2571  union iwreq_data *wrqu, char *extra)
2572 {
2573  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2574  unifi_priv_t *priv = interfacePriv->privPtr;
2575  int len;
2576 
2577  func_enter();
2578  unifi_trace(priv, UDBG2, "unifi_giwgenie\n");
2579 
2580  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2581  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2582  unifi_error(priv, "unifi_giwgenie: not permitted in Mode %d\n",
2583  interfacePriv->interfaceMode);
2584  return -EPERM;
2585  }
2586 
2587 
2588  len = priv->connection_config.mlmeAssociateReqInformationElementsLength;
2589 
2590  if (len == 0) {
2591  wrqu->data.length = 0;
2592  return 0;
2593  }
2594 
2595  if (wrqu->data.length < len) {
2596  return -E2BIG;
2597  }
2598 
2599  wrqu->data.length = len;
2600  memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len);
2601 
2602  func_exit();
2603  return 0;
2604 } /* unifi_giwgenie() */
2605 
2606 
2607 /*
2608  * ---------------------------------------------------------------------------
2609  * unifi_siwauth
2610  * unifi_giwauth
2611  *
2612  * Handlers for SIOCSIWAUTH, SIOCGIWAUTH
2613  * Set/get various authentication parameters.
2614  *
2615  * Arguments:
2616  *
2617  *
2618  * Returns:
2619  * None.
2620  * ---------------------------------------------------------------------------
2621  */
2622 static int
2623 _unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
2624  union iwreq_data *wrqu, char *extra)
2625 {
2626  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2627  unifi_priv_t *priv = interfacePriv->privPtr;
2628  CsrWifiSmeAuthModeMask new_auth;
2629 
2630  func_enter();
2631  unifi_trace(priv, UDBG2, "unifi_siwauth\n");
2632 
2633  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2634  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2635  unifi_error(priv, "unifi_siwauth: not permitted in Mode %d\n",
2636  interfacePriv->interfaceMode);
2637  return -EPERM;
2638  }
2639 
2640 
2641  /*
2642  * This ioctl is safe to call even when UniFi is powered off.
2643  * wpa_supplicant calls it to test whether we support WPA.
2644  */
2645 
2646  switch (wrqu->param.flags & IW_AUTH_INDEX) {
2647 
2648  case IW_AUTH_WPA_ENABLED:
2649  unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value);
2650 
2651  if (wrqu->param.value == 0) {
2652  unifi_trace(priv, UDBG5, "IW_AUTH_WPA_ENABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
2653  priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
2654  }
2655  break;
2656 
2658  unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value);
2659 
2660  priv->connection_config.privacyMode = wrqu->param.value ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
2662  {
2663  priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
2664  }
2665  break;
2666 
2668  /*
2669  IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
2670  IW_AUTH_ALG_SHARED_KEY 0x00000002
2671  IW_AUTH_ALG_LEAP 0x00000004
2672  */
2673  new_auth = 0;
2674  if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) {
2675  unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value);
2677  }
2678  if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) {
2679  unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value);
2681  }
2682  if (wrqu->param.value & IW_AUTH_ALG_LEAP) {
2683  /* Initial exchanges using open-system to set EAP */
2684  unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value);
2686  }
2687  if (new_auth == 0) {
2688  unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
2689  wrqu->param.value);
2690  return -EINVAL;
2691  } else {
2692  priv->connection_config.authModeMask = new_auth;
2693  }
2694  break;
2695 
2696  case IW_AUTH_WPA_VERSION:
2697  unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value);
2698  priv->ignore_bssid_join = TRUE;
2699  /*
2700  IW_AUTH_WPA_VERSION_DISABLED 0x00000001
2701  IW_AUTH_WPA_VERSION_WPA 0x00000002
2702  IW_AUTH_WPA_VERSION_WPA2 0x00000004
2703  */
2704 
2705  if (!(wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED)) {
2706 
2707  priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
2708 
2709  if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA) {
2710  unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n");
2711  priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK);
2712  }
2713  if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA2) {
2714  unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n");
2715  priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK);
2716  }
2717  }
2718  break;
2719 
2721  unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value);
2722  /*
2723  * one of:
2724  IW_AUTH_CIPHER_NONE 0x00000001
2725  IW_AUTH_CIPHER_WEP40 0x00000002
2726  IW_AUTH_CIPHER_TKIP 0x00000004
2727  IW_AUTH_CIPHER_CCMP 0x00000008
2728  IW_AUTH_CIPHER_WEP104 0x00000010
2729  */
2730 
2731  priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
2732 
2733  if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
2734  priv->connection_config.encryptionModeMask |=
2736  }
2737  if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
2738  priv->connection_config.encryptionModeMask |=
2740  }
2741  if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
2742  priv->connection_config.encryptionModeMask |=
2744  }
2745  if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
2746  priv->connection_config.encryptionModeMask |=
2748  }
2749 
2750  break;
2751 
2752  case IW_AUTH_CIPHER_GROUP:
2753  unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value);
2754  /*
2755  * Use the WPA version and the group cipher suite to set the permitted
2756  * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
2757  * in the probe responses from the desired BSS(ID)
2758  */
2759 
2760  priv->connection_config.encryptionModeMask &= ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 |
2764  if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
2765  priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40;
2766  }
2767  if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
2768  priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104;
2769  }
2770  if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
2771  priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP;
2772  }
2773  if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
2774  priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP;
2775  }
2776 
2777  break;
2778 
2779  case IW_AUTH_KEY_MGMT:
2780  unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value);
2781  /*
2782  IW_AUTH_KEY_MGMT_802_1X 1
2783  IW_AUTH_KEY_MGMT_PSK 2
2784  */
2785  if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK)) {
2786  /* Check for explicitly set mode. */
2787  if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
2788  priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK;
2789  }
2790  if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
2791  priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA;
2792  }
2793  unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA: %d\n",
2794  priv->connection_config.authModeMask);
2795  }
2796  if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK)) {
2797  /* Check for explicitly set mode. */
2798  if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
2799  priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK;
2800  }
2801  if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
2802  priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2;
2803  }
2804  unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA2: %d\n",
2805  priv->connection_config.authModeMask);
2806  }
2807 
2808  break;
2810  /*
2811  * Set to true at the start of the 60 second backup-off period
2812  * following 2 MichaelMIC failures within 60s.
2813  */
2814  unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value);
2815  break;
2816 
2818  /*
2819  * Set to true on init.
2820  * Set to false just before associate if encryption will not be
2821  * required.
2822  *
2823  * Note this is not the same as the 802.1X controlled port
2824  */
2825  unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value);
2826  break;
2827 
2829  /*
2830  * This is set by wpa_supplicant to allow unencrypted EAPOL messages
2831  * even if pairwise keys are set when not using WPA. IEEE 802.1X
2832  * specifies that these frames are not encrypted, but WPA encrypts
2833  * them when pairwise keys are in use.
2834  * I think the UniFi f/w handles this decision for us.
2835  */
2836  unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value);
2837  break;
2838 
2840  unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value);
2841  break;
2842 
2843  default:
2844  unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n",
2845  wrqu->param.flags & IW_AUTH_INDEX,
2846  wrqu->param.value);
2847  return -EOPNOTSUPP;
2848  }
2849 
2850  unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask);
2851  func_exit();
2852 
2853  return 0;
2854 } /* _unifi_siwauth() */
2855 
2856 
2857 static int
2858 unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
2859  union iwreq_data *wrqu, char *extra)
2860 {
2861  int err = 0;
2862 
2863  UF_RTNL_UNLOCK();
2864  err = _unifi_siwauth(dev, info, wrqu, extra);
2865  UF_RTNL_LOCK();
2866 
2867  return err;
2868 } /* unifi_siwauth() */
2869 
2870 
2871 static int
2872 unifi_giwauth(struct net_device *dev, struct iw_request_info *info,
2873  union iwreq_data *wrqu, char *extra)
2874 {
2875  unifi_trace(NULL, UDBG2, "unifi_giwauth\n");
2876  return -EOPNOTSUPP;
2877 } /* unifi_giwauth() */
2878 
2879 /*
2880  * ---------------------------------------------------------------------------
2881  * unifi_siwencodeext
2882  * unifi_giwencodeext
2883  *
2884  * Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
2885  * encoding token & mode
2886  *
2887  * Arguments:
2888  * None.
2889  *
2890  * Returns:
2891  * None.
2892  *
2893  * Notes:
2894  * For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
2895  * This flag means "use this key to encode transmissions"; we just
2896  * assume only one key will be set and that is the one to use.
2897  * ---------------------------------------------------------------------------
2898  */
2899 static int
2900 _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
2901  union iwreq_data *wrqu, char *extra)
2902 {
2903  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
2904  unifi_priv_t *priv = interfacePriv->privPtr;
2905  struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2906  int r = 0;
2907  unsigned char *keydata;
2908  unsigned char tkip_key[32];
2909  int keyid;
2910  unsigned char *a = (unsigned char *)ext->addr.sa_data;
2911  CsrWifiSmeKey sme_key;
2912  CsrWifiSmeKeyType key_type;
2913 
2914  func_enter();
2915 
2916  CHECK_INITED(priv);
2917 
2918  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
2919  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
2920  unifi_error(priv, "unifi_siwencodeext: not permitted in Mode %d\n",
2921  interfacePriv->interfaceMode);
2922  return -EPERM;
2923  }
2924 
2925 
2926  unifi_trace(priv, UDBG1, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n",
2927  wrqu->encoding.flags, ext->alg, ext->ext_flags,
2928  ext->key_len, (wrqu->encoding.flags & IW_ENCODE_INDEX));
2929  unifi_trace(priv, UDBG3, " addr=%pM\n", a);
2930 
2931  if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
2932  /* This means use a different key (given by key_idx) for Tx. */
2933  /* NYI */
2934  unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n");
2935  return -ENOTSUPP;
2936  }
2937 
2938  memset(&sme_key, 0, sizeof(sme_key));
2939 
2940  keydata = (unsigned char *)(ext + 1);
2941  keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX);
2942 
2943  /*
2944  * Check for request to delete keys for an address.
2945  */
2946  /* Pick out request for no privacy. */
2947  if (ext->alg == IW_ENCODE_ALG_NONE) {
2948 
2949  unifi_trace(priv, UDBG1, "Deleting %s key %d\n",
2950  (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE",
2951  keyid);
2952 
2953  if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2955  } else {
2957  }
2958  sme_key.keyIndex = (keyid - 1);
2959  sme_key.keyLength = 0;
2960  sme_key.authenticator = 0;
2961  memcpy(sme_key.address.a, a, ETH_ALEN);
2962  UF_RTNL_UNLOCK();
2963  r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_REMOVE);
2964  UF_RTNL_LOCK();
2965  if (r) {
2966  unifi_error(priv, "Delete key request was rejected with result %d\n", r);
2967  return convert_sme_error(r);
2968  }
2969 
2970  return 0;
2971  }
2972 
2973  /*
2974  * Request is to set a key, not delete
2975  */
2976 
2977  /* Pick out WEP and use set_wep_key(). */
2978  if (ext->alg == IW_ENCODE_ALG_WEP) {
2979  /* WEP-40, WEP-104 */
2980 
2981  /* Check for valid key length */
2982  if (!((ext->key_len == 5) || (ext->key_len == 13))) {
2983  unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len);
2984  return -EINVAL;
2985  }
2986 
2987  unifi_trace(priv, UDBG1, "Setting WEP key %d tx:%d\n",
2988  keyid, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY);
2989 
2990  if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
2991  sme_key.wepTxKey = TRUE;
2993  } else {
2994  sme_key.wepTxKey = FALSE;
2996  }
2997  sme_key.keyIndex = (keyid - 1);
2998  sme_key.keyLength = ext->key_len;
2999  sme_key.authenticator = 0;
3000  memset(sme_key.address.a, 0xFF, ETH_ALEN);
3001  memcpy(sme_key.key, keydata, ext->key_len);
3002  UF_RTNL_UNLOCK();
3003  r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
3004  UF_RTNL_LOCK();
3005  if (r) {
3006  unifi_error(priv, "siwencodeext: Set key failed (%d)", r);
3007  return convert_sme_error(r);
3008  }
3009 
3010  return 0;
3011  }
3012 
3013  /*
3014  *
3015  * If we reach here, we are dealing with a WPA/WPA2 key
3016  *
3017  */
3018  if (ext->key_len > 32) {
3019  return -EINVAL;
3020  }
3021 
3022  /*
3023  * TKIP keys from wpa_supplicant need swapping.
3024  * What about other supplicants (when they come along)?
3025  */
3026  if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) {
3027  memcpy(tkip_key, keydata, 16);
3028  memcpy(tkip_key + 16, keydata + 24, 8);
3029  memcpy(tkip_key + 24, keydata + 16, 8);
3030  keydata = tkip_key;
3031  }
3032 
3033  key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ?
3034  CSR_WIFI_SME_KEY_TYPE_GROUP : /* Group Key */
3035  CSR_WIFI_SME_KEY_TYPE_PAIRWISE; /* Pairwise Key */
3036 
3037  sme_key.keyType = key_type;
3038  sme_key.keyIndex = (keyid - 1);
3039  sme_key.keyLength = ext->key_len;
3040  sme_key.authenticator = 0;
3041  memcpy(sme_key.address.a, ext->addr.sa_data, ETH_ALEN);
3043 
3044  unifi_trace(priv, UDBG5, "RSC first 6 bytes = %*phC\n",
3045  6, ext->rx_seq);
3046 
3047  /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */
3048  sme_key.keyRsc[0] = ext->rx_seq[1] << 8 | ext->rx_seq[0];
3049  sme_key.keyRsc[1] = ext->rx_seq[3] << 8 | ext->rx_seq[2];
3050  sme_key.keyRsc[2] = ext->rx_seq[5] << 8 | ext->rx_seq[4];
3051  sme_key.keyRsc[3] = ext->rx_seq[7] << 8 | ext->rx_seq[6];
3052 
3053  }
3054 
3055  memcpy(sme_key.key, keydata, ext->key_len);
3056  UF_RTNL_UNLOCK();
3057  r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
3058  UF_RTNL_LOCK();
3059  if (r) {
3060  unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
3061  return convert_sme_error(r);
3062  }
3063 
3064  func_exit();
3065  return r;
3066 } /* _unifi_siwencodeext() */
3067 
3068 
3069 static int
3070 unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
3071  union iwreq_data *wrqu, char *extra)
3072 {
3073  int err = 0;
3074 
3075  err = _unifi_siwencodeext(dev, info, wrqu, extra);
3076 
3077  return err;
3078 } /* unifi_siwencodeext() */
3079 
3080 
3081 static int
3082 unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info,
3083  union iwreq_data *wrqu, char *extra)
3084 {
3085  return -EOPNOTSUPP;
3086 } /* unifi_giwencodeext() */
3087 
3088 
3089 /*
3090  * ---------------------------------------------------------------------------
3091  * unifi_siwpmksa
3092  *
3093  * SIOCSIWPMKSA - PMKSA cache operation
3094  * The caller passes a pmksa structure:
3095  * - cmd one of ADD, REMOVE, FLUSH
3096  * - bssid MAC address
3097  * - pmkid ID string (16 bytes)
3098  *
3099  * Arguments:
3100  * None.
3101  *
3102  * Returns:
3103  * None.
3104  *
3105  * Notes:
3106  * This is not needed since we provide a siwgenie method.
3107  * ---------------------------------------------------------------------------
3108  */
3109 #define UNIFI_PMKID_KEY_SIZE 16
3110 static int
3111 unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info,
3112  union iwreq_data *wrqu, char *extra)
3113 {
3114  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
3115  unifi_priv_t *priv = interfacePriv->privPtr;
3116  struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
3117  CsrResult r = 0;
3121 
3122  CHECK_INITED(priv);
3123 
3124  if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
3125  interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
3126  unifi_error(priv, "unifi_siwpmksa: not permitted in Mode %d\n",
3127  interfacePriv->interfaceMode);
3128  return -EPERM;
3129  }
3130 
3131 
3132  unifi_trace(priv, UDBG1, "SIWPMKSA: cmd %d, %pM\n", pmksa->cmd,
3133  pmksa->bssid.sa_data);
3134 
3135  pmkid_list.pmkids = NULL;
3136  switch (pmksa->cmd) {
3137  case IW_PMKSA_ADD:
3138  pmkid_list.pmkids = &pmkid;
3140  pmkid_list.pmkidsCount = 1;
3141  memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
3142  memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
3143  break;
3144  case IW_PMKSA_REMOVE:
3145  pmkid_list.pmkids = &pmkid;
3147  pmkid_list.pmkidsCount = 1;
3148  memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
3149  memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
3150  break;
3151  case IW_PMKSA_FLUSH:
3152  /* Replace current PMKID's with an empty list */
3153  pmkid_list.pmkidsCount = 0;
3155  break;
3156  default:
3157  unifi_notice(priv, "SIWPMKSA: Unknown command (0x%x)\n", pmksa->cmd);
3158  return -EINVAL;
3159  }
3160 
3161  /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */
3162  UF_RTNL_UNLOCK();
3163  r = sme_mgt_pmkid(priv, action, &pmkid_list);
3164  UF_RTNL_LOCK();
3165  if (r) {
3166  unifi_error(priv, "SIWPMKSA: Set PMKID's Failed.\n");
3167  }
3168 
3169  return r;
3170 
3171 } /* unifi_siwpmksa() */
3172 
3173 
3174 /*
3175  * ---------------------------------------------------------------------------
3176  * unifi_get_wireless_stats
3177  *
3178  * get_wireless_stats method for Linux wireless extensions.
3179  *
3180  * Arguments:
3181  * dev Pointer to associated netdevice.
3182  *
3183  * Returns:
3184  * Pointer to iw_statistics struct.
3185  * ---------------------------------------------------------------------------
3186  */
3187 struct iw_statistics *
3189 {
3190  netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
3191  unifi_priv_t *priv = interfacePriv->privPtr;
3192 
3193  if (priv->init_progress != UNIFI_INIT_COMPLETED) {
3194  return NULL;
3195  }
3196 
3197  return &priv->wext_wireless_stats;
3198 } /* unifi_get_wireless_stats() */
3199 
3200 
3201 /*
3202  * Structures to export the Wireless Handlers
3203  */
3204 
3205 static const struct iw_priv_args unifi_private_args[] = {
3206  /*{ cmd, set_args, get_args, name } */
3208  IW_PRIV_TYPE_NONE, "iwprivs80211ps" },
3212  IW_PRIV_TYPE_NONE, "iwprivsdefs" },
3214 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3216  IW_PRIV_TYPE_NONE, "iwprivsconfwapi" },
3218  IW_PRIV_TYPE_NONE, "iwprivswpikey" },
3219 #endif
3220 #ifdef CSR_SUPPORT_WEXT_AP
3221  { SIOCIWSAPCFGPRIV, IW_PRIV_TYPE_CHAR | 256, IW_PRIV_TYPE_NONE, "AP_SET_CFG" },
3224  IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "AP_BSS_STOP" },
3225 #ifdef ANDROID_BUILD
3227  IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "WL_FW_RELOAD" },
3228  { SIOCIWSSTACKSTART, 0,
3230  { SIOCIWSSTACKSTOP, 0,
3232 #endif /* ANDROID_BUILD */
3233 #endif /* CSR_SUPPORT_WEXT_AP */
3234 };
3235 
3236 static const iw_handler unifi_handler[] =
3237 {
3238  (iw_handler) unifi_siwcommit, /* SIOCSIWCOMMIT */
3239  (iw_handler) unifi_giwname, /* SIOCGIWNAME */
3240  (iw_handler) NULL, /* SIOCSIWNWID */
3241  (iw_handler) NULL, /* SIOCGIWNWID */
3242  (iw_handler) unifi_siwfreq, /* SIOCSIWFREQ */
3243  (iw_handler) unifi_giwfreq, /* SIOCGIWFREQ */
3244  (iw_handler) unifi_siwmode, /* SIOCSIWMODE */
3245  (iw_handler) unifi_giwmode, /* SIOCGIWMODE */
3246  (iw_handler) NULL, /* SIOCSIWSENS */
3247  (iw_handler) NULL, /* SIOCGIWSENS */
3248  (iw_handler) NULL, /* SIOCSIWRANGE */
3249  (iw_handler) unifi_giwrange, /* SIOCGIWRANGE */
3250  (iw_handler) NULL, /* SIOCSIWPRIV */
3251  (iw_handler) NULL, /* SIOCGIWPRIV */
3252  (iw_handler) NULL, /* SIOCSIWSTATS */
3253  (iw_handler) NULL, /* SIOCGIWSTATS */
3254  (iw_handler) NULL, /* SIOCSIWSPY */
3255  (iw_handler) NULL, /* SIOCGIWSPY */
3256  (iw_handler) NULL, /* SIOCSIWTHRSPY */
3257  (iw_handler) NULL, /* SIOCGIWTHRSPY */
3258  (iw_handler) unifi_siwap, /* SIOCSIWAP */
3259  (iw_handler) unifi_giwap, /* SIOCGIWAP */
3260 #if WIRELESS_EXT > 17
3261  /* WPA : IEEE 802.11 MLME requests */
3262  unifi_siwmlme, /* SIOCSIWMLME, request MLME operation */
3263 #else
3264  (iw_handler) NULL, /* -- hole -- */
3265 #endif
3266  (iw_handler) NULL, /* SIOCGIWAPLIST */
3267  (iw_handler) unifi_siwscan, /* SIOCSIWSCAN */
3268  (iw_handler) unifi_giwscan, /* SIOCGIWSCAN */
3269  (iw_handler) unifi_siwessid, /* SIOCSIWESSID */
3270  (iw_handler) unifi_giwessid, /* SIOCGIWESSID */
3271  (iw_handler) NULL, /* SIOCSIWNICKN */
3272  (iw_handler) NULL, /* SIOCGIWNICKN */
3273  (iw_handler) NULL, /* -- hole -- */
3274  (iw_handler) NULL, /* -- hole -- */
3275  unifi_siwrate, /* SIOCSIWRATE */
3276  unifi_giwrate, /* SIOCGIWRATE */
3277  unifi_siwrts, /* SIOCSIWRTS */
3278  unifi_giwrts, /* SIOCGIWRTS */
3279  unifi_siwfrag, /* SIOCSIWFRAG */
3280  unifi_giwfrag, /* SIOCGIWFRAG */
3281  (iw_handler) NULL, /* SIOCSIWTXPOW */
3282  (iw_handler) NULL, /* SIOCGIWTXPOW */
3283  (iw_handler) NULL, /* SIOCSIWRETRY */
3284  (iw_handler) NULL, /* SIOCGIWRETRY */
3285  unifi_siwencode, /* SIOCSIWENCODE */
3286  unifi_giwencode, /* SIOCGIWENCODE */
3287  unifi_siwpower, /* SIOCSIWPOWER */
3288  unifi_giwpower, /* SIOCGIWPOWER */
3289 #if WIRELESS_EXT > 17
3290  (iw_handler) NULL, /* -- hole -- */
3291  (iw_handler) NULL, /* -- hole -- */
3292 
3293  /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
3294  unifi_siwgenie, /* SIOCSIWGENIE */ /* set generic IE */
3295  unifi_giwgenie, /* SIOCGIWGENIE */ /* get generic IE */
3296 
3297  /* WPA : Authentication mode parameters */
3298  unifi_siwauth, /* SIOCSIWAUTH */ /* set authentication mode params */
3299  unifi_giwauth, /* SIOCGIWAUTH */ /* get authentication mode params */
3300 
3301  /* WPA : Extended version of encoding configuration */
3302  unifi_siwencodeext, /* SIOCSIWENCODEEXT */ /* set encoding token & mode */
3303  unifi_giwencodeext, /* SIOCGIWENCODEEXT */ /* get encoding token & mode */
3304 
3305  /* WPA2 : PMKSA cache management */
3306  unifi_siwpmksa, /* SIOCSIWPMKSA */ /* PMKSA cache operation */
3307  (iw_handler) NULL, /* -- hole -- */
3308 #endif /* WIRELESS_EXT > 17 */
3309 };
3310 
3311 
3312 static const iw_handler unifi_private_handler[] =
3313 {
3314  iwprivs80211ps, /* SIOCIWFIRSTPRIV */
3315  iwprivg80211ps, /* SIOCIWFIRSTPRIV + 1 */
3316  iwprivsdefs, /* SIOCIWFIRSTPRIV + 2 */
3317  (iw_handler) NULL,
3318 #ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3319  iwprivsconfwapi, /* SIOCIWFIRSTPRIV + 4 */
3320  (iw_handler) NULL, /* SIOCIWFIRSTPRIV + 5 */
3321  iwprivswpikey, /* SIOCIWFIRSTPRIV + 6 */
3322 #else
3323  (iw_handler) NULL,
3324  (iw_handler) NULL,
3325  (iw_handler) NULL,
3326 #endif
3327  (iw_handler) NULL,
3328  iwprivssmedebug, /* SIOCIWFIRSTPRIV + 8 */
3329 #ifdef CSR_SUPPORT_WEXT_AP
3330  (iw_handler) NULL,
3331  iwprivsapconfig,
3332  (iw_handler) NULL,
3333  iwprivsapstart,
3334  (iw_handler) NULL,
3335  iwprivsapstop,
3336  (iw_handler) NULL,
3337 #ifdef ANDROID_BUILD
3338  iwprivsapfwreload,
3339  (iw_handler) NULL,
3340  iwprivsstackstart,
3341  (iw_handler) NULL,
3342  iwprivsstackstop,
3343 #else
3344  (iw_handler) NULL,
3345  (iw_handler) NULL,
3346  (iw_handler) NULL,
3347  (iw_handler) NULL,
3348  (iw_handler) NULL,
3349 #endif /* ANDROID_BUILD */
3350 #else
3351  (iw_handler) NULL,
3352  (iw_handler) NULL,
3353  (iw_handler) NULL,
3354  (iw_handler) NULL,
3355  (iw_handler) NULL,
3356  (iw_handler) NULL,
3357  (iw_handler) NULL,
3358  (iw_handler) NULL,
3359  (iw_handler) NULL,
3360  (iw_handler) NULL,
3361  (iw_handler) NULL,
3362  (iw_handler) NULL,
3363 #endif /* CSR_SUPPORT_WEXT_AP */
3364 };
3365 
3367 {
3368  .num_standard = sizeof(unifi_handler) / sizeof(iw_handler),
3369  .num_private = sizeof(unifi_private_handler) / sizeof(iw_handler),
3370  .num_private_args = sizeof(unifi_private_args) / sizeof(struct iw_priv_args),
3371  .standard = (iw_handler *) unifi_handler,
3372  .private = (iw_handler *) unifi_private_handler,
3373  .private_args = (struct iw_priv_args *) unifi_private_args,
3374 #if IW_HANDLER_VERSION >= 6
3376 #endif
3377 };
3378 
3379