root/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. indicate_wx_scan_complete_event
  2. rtw_indicate_wx_assoc_event
  3. rtw_indicate_wx_disassoc_event
  4. translate_scan
  5. wpa_set_auth_algs
  6. wpa_set_encryption
  7. rtw_set_wpa_ie
  8. rtw_wx_get_name
  9. rtw_wx_set_freq
  10. rtw_wx_get_freq
  11. rtw_wx_set_mode
  12. rtw_wx_get_mode
  13. rtw_wx_set_pmkid
  14. rtw_wx_get_sens
  15. rtw_wx_get_range
  16. rtw_wx_set_wap
  17. rtw_wx_get_wap
  18. rtw_wx_set_mlme
  19. rtw_wx_set_scan
  20. rtw_wx_get_scan
  21. rtw_wx_set_essid
  22. rtw_wx_get_essid
  23. rtw_wx_set_rate
  24. rtw_wx_get_rate
  25. rtw_wx_set_rts
  26. rtw_wx_get_rts
  27. rtw_wx_set_frag
  28. rtw_wx_get_frag
  29. rtw_wx_get_retry
  30. rtw_wx_set_enc
  31. rtw_wx_get_enc
  32. rtw_wx_get_power
  33. rtw_wx_set_gen_ie
  34. rtw_wx_set_auth
  35. rtw_wx_set_enc_ext
  36. rtw_wx_get_nick
  37. dummy
  38. wpa_set_param
  39. wpa_mlme
  40. wpa_supplicant_ioctl
  41. set_pairwise_key
  42. set_group_key
  43. set_wep_key
  44. rtw_set_encryption
  45. rtw_set_beacon
  46. rtw_hostapd_sta_flush
  47. rtw_add_sta
  48. rtw_del_sta
  49. rtw_ioctl_get_sta_data
  50. rtw_get_sta_wpaie
  51. rtw_set_wps_beacon
  52. rtw_set_wps_probe_resp
  53. rtw_set_wps_assoc_resp
  54. rtw_set_hidden_ssid
  55. rtw_ioctl_acl_remove_sta
  56. rtw_ioctl_acl_add_sta
  57. rtw_ioctl_set_macaddr_acl
  58. rtw_hostapd_ioctl
  59. rtw_wx_set_priv
  60. rtw_get_wireless_stats
  61. rtw_ioctl

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 #define _IOCTL_LINUX_C_
   8 
   9 #include <linux/ieee80211.h>
  10 
  11 #include <osdep_service.h>
  12 #include <drv_types.h>
  13 #include <wlan_bssdef.h>
  14 #include <rtw_debug.h>
  15 #include <wifi.h>
  16 #include <rtw_mlme.h>
  17 #include <rtw_mlme_ext.h>
  18 #include <rtw_ioctl.h>
  19 #include <rtw_ioctl_set.h>
  20 #include <rtl8188e_hal.h>
  21 
  22 #include <linux/vmalloc.h>
  23 #include <linux/etherdevice.h>
  24 
  25 #include "osdep_intf.h"
  26 
  27 #define RTL_IOCTL_WPA_SUPPLICANT        (SIOCIWFIRSTPRIV + 30)
  28 
  29 #define SCAN_ITEM_SIZE 768
  30 #define MAX_CUSTOM_LEN 64
  31 #define RATE_COUNT 4
  32 
  33 /*  combo scan */
  34 #define WEXT_CSCAN_AMOUNT 9
  35 #define WEXT_CSCAN_BUF_LEN              360
  36 #define WEXT_CSCAN_HEADER               "CSCAN S\x01\x00\x00S\x00"
  37 #define WEXT_CSCAN_HEADER_SIZE          12
  38 #define WEXT_CSCAN_SSID_SECTION         'S'
  39 #define WEXT_CSCAN_CHANNEL_SECTION      'C'
  40 #define WEXT_CSCAN_NPROBE_SECTION       'N'
  41 #define WEXT_CSCAN_ACTV_DWELL_SECTION   'A'
  42 #define WEXT_CSCAN_PASV_DWELL_SECTION   'P'
  43 #define WEXT_CSCAN_HOME_DWELL_SECTION   'H'
  44 #define WEXT_CSCAN_TYPE_SECTION         'T'
  45 
  46 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
  47         6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
  48         48000000, 54000000};
  49 
  50 static const char * const iw_operation_mode[] = {
  51         "Auto", "Ad-Hoc", "Managed",  "Master", "Repeater",
  52         "Secondary", "Monitor"
  53 };
  54 
  55 void indicate_wx_scan_complete_event(struct adapter *padapter)
  56 {
  57         union iwreq_data wrqu;
  58 
  59         memset(&wrqu, 0, sizeof(union iwreq_data));
  60         wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
  61 }
  62 
  63 void rtw_indicate_wx_assoc_event(struct adapter *padapter)
  64 {
  65         union iwreq_data wrqu;
  66         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
  67 
  68         memset(&wrqu, 0, sizeof(union iwreq_data));
  69 
  70         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
  71 
  72         memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
  73 
  74         DBG_88E_LEVEL(_drv_always_, "assoc success\n");
  75         wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
  76 }
  77 
  78 void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
  79 {
  80         union iwreq_data wrqu;
  81 
  82         memset(&wrqu, 0, sizeof(union iwreq_data));
  83 
  84         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
  85         eth_zero_addr(wrqu.ap_addr.sa_data);
  86 
  87         DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n");
  88         wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
  89 }
  90 
  91 static char *translate_scan(struct adapter *padapter,
  92                             struct iw_request_info *info,
  93                             struct wlan_network *pnetwork,
  94                             char *start, char *stop)
  95 {
  96         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  97         struct iw_event iwe;
  98         u16 cap;
  99         __le16 le_tmp;
 100         u32 ht_ielen = 0;
 101         char custom[MAX_CUSTOM_LEN];
 102         char *p;
 103         u16 max_rate = 0, rate, ht_cap = false;
 104         u32 i = 0;
 105         u8 bw_40MHz = 0, short_GI = 0;
 106         u16 mcs_rate = 0;
 107         u8 ss, sq;
 108 
 109         /*  AP MAC address  */
 110         iwe.cmd = SIOCGIWAP;
 111         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 112 
 113         memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
 114         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
 115 
 116         /* Add the ESSID */
 117         iwe.cmd = SIOCGIWESSID;
 118         iwe.u.data.flags = 1;
 119         iwe.u.data.length = min_t(u16, pnetwork->network.ssid.ssid_length, 32);
 120         start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid);
 121 
 122         /* parsing HT_CAP_IE */
 123         p = rtw_get_ie(&pnetwork->network.ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.ie_length-12);
 124 
 125         if (p && ht_ielen > 0) {
 126                 struct ieee80211_ht_cap *pht_capie;
 127                 ht_cap = true;
 128 
 129                 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
 130                 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
 131                 bw_40MHz = !!(le16_to_cpu(pht_capie->cap_info) &
 132                               IEEE80211_HT_CAP_SUP_WIDTH);
 133                 short_GI = !!(le16_to_cpu(pht_capie->cap_info) &
 134                               (IEEE80211_HT_CAP_SGI_20 |
 135                                IEEE80211_HT_CAP_SGI_40));
 136         }
 137 
 138         /* Add the protocol name */
 139         iwe.cmd = SIOCGIWNAME;
 140         if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
 141                 if (ht_cap)
 142                         snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
 143                 else
 144                         snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
 145         } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
 146                 if (ht_cap)
 147                         snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
 148                 else
 149                         snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
 150         } else {
 151                 if (pnetwork->network.Configuration.DSConfig > 14) {
 152                         if (ht_cap)
 153                                 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
 154                         else
 155                                 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
 156                 } else {
 157                         if (ht_cap)
 158                                 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
 159                         else
 160                                 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
 161                 }
 162         }
 163 
 164         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
 165 
 166           /* Add mode */
 167         iwe.cmd = SIOCGIWMODE;
 168         memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.ies), 2);
 169 
 170         cap = le16_to_cpu(le_tmp);
 171 
 172         if (!WLAN_CAPABILITY_IS_STA_BSS(cap)) {
 173                 if (cap & WLAN_CAPABILITY_ESS)
 174                         iwe.u.mode = IW_MODE_MASTER;
 175                 else
 176                         iwe.u.mode = IW_MODE_ADHOC;
 177 
 178                 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
 179         }
 180 
 181         if (pnetwork->network.Configuration.DSConfig < 1)
 182                 pnetwork->network.Configuration.DSConfig = 1;
 183 
 184          /* Add frequency/channel */
 185         iwe.cmd = SIOCGIWFREQ;
 186         iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
 187         iwe.u.freq.e = 1;
 188         iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
 189         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
 190 
 191         /* Add encryption capability */
 192         iwe.cmd = SIOCGIWENCODE;
 193         if (cap & WLAN_CAPABILITY_PRIVACY)
 194                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 195         else
 196                 iwe.u.data.flags = IW_ENCODE_DISABLED;
 197         iwe.u.data.length = 0;
 198         start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid);
 199 
 200         /*Add basic and extended rates */
 201         max_rate = 0;
 202         p = custom;
 203         p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
 204         while (pnetwork->network.SupportedRates[i] != 0) {
 205                 rate = pnetwork->network.SupportedRates[i]&0x7F;
 206                 if (rate > max_rate)
 207                         max_rate = rate;
 208                 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
 209                               "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
 210                 i++;
 211         }
 212 
 213         if (ht_cap) {
 214                 if (mcs_rate&0x8000)/* MCS15 */
 215                         max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
 216                 else if (mcs_rate&0x0080)/* MCS7 */
 217                         ;
 218                 else/* default MCS7 */
 219                         max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
 220 
 221                 max_rate = max_rate*2;/* Mbps/2; */
 222         }
 223 
 224         iwe.cmd = SIOCGIWRATE;
 225         iwe.u.bitrate.fixed = 0;
 226         iwe.u.bitrate.disabled = 0;
 227         iwe.u.bitrate.value = max_rate * 500000;
 228         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
 229 
 230         /* parsing WPA/WPA2 IE */
 231         {
 232                 u8 *buf;
 233                 u8 wpa_ie[255], rsn_ie[255];
 234                 u16 wpa_len = 0, rsn_len = 0;
 235                 u8 *p;
 236 
 237                 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
 238                 if (!buf)
 239                         return start;
 240 
 241                 rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
 242                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.ssid.ssid));
 243                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
 244 
 245                 if (wpa_len > 0) {
 246                         p = buf;
 247                         p += sprintf(p, "wpa_ie=");
 248                         for (i = 0; i < wpa_len; i++)
 249                                 p += sprintf(p, "%02x", wpa_ie[i]);
 250 
 251                         memset(&iwe, 0, sizeof(iwe));
 252                         iwe.cmd = IWEVCUSTOM;
 253                         iwe.u.data.length = strlen(buf);
 254                         start = iwe_stream_add_point(info, start, stop, &iwe, buf);
 255 
 256                         memset(&iwe, 0, sizeof(iwe));
 257                         iwe.cmd = IWEVGENIE;
 258                         iwe.u.data.length = wpa_len;
 259                         start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
 260                 }
 261                 if (rsn_len > 0) {
 262                         p = buf;
 263                         p += sprintf(p, "rsn_ie=");
 264                         for (i = 0; i < rsn_len; i++)
 265                                 p += sprintf(p, "%02x", rsn_ie[i]);
 266                         memset(&iwe, 0, sizeof(iwe));
 267                         iwe.cmd = IWEVCUSTOM;
 268                         iwe.u.data.length = strlen(buf);
 269                         start = iwe_stream_add_point(info, start, stop, &iwe, buf);
 270 
 271                         memset(&iwe, 0, sizeof(iwe));
 272                         iwe.cmd = IWEVGENIE;
 273                         iwe.u.data.length = rsn_len;
 274                         start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
 275                 }
 276                 kfree(buf);
 277         }
 278 
 279         {/* parsing WPS IE */
 280                 uint cnt = 0, total_ielen;
 281                 u8 *wpsie_ptr = NULL;
 282                 uint wps_ielen = 0;
 283                 u8 *ie_ptr = pnetwork->network.ies + _FIXED_IE_LENGTH_;
 284 
 285                 total_ielen = pnetwork->network.ie_length - _FIXED_IE_LENGTH_;
 286 
 287                 while (cnt < total_ielen) {
 288                         if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
 289                                 wpsie_ptr = &ie_ptr[cnt];
 290                                 iwe.cmd = IWEVGENIE;
 291                                 iwe.u.data.length = (u16)wps_ielen;
 292                                 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
 293                         }
 294                         cnt += ie_ptr[cnt+1]+2; /* goto next */
 295                 }
 296         }
 297 
 298         /* Add quality statistics */
 299         iwe.cmd = IWEVQUAL;
 300         iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
 301 
 302         if (check_fwstate(pmlmepriv, _FW_LINKED) &&
 303             is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
 304                 ss = padapter->recvpriv.signal_strength;
 305                 sq = padapter->recvpriv.signal_qual;
 306         } else {
 307                 ss = pnetwork->network.PhyInfo.SignalStrength;
 308                 sq = pnetwork->network.PhyInfo.SignalQuality;
 309         }
 310 
 311         iwe.u.qual.level = (u8)ss;
 312         iwe.u.qual.qual = (u8)sq;   /*  signal quality */
 313         iwe.u.qual.noise = 0; /*  noise level */
 314         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
 315         return start;
 316 }
 317 
 318 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
 319 {
 320         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 321         int ret = 0;
 322 
 323         if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
 324                 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and  AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
 325                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 326                 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
 327                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
 328         } else if (value & AUTH_ALG_SHARED_KEY) {
 329                 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY  [value:0x%x]\n", value);
 330                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 331 
 332                 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
 333                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
 334         } else if (value & AUTH_ALG_OPEN_SYSTEM) {
 335                 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
 336                 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
 337                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
 338                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
 339                 }
 340         } else if (value & AUTH_ALG_LEAP) {
 341                 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
 342         } else {
 343                 DBG_88E("wpa_set_auth_algs, error!\n");
 344                 ret = -EINVAL;
 345         }
 346         return ret;
 347 }
 348 
 349 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
 350 {
 351         int ret = 0;
 352         u32 wep_key_idx, wep_key_len, wep_total_len;
 353         struct ndis_802_11_wep   *pwep = NULL;
 354         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 355         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 356         struct security_priv *psecuritypriv = &padapter->securitypriv;
 357 
 358         param->u.crypt.err = 0;
 359         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
 360 
 361         if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
 362                 ret =  -EINVAL;
 363                 goto exit;
 364         }
 365 
 366         if (is_broadcast_ether_addr(param->sta_addr)) {
 367                 if (param->u.crypt.idx >= WEP_KEYS) {
 368                         ret = -EINVAL;
 369                         goto exit;
 370                 }
 371         } else {
 372                 ret = -EINVAL;
 373                 goto exit;
 374         }
 375 
 376         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
 377                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
 378                 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
 379 
 380                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 381                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
 382                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
 383 
 384                 wep_key_idx = param->u.crypt.idx;
 385                 wep_key_len = param->u.crypt.key_len;
 386 
 387                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(1)wep_key_idx =%d\n", wep_key_idx));
 388                 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx);
 389 
 390                 if (wep_key_idx > WEP_KEYS)
 391                         return -EINVAL;
 392 
 393                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx));
 394 
 395                 if (wep_key_len > 0) {
 396                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
 397                         wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
 398                         pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
 399                         if (!pwep) {
 400                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
 401                                 goto exit;
 402                         }
 403                         memset(pwep, 0, wep_total_len);
 404                         pwep->KeyLength = wep_key_len;
 405                         pwep->Length = wep_total_len;
 406                         if (wep_key_len == 13) {
 407                                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
 408                                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
 409                         }
 410                 } else {
 411                         ret = -EINVAL;
 412                         goto exit;
 413                 }
 414                 pwep->KeyIndex = wep_key_idx;
 415                 pwep->KeyIndex |= 0x80000000;
 416                 memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
 417                 if (param->u.crypt.set_tx) {
 418                         DBG_88E("wep, set_tx = 1\n");
 419                         if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
 420                                 ret = -EOPNOTSUPP;
 421                 } else {
 422                         DBG_88E("wep, set_tx = 0\n");
 423                         if (wep_key_idx >= WEP_KEYS) {
 424                                 ret = -EOPNOTSUPP;
 425                                 goto exit;
 426                         }
 427                         memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
 428                         psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
 429                         rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
 430                 }
 431                 goto exit;
 432         }
 433 
 434         if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
 435                 struct sta_info *psta, *pbcmc_sta;
 436                 struct sta_priv *pstapriv = &padapter->stapriv;
 437 
 438                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { /* sta mode */
 439                         psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
 440                         if (!psta) {
 441                                 ;
 442                         } else {
 443                                 if (strcmp(param->u.crypt.alg, "none") != 0)
 444                                         psta->ieee8021x_blocked = false;
 445 
 446                                 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
 447                                     (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
 448                                         psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
 449 
 450                                 if (param->u.crypt.set_tx == 1) { /* pairwise key */
 451                                         memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
 452 
 453                                         if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
 454                                                 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
 455                                                 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
 456                                                 padapter->securitypriv.busetkipkey = false;
 457                                         }
 458 
 459                                         DBG_88E(" ~~~~set sta key:unicastkey\n");
 460 
 461                                         rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
 462                                 } else { /* group key */
 463                                         memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16 ));
 464                                         memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
 465                                         memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
 466                                         padapter->securitypriv.binstallGrpkey = true;
 467                                         DBG_88E(" ~~~~set sta key:groupkey\n");
 468 
 469                                         padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
 470 
 471                                         rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
 472                                 }
 473                         }
 474                         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
 475                         if (!pbcmc_sta) {
 476                                 ;
 477                         } else {
 478                                 /* Jeff: don't disable ieee8021x_blocked while clearing key */
 479                                 if (strcmp(param->u.crypt.alg, "none") != 0)
 480                                         pbcmc_sta->ieee8021x_blocked = false;
 481 
 482                                 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
 483                                     (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
 484                                         pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
 485                         }
 486                 }
 487         }
 488 
 489 exit:
 490 
 491         kfree(pwep);
 492         return ret;
 493 }
 494 
 495 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
 496 {
 497         u8 *buf = NULL;
 498         int group_cipher = 0, pairwise_cipher = 0;
 499         int ret = 0;
 500 
 501         if ((ielen > MAX_WPA_IE_LEN) || (!pie)) {
 502                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
 503                 if (!pie)
 504                         return ret;
 505                 else
 506                         return -EINVAL;
 507         }
 508 
 509         if (ielen) {
 510                 buf = kmemdup(pie, ielen, GFP_KERNEL);
 511                 if (!buf) {
 512                         ret =  -ENOMEM;
 513                         goto exit;
 514                 }
 515 
 516                 /* dump */
 517                 {
 518                         int i;
 519 
 520                         DBG_88E("\n wpa_ie(length:%d):\n", ielen);
 521                         for (i = 0; i < ielen; i += 8)
 522                                 DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
 523                 }
 524 
 525                 if (ielen < RSN_HEADER_LEN) {
 526                         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
 527                         ret  = -1;
 528                         goto exit;
 529                 }
 530 
 531                 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
 532                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
 533                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
 534                         memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
 535                 }
 536 
 537                 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
 538                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
 539                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
 540                         memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
 541                 }
 542 
 543                 switch (group_cipher) {
 544                 case WPA_CIPHER_NONE:
 545                         padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
 546                         padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
 547                         break;
 548                 case WPA_CIPHER_WEP40:
 549                         padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
 550                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 551                         break;
 552                 case WPA_CIPHER_TKIP:
 553                         padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
 554                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
 555                         break;
 556                 case WPA_CIPHER_CCMP:
 557                         padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
 558                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
 559                         break;
 560                 case WPA_CIPHER_WEP104:
 561                         padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
 562                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 563                         break;
 564                 }
 565 
 566                 switch (pairwise_cipher) {
 567                 case WPA_CIPHER_NONE:
 568                         padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
 569                         padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
 570                         break;
 571                 case WPA_CIPHER_WEP40:
 572                         padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
 573                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 574                         break;
 575                 case WPA_CIPHER_TKIP:
 576                         padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
 577                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
 578                         break;
 579                 case WPA_CIPHER_CCMP:
 580                         padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
 581                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
 582                         break;
 583                 case WPA_CIPHER_WEP104:
 584                         padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
 585                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
 586                         break;
 587                 }
 588 
 589                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
 590                 {/* set wps_ie */
 591                         u16 cnt = 0;
 592                         u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
 593 
 594                         while (cnt < ielen) {
 595                                 eid = buf[cnt];
 596                                 if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
 597                                         DBG_88E("SET WPS_IE\n");
 598 
 599                                         padapter->securitypriv.wps_ie_len = min(buf[cnt + 1] + 2, MAX_WPA_IE_LEN << 2);
 600 
 601                                         memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
 602 
 603                                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
 604                                         cnt += buf[cnt+1]+2;
 605                                         break;
 606                                 } else {
 607                                         cnt += buf[cnt+1]+2; /* goto next */
 608                                 }
 609                         }
 610                 }
 611         }
 612 
 613         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
 614                  ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
 615                  pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
 616 exit:
 617         kfree(buf);
 618         return ret;
 619 }
 620 
 621 typedef unsigned char   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
 622 
 623 static int rtw_wx_get_name(struct net_device *dev,
 624                              struct iw_request_info *info,
 625                              union iwreq_data *wrqu, char *extra)
 626 {
 627         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 628         u32 ht_ielen = 0;
 629         char *p;
 630         u8 ht_cap = false;
 631         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
 632         struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 633         NDIS_802_11_RATES_EX *prates = NULL;
 634 
 635         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code =%x\n", info->cmd));
 636 
 637         if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
 638                 /* parsing HT_CAP_IE */
 639                 p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->ie_length-12);
 640                 if (p && ht_ielen > 0)
 641                         ht_cap = true;
 642 
 643                 prates = &pcur_bss->SupportedRates;
 644 
 645                 if (rtw_is_cckratesonly_included((u8 *)prates)) {
 646                         if (ht_cap)
 647                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
 648                         else
 649                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
 650                 } else if (rtw_is_cckrates_included((u8 *)prates)) {
 651                         if (ht_cap)
 652                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
 653                         else
 654                                 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
 655                 } else {
 656                         if (pcur_bss->Configuration.DSConfig > 14) {
 657                                 if (ht_cap)
 658                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
 659                                 else
 660                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
 661                         } else {
 662                                 if (ht_cap)
 663                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
 664                                 else
 665                                         snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
 666                         }
 667                 }
 668         } else {
 669                 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
 670         }
 671         return 0;
 672 }
 673 
 674 static int rtw_wx_set_freq(struct net_device *dev,
 675                              struct iw_request_info *info,
 676                              union iwreq_data *wrqu, char *extra)
 677 {
 678         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
 679         return 0;
 680 }
 681 
 682 static int rtw_wx_get_freq(struct net_device *dev,
 683                              struct iw_request_info *info,
 684                              union iwreq_data *wrqu, char *extra)
 685 {
 686         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 687         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
 688         struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 689 
 690         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 691                 /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
 692                 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
 693                 wrqu->freq.e = 1;
 694                 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
 695         } else {
 696                 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
 697                 wrqu->freq.e = 1;
 698                 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
 699         }
 700 
 701         return 0;
 702 }
 703 
 704 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
 705                              union iwreq_data *wrqu, char *b)
 706 {
 707         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 708         enum ndis_802_11_network_infra networkType;
 709         int ret = 0;
 710 
 711         if (_FAIL == rtw_pwr_wakeup(padapter)) {
 712                 ret = -EPERM;
 713                 goto exit;
 714         }
 715 
 716         if (!padapter->hw_init_completed) {
 717                 ret = -EPERM;
 718                 goto exit;
 719         }
 720 
 721         switch (wrqu->mode) {
 722         case IW_MODE_AUTO:
 723                 networkType = Ndis802_11AutoUnknown;
 724                 DBG_88E("set_mode = IW_MODE_AUTO\n");
 725                 break;
 726         case IW_MODE_ADHOC:
 727                 networkType = Ndis802_11IBSS;
 728                 DBG_88E("set_mode = IW_MODE_ADHOC\n");
 729                 break;
 730         case IW_MODE_MASTER:
 731                 networkType = Ndis802_11APMode;
 732                 DBG_88E("set_mode = IW_MODE_MASTER\n");
 733                 break;
 734         case IW_MODE_INFRA:
 735                 networkType = Ndis802_11Infrastructure;
 736                 DBG_88E("set_mode = IW_MODE_INFRA\n");
 737                 break;
 738         default:
 739                 ret = -EINVAL;
 740                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported\n", iw_operation_mode[wrqu->mode]));
 741                 goto exit;
 742         }
 743         if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
 744                 ret = -EPERM;
 745                 goto exit;
 746         }
 747         rtw_setopmode_cmd(padapter, networkType);
 748 exit:
 749         return ret;
 750 }
 751 
 752 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
 753                              union iwreq_data *wrqu, char *b)
 754 {
 755         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 756         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
 757 
 758         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
 759 
 760         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
 761                 wrqu->mode = IW_MODE_INFRA;
 762         else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
 763                   (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
 764                 wrqu->mode = IW_MODE_ADHOC;
 765         else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
 766                 wrqu->mode = IW_MODE_MASTER;
 767         else
 768                 wrqu->mode = IW_MODE_AUTO;
 769 
 770         return 0;
 771 }
 772 
 773 static int rtw_wx_set_pmkid(struct net_device *dev,
 774                             struct iw_request_info *a,
 775                             union iwreq_data *wrqu, char *extra)
 776 {
 777         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 778         u8   j, blInserted = false;
 779         int  ret = false;
 780         struct security_priv *psecuritypriv = &padapter->securitypriv;
 781         struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
 782         u8     strZeroMacAddress[ETH_ALEN] = {0x00};
 783         u8     strIssueBssid[ETH_ALEN] = {0x00};
 784 
 785         memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
 786         if (pPMK->cmd == IW_PMKSA_ADD) {
 787                 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
 788                 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
 789                         return ret;
 790                 else
 791                         ret = true;
 792                 blInserted = false;
 793 
 794                 /* overwrite PMKID */
 795                 for (j = 0; j < NUM_PMKID_CACHE; j++) {
 796                         if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
 797                                 /*  BSSID is matched, the same AP => rewrite with new PMKID. */
 798                                 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
 799                                 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
 800                                 psecuritypriv->PMKIDList[j].bUsed = true;
 801                                 psecuritypriv->PMKIDIndex = j+1;
 802                                 blInserted = true;
 803                                 break;
 804                         }
 805                 }
 806 
 807                 if (!blInserted) {
 808                         /*  Find a new entry */
 809                         DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
 810                                 psecuritypriv->PMKIDIndex);
 811 
 812                         memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
 813                         memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
 814 
 815                         psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
 816                         psecuritypriv->PMKIDIndex++;
 817                         if (psecuritypriv->PMKIDIndex == 16)
 818                                 psecuritypriv->PMKIDIndex = 0;
 819                 }
 820         } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
 821                 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
 822                 ret = true;
 823                 for (j = 0; j < NUM_PMKID_CACHE; j++) {
 824                         if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
 825                                 /*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
 826                                 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
 827                                 psecuritypriv->PMKIDList[j].bUsed = false;
 828                                 break;
 829                         }
 830                }
 831         } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
 832                 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
 833                 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
 834                 psecuritypriv->PMKIDIndex = 0;
 835                 ret = true;
 836         }
 837         return ret;
 838 }
 839 
 840 static int rtw_wx_get_sens(struct net_device *dev,
 841                              struct iw_request_info *info,
 842                              union iwreq_data *wrqu, char *extra)
 843 {
 844         wrqu->sens.value = 0;
 845         wrqu->sens.fixed = 0;   /* no auto select */
 846         wrqu->sens.disabled = 1;
 847         return 0;
 848 }
 849 
 850 static int rtw_wx_get_range(struct net_device *dev,
 851                                 struct iw_request_info *info,
 852                                 union iwreq_data *wrqu, char *extra)
 853 {
 854         struct iw_range *range = (struct iw_range *)extra;
 855         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 856         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
 857 
 858         u16 val;
 859         int i;
 860 
 861         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd));
 862 
 863         wrqu->data.length = sizeof(*range);
 864         memset(range, 0, sizeof(*range));
 865 
 866         /* Let's try to keep this struct in the same order as in
 867          * linux/include/wireless.h
 868          */
 869 
 870         /* TODO: See what values we can set, and remove the ones we can't
 871          * set, or fill them with some default data.
 872          */
 873 
 874         /* ~5 Mb/s real (802.11b) */
 875         range->throughput = 5 * 1000 * 1000;
 876 
 877         /* signal level threshold range */
 878 
 879         /* percent values between 0 and 100. */
 880         range->max_qual.qual = 100;
 881         range->max_qual.level = 100;
 882         range->max_qual.noise = 100;
 883         range->max_qual.updated = 7; /* Updated all three */
 884 
 885         range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
 886         /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
 887         range->avg_qual.level = 178; /* -78 dBm */
 888         range->avg_qual.noise = 0;
 889         range->avg_qual.updated = 7; /* Updated all three */
 890 
 891         range->num_bitrates = RATE_COUNT;
 892 
 893         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
 894                 range->bitrate[i] = rtw_rates[i];
 895 
 896         range->min_frag = MIN_FRAG_THRESHOLD;
 897         range->max_frag = MAX_FRAG_THRESHOLD;
 898 
 899         range->pm_capa = 0;
 900 
 901         range->we_version_compiled = WIRELESS_EXT;
 902         range->we_version_source = 16;
 903 
 904         for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
 905                 /*  Include only legal frequencies for some countries */
 906                 if (pmlmeext->channel_set[i].ChannelNum != 0) {
 907                         range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
 908                         range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
 909                         range->freq[val].e = 1;
 910                         val++;
 911                 }
 912 
 913                 if (val == IW_MAX_FREQUENCIES)
 914                         break;
 915         }
 916 
 917         range->num_channels = val;
 918         range->num_frequency = val;
 919 
 920 /*  The following code will proivde the security capability to network manager. */
 921 /*  If the driver doesn't provide this capability to network manager, */
 922 /*  the WPA/WPA2 routers can't be chosen in the network manager. */
 923 
 924 /*
 925 #define IW_SCAN_CAPA_NONE               0x00
 926 #define IW_SCAN_CAPA_ESSID              0x01
 927 #define IW_SCAN_CAPA_BSSID              0x02
 928 #define IW_SCAN_CAPA_CHANNEL            0x04
 929 #define IW_SCAN_CAPA_MODE               0x08
 930 #define IW_SCAN_CAPA_RATE               0x10
 931 #define IW_SCAN_CAPA_TYPE               0x20
 932 #define IW_SCAN_CAPA_TIME               0x40
 933 */
 934 
 935         range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 936                           IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 937 
 938         range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
 939                            IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
 940                            IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
 941         return 0;
 942 }
 943 
 944 /* set bssid flow */
 945 /* s1. rtw_set_802_11_infrastructure_mode() */
 946 /* s2. rtw_set_802_11_authentication_mode() */
 947 /* s3. set_802_11_encryption_mode() */
 948 /* s4. rtw_set_802_11_bssid() */
 949 static int rtw_wx_set_wap(struct net_device *dev,
 950                          struct iw_request_info *info,
 951                          union iwreq_data *awrq,
 952                          char *extra)
 953 {
 954         uint ret = 0;
 955         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 956         struct sockaddr *temp = (struct sockaddr *)awrq;
 957         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
 958         struct list_head *phead;
 959         u8 *dst_bssid, *src_bssid;
 960         struct __queue *queue   = &(pmlmepriv->scanned_queue);
 961         struct  wlan_network    *pnetwork = NULL;
 962         enum ndis_802_11_auth_mode      authmode;
 963 
 964         if (_FAIL == rtw_pwr_wakeup(padapter)) {
 965                 ret = -1;
 966                 goto exit;
 967         }
 968 
 969         if (!padapter->bup) {
 970                 ret = -1;
 971                 goto exit;
 972         }
 973 
 974         if (temp->sa_family != ARPHRD_ETHER) {
 975                 ret = -EINVAL;
 976                 goto exit;
 977         }
 978 
 979         authmode = padapter->securitypriv.ndisauthtype;
 980         spin_lock_bh(&queue->lock);
 981         phead = get_list_head(queue);
 982         pmlmepriv->pscanned = phead->next;
 983 
 984         while (phead != pmlmepriv->pscanned) {
 985                 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
 986 
 987                 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
 988 
 989                 dst_bssid = pnetwork->network.MacAddress;
 990 
 991                 src_bssid = temp->sa_data;
 992 
 993                 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
 994                         if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
 995                                 ret = -1;
 996                                 spin_unlock_bh(&queue->lock);
 997                                 goto exit;
 998                         }
 999 
1000                                 break;
1001                 }
1002         }
1003         spin_unlock_bh(&queue->lock);
1004 
1005         rtw_set_802_11_authentication_mode(padapter, authmode);
1006         if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
1007                 ret = -1;
1008                 goto exit;
1009         }
1010 
1011 exit:
1012 
1013         return ret;
1014 }
1015 
1016 static int rtw_wx_get_wap(struct net_device *dev,
1017                             struct iw_request_info *info,
1018                             union iwreq_data *wrqu, char *extra)
1019 {
1020         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1021         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1022         struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1023 
1024         wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1025 
1026         eth_zero_addr(wrqu->ap_addr.sa_data);
1027 
1028         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
1029 
1030         if (check_fwstate(pmlmepriv, _FW_LINKED) ||
1031             check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1032             check_fwstate(pmlmepriv, WIFI_AP_STATE))
1033                 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1034         else
1035                 eth_zero_addr(wrqu->ap_addr.sa_data);
1036         return 0;
1037 }
1038 
1039 static int rtw_wx_set_mlme(struct net_device *dev,
1040                              struct iw_request_info *info,
1041                              union iwreq_data *wrqu, char *extra)
1042 {
1043         int ret = 0;
1044         u16 reason;
1045         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1046         struct iw_mlme *mlme = (struct iw_mlme *)extra;
1047 
1048         if (!mlme)
1049                 return -1;
1050 
1051         DBG_88E("%s\n", __func__);
1052 
1053         reason = mlme->reason_code;
1054 
1055         DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1056 
1057         switch (mlme->cmd) {
1058         case IW_MLME_DEAUTH:
1059                 if (!rtw_set_802_11_disassociate(padapter))
1060                         ret = -1;
1061                 break;
1062         case IW_MLME_DISASSOC:
1063                 if (!rtw_set_802_11_disassociate(padapter))
1064                         ret = -1;
1065                 break;
1066         default:
1067                 return -EOPNOTSUPP;
1068         }
1069         return ret;
1070 }
1071 
1072 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1073                              union iwreq_data *wrqu, char *extra)
1074 {
1075         u8 _status = false;
1076         int ret = 0;
1077         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1078         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1079         struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1080 
1081         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
1082 
1083         if (_FAIL == rtw_pwr_wakeup(padapter)) {
1084                 ret = -1;
1085                 goto exit;
1086         }
1087 
1088         if (padapter->bDriverStopped) {
1089                 DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped);
1090                 ret = -1;
1091                 goto exit;
1092         }
1093 
1094         if (!padapter->bup) {
1095                 ret = -1;
1096                 goto exit;
1097         }
1098 
1099         if (!padapter->hw_init_completed) {
1100                 ret = -1;
1101                 goto exit;
1102         }
1103 
1104         /*  When Busy Traffic, driver do not site survey. So driver return success. */
1105         /*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1106         /*  modify by thomas 2011-02-22. */
1107         if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1108                 indicate_wx_scan_complete_event(padapter);
1109                 goto exit;
1110         }
1111 
1112         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1113                 indicate_wx_scan_complete_event(padapter);
1114                 goto exit;
1115         }
1116 
1117 /*      For the DMP WiFi Display project, the driver won't to scan because */
1118 /*      the pmlmepriv->scan_interval is always equal to 3. */
1119 /*      So, the wpa_supplicant won't find out the WPS SoftAP. */
1120 
1121         memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1122 
1123         if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1124                 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1125 
1126                 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1127                         int len = min_t(int, req->essid_len,
1128                                         IW_ESSID_MAX_SIZE);
1129 
1130                         memcpy(ssid[0].ssid, req->essid, len);
1131                         ssid[0].ssid_length = len;
1132 
1133                         DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1134 
1135                         spin_lock_bh(&pmlmepriv->lock);
1136 
1137                         _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1138 
1139                         spin_unlock_bh(&pmlmepriv->lock);
1140                 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1141                         DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1142                 }
1143         } else {
1144                 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1145                     !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1146                         int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1147                         char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1148                         char section;
1149                         char sec_len;
1150                         int ssid_index = 0;
1151 
1152                         while (len >= 1) {
1153                                 section = *(pos++);
1154                                 len -= 1;
1155 
1156                                 switch (section) {
1157                                 case WEXT_CSCAN_SSID_SECTION:
1158                                         if (len < 1) {
1159                                                 len = 0;
1160                                                 break;
1161                                         }
1162                                         sec_len = *(pos++); len -= 1;
1163                                         if (sec_len > 0 && sec_len <= len) {
1164                                                 ssid[ssid_index].ssid_length = sec_len;
1165                                                 memcpy(ssid[ssid_index].ssid, pos, ssid[ssid_index].ssid_length);
1166                                                 ssid_index++;
1167                                         }
1168                                         pos += sec_len;
1169                                         len -= sec_len;
1170                                         break;
1171                                 case WEXT_CSCAN_TYPE_SECTION:
1172                                 case WEXT_CSCAN_CHANNEL_SECTION:
1173                                         pos += 1;
1174                                         len -= 1;
1175                                         break;
1176                                 case WEXT_CSCAN_PASV_DWELL_SECTION:
1177                                 case WEXT_CSCAN_HOME_DWELL_SECTION:
1178                                 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1179                                         pos += 2;
1180                                         len -= 2;
1181                                         break;
1182                                 default:
1183                                         len = 0; /*  stop parsing */
1184                                 }
1185                         }
1186 
1187                         /* it has still some scan parameter to parse, we only do this now... */
1188                         _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1189                 } else {
1190                         _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1191                 }
1192         }
1193 
1194         if (!_status)
1195                 ret = -1;
1196 
1197 exit:
1198 
1199         return ret;
1200 }
1201 
1202 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1203                              union iwreq_data *wrqu, char *extra)
1204 {
1205         struct list_head *plist, *phead;
1206         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1207         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1208         struct __queue *queue   = &(pmlmepriv->scanned_queue);
1209         struct  wlan_network    *pnetwork = NULL;
1210         char *ev = extra;
1211         char *stop = ev + wrqu->data.length;
1212         u32 ret = 0;
1213         u32 cnt = 0;
1214         u32 wait_for_surveydone;
1215         int wait_status;
1216 
1217         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
1218         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
1219 
1220         if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) {
1221                 ret = -EINVAL;
1222                 goto exit;
1223         }
1224 
1225         wait_for_surveydone = 100;
1226 
1227         wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1228 
1229         while (check_fwstate(pmlmepriv, wait_status)) {
1230                 msleep(30);
1231                 cnt++;
1232                 if (cnt > wait_for_surveydone)
1233                         break;
1234         }
1235 
1236         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1237 
1238         phead = get_list_head(queue);
1239         plist = phead->next;
1240 
1241         while (phead != plist) {
1242                 if ((stop - ev) < SCAN_ITEM_SIZE) {
1243                         ret = -E2BIG;
1244                         break;
1245                 }
1246 
1247                 pnetwork = container_of(plist, struct wlan_network, list);
1248 
1249                 /* report network only if the current channel set contains the channel to which this network belongs */
1250                 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
1251                         ev = translate_scan(padapter, a, pnetwork, ev, stop);
1252 
1253                 plist = plist->next;
1254         }
1255 
1256         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1257 
1258         wrqu->data.length = ev-extra;
1259         wrqu->data.flags = 0;
1260 
1261 exit:
1262         return ret;
1263 }
1264 
1265 /* set ssid flow */
1266 /* s1. rtw_set_802_11_infrastructure_mode() */
1267 /* s2. set_802_11_authenticaion_mode() */
1268 /* s3. set_802_11_encryption_mode() */
1269 /* s4. rtw_set_802_11_ssid() */
1270 static int rtw_wx_set_essid(struct net_device *dev,
1271                               struct iw_request_info *a,
1272                               union iwreq_data *wrqu, char *extra)
1273 {
1274         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1275         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1276         struct __queue *queue = &pmlmepriv->scanned_queue;
1277         struct list_head *phead;
1278         struct wlan_network *pnetwork = NULL;
1279         enum ndis_802_11_auth_mode authmode;
1280         struct ndis_802_11_ssid ndis_ssid;
1281         u8 *dst_ssid, *src_ssid;
1282 
1283         uint ret = 0, len;
1284 
1285         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1286                  ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv)));
1287         if (_FAIL == rtw_pwr_wakeup(padapter)) {
1288                 ret = -1;
1289                 goto exit;
1290         }
1291 
1292         if (!padapter->bup) {
1293                 ret = -1;
1294                 goto exit;
1295         }
1296 
1297         if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1298                 ret = -E2BIG;
1299                 goto exit;
1300         }
1301 
1302         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1303                 ret = -1;
1304                 goto exit;
1305         }
1306 
1307         authmode = padapter->securitypriv.ndisauthtype;
1308         DBG_88E("=>%s\n", __func__);
1309         if (wrqu->essid.flags && wrqu->essid.length) {
1310                 len = min_t(uint, wrqu->essid.length, IW_ESSID_MAX_SIZE);
1311 
1312                 if (wrqu->essid.length != 33)
1313                         DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1314 
1315                 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1316                 ndis_ssid.ssid_length = len;
1317                 memcpy(ndis_ssid.ssid, extra, len);
1318                 src_ssid = ndis_ssid.ssid;
1319 
1320                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid));
1321                 spin_lock_bh(&queue->lock);
1322                 phead = get_list_head(queue);
1323                 pmlmepriv->pscanned = phead->next;
1324 
1325                 while (phead != pmlmepriv->pscanned) {
1326                         pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1327 
1328                         pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1329 
1330                         dst_ssid = pnetwork->network.ssid.ssid;
1331 
1332                         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1333                                  ("rtw_wx_set_essid: dst_ssid =%s\n",
1334                                   pnetwork->network.ssid.ssid));
1335 
1336                         if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_length)) &&
1337                             (pnetwork->network.ssid.ssid_length == ndis_ssid.ssid_length)) {
1338                                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1339                                          ("rtw_wx_set_essid: find match, set infra mode\n"));
1340 
1341                                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1342                                         if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1343                                                 continue;
1344                                 }
1345 
1346                                 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1347                                         ret = -1;
1348                                         spin_unlock_bh(&queue->lock);
1349                                         goto exit;
1350                                 }
1351 
1352                                 break;
1353                         }
1354                 }
1355                 spin_unlock_bh(&queue->lock);
1356                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1357                          ("set ssid: set_802_11_auth. mode =%d\n", authmode));
1358                 rtw_set_802_11_authentication_mode(padapter, authmode);
1359                 if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
1360                         ret = -1;
1361                         goto exit;
1362                 }
1363         }
1364 
1365 exit:
1366         DBG_88E("<=%s, ret %d\n", __func__, ret);
1367 
1368         return ret;
1369 }
1370 
1371 static int rtw_wx_get_essid(struct net_device *dev,
1372                               struct iw_request_info *a,
1373                               union iwreq_data *wrqu, char *extra)
1374 {
1375         u32 len;
1376         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1377         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1378         struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1379 
1380         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
1381 
1382         if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
1383             (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
1384                 len = pcur_bss->ssid.ssid_length;
1385                 memcpy(extra, pcur_bss->ssid.ssid, len);
1386         } else {
1387                 len = 0;
1388                 *extra = 0;
1389         }
1390         wrqu->essid.length = len;
1391         wrqu->essid.flags = 1;
1392 
1393         return 0;
1394 }
1395 
1396 static int rtw_wx_set_rate(struct net_device *dev,
1397                               struct iw_request_info *a,
1398                               union iwreq_data *wrqu, char *extra)
1399 {
1400         int i;
1401         u8 datarates[NumRates];
1402         u32     target_rate = wrqu->bitrate.value;
1403         u32     fixed = wrqu->bitrate.fixed;
1404         u32     ratevalue = 0;
1405         u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1406 
1407         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
1408         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
1409 
1410         if (target_rate == -1) {
1411                 ratevalue = 11;
1412                 goto set_rate;
1413         }
1414         target_rate = target_rate/100000;
1415 
1416         switch (target_rate) {
1417         case 10:
1418                 ratevalue = 0;
1419                 break;
1420         case 20:
1421                 ratevalue = 1;
1422                 break;
1423         case 55:
1424                 ratevalue = 2;
1425                 break;
1426         case 60:
1427                 ratevalue = 3;
1428                 break;
1429         case 90:
1430                 ratevalue = 4;
1431                 break;
1432         case 110:
1433                 ratevalue = 5;
1434                 break;
1435         case 120:
1436                 ratevalue = 6;
1437                 break;
1438         case 180:
1439                 ratevalue = 7;
1440                 break;
1441         case 240:
1442                 ratevalue = 8;
1443                 break;
1444         case 360:
1445                 ratevalue = 9;
1446                 break;
1447         case 480:
1448                 ratevalue = 10;
1449                 break;
1450         case 540:
1451                 ratevalue = 11;
1452                 break;
1453         default:
1454                 ratevalue = 11;
1455                 break;
1456         }
1457 
1458 set_rate:
1459 
1460         for (i = 0; i < NumRates; i++) {
1461                 if (ratevalue == mpdatarate[i]) {
1462                         datarates[i] = mpdatarate[i];
1463                         if (fixed == 0)
1464                                 break;
1465                 } else {
1466                         datarates[i] = 0xff;
1467                 }
1468 
1469                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i]));
1470         }
1471 
1472         return 0;
1473 }
1474 
1475 static int rtw_wx_get_rate(struct net_device *dev,
1476                              struct iw_request_info *info,
1477                              union iwreq_data *wrqu, char *extra)
1478 {
1479         u16 max_rate = 0;
1480 
1481         max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1482 
1483         if (max_rate == 0)
1484                 return -EPERM;
1485 
1486         wrqu->bitrate.fixed = 0;        /* no auto select */
1487         wrqu->bitrate.value = max_rate * 100000;
1488 
1489         return 0;
1490 }
1491 
1492 static int rtw_wx_set_rts(struct net_device *dev,
1493                              struct iw_request_info *info,
1494                              union iwreq_data *wrqu, char *extra)
1495 {
1496         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1497 
1498         if (wrqu->rts.disabled) {
1499                 padapter->registrypriv.rts_thresh = 2347;
1500         } else {
1501                 if (wrqu->rts.value < 0 ||
1502                     wrqu->rts.value > 2347)
1503                         return -EINVAL;
1504 
1505                 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1506         }
1507 
1508         DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1509 
1510         return 0;
1511 }
1512 
1513 static int rtw_wx_get_rts(struct net_device *dev,
1514                              struct iw_request_info *info,
1515                              union iwreq_data *wrqu, char *extra)
1516 {
1517         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1518 
1519         DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1520 
1521         wrqu->rts.value = padapter->registrypriv.rts_thresh;
1522         wrqu->rts.fixed = 0;    /* no auto select */
1523         /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1524 
1525         return 0;
1526 }
1527 
1528 static int rtw_wx_set_frag(struct net_device *dev,
1529                              struct iw_request_info *info,
1530                              union iwreq_data *wrqu, char *extra)
1531 {
1532         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1533 
1534         if (wrqu->frag.disabled) {
1535                 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1536         } else {
1537                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1538                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
1539                         return -EINVAL;
1540 
1541                 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1542         }
1543 
1544         DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1545 
1546         return 0;
1547 }
1548 
1549 static int rtw_wx_get_frag(struct net_device *dev,
1550                              struct iw_request_info *info,
1551                              union iwreq_data *wrqu, char *extra)
1552 {
1553         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1554 
1555         DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1556 
1557         wrqu->frag.value = padapter->xmitpriv.frag_len;
1558         wrqu->frag.fixed = 0;   /* no auto select */
1559 
1560         return 0;
1561 }
1562 
1563 static int rtw_wx_get_retry(struct net_device *dev,
1564                              struct iw_request_info *info,
1565                              union iwreq_data *wrqu, char *extra)
1566 {
1567         wrqu->retry.value = 7;
1568         wrqu->retry.fixed = 0;  /* no auto select */
1569         wrqu->retry.disabled = 1;
1570 
1571         return 0;
1572 }
1573 
1574 static int rtw_wx_set_enc(struct net_device *dev,
1575                             struct iw_request_info *info,
1576                             union iwreq_data *wrqu, char *keybuf)
1577 {
1578         u32 key, ret = 0;
1579         u32 keyindex_provided;
1580         struct ndis_802_11_wep   wep;
1581         enum ndis_802_11_auth_mode authmode;
1582 
1583         struct iw_point *erq = &(wrqu->encoding);
1584         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1585         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1586 
1587         DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1588 
1589         memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1590 
1591         key = erq->flags & IW_ENCODE_INDEX;
1592 
1593         if (erq->flags & IW_ENCODE_DISABLED) {
1594                 DBG_88E("EncryptionDisabled\n");
1595                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1596                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1597                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1598                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1599                 authmode = Ndis802_11AuthModeOpen;
1600                 padapter->securitypriv.ndisauthtype = authmode;
1601 
1602                 goto exit;
1603         }
1604 
1605         if (key) {
1606                 if (key > WEP_KEYS)
1607                         return -EINVAL;
1608                 key--;
1609                 keyindex_provided = 1;
1610         } else {
1611                 keyindex_provided = 0;
1612                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1613                 DBG_88E("rtw_wx_set_enc, key =%d\n", key);
1614         }
1615 
1616         /* set authentication mode */
1617         if (erq->flags & IW_ENCODE_OPEN) {
1618                 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1619                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1620                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1621                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1622                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1623                 authmode = Ndis802_11AuthModeOpen;
1624                 padapter->securitypriv.ndisauthtype = authmode;
1625         } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1626                 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1627                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1628                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1629                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1630                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1631                 authmode = Ndis802_11AuthModeShared;
1632                 padapter->securitypriv.ndisauthtype = authmode;
1633         } else {
1634                 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1635 
1636                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1637                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1638                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1639                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1640                 authmode = Ndis802_11AuthModeOpen;
1641                 padapter->securitypriv.ndisauthtype = authmode;
1642         }
1643 
1644         wep.KeyIndex = key;
1645         if (erq->length > 0) {
1646                 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1647 
1648                 wep.Length = wep.KeyLength + offsetof(struct ndis_802_11_wep, KeyMaterial);
1649         } else {
1650                 wep.KeyLength = 0;
1651 
1652                 if (keyindex_provided == 1) {
1653                         /*  set key_id only, no given KeyMaterial(erq->length == 0). */
1654                         padapter->securitypriv.dot11PrivacyKeyIndex = key;
1655 
1656                         DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1657 
1658                         switch (padapter->securitypriv.dot11DefKeylen[key]) {
1659                         case 5:
1660                                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1661                                 break;
1662                         case 13:
1663                                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1664                                 break;
1665                         default:
1666                                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1667                                 break;
1668                         }
1669 
1670                         goto exit;
1671                 }
1672         }
1673 
1674         wep.KeyIndex |= 0x80000000;
1675 
1676         memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1677 
1678         if (!rtw_set_802_11_add_wep(padapter, &wep)) {
1679                 if (rf_on == pwrpriv->rf_pwrstate)
1680                         ret = -EOPNOTSUPP;
1681                 goto exit;
1682         }
1683 
1684 exit:
1685         return ret;
1686 }
1687 
1688 static int rtw_wx_get_enc(struct net_device *dev,
1689                             struct iw_request_info *info,
1690                             union iwreq_data *wrqu, char *keybuf)
1691 {
1692         uint key;
1693         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1694         struct iw_point *erq = &(wrqu->encoding);
1695         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1696 
1697         if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1698                 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1699                         erq->length = 0;
1700                         erq->flags |= IW_ENCODE_DISABLED;
1701                         return 0;
1702                 }
1703         }
1704 
1705         key = erq->flags & IW_ENCODE_INDEX;
1706 
1707         if (key) {
1708                 if (key > WEP_KEYS)
1709                         return -EINVAL;
1710                 key--;
1711         } else {
1712                 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1713         }
1714 
1715         erq->flags = key + 1;
1716 
1717         switch (padapter->securitypriv.ndisencryptstatus) {
1718         case Ndis802_11EncryptionNotSupported:
1719         case Ndis802_11EncryptionDisabled:
1720                 erq->length = 0;
1721                 erq->flags |= IW_ENCODE_DISABLED;
1722                 break;
1723         case Ndis802_11Encryption1Enabled:
1724                 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1725                 if (erq->length) {
1726                         memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1727 
1728                         erq->flags |= IW_ENCODE_ENABLED;
1729 
1730                         if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1731                                 erq->flags |= IW_ENCODE_OPEN;
1732                         else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1733                                 erq->flags |= IW_ENCODE_RESTRICTED;
1734                 } else {
1735                         erq->length = 0;
1736                         erq->flags |= IW_ENCODE_DISABLED;
1737                 }
1738                 break;
1739         case Ndis802_11Encryption2Enabled:
1740         case Ndis802_11Encryption3Enabled:
1741                 erq->length = 16;
1742                 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1743                 break;
1744         default:
1745                 erq->length = 0;
1746                 erq->flags |= IW_ENCODE_DISABLED;
1747                 break;
1748         }
1749 
1750         return 0;
1751 }
1752 
1753 static int rtw_wx_get_power(struct net_device *dev,
1754                              struct iw_request_info *info,
1755                              union iwreq_data *wrqu, char *extra)
1756 {
1757         wrqu->power.value = 0;
1758         wrqu->power.fixed = 0;  /* no auto select */
1759         wrqu->power.disabled = 1;
1760 
1761         return 0;
1762 }
1763 
1764 static int rtw_wx_set_gen_ie(struct net_device *dev,
1765                              struct iw_request_info *info,
1766                              union iwreq_data *wrqu, char *extra)
1767 {
1768         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1769 
1770         return rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1771 }
1772 
1773 static int rtw_wx_set_auth(struct net_device *dev,
1774                              struct iw_request_info *info,
1775                              union iwreq_data *wrqu, char *extra)
1776 {
1777         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1778         struct iw_param *param = (struct iw_param *)&(wrqu->param);
1779         int ret = 0;
1780 
1781         switch (param->flags & IW_AUTH_INDEX) {
1782         case IW_AUTH_WPA_VERSION:
1783                 break;
1784         case IW_AUTH_CIPHER_PAIRWISE:
1785 
1786                 break;
1787         case IW_AUTH_CIPHER_GROUP:
1788 
1789                 break;
1790         case IW_AUTH_KEY_MGMT:
1791                 /*
1792                  *  ??? does not use these parameters
1793                  */
1794                 break;
1795         case IW_AUTH_TKIP_COUNTERMEASURES:
1796                 if (param->value) {
1797                         /*  wpa_supplicant is enabling the tkip countermeasure. */
1798                         padapter->securitypriv.btkip_countermeasure = true;
1799                 } else {
1800                         /*  wpa_supplicant is disabling the tkip countermeasure. */
1801                         padapter->securitypriv.btkip_countermeasure = false;
1802                 }
1803                 break;
1804         case IW_AUTH_DROP_UNENCRYPTED:
1805                 /* HACK:
1806                  *
1807                  * wpa_supplicant calls set_wpa_enabled when the driver
1808                  * is loaded and unloaded, regardless of if WPA is being
1809                  * used.  No other calls are made which can be used to
1810                  * determine if encryption will be used or not prior to
1811                  * association being expected.  If encryption is not being
1812                  * used, drop_unencrypted is set to false, else true -- we
1813                  * can use this to determine if the CAP_PRIVACY_ON bit should
1814                  * be set.
1815                  */
1816 
1817                 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1818                         break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1819                                         /*  then it needn't reset it; */
1820 
1821                 if (param->value) {
1822                         padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1823                         padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1824                         padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1825                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1826                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1827                 }
1828 
1829                 break;
1830         case IW_AUTH_80211_AUTH_ALG:
1831                 /*
1832                  *  It's the starting point of a link layer connection using wpa_supplicant
1833                 */
1834                 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1835                         LeaveAllPowerSaveMode(padapter);
1836                         rtw_disassoc_cmd(padapter, 500, false);
1837                         DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__);
1838                         rtw_indicate_disconnect(padapter);
1839                         rtw_free_assoc_resources(padapter);
1840                 }
1841                 ret = wpa_set_auth_algs(dev, (u32)param->value);
1842                 break;
1843         case IW_AUTH_WPA_ENABLED:
1844                 break;
1845         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1846                 break;
1847         case IW_AUTH_PRIVACY_INVOKED:
1848                 break;
1849         default:
1850                 return -EOPNOTSUPP;
1851         }
1852 
1853         return ret;
1854 }
1855 
1856 static int rtw_wx_set_enc_ext(struct net_device *dev,
1857                              struct iw_request_info *info,
1858                              union iwreq_data *wrqu, char *extra)
1859 {
1860         char *alg_name;
1861         u32 param_len;
1862         struct ieee_param *param = NULL;
1863         struct iw_point *pencoding = &wrqu->encoding;
1864         struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1865         int ret = 0;
1866 
1867         param_len = sizeof(struct ieee_param) + pext->key_len;
1868         param = (struct ieee_param *)rtw_malloc(param_len);
1869         if (!param)
1870                 return -1;
1871 
1872         memset(param, 0, param_len);
1873 
1874         param->cmd = IEEE_CMD_SET_ENCRYPTION;
1875         eth_broadcast_addr(param->sta_addr);
1876 
1877         switch (pext->alg) {
1878         case IW_ENCODE_ALG_NONE:
1879                 /* todo: remove key */
1880                 /* remove = 1; */
1881                 alg_name = "none";
1882                 break;
1883         case IW_ENCODE_ALG_WEP:
1884                 alg_name = "WEP";
1885                 break;
1886         case IW_ENCODE_ALG_TKIP:
1887                 alg_name = "TKIP";
1888                 break;
1889         case IW_ENCODE_ALG_CCMP:
1890                 alg_name = "CCMP";
1891                 break;
1892         default:
1893                 ret = -1;
1894                 goto exit;
1895         }
1896 
1897         strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1898 
1899         if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1900                 param->u.crypt.set_tx = 1;
1901 
1902         /* cliW: WEP does not have group key
1903          * just not checking GROUP key setting
1904          */
1905         if ((pext->alg != IW_ENCODE_ALG_WEP) &&
1906             (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
1907                 param->u.crypt.set_tx = 0;
1908 
1909         param->u.crypt.idx = (pencoding->flags&0x00FF) - 1;
1910 
1911         if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1912                 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1913 
1914         if (pext->key_len) {
1915                 param->u.crypt.key_len = pext->key_len;
1916                 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
1917         }
1918 
1919         ret =  wpa_set_encryption(dev, param, param_len);
1920 
1921 exit:
1922         kfree(param);
1923         return ret;
1924 }
1925 
1926 static int rtw_wx_get_nick(struct net_device *dev,
1927                            struct iw_request_info *info,
1928                            union iwreq_data *wrqu, char *extra)
1929 {
1930         if (extra) {
1931                 wrqu->data.length = 14;
1932                 wrqu->data.flags = 1;
1933                 memcpy(extra, "<WIFI@REALTEK>", 14);
1934         }
1935 
1936         /* dump debug info here */
1937         return 0;
1938 }
1939 
1940 static int dummy(struct net_device *dev, struct iw_request_info *a,
1941                  union iwreq_data *wrqu, char *b)
1942 {
1943         return -1;
1944 }
1945 
1946 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1947 {
1948         uint ret = 0;
1949         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1950 
1951         switch (name) {
1952         case IEEE_PARAM_WPA_ENABLED:
1953                 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
1954                 switch ((value)&0xff) {
1955                 case 1: /* WPA */
1956                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
1957                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1958                         break;
1959                 case 2: /* WPA2 */
1960                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
1961                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1962                         break;
1963                 }
1964                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1965                          ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype));
1966                 break;
1967         case IEEE_PARAM_TKIP_COUNTERMEASURES:
1968                 break;
1969         case IEEE_PARAM_DROP_UNENCRYPTED: {
1970                 /* HACK:
1971                  *
1972                  * wpa_supplicant calls set_wpa_enabled when the driver
1973                  * is loaded and unloaded, regardless of if WPA is being
1974                  * used.  No other calls are made which can be used to
1975                  * determine if encryption will be used or not prior to
1976                  * association being expected.  If encryption is not being
1977                  * used, drop_unencrypted is set to false, else true -- we
1978                  * can use this to determine if the CAP_PRIVACY_ON bit should
1979                  * be set.
1980                  */
1981 
1982                 break;
1983         }
1984         case IEEE_PARAM_PRIVACY_INVOKED:
1985                 break;
1986 
1987         case IEEE_PARAM_AUTH_ALGS:
1988                 ret = wpa_set_auth_algs(dev, value);
1989                 break;
1990         case IEEE_PARAM_IEEE_802_1X:
1991                 break;
1992         case IEEE_PARAM_WPAX_SELECT:
1993                 break;
1994         default:
1995                 ret = -EOPNOTSUPP;
1996                 break;
1997         }
1998         return ret;
1999 }
2000 
2001 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2002 {
2003         int ret = 0;
2004         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2005 
2006         switch (command) {
2007         case IEEE_MLME_STA_DEAUTH:
2008                 if (!rtw_set_802_11_disassociate(padapter))
2009                         ret = -1;
2010                 break;
2011         case IEEE_MLME_STA_DISASSOC:
2012                 if (!rtw_set_802_11_disassociate(padapter))
2013                         ret = -1;
2014                 break;
2015         default:
2016                 ret = -EOPNOTSUPP;
2017                 break;
2018         }
2019 
2020         return ret;
2021 }
2022 
2023 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2024 {
2025         struct ieee_param *param;
2026         uint ret = 0;
2027 
2028         if (!p->pointer || p->length != sizeof(struct ieee_param)) {
2029                 ret = -EINVAL;
2030                 goto out;
2031         }
2032 
2033         param = (struct ieee_param *)rtw_malloc(p->length);
2034         if (!param) {
2035                 ret = -ENOMEM;
2036                 goto out;
2037         }
2038 
2039         if (copy_from_user(param, p->pointer, p->length)) {
2040                 kfree(param);
2041                 ret = -EFAULT;
2042                 goto out;
2043         }
2044 
2045         switch (param->cmd) {
2046         case IEEE_CMD_SET_WPA_PARAM:
2047                 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
2048                 break;
2049 
2050         case IEEE_CMD_SET_WPA_IE:
2051                 ret =  rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev),
2052                                       (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
2053                 break;
2054 
2055         case IEEE_CMD_SET_ENCRYPTION:
2056                 ret = wpa_set_encryption(dev, param, p->length);
2057                 break;
2058 
2059         case IEEE_CMD_MLME:
2060                 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
2061                 break;
2062 
2063         default:
2064                 DBG_88E("Unknown WPA supplicant request: %d\n", param->cmd);
2065                 ret = -EOPNOTSUPP;
2066                 break;
2067         }
2068 
2069         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2070                 ret = -EFAULT;
2071 
2072         kfree(param);
2073 
2074 out:
2075 
2076         return ret;
2077 }
2078 
2079 #ifdef CONFIG_88EU_AP_MODE
2080 static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
2081 {
2082         struct cmd_obj *ph2c;
2083         struct set_stakey_parm  *psetstakey_para;
2084         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2085         u8 res = _SUCCESS;
2086 
2087         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
2088         if (!ph2c) {
2089                 res = _FAIL;
2090                 goto exit;
2091         }
2092 
2093         psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
2094         if (!psetstakey_para) {
2095                 kfree(ph2c);
2096                 res = _FAIL;
2097                 goto exit;
2098         }
2099 
2100         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
2101 
2102         psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
2103 
2104         memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
2105 
2106         memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
2107 
2108         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2109 
2110 exit:
2111 
2112         return res;
2113 }
2114 
2115 static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
2116 {
2117         u8 keylen;
2118         struct cmd_obj *pcmd;
2119         struct setkey_parm *psetkeyparm;
2120         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
2121         int res = _SUCCESS;
2122 
2123         DBG_88E("%s\n", __func__);
2124 
2125         pcmd = kzalloc(sizeof(struct    cmd_obj), GFP_KERNEL);
2126         if (!pcmd) {
2127                 res = _FAIL;
2128                 goto exit;
2129         }
2130         psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
2131         if (!psetkeyparm) {
2132                 kfree(pcmd);
2133                 res = _FAIL;
2134                 goto exit;
2135         }
2136 
2137         psetkeyparm->keyid = (u8)keyid;
2138 
2139         psetkeyparm->algorithm = alg;
2140 
2141         psetkeyparm->set_tx = 1;
2142 
2143         switch (alg) {
2144         case _WEP40_:
2145                 keylen = 5;
2146                 break;
2147         case _WEP104_:
2148                 keylen = 13;
2149                 break;
2150         case _TKIP_:
2151         case _TKIP_WTMIC_:
2152         case _AES_:
2153         default:
2154                 keylen = 16;
2155         }
2156 
2157         memcpy(&(psetkeyparm->key[0]), key, keylen);
2158 
2159         pcmd->cmdcode = _SetKey_CMD_;
2160         pcmd->parmbuf = (u8 *)psetkeyparm;
2161         pcmd->cmdsz =  (sizeof(struct setkey_parm));
2162         pcmd->rsp = NULL;
2163         pcmd->rspsz = 0;
2164 
2165         INIT_LIST_HEAD(&pcmd->list);
2166 
2167         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
2168 
2169 exit:
2170 
2171         return res;
2172 }
2173 
2174 static int set_wep_key(struct adapter *padapter, u8 *key, u8 keylen, int keyid)
2175 {
2176         u8 alg;
2177 
2178         switch (keylen) {
2179         case 5:
2180                 alg = _WEP40_;
2181                 break;
2182         case 13:
2183                 alg = _WEP104_;
2184                 break;
2185         default:
2186                 alg = _NO_PRIVACY_;
2187         }
2188 
2189         return set_group_key(padapter, key, alg, keyid);
2190 }
2191 
2192 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
2193 {
2194         int ret = 0;
2195         u32 wep_key_idx, wep_key_len, wep_total_len;
2196         struct ndis_802_11_wep   *pwep = NULL;
2197         struct sta_info *psta = NULL, *pbcmc_sta = NULL;
2198         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2199         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2200         struct security_priv *psecuritypriv = &(padapter->securitypriv);
2201         struct sta_priv *pstapriv = &padapter->stapriv;
2202 
2203         DBG_88E("%s\n", __func__);
2204         param->u.crypt.err = 0;
2205         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2206         if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
2207                 ret =  -EINVAL;
2208                 goto exit;
2209         }
2210         if (is_broadcast_ether_addr(param->sta_addr)) {
2211                 if (param->u.crypt.idx >= WEP_KEYS) {
2212                         ret = -EINVAL;
2213                         goto exit;
2214                 }
2215         } else {
2216                 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2217                 if (!psta) {
2218                         DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
2219                         goto exit;
2220                 }
2221         }
2222 
2223         if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
2224                 /* todo:clear default encryption keys */
2225 
2226                 DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
2227                 goto exit;
2228         }
2229         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
2230                 DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
2231                 wep_key_idx = param->u.crypt.idx;
2232                 wep_key_len = param->u.crypt.key_len;
2233                 DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
2234                 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
2235                         ret = -EINVAL;
2236                         goto exit;
2237                 }
2238 
2239                 if (wep_key_len > 0) {
2240                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
2241                         wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
2242                         pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
2243                         if (!pwep) {
2244                                 DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
2245                                 goto exit;
2246                         }
2247 
2248                         memset(pwep, 0, wep_total_len);
2249 
2250                         pwep->KeyLength = wep_key_len;
2251                         pwep->Length = wep_total_len;
2252                 }
2253 
2254                 pwep->KeyIndex = wep_key_idx;
2255 
2256                 memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
2257 
2258                 if (param->u.crypt.set_tx) {
2259                         DBG_88E("wep, set_tx = 1\n");
2260 
2261                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2262                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
2263                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2264 
2265                         if (pwep->KeyLength == 13) {
2266                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
2267                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2268                         }
2269 
2270                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
2271 
2272                         memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
2273 
2274                         psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2275 
2276                         set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2277                 } else {
2278                         DBG_88E("wep, set_tx = 0\n");
2279 
2280                         /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
2281                         /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
2282 
2283                         memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
2284 
2285                         psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2286 
2287                         set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2288                 }
2289 
2290                 goto exit;
2291         }
2292 
2293         if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
2294                 if (param->u.crypt.set_tx == 1) {
2295                         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2296                                 DBG_88E("%s, set group_key, WEP\n", __func__);
2297 
2298                                 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2299                                             param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2300 
2301                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2302                                 if (param->u.crypt.key_len == 13)
2303                                         psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2304                         } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2305                                 DBG_88E("%s, set group_key, TKIP\n", __func__);
2306                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2307                                 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2308                                             param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2309                                 /* set mic key */
2310                                 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
2311                                 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
2312 
2313                                 psecuritypriv->busetkipkey = true;
2314                         } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2315                                 DBG_88E("%s, set group_key, CCMP\n", __func__);
2316                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
2317                                 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2318                                             param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2319                         } else {
2320                                 DBG_88E("%s, set group_key, none\n", __func__);
2321                                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2322                         }
2323                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2324                         psecuritypriv->binstallGrpkey = true;
2325                         psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
2326                         set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2327                         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2328                         if (pbcmc_sta) {
2329                                 pbcmc_sta->ieee8021x_blocked = false;
2330                                 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
2331                         }
2332                 }
2333                 goto exit;
2334         }
2335 
2336         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
2337                 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2338                         if (param->u.crypt.set_tx == 1) {
2339                                 memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2340 
2341                                 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2342                                         DBG_88E("%s, set pairwise key, WEP\n", __func__);
2343 
2344                                         psta->dot118021XPrivacy = _WEP40_;
2345                                         if (param->u.crypt.key_len == 13)
2346                                                 psta->dot118021XPrivacy = _WEP104_;
2347                                 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2348                                         DBG_88E("%s, set pairwise key, TKIP\n", __func__);
2349 
2350                                         psta->dot118021XPrivacy = _TKIP_;
2351 
2352                                         /* set mic key */
2353                                         memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
2354                                         memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
2355 
2356                                         psecuritypriv->busetkipkey = true;
2357                                 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2358                                         DBG_88E("%s, set pairwise key, CCMP\n", __func__);
2359 
2360                                         psta->dot118021XPrivacy = _AES_;
2361                                 } else {
2362                                         DBG_88E("%s, set pairwise key, none\n", __func__);
2363 
2364                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
2365                                 }
2366 
2367                                 set_pairwise_key(padapter, psta);
2368 
2369                                 psta->ieee8021x_blocked = false;
2370                         } else { /* group key??? */
2371                                 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2372                                         memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2373                                                     param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2374                                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2375                                         if (param->u.crypt.key_len == 13)
2376                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2377                                 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2378                                         psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2379 
2380                                         memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2381                                                     param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2382 
2383                                         /* set mic key */
2384                                         memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
2385                                         memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
2386 
2387                                         psecuritypriv->busetkipkey = true;
2388                                 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2389                                         psecuritypriv->dot118021XGrpPrivacy = _AES_;
2390 
2391                                         memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2392                                                     param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2393                                 } else {
2394                                         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2395                                 }
2396 
2397                                 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2398 
2399                                 psecuritypriv->binstallGrpkey = true;
2400 
2401                                 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
2402 
2403                                 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2404 
2405                                 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2406                                 if (pbcmc_sta) {
2407                                         pbcmc_sta->ieee8021x_blocked = false;
2408                                         pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
2409                                 }
2410                         }
2411                 }
2412         }
2413 
2414 exit:
2415 
2416         kfree(pwep);
2417 
2418         return ret;
2419 }
2420 
2421 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
2422 {
2423         int ret = 0;
2424         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2425         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2426         struct sta_priv *pstapriv = &padapter->stapriv;
2427         unsigned char *pbuf = param->u.bcn_ie.buf;
2428 
2429         DBG_88E("%s, len =%d\n", __func__, len);
2430 
2431         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2432                 return -EINVAL;
2433 
2434         memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
2435 
2436         if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
2437                 pstapriv->max_num_sta = NUM_STA;
2438 
2439         if (rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)/*  12 = param header, 2:no packed */
2440                 ret = 0;
2441         else
2442                 ret = -EINVAL;
2443 
2444         return ret;
2445 }
2446 
2447 static int rtw_hostapd_sta_flush(struct net_device *dev)
2448 {
2449         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2450 
2451         DBG_88E("%s\n", __func__);
2452 
2453         flush_all_cam_entry(padapter);  /* clear CAM */
2454 
2455         return rtw_sta_flush(padapter);
2456 }
2457 
2458 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
2459 {
2460         int ret = 0;
2461         struct sta_info *psta = NULL;
2462         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2463         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2464         struct sta_priv *pstapriv = &padapter->stapriv;
2465 
2466         DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
2467 
2468         if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
2469                 return -EINVAL;
2470 
2471         if (is_broadcast_ether_addr(param->sta_addr))
2472                 return -EINVAL;
2473 
2474         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2475         if (psta) {
2476                 int flags = param->u.add_sta.flags;
2477 
2478                 psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */
2479 
2480                 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
2481 
2482                 /* check wmm cap. */
2483                 if (WLAN_STA_WME&flags)
2484                         psta->qos_option = 1;
2485                 else
2486                         psta->qos_option = 0;
2487 
2488                 if (pmlmepriv->qospriv.qos_option == 0)
2489                         psta->qos_option = 0;
2490 
2491                 /* chec 802.11n ht cap. */
2492                 if (WLAN_STA_HT&flags) {
2493                         psta->htpriv.ht_option = true;
2494                         psta->qos_option = 1;
2495                         memcpy(&psta->htpriv.ht_cap, &param->u.add_sta.ht_cap,
2496                                sizeof(struct ieee80211_ht_cap));
2497                 } else {
2498                         psta->htpriv.ht_option = false;
2499                 }
2500 
2501                 if (!pmlmepriv->htpriv.ht_option)
2502                         psta->htpriv.ht_option = false;
2503 
2504                 update_sta_info_apmode(padapter, psta);
2505         } else {
2506                 ret = -ENOMEM;
2507         }
2508 
2509         return ret;
2510 }
2511 
2512 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
2513 {
2514         struct sta_info *psta = NULL;
2515         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2516         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2517         struct sta_priv *pstapriv = &padapter->stapriv;
2518         int updated = 0;
2519 
2520         DBG_88E("rtw_del_sta =%pM\n", (param->sta_addr));
2521 
2522         if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2523                 return -EINVAL;
2524 
2525         if (is_broadcast_ether_addr(param->sta_addr))
2526                 return -EINVAL;
2527 
2528         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2529         if (psta) {
2530                 spin_lock_bh(&pstapriv->asoc_list_lock);
2531                 if (!list_empty(&psta->asoc_list)) {
2532                         list_del_init(&psta->asoc_list);
2533                         pstapriv->asoc_list_cnt--;
2534                         updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2535                 }
2536                 spin_unlock_bh(&pstapriv->asoc_list_lock);
2537                 associated_clients_update(padapter, updated);
2538                 psta = NULL;
2539         } else {
2540                 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
2541         }
2542 
2543         return 0;
2544 }
2545 
2546 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
2547 {
2548         int ret = 0;
2549         struct sta_info *psta = NULL;
2550         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2551         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2552         struct sta_priv *pstapriv = &padapter->stapriv;
2553         struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
2554         struct sta_data *psta_data = (struct sta_data *)param_ex->data;
2555 
2556         DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex->sta_addr));
2557 
2558         if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2559                 return -EINVAL;
2560 
2561         if (is_broadcast_ether_addr(param_ex->sta_addr))
2562                 return -EINVAL;
2563 
2564         psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
2565         if (psta) {
2566                 psta_data->aid = (u16)psta->aid;
2567                 psta_data->capability = psta->capability;
2568                 psta_data->flags = psta->flags;
2569 
2570 /*
2571                 nonerp_set : BIT(0)
2572                 no_short_slot_time_set : BIT(1)
2573                 no_short_preamble_set : BIT(2)
2574                 no_ht_gf_set : BIT(3)
2575                 no_ht_set : BIT(4)
2576                 ht_20mhz_set : BIT(5)
2577 */
2578 
2579                 psta_data->sta_set = ((psta->nonerp_set) |
2580                                       (psta->no_short_slot_time_set << 1) |
2581                                       (psta->no_short_preamble_set << 2) |
2582                                       (psta->no_ht_gf_set << 3) |
2583                                       (psta->no_ht_set << 4) |
2584                                       (psta->ht_20mhz_set << 5));
2585                 psta_data->tx_supp_rates_len =  psta->bssratelen;
2586                 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
2587                 memcpy(&psta_data->ht_cap,
2588                        &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
2589                 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
2590                 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
2591                 psta_data->rx_drops = psta->sta_stats.rx_drops;
2592                 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
2593                 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
2594                 psta_data->tx_drops = psta->sta_stats.tx_drops;
2595         } else {
2596                 ret = -1;
2597         }
2598 
2599         return ret;
2600 }
2601 
2602 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
2603 {
2604         int ret = 0;
2605         struct sta_info *psta = NULL;
2606         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2607         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2608         struct sta_priv *pstapriv = &padapter->stapriv;
2609 
2610         DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
2611 
2612         if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2613                 return -EINVAL;
2614 
2615         if (is_broadcast_ether_addr(param->sta_addr))
2616                 return -EINVAL;
2617 
2618         psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2619         if (psta) {
2620                 if (psta->wpa_ie[0] == WLAN_EID_RSN ||
2621                     psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
2622                         int wpa_ie_len;
2623                         int copy_len;
2624 
2625                         wpa_ie_len = psta->wpa_ie[1];
2626                         copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
2627                         param->u.wpa_ie.len = copy_len;
2628                         memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
2629                 } else {
2630                         DBG_88E("sta's wpa_ie is NONE\n");
2631                 }
2632         } else {
2633                 ret = -1;
2634         }
2635 
2636         return ret;
2637 }
2638 
2639 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
2640 {
2641         unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2642         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2643         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2644         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2645         int ie_len;
2646 
2647         DBG_88E("%s, len =%d\n", __func__, len);
2648 
2649         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2650                 return -EINVAL;
2651 
2652         ie_len = len-12-2;/*  12 = param header, 2:no packed */
2653 
2654         kfree(pmlmepriv->wps_beacon_ie);
2655         pmlmepriv->wps_beacon_ie = NULL;
2656 
2657         if (ie_len > 0) {
2658                 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
2659                 pmlmepriv->wps_beacon_ie_len = ie_len;
2660                 if (!pmlmepriv->wps_beacon_ie) {
2661                         DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2662                         return -EINVAL;
2663                 }
2664 
2665                 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
2666 
2667                 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
2668 
2669                 pmlmeext->bstart_bss = true;
2670         }
2671 
2672         return 0;
2673 }
2674 
2675 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
2676 {
2677         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2678         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2679         int ie_len;
2680 
2681         DBG_88E("%s, len =%d\n", __func__, len);
2682 
2683         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2684                 return -EINVAL;
2685 
2686         ie_len = len-12-2;/*  12 = param header, 2:no packed */
2687 
2688         kfree(pmlmepriv->wps_probe_resp_ie);
2689         pmlmepriv->wps_probe_resp_ie = NULL;
2690 
2691         if (ie_len > 0) {
2692                 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
2693                 pmlmepriv->wps_probe_resp_ie_len = ie_len;
2694                 if (!pmlmepriv->wps_probe_resp_ie) {
2695                         DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2696                         return -EINVAL;
2697                 }
2698                 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
2699         }
2700 
2701         return 0;
2702 }
2703 
2704 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
2705 {
2706         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2707         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2708         int ie_len;
2709 
2710         DBG_88E("%s, len =%d\n", __func__, len);
2711 
2712         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2713                 return -EINVAL;
2714 
2715         ie_len = len-12-2;/*  12 = param header, 2:no packed */
2716 
2717         kfree(pmlmepriv->wps_assoc_resp_ie);
2718         pmlmepriv->wps_assoc_resp_ie = NULL;
2719 
2720         if (ie_len > 0) {
2721                 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
2722                 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
2723                 if (!pmlmepriv->wps_assoc_resp_ie) {
2724                         DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2725                         return -EINVAL;
2726                 }
2727 
2728                 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
2729         }
2730 
2731         return 0;
2732 }
2733 
2734 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
2735 {
2736         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2737         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2738         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2739         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2740 
2741         u8 value;
2742 
2743         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2744                 return -EINVAL;
2745 
2746         if (param->u.wpa_param.name != 0) /* dummy test... */
2747                 DBG_88E("%s name(%u) != 0\n", __func__, param->u.wpa_param.name);
2748         value = param->u.wpa_param.value;
2749 
2750         /* use the same definition of hostapd's ignore_broadcast_ssid */
2751         if (value != 1 && value != 2)
2752                 value = 0;
2753         DBG_88E("%s value(%u)\n", __func__, value);
2754         pmlmeinfo->hidden_ssid_mode = value;
2755         return 0;
2756 }
2757 
2758 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
2759 {
2760         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2761         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2762 
2763         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2764                 return -EINVAL;
2765 
2766         if (is_broadcast_ether_addr(param->sta_addr))
2767                 return -EINVAL;
2768 
2769         return rtw_acl_remove_sta(padapter, param->sta_addr);
2770 }
2771 
2772 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
2773 {
2774         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2775         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2776 
2777         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2778                 return -EINVAL;
2779 
2780         if (is_broadcast_ether_addr(param->sta_addr))
2781                 return -EINVAL;
2782 
2783         return rtw_acl_add_sta(padapter, param->sta_addr);
2784 }
2785 
2786 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
2787 {
2788         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2789         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2790 
2791         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2792                 return -EINVAL;
2793 
2794         rtw_set_macaddr_acl(padapter, param->u.mlme.command);
2795 
2796         return 0;
2797 }
2798 
2799 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
2800 {
2801         struct ieee_param *param;
2802         int ret = 0;
2803         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2804 
2805         /*
2806         * this function is expect to call in master mode, which allows no power saving
2807         * so, we just check hw_init_completed
2808         */
2809 
2810         if (!padapter->hw_init_completed) {
2811                 ret = -EPERM;
2812                 goto out;
2813         }
2814 
2815         if (!p->pointer || p->length != sizeof(struct ieee_param)) {
2816                 ret = -EINVAL;
2817                 goto out;
2818         }
2819 
2820         param = (struct ieee_param *)rtw_malloc(p->length);
2821         if (!param) {
2822                 ret = -ENOMEM;
2823                 goto out;
2824         }
2825 
2826         if (copy_from_user(param, p->pointer, p->length)) {
2827                 kfree(param);
2828                 ret = -EFAULT;
2829                 goto out;
2830         }
2831 
2832         switch (param->cmd) {
2833         case RTL871X_HOSTAPD_FLUSH:
2834                 ret = rtw_hostapd_sta_flush(dev);
2835                 break;
2836         case RTL871X_HOSTAPD_ADD_STA:
2837                 ret = rtw_add_sta(dev, param);
2838                 break;
2839         case RTL871X_HOSTAPD_REMOVE_STA:
2840                 ret = rtw_del_sta(dev, param);
2841                 break;
2842         case RTL871X_HOSTAPD_SET_BEACON:
2843                 ret = rtw_set_beacon(dev, param, p->length);
2844                 break;
2845         case RTL871X_SET_ENCRYPTION:
2846                 ret = rtw_set_encryption(dev, param, p->length);
2847                 break;
2848         case RTL871X_HOSTAPD_GET_WPAIE_STA:
2849                 ret = rtw_get_sta_wpaie(dev, param);
2850                 break;
2851         case RTL871X_HOSTAPD_SET_WPS_BEACON:
2852                 ret = rtw_set_wps_beacon(dev, param, p->length);
2853                 break;
2854         case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
2855                 ret = rtw_set_wps_probe_resp(dev, param, p->length);
2856                 break;
2857         case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
2858                 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
2859                 break;
2860         case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
2861                 ret = rtw_set_hidden_ssid(dev, param, p->length);
2862                 break;
2863         case RTL871X_HOSTAPD_GET_INFO_STA:
2864                 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
2865                 break;
2866         case RTL871X_HOSTAPD_SET_MACADDR_ACL:
2867                 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
2868                 break;
2869         case RTL871X_HOSTAPD_ACL_ADD_STA:
2870                 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
2871                 break;
2872         case RTL871X_HOSTAPD_ACL_REMOVE_STA:
2873                 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
2874                 break;
2875         default:
2876                 DBG_88E("Unknown hostapd request: %d\n", param->cmd);
2877                 ret = -EOPNOTSUPP;
2878                 break;
2879         }
2880 
2881         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2882                 ret = -EFAULT;
2883         kfree(param);
2884 out:
2885         return ret;
2886 }
2887 #endif
2888 
2889 #include <rtw_android.h>
2890 static int rtw_wx_set_priv(struct net_device *dev,
2891                                 struct iw_request_info *info,
2892                                 union iwreq_data *awrq,
2893                                 char *extra)
2894 {
2895         int ret = 0;
2896         int len = 0;
2897         char *ext;
2898         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2899         struct iw_point *dwrq = (struct iw_point *)awrq;
2900 
2901         if (dwrq->length == 0)
2902                 return -EFAULT;
2903 
2904         len = dwrq->length;
2905         ext = vmalloc(len);
2906         if (!ext)
2907                 return -ENOMEM;
2908 
2909         if (copy_from_user(ext, dwrq->pointer, len)) {
2910                 vfree(ext);
2911                 return -EFAULT;
2912         }
2913 
2914         /* added for wps2.0 @20110524 */
2915         if (dwrq->flags == 0x8766 && len > 8) {
2916                 u32 cp_sz;
2917                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2918                 u8 *probereq_wpsie = ext;
2919                 int probereq_wpsie_len = len;
2920                 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2921 
2922                 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
2923                     (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
2924                         cp_sz = min(probereq_wpsie_len, MAX_WPS_IE_LEN);
2925 
2926                         pmlmepriv->wps_probe_req_ie_len = 0;
2927                         kfree(pmlmepriv->wps_probe_req_ie);
2928                         pmlmepriv->wps_probe_req_ie = NULL;
2929 
2930                         pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
2931                         if (!pmlmepriv->wps_probe_req_ie) {
2932                                 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2933                                 ret =  -EINVAL;
2934                                 goto FREE_EXT;
2935                         }
2936                         memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
2937                         pmlmepriv->wps_probe_req_ie_len = cp_sz;
2938                 }
2939                 goto FREE_EXT;
2940         }
2941 
2942         if (len >= WEXT_CSCAN_HEADER_SIZE &&
2943             !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
2944                 ret = rtw_wx_set_scan(dev, info, awrq, ext);
2945                 goto FREE_EXT;
2946         }
2947 
2948 FREE_EXT:
2949 
2950         vfree(ext);
2951 
2952         return ret;
2953 }
2954 
2955 static iw_handler rtw_handlers[] = {
2956         NULL,                                   /* SIOCSIWCOMMIT */
2957         rtw_wx_get_name,                /* SIOCGIWNAME */
2958         dummy,                                  /* SIOCSIWNWID */
2959         dummy,                                  /* SIOCGIWNWID */
2960         rtw_wx_set_freq,                /* SIOCSIWFREQ */
2961         rtw_wx_get_freq,                /* SIOCGIWFREQ */
2962         rtw_wx_set_mode,                /* SIOCSIWMODE */
2963         rtw_wx_get_mode,                /* SIOCGIWMODE */
2964         dummy,                                  /* SIOCSIWSENS */
2965         rtw_wx_get_sens,                /* SIOCGIWSENS */
2966         NULL,                                   /* SIOCSIWRANGE */
2967         rtw_wx_get_range,               /* SIOCGIWRANGE */
2968         rtw_wx_set_priv,                /* SIOCSIWPRIV */
2969         NULL,                                   /* SIOCGIWPRIV */
2970         NULL,                                   /* SIOCSIWSTATS */
2971         NULL,                                   /* SIOCGIWSTATS */
2972         dummy,                                  /* SIOCSIWSPY */
2973         dummy,                                  /* SIOCGIWSPY */
2974         NULL,                                   /* SIOCGIWTHRSPY */
2975         NULL,                                   /* SIOCWIWTHRSPY */
2976         rtw_wx_set_wap,         /* SIOCSIWAP */
2977         rtw_wx_get_wap,         /* SIOCGIWAP */
2978         rtw_wx_set_mlme,                /* request MLME operation; uses struct iw_mlme */
2979         dummy,                                  /* SIOCGIWAPLIST -- depricated */
2980         rtw_wx_set_scan,                /* SIOCSIWSCAN */
2981         rtw_wx_get_scan,                /* SIOCGIWSCAN */
2982         rtw_wx_set_essid,               /* SIOCSIWESSID */
2983         rtw_wx_get_essid,               /* SIOCGIWESSID */
2984         dummy,                                  /* SIOCSIWNICKN */
2985         rtw_wx_get_nick,                /* SIOCGIWNICKN */
2986         NULL,                                   /* -- hole -- */
2987         NULL,                                   /* -- hole -- */
2988         rtw_wx_set_rate,                /* SIOCSIWRATE */
2989         rtw_wx_get_rate,                /* SIOCGIWRATE */
2990         rtw_wx_set_rts,                 /* SIOCSIWRTS */
2991         rtw_wx_get_rts,                 /* SIOCGIWRTS */
2992         rtw_wx_set_frag,                /* SIOCSIWFRAG */
2993         rtw_wx_get_frag,                /* SIOCGIWFRAG */
2994         dummy,                                  /* SIOCSIWTXPOW */
2995         dummy,                                  /* SIOCGIWTXPOW */
2996         dummy,                                  /* SIOCSIWRETRY */
2997         rtw_wx_get_retry,               /* SIOCGIWRETRY */
2998         rtw_wx_set_enc,                 /* SIOCSIWENCODE */
2999         rtw_wx_get_enc,                 /* SIOCGIWENCODE */
3000         dummy,                                  /* SIOCSIWPOWER */
3001         rtw_wx_get_power,               /* SIOCGIWPOWER */
3002         NULL,                                   /*---hole---*/
3003         NULL,                                   /*---hole---*/
3004         rtw_wx_set_gen_ie,              /* SIOCSIWGENIE */
3005         NULL,                                   /* SIOCGWGENIE */
3006         rtw_wx_set_auth,                /* SIOCSIWAUTH */
3007         NULL,                                   /* SIOCGIWAUTH */
3008         rtw_wx_set_enc_ext,             /* SIOCSIWENCODEEXT */
3009         NULL,                                   /* SIOCGIWENCODEEXT */
3010         rtw_wx_set_pmkid,               /* SIOCSIWPMKSA */
3011         NULL,                                   /*---hole---*/
3012 };
3013 
3014 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
3015 {
3016         struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3017         struct iw_statistics *piwstats = &padapter->iwstats;
3018         int tmp_level = 0;
3019         int tmp_qual = 0;
3020         int tmp_noise = 0;
3021 
3022         if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3023                 piwstats->qual.qual = 0;
3024                 piwstats->qual.level = 0;
3025                 piwstats->qual.noise = 0;
3026         } else {
3027                 tmp_level = padapter->recvpriv.signal_strength;
3028                 tmp_qual = padapter->recvpriv.signal_qual;
3029                 tmp_noise = padapter->recvpriv.noise;
3030 
3031                 piwstats->qual.level = tmp_level;
3032                 piwstats->qual.qual = tmp_qual;
3033                 piwstats->qual.noise = tmp_noise;
3034         }
3035         piwstats->qual.updated = IW_QUAL_ALL_UPDATED;/* IW_QUAL_DBM; */
3036         return &padapter->iwstats;
3037 }
3038 
3039 struct iw_handler_def rtw_handlers_def = {
3040         .standard = rtw_handlers,
3041         .num_standard = ARRAY_SIZE(rtw_handlers),
3042         .get_wireless_stats = rtw_get_wireless_stats,
3043 };
3044 
3045 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3046 {
3047         struct iwreq *wrq = (struct iwreq *)rq;
3048         int ret = 0;
3049 
3050         switch (cmd) {
3051         case RTL_IOCTL_WPA_SUPPLICANT:
3052                 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
3053                 break;
3054 #ifdef CONFIG_88EU_AP_MODE
3055         case RTL_IOCTL_HOSTAPD:
3056                 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
3057                 break;
3058 #endif /*  CONFIG_88EU_AP_MODE */
3059         case (SIOCDEVPRIVATE+1):
3060                 ret = rtw_android_priv_cmd(dev, rq, cmd);
3061                 break;
3062         default:
3063                 ret = -EOPNOTSUPP;
3064                 break;
3065         }
3066         return ret;
3067 }

/* [<][>][^][v][top][bottom][index][help] */