root/drivers/net/wireless/ath/ath6kl/cfg80211.c

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

DEFINITIONS

This source file includes following definitions.
  1. __ath6kl_cfg80211_sscan_stop
  2. ath6kl_cfg80211_sscan_disable
  3. ath6kl_set_wpa_version
  4. ath6kl_set_auth_type
  5. ath6kl_set_cipher
  6. ath6kl_set_key_mgmt
  7. ath6kl_cfg80211_ready
  8. ath6kl_is_wpa_ie
  9. ath6kl_is_rsn_ie
  10. ath6kl_is_wps_ie
  11. ath6kl_set_assoc_req_ies
  12. ath6kl_nliftype_to_drv_iftype
  13. ath6kl_is_valid_iftype
  14. ath6kl_is_tx_pending
  15. ath6kl_cfg80211_sta_bmiss_enhance
  16. ath6kl_cfg80211_connect
  17. ath6kl_add_bss_if_needed
  18. ath6kl_cfg80211_connect_event
  19. ath6kl_cfg80211_disconnect
  20. ath6kl_cfg80211_disconnect_event
  21. ath6kl_set_probed_ssids
  22. ath6kl_cfg80211_scan
  23. ath6kl_cfg80211_scan_complete_event
  24. ath6kl_cfg80211_ch_switch_notify
  25. ath6kl_cfg80211_add_key
  26. ath6kl_cfg80211_del_key
  27. ath6kl_cfg80211_get_key
  28. ath6kl_cfg80211_set_default_key
  29. ath6kl_cfg80211_tkip_micerr_event
  30. ath6kl_cfg80211_set_wiphy_params
  31. ath6kl_cfg80211_set_txpower
  32. ath6kl_cfg80211_get_txpower
  33. ath6kl_cfg80211_set_power_mgmt
  34. ath6kl_cfg80211_add_iface
  35. ath6kl_cfg80211_del_iface
  36. ath6kl_cfg80211_change_iface
  37. ath6kl_cfg80211_join_ibss
  38. ath6kl_cfg80211_leave_ibss
  39. is_rate_legacy
  40. is_rate_ht20
  41. is_rate_ht40
  42. ath6kl_get_station
  43. ath6kl_set_pmksa
  44. ath6kl_del_pmksa
  45. ath6kl_flush_pmksa
  46. ath6kl_wow_usr
  47. ath6kl_wow_ap
  48. ath6kl_wow_sta
  49. is_hsleep_mode_procsed
  50. is_ctrl_ep_empty
  51. ath6kl_cfg80211_host_sleep
  52. ath6kl_wow_suspend_vif
  53. ath6kl_wow_suspend
  54. ath6kl_wow_resume_vif
  55. ath6kl_wow_resume
  56. ath6kl_cfg80211_deepsleep_suspend
  57. ath6kl_cfg80211_deepsleep_resume
  58. ath6kl_cfg80211_suspend
  59. ath6kl_cfg80211_resume
  60. __ath6kl_cfg80211_suspend
  61. __ath6kl_cfg80211_resume
  62. ath6kl_check_wow_status
  63. ath6kl_check_wow_status
  64. ath6kl_set_htcap
  65. ath6kl_restore_htcap
  66. ath6kl_is_p2p_ie
  67. ath6kl_set_ap_probe_resp_ies
  68. ath6kl_set_ies
  69. ath6kl_get_rsn_capab
  70. ath6kl_start_ap
  71. ath6kl_change_beacon
  72. ath6kl_stop_ap
  73. ath6kl_del_station
  74. ath6kl_change_station
  75. ath6kl_remain_on_channel
  76. ath6kl_cancel_remain_on_channel
  77. ath6kl_send_go_probe_resp
  78. ath6kl_mgmt_powersave_ap
  79. ath6kl_is_p2p_go_ssid
  80. ath6kl_mgmt_tx
  81. ath6kl_get_antenna
  82. ath6kl_mgmt_frame_register
  83. ath6kl_cfg80211_sscan_start
  84. ath6kl_cfg80211_sscan_stop
  85. ath6kl_cfg80211_set_bitrate
  86. ath6kl_cfg80211_set_txe_config
  87. ath6kl_cfg80211_stop
  88. ath6kl_cfg80211_stop_all
  89. ath6kl_cfg80211_reg_notify
  90. ath6kl_cfg80211_vif_init
  91. ath6kl_cfg80211_vif_stop
  92. ath6kl_cfg80211_vif_cleanup
  93. ath6kl_get_sset_count
  94. ath6kl_get_stats
  95. ath6kl_get_strings
  96. ath6kl_interface_add
  97. ath6kl_cfg80211_init
  98. ath6kl_cfg80211_cleanup
  99. ath6kl_cfg80211_create
  100. ath6kl_cfg80211_destroy

   1 /*
   2  * Copyright (c) 2004-2011 Atheros Communications Inc.
   3  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
   4  *
   5  * Permission to use, copy, modify, and/or distribute this software for any
   6  * purpose with or without fee is hereby granted, provided that the above
   7  * copyright notice and this permission notice appear in all copies.
   8  *
   9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16  */
  17 
  18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19 
  20 #include <linux/moduleparam.h>
  21 #include <linux/inetdevice.h>
  22 #include <linux/export.h>
  23 #include <linux/sched/signal.h>
  24 
  25 #include "core.h"
  26 #include "cfg80211.h"
  27 #include "debug.h"
  28 #include "hif-ops.h"
  29 #include "testmode.h"
  30 
  31 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
  32         .bitrate    = (_rate),                  \
  33         .flags      = (_flags),                 \
  34         .hw_value   = (_rateid),                \
  35 }
  36 
  37 #define CHAN2G(_channel, _freq, _flags) {   \
  38         .band           = NL80211_BAND_2GHZ,  \
  39         .hw_value       = (_channel),           \
  40         .center_freq    = (_freq),              \
  41         .flags          = (_flags),             \
  42         .max_antenna_gain   = 0,                \
  43         .max_power      = 30,                   \
  44 }
  45 
  46 #define CHAN5G(_channel, _flags) {                  \
  47         .band           = NL80211_BAND_5GHZ,      \
  48         .hw_value       = (_channel),               \
  49         .center_freq    = 5000 + (5 * (_channel)),  \
  50         .flags          = (_flags),                 \
  51         .max_antenna_gain   = 0,                    \
  52         .max_power      = 30,                       \
  53 }
  54 
  55 #define DEFAULT_BG_SCAN_PERIOD 60
  56 
  57 struct ath6kl_cfg80211_match_probe_ssid {
  58         struct cfg80211_ssid ssid;
  59         u8 flag;
  60 };
  61 
  62 static struct ieee80211_rate ath6kl_rates[] = {
  63         RATETAB_ENT(10, 0x1, 0),
  64         RATETAB_ENT(20, 0x2, 0),
  65         RATETAB_ENT(55, 0x4, 0),
  66         RATETAB_ENT(110, 0x8, 0),
  67         RATETAB_ENT(60, 0x10, 0),
  68         RATETAB_ENT(90, 0x20, 0),
  69         RATETAB_ENT(120, 0x40, 0),
  70         RATETAB_ENT(180, 0x80, 0),
  71         RATETAB_ENT(240, 0x100, 0),
  72         RATETAB_ENT(360, 0x200, 0),
  73         RATETAB_ENT(480, 0x400, 0),
  74         RATETAB_ENT(540, 0x800, 0),
  75 };
  76 
  77 #define ath6kl_a_rates     (ath6kl_rates + 4)
  78 #define ath6kl_a_rates_size    8
  79 #define ath6kl_g_rates     (ath6kl_rates + 0)
  80 #define ath6kl_g_rates_size    12
  81 
  82 #define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
  83 #define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
  84                         IEEE80211_HT_CAP_SGI_20          | \
  85                         IEEE80211_HT_CAP_SGI_40)
  86 
  87 static struct ieee80211_channel ath6kl_2ghz_channels[] = {
  88         CHAN2G(1, 2412, 0),
  89         CHAN2G(2, 2417, 0),
  90         CHAN2G(3, 2422, 0),
  91         CHAN2G(4, 2427, 0),
  92         CHAN2G(5, 2432, 0),
  93         CHAN2G(6, 2437, 0),
  94         CHAN2G(7, 2442, 0),
  95         CHAN2G(8, 2447, 0),
  96         CHAN2G(9, 2452, 0),
  97         CHAN2G(10, 2457, 0),
  98         CHAN2G(11, 2462, 0),
  99         CHAN2G(12, 2467, 0),
 100         CHAN2G(13, 2472, 0),
 101         CHAN2G(14, 2484, 0),
 102 };
 103 
 104 static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
 105         CHAN5G(36, 0), CHAN5G(40, 0),
 106         CHAN5G(44, 0), CHAN5G(48, 0),
 107         CHAN5G(52, 0), CHAN5G(56, 0),
 108         CHAN5G(60, 0), CHAN5G(64, 0),
 109         CHAN5G(100, 0), CHAN5G(104, 0),
 110         CHAN5G(108, 0), CHAN5G(112, 0),
 111         CHAN5G(116, 0), CHAN5G(120, 0),
 112         CHAN5G(124, 0), CHAN5G(128, 0),
 113         CHAN5G(132, 0), CHAN5G(136, 0),
 114         CHAN5G(140, 0), CHAN5G(149, 0),
 115         CHAN5G(153, 0), CHAN5G(157, 0),
 116         CHAN5G(161, 0), CHAN5G(165, 0),
 117         CHAN5G(184, 0), CHAN5G(188, 0),
 118         CHAN5G(192, 0), CHAN5G(196, 0),
 119         CHAN5G(200, 0), CHAN5G(204, 0),
 120         CHAN5G(208, 0), CHAN5G(212, 0),
 121         CHAN5G(216, 0),
 122 };
 123 
 124 static struct ieee80211_supported_band ath6kl_band_2ghz = {
 125         .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
 126         .channels = ath6kl_2ghz_channels,
 127         .n_bitrates = ath6kl_g_rates_size,
 128         .bitrates = ath6kl_g_rates,
 129         .ht_cap.cap = ath6kl_g_htcap,
 130         .ht_cap.ht_supported = true,
 131 };
 132 
 133 static struct ieee80211_supported_band ath6kl_band_5ghz = {
 134         .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
 135         .channels = ath6kl_5ghz_a_channels,
 136         .n_bitrates = ath6kl_a_rates_size,
 137         .bitrates = ath6kl_a_rates,
 138         .ht_cap.cap = ath6kl_a_htcap,
 139         .ht_cap.ht_supported = true,
 140 };
 141 
 142 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
 143 
 144 /* returns true if scheduled scan was stopped */
 145 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
 146 {
 147         struct ath6kl *ar = vif->ar;
 148 
 149         if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
 150                 return false;
 151 
 152         del_timer_sync(&vif->sched_scan_timer);
 153 
 154         if (ar->state == ATH6KL_STATE_RECOVERY)
 155                 return true;
 156 
 157         ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
 158 
 159         return true;
 160 }
 161 
 162 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
 163 {
 164         struct ath6kl *ar = vif->ar;
 165         bool stopped;
 166 
 167         stopped = __ath6kl_cfg80211_sscan_stop(vif);
 168 
 169         if (!stopped)
 170                 return;
 171 
 172         cfg80211_sched_scan_stopped(ar->wiphy, 0);
 173 }
 174 
 175 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
 176                                   enum nl80211_wpa_versions wpa_version)
 177 {
 178         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
 179 
 180         if (!wpa_version) {
 181                 vif->auth_mode = NONE_AUTH;
 182         } else if (wpa_version & NL80211_WPA_VERSION_2) {
 183                 vif->auth_mode = WPA2_AUTH;
 184         } else if (wpa_version & NL80211_WPA_VERSION_1) {
 185                 vif->auth_mode = WPA_AUTH;
 186         } else {
 187                 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
 188                 return -ENOTSUPP;
 189         }
 190 
 191         return 0;
 192 }
 193 
 194 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
 195                                 enum nl80211_auth_type auth_type)
 196 {
 197         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
 198 
 199         switch (auth_type) {
 200         case NL80211_AUTHTYPE_OPEN_SYSTEM:
 201                 vif->dot11_auth_mode = OPEN_AUTH;
 202                 break;
 203         case NL80211_AUTHTYPE_SHARED_KEY:
 204                 vif->dot11_auth_mode = SHARED_AUTH;
 205                 break;
 206         case NL80211_AUTHTYPE_NETWORK_EAP:
 207                 vif->dot11_auth_mode = LEAP_AUTH;
 208                 break;
 209 
 210         case NL80211_AUTHTYPE_AUTOMATIC:
 211                 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
 212                 break;
 213 
 214         default:
 215                 ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
 216                 return -ENOTSUPP;
 217         }
 218 
 219         return 0;
 220 }
 221 
 222 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
 223 {
 224         u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
 225         u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
 226                 &vif->grp_crypto_len;
 227 
 228         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
 229                    __func__, cipher, ucast);
 230 
 231         switch (cipher) {
 232         case 0:
 233                 /* our own hack to use value 0 as no crypto used */
 234                 *ar_cipher = NONE_CRYPT;
 235                 *ar_cipher_len = 0;
 236                 break;
 237         case WLAN_CIPHER_SUITE_WEP40:
 238                 *ar_cipher = WEP_CRYPT;
 239                 *ar_cipher_len = 5;
 240                 break;
 241         case WLAN_CIPHER_SUITE_WEP104:
 242                 *ar_cipher = WEP_CRYPT;
 243                 *ar_cipher_len = 13;
 244                 break;
 245         case WLAN_CIPHER_SUITE_TKIP:
 246                 *ar_cipher = TKIP_CRYPT;
 247                 *ar_cipher_len = 0;
 248                 break;
 249         case WLAN_CIPHER_SUITE_CCMP:
 250                 *ar_cipher = AES_CRYPT;
 251                 *ar_cipher_len = 0;
 252                 break;
 253         case WLAN_CIPHER_SUITE_SMS4:
 254                 *ar_cipher = WAPI_CRYPT;
 255                 *ar_cipher_len = 0;
 256                 break;
 257         default:
 258                 ath6kl_err("cipher 0x%x not supported\n", cipher);
 259                 return -ENOTSUPP;
 260         }
 261 
 262         return 0;
 263 }
 264 
 265 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
 266 {
 267         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
 268 
 269         if (key_mgmt == WLAN_AKM_SUITE_PSK) {
 270                 if (vif->auth_mode == WPA_AUTH)
 271                         vif->auth_mode = WPA_PSK_AUTH;
 272                 else if (vif->auth_mode == WPA2_AUTH)
 273                         vif->auth_mode = WPA2_PSK_AUTH;
 274         } else if (key_mgmt == 0x00409600) {
 275                 if (vif->auth_mode == WPA_AUTH)
 276                         vif->auth_mode = WPA_AUTH_CCKM;
 277                 else if (vif->auth_mode == WPA2_AUTH)
 278                         vif->auth_mode = WPA2_AUTH_CCKM;
 279         } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
 280                 vif->auth_mode = NONE_AUTH;
 281         }
 282 }
 283 
 284 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
 285 {
 286         struct ath6kl *ar = vif->ar;
 287 
 288         if (!test_bit(WMI_READY, &ar->flag)) {
 289                 ath6kl_err("wmi is not ready\n");
 290                 return false;
 291         }
 292 
 293         if (!test_bit(WLAN_ENABLED, &vif->flags)) {
 294                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "wlan disabled\n");
 295                 return false;
 296         }
 297 
 298         return true;
 299 }
 300 
 301 static bool ath6kl_is_wpa_ie(const u8 *pos)
 302 {
 303         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
 304                 pos[2] == 0x00 && pos[3] == 0x50 &&
 305                 pos[4] == 0xf2 && pos[5] == 0x01;
 306 }
 307 
 308 static bool ath6kl_is_rsn_ie(const u8 *pos)
 309 {
 310         return pos[0] == WLAN_EID_RSN;
 311 }
 312 
 313 static bool ath6kl_is_wps_ie(const u8 *pos)
 314 {
 315         return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
 316                 pos[1] >= 4 &&
 317                 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
 318                 pos[5] == 0x04);
 319 }
 320 
 321 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
 322                                     size_t ies_len)
 323 {
 324         struct ath6kl *ar = vif->ar;
 325         const u8 *pos;
 326         u8 *buf = NULL;
 327         size_t len = 0;
 328         int ret;
 329 
 330         /*
 331          * Clear previously set flag
 332          */
 333 
 334         ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 335 
 336         /*
 337          * Filter out RSN/WPA IE(s)
 338          */
 339 
 340         if (ies && ies_len) {
 341                 buf = kmalloc(ies_len, GFP_KERNEL);
 342                 if (buf == NULL)
 343                         return -ENOMEM;
 344                 pos = ies;
 345 
 346                 while (pos + 1 < ies + ies_len) {
 347                         if (pos + 2 + pos[1] > ies + ies_len)
 348                                 break;
 349                         if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
 350                                 memcpy(buf + len, pos, 2 + pos[1]);
 351                                 len += 2 + pos[1];
 352                         }
 353 
 354                         if (ath6kl_is_wps_ie(pos))
 355                                 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
 356 
 357                         pos += 2 + pos[1];
 358                 }
 359         }
 360 
 361         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
 362                                        WMI_FRAME_ASSOC_REQ, buf, len);
 363         kfree(buf);
 364         return ret;
 365 }
 366 
 367 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
 368 {
 369         switch (type) {
 370         case NL80211_IFTYPE_STATION:
 371         case NL80211_IFTYPE_P2P_CLIENT:
 372                 *nw_type = INFRA_NETWORK;
 373                 break;
 374         case NL80211_IFTYPE_ADHOC:
 375                 *nw_type = ADHOC_NETWORK;
 376                 break;
 377         case NL80211_IFTYPE_AP:
 378         case NL80211_IFTYPE_P2P_GO:
 379                 *nw_type = AP_NETWORK;
 380                 break;
 381         default:
 382                 ath6kl_err("invalid interface type %u\n", type);
 383                 return -ENOTSUPP;
 384         }
 385 
 386         return 0;
 387 }
 388 
 389 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
 390                                    u8 *if_idx, u8 *nw_type)
 391 {
 392         int i;
 393 
 394         if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
 395                 return false;
 396 
 397         if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
 398                                    ar->num_vif))
 399                 return false;
 400 
 401         if (type == NL80211_IFTYPE_STATION ||
 402             type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
 403                 for (i = 0; i < ar->vif_max; i++) {
 404                         if ((ar->avail_idx_map) & BIT(i)) {
 405                                 *if_idx = i;
 406                                 return true;
 407                         }
 408                 }
 409         }
 410 
 411         if (type == NL80211_IFTYPE_P2P_CLIENT ||
 412             type == NL80211_IFTYPE_P2P_GO) {
 413                 for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
 414                         if ((ar->avail_idx_map) & BIT(i)) {
 415                                 *if_idx = i;
 416                                 return true;
 417                         }
 418                 }
 419         }
 420 
 421         return false;
 422 }
 423 
 424 static bool ath6kl_is_tx_pending(struct ath6kl *ar)
 425 {
 426         return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
 427 }
 428 
 429 static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
 430                                               bool enable)
 431 {
 432         int err;
 433 
 434         if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
 435                 return;
 436 
 437         if (vif->nw_type != INFRA_NETWORK)
 438                 return;
 439 
 440         if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
 441                       vif->ar->fw_capabilities))
 442                 return;
 443 
 444         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
 445                    enable ? "enable" : "disable");
 446 
 447         err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
 448                                                vif->fw_vif_idx, enable);
 449         if (err)
 450                 ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
 451                            enable ? "enable" : "disable", err);
 452 }
 453 
 454 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 455                                    struct cfg80211_connect_params *sme)
 456 {
 457         struct ath6kl *ar = ath6kl_priv(dev);
 458         struct ath6kl_vif *vif = netdev_priv(dev);
 459         int status;
 460         u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
 461         u16 interval;
 462 
 463         ath6kl_cfg80211_sscan_disable(vif);
 464 
 465         vif->sme_state = SME_CONNECTING;
 466 
 467         if (!ath6kl_cfg80211_ready(vif))
 468                 return -EIO;
 469 
 470         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 471                 ath6kl_err("destroy in progress\n");
 472                 return -EBUSY;
 473         }
 474 
 475         if (test_bit(SKIP_SCAN, &ar->flag) &&
 476             ((sme->channel && sme->channel->center_freq == 0) ||
 477              (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
 478                 ath6kl_err("SkipScan: channel or bssid invalid\n");
 479                 return -EINVAL;
 480         }
 481 
 482         if (down_interruptible(&ar->sem)) {
 483                 ath6kl_err("busy, couldn't get access\n");
 484                 return -ERESTARTSYS;
 485         }
 486 
 487         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 488                 ath6kl_err("busy, destroy in progress\n");
 489                 up(&ar->sem);
 490                 return -EBUSY;
 491         }
 492 
 493         if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
 494                 /*
 495                  * sleep until the command queue drains
 496                  */
 497                 wait_event_interruptible_timeout(ar->event_wq,
 498                                                  ath6kl_is_tx_pending(ar),
 499                                                  WMI_TIMEOUT);
 500                 if (signal_pending(current)) {
 501                         ath6kl_err("cmd queue drain timeout\n");
 502                         up(&ar->sem);
 503                         return -EINTR;
 504                 }
 505         }
 506 
 507         status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
 508         if (status) {
 509                 up(&ar->sem);
 510                 return status;
 511         }
 512 
 513         if (sme->ie == NULL || sme->ie_len == 0)
 514                 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 515 
 516         if (test_bit(CONNECTED, &vif->flags) &&
 517             vif->ssid_len == sme->ssid_len &&
 518             !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 519                 vif->reconnect_flag = true;
 520                 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
 521                                                   vif->req_bssid,
 522                                                   vif->ch_hint);
 523 
 524                 up(&ar->sem);
 525                 if (status) {
 526                         ath6kl_err("wmi_reconnect_cmd failed\n");
 527                         return -EIO;
 528                 }
 529                 return 0;
 530         } else if (vif->ssid_len == sme->ssid_len &&
 531                    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 532                 ath6kl_disconnect(vif);
 533         }
 534 
 535         memset(vif->ssid, 0, sizeof(vif->ssid));
 536         vif->ssid_len = sme->ssid_len;
 537         memcpy(vif->ssid, sme->ssid, sme->ssid_len);
 538 
 539         if (sme->channel)
 540                 vif->ch_hint = sme->channel->center_freq;
 541 
 542         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 543         if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
 544                 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
 545 
 546         ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
 547 
 548         status = ath6kl_set_auth_type(vif, sme->auth_type);
 549         if (status) {
 550                 up(&ar->sem);
 551                 return status;
 552         }
 553 
 554         if (sme->crypto.n_ciphers_pairwise)
 555                 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
 556         else
 557                 ath6kl_set_cipher(vif, 0, true);
 558 
 559         ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
 560 
 561         if (sme->crypto.n_akm_suites)
 562                 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
 563 
 564         if ((sme->key_len) &&
 565             (vif->auth_mode == NONE_AUTH) &&
 566             (vif->prwise_crypto == WEP_CRYPT)) {
 567                 struct ath6kl_key *key = NULL;
 568 
 569                 if (sme->key_idx > WMI_MAX_KEY_INDEX) {
 570                         ath6kl_err("key index %d out of bounds\n",
 571                                    sme->key_idx);
 572                         up(&ar->sem);
 573                         return -ENOENT;
 574                 }
 575 
 576                 key = &vif->keys[sme->key_idx];
 577                 key->key_len = sme->key_len;
 578                 memcpy(key->key, sme->key, key->key_len);
 579                 key->cipher = vif->prwise_crypto;
 580                 vif->def_txkey_index = sme->key_idx;
 581 
 582                 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
 583                                       vif->prwise_crypto,
 584                                       GROUP_USAGE | TX_USAGE,
 585                                       key->key_len,
 586                                       NULL, 0,
 587                                       key->key, KEY_OP_INIT_VAL, NULL,
 588                                       NO_SYNC_WMIFLAG);
 589         }
 590 
 591         if (!ar->usr_bss_filter) {
 592                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 593                 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 594                                              ALL_BSS_FILTER, 0) != 0) {
 595                         ath6kl_err("couldn't set bss filtering\n");
 596                         up(&ar->sem);
 597                         return -EIO;
 598                 }
 599         }
 600 
 601         vif->nw_type = vif->next_mode;
 602 
 603         /* enable enhanced bmiss detection if applicable */
 604         ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
 605 
 606         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
 607                 nw_subtype = SUBTYPE_P2PCLIENT;
 608 
 609         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 610                    "%s: connect called with authmode %d dot11 auth %d"
 611                    " PW crypto %d PW crypto len %d GRP crypto %d"
 612                    " GRP crypto len %d channel hint %u\n",
 613                    __func__,
 614                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
 615                    vif->prwise_crypto_len, vif->grp_crypto,
 616                    vif->grp_crypto_len, vif->ch_hint);
 617 
 618         vif->reconnect_flag = 0;
 619 
 620         if (vif->nw_type == INFRA_NETWORK) {
 621                 interval = max_t(u16, vif->listen_intvl_t,
 622                                  ATH6KL_MAX_WOW_LISTEN_INTL);
 623                 status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 624                                                        interval,
 625                                                        0);
 626                 if (status) {
 627                         ath6kl_err("couldn't set listen intervel\n");
 628                         up(&ar->sem);
 629                         return status;
 630                 }
 631         }
 632 
 633         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
 634                                         vif->dot11_auth_mode, vif->auth_mode,
 635                                         vif->prwise_crypto,
 636                                         vif->prwise_crypto_len,
 637                                         vif->grp_crypto, vif->grp_crypto_len,
 638                                         vif->ssid_len, vif->ssid,
 639                                         vif->req_bssid, vif->ch_hint,
 640                                         ar->connect_ctrl_flags, nw_subtype);
 641 
 642         if (sme->bg_scan_period == 0) {
 643                 /* disable background scan if period is 0 */
 644                 sme->bg_scan_period = 0xffff;
 645         } else if (sme->bg_scan_period == -1) {
 646                 /* configure default value if not specified */
 647                 sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
 648         }
 649 
 650         ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
 651                                   sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
 652 
 653         up(&ar->sem);
 654 
 655         if (status == -EINVAL) {
 656                 memset(vif->ssid, 0, sizeof(vif->ssid));
 657                 vif->ssid_len = 0;
 658                 ath6kl_err("invalid request\n");
 659                 return -ENOENT;
 660         } else if (status) {
 661                 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
 662                 return -EIO;
 663         }
 664 
 665         if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
 666             ((vif->auth_mode == WPA_PSK_AUTH) ||
 667              (vif->auth_mode == WPA2_PSK_AUTH))) {
 668                 mod_timer(&vif->disconnect_timer,
 669                           jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
 670         }
 671 
 672         ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
 673         set_bit(CONNECT_PEND, &vif->flags);
 674 
 675         return 0;
 676 }
 677 
 678 static struct cfg80211_bss *
 679 ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 680                          enum network_type nw_type,
 681                          const u8 *bssid,
 682                          struct ieee80211_channel *chan,
 683                          const u8 *beacon_ie,
 684                          size_t beacon_ie_len)
 685 {
 686         struct ath6kl *ar = vif->ar;
 687         struct cfg80211_bss *bss;
 688         u16 cap_val;
 689         enum ieee80211_bss_type bss_type;
 690         u8 *ie;
 691 
 692         if (nw_type & ADHOC_NETWORK) {
 693                 cap_val = WLAN_CAPABILITY_IBSS;
 694                 bss_type = IEEE80211_BSS_TYPE_IBSS;
 695         } else {
 696                 cap_val = WLAN_CAPABILITY_ESS;
 697                 bss_type = IEEE80211_BSS_TYPE_ESS;
 698         }
 699 
 700         bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
 701                                vif->ssid, vif->ssid_len,
 702                                bss_type, IEEE80211_PRIVACY_ANY);
 703         if (bss == NULL) {
 704                 /*
 705                  * Since cfg80211 may not yet know about the BSS,
 706                  * generate a partial entry until the first BSS info
 707                  * event becomes available.
 708                  *
 709                  * Prepend SSID element since it is not included in the Beacon
 710                  * IEs from the target.
 711                  */
 712                 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
 713                 if (ie == NULL)
 714                         return NULL;
 715                 ie[0] = WLAN_EID_SSID;
 716                 ie[1] = vif->ssid_len;
 717                 memcpy(ie + 2, vif->ssid, vif->ssid_len);
 718                 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
 719                 bss = cfg80211_inform_bss(ar->wiphy, chan,
 720                                           CFG80211_BSS_FTYPE_UNKNOWN,
 721                                           bssid, 0, cap_val, 100,
 722                                           ie, 2 + vif->ssid_len + beacon_ie_len,
 723                                           0, GFP_KERNEL);
 724                 if (bss)
 725                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 726                                    "added bss %pM to cfg80211\n", bssid);
 727                 kfree(ie);
 728         } else {
 729                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 730         }
 731 
 732         return bss;
 733 }
 734 
 735 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 736                                    u8 *bssid, u16 listen_intvl,
 737                                    u16 beacon_intvl,
 738                                    enum network_type nw_type,
 739                                    u8 beacon_ie_len, u8 assoc_req_len,
 740                                    u8 assoc_resp_len, u8 *assoc_info)
 741 {
 742         struct ieee80211_channel *chan;
 743         struct ath6kl *ar = vif->ar;
 744         struct cfg80211_bss *bss;
 745 
 746         /* capinfo + listen interval */
 747         u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
 748 
 749         /* capinfo + status code +  associd */
 750         u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
 751 
 752         u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
 753         u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
 754             assoc_resp_ie_offset;
 755 
 756         assoc_req_len -= assoc_req_ie_offset;
 757         assoc_resp_len -= assoc_resp_ie_offset;
 758 
 759         /*
 760          * Store Beacon interval here; DTIM period will be available only once
 761          * a Beacon frame from the AP is seen.
 762          */
 763         vif->assoc_bss_beacon_int = beacon_intvl;
 764         clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
 765 
 766         if (nw_type & ADHOC_NETWORK) {
 767                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
 768                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 769                                    "%s: ath6k not in ibss mode\n", __func__);
 770                         return;
 771                 }
 772         }
 773 
 774         if (nw_type & INFRA_NETWORK) {
 775                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 776                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 777                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 778                                    "%s: ath6k not in station mode\n", __func__);
 779                         return;
 780                 }
 781         }
 782 
 783         chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 784 
 785         bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
 786                                        assoc_info, beacon_ie_len);
 787         if (!bss) {
 788                 ath6kl_err("could not add cfg80211 bss entry\n");
 789                 return;
 790         }
 791 
 792         if (nw_type & ADHOC_NETWORK) {
 793                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
 794                            nw_type & ADHOC_CREATOR ? "creator" : "joiner");
 795                 cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
 796                 cfg80211_put_bss(ar->wiphy, bss);
 797                 return;
 798         }
 799 
 800         if (vif->sme_state == SME_CONNECTING) {
 801                 /* inform connect result to cfg80211 */
 802                 vif->sme_state = SME_CONNECTED;
 803                 cfg80211_connect_result(vif->ndev, bssid,
 804                                         assoc_req_ie, assoc_req_len,
 805                                         assoc_resp_ie, assoc_resp_len,
 806                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
 807                 cfg80211_put_bss(ar->wiphy, bss);
 808         } else if (vif->sme_state == SME_CONNECTED) {
 809                 struct cfg80211_roam_info roam_info = {
 810                         .bss = bss,
 811                         .req_ie = assoc_req_ie,
 812                         .req_ie_len = assoc_req_len,
 813                         .resp_ie = assoc_resp_ie,
 814                         .resp_ie_len = assoc_resp_len,
 815                 };
 816                 /* inform roam event to cfg80211 */
 817                 cfg80211_roamed(vif->ndev, &roam_info, GFP_KERNEL);
 818         }
 819 }
 820 
 821 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
 822                                       struct net_device *dev, u16 reason_code)
 823 {
 824         struct ath6kl *ar = ath6kl_priv(dev);
 825         struct ath6kl_vif *vif = netdev_priv(dev);
 826 
 827         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
 828                    reason_code);
 829 
 830         ath6kl_cfg80211_sscan_disable(vif);
 831 
 832         if (!ath6kl_cfg80211_ready(vif))
 833                 return -EIO;
 834 
 835         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 836                 ath6kl_err("busy, destroy in progress\n");
 837                 return -EBUSY;
 838         }
 839 
 840         if (down_interruptible(&ar->sem)) {
 841                 ath6kl_err("busy, couldn't get access\n");
 842                 return -ERESTARTSYS;
 843         }
 844 
 845         vif->reconnect_flag = 0;
 846         ath6kl_disconnect(vif);
 847         memset(vif->ssid, 0, sizeof(vif->ssid));
 848         vif->ssid_len = 0;
 849 
 850         if (!test_bit(SKIP_SCAN, &ar->flag))
 851                 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 852 
 853         up(&ar->sem);
 854 
 855         return 0;
 856 }
 857 
 858 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
 859                                       u8 *bssid, u8 assoc_resp_len,
 860                                       u8 *assoc_info, u16 proto_reason)
 861 {
 862         struct ath6kl *ar = vif->ar;
 863 
 864         if (vif->scan_req) {
 865                 struct cfg80211_scan_info info = {
 866                         .aborted = true,
 867                 };
 868 
 869                 cfg80211_scan_done(vif->scan_req, &info);
 870                 vif->scan_req = NULL;
 871         }
 872 
 873         if (vif->nw_type & ADHOC_NETWORK) {
 874                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
 875                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 876                                    "%s: ath6k not in ibss mode\n", __func__);
 877                 return;
 878         }
 879 
 880         if (vif->nw_type & INFRA_NETWORK) {
 881                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 882                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 883                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 884                                    "%s: ath6k not in station mode\n", __func__);
 885                         return;
 886                 }
 887         }
 888 
 889         clear_bit(CONNECT_PEND, &vif->flags);
 890 
 891         if (vif->sme_state == SME_CONNECTING) {
 892                 cfg80211_connect_result(vif->ndev,
 893                                         bssid, NULL, 0,
 894                                         NULL, 0,
 895                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
 896                                         GFP_KERNEL);
 897         } else if (vif->sme_state == SME_CONNECTED) {
 898                 cfg80211_disconnected(vif->ndev, proto_reason,
 899                                       NULL, 0, false, GFP_KERNEL);
 900         }
 901 
 902         vif->sme_state = SME_DISCONNECTED;
 903 
 904         /*
 905          * Send a disconnect command to target when a disconnect event is
 906          * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 907          * request from host) to make the firmware stop trying to connect even
 908          * after giving disconnect event. There will be one more disconnect
 909          * event for this disconnect command with reason code DISCONNECT_CMD
 910          * which won't be notified to cfg80211.
 911          */
 912         if (reason != DISCONNECT_CMD)
 913                 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
 914 }
 915 
 916 static int ath6kl_set_probed_ssids(struct ath6kl *ar,
 917                                    struct ath6kl_vif *vif,
 918                                    struct cfg80211_ssid *ssids, int n_ssids,
 919                                    struct cfg80211_match_set *match_set,
 920                                    int n_match_ssid)
 921 {
 922         u8 i, j, index_to_add, ssid_found = false;
 923         struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
 924 
 925         memset(ssid_list, 0, sizeof(ssid_list));
 926 
 927         if (n_ssids > MAX_PROBED_SSIDS ||
 928             n_match_ssid > MAX_PROBED_SSIDS)
 929                 return -EINVAL;
 930 
 931         for (i = 0; i < n_ssids; i++) {
 932                 memcpy(ssid_list[i].ssid.ssid,
 933                        ssids[i].ssid,
 934                        ssids[i].ssid_len);
 935                 ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
 936 
 937                 if (ssids[i].ssid_len)
 938                         ssid_list[i].flag = SPECIFIC_SSID_FLAG;
 939                 else
 940                         ssid_list[i].flag = ANY_SSID_FLAG;
 941 
 942                 if (ar->wiphy->max_match_sets != 0 && n_match_ssid == 0)
 943                         ssid_list[i].flag |= MATCH_SSID_FLAG;
 944         }
 945 
 946         index_to_add = i;
 947 
 948         for (i = 0; i < n_match_ssid; i++) {
 949                 ssid_found = false;
 950 
 951                 for (j = 0; j < n_ssids; j++) {
 952                         if ((match_set[i].ssid.ssid_len ==
 953                              ssid_list[j].ssid.ssid_len) &&
 954                             (!memcmp(ssid_list[j].ssid.ssid,
 955                                      match_set[i].ssid.ssid,
 956                                      match_set[i].ssid.ssid_len))) {
 957                                 ssid_list[j].flag |= MATCH_SSID_FLAG;
 958                                 ssid_found = true;
 959                                 break;
 960                         }
 961                 }
 962 
 963                 if (ssid_found)
 964                         continue;
 965 
 966                 if (index_to_add >= MAX_PROBED_SSIDS)
 967                         continue;
 968 
 969                 ssid_list[index_to_add].ssid.ssid_len =
 970                         match_set[i].ssid.ssid_len;
 971                 memcpy(ssid_list[index_to_add].ssid.ssid,
 972                        match_set[i].ssid.ssid,
 973                        match_set[i].ssid.ssid_len);
 974                 ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
 975                 index_to_add++;
 976         }
 977 
 978         for (i = 0; i < index_to_add; i++) {
 979                 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 980                                           ssid_list[i].flag,
 981                                           ssid_list[i].ssid.ssid_len,
 982                                           ssid_list[i].ssid.ssid);
 983         }
 984 
 985         /* Make sure no old entries are left behind */
 986         for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
 987                 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 988                                           DISABLE_SSID_FLAG, 0, NULL);
 989         }
 990 
 991         return 0;
 992 }
 993 
 994 static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
 995                                 struct cfg80211_scan_request *request)
 996 {
 997         struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
 998         struct ath6kl *ar = ath6kl_priv(vif->ndev);
 999         s8 n_channels = 0;
1000         u16 *channels = NULL;
1001         int ret = 0;
1002         u32 force_fg_scan = 0;
1003 
1004         if (!ath6kl_cfg80211_ready(vif))
1005                 return -EIO;
1006 
1007         ath6kl_cfg80211_sscan_disable(vif);
1008 
1009         if (!ar->usr_bss_filter) {
1010                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1011                 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1012                                                ALL_BSS_FILTER, 0);
1013                 if (ret) {
1014                         ath6kl_err("couldn't set bss filtering\n");
1015                         return ret;
1016                 }
1017         }
1018 
1019         ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1020                                       request->n_ssids, NULL, 0);
1021         if (ret < 0)
1022                 return ret;
1023 
1024         /* this also clears IE in fw if it's not set */
1025         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1026                                        WMI_FRAME_PROBE_REQ,
1027                                        request->ie, request->ie_len);
1028         if (ret) {
1029                 ath6kl_err("failed to set Probe Request appie for scan\n");
1030                 return ret;
1031         }
1032 
1033         /*
1034          * Scan only the requested channels if the request specifies a set of
1035          * channels. If the list is longer than the target supports, do not
1036          * configure the list and instead, scan all available channels.
1037          */
1038         if (request->n_channels > 0 &&
1039             request->n_channels <= WMI_MAX_CHANNELS) {
1040                 u8 i;
1041 
1042                 n_channels = request->n_channels;
1043 
1044                 channels = kcalloc(n_channels, sizeof(u16), GFP_KERNEL);
1045                 if (channels == NULL) {
1046                         ath6kl_warn("failed to set scan channels, scan all channels");
1047                         n_channels = 0;
1048                 }
1049 
1050                 for (i = 0; i < n_channels; i++)
1051                         channels[i] = request->channels[i]->center_freq;
1052         }
1053 
1054         if (test_bit(CONNECTED, &vif->flags))
1055                 force_fg_scan = 1;
1056 
1057         vif->scan_req = request;
1058 
1059         ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1060                                        WMI_LONG_SCAN, force_fg_scan,
1061                                        false, 0,
1062                                        ATH6KL_FG_SCAN_INTERVAL,
1063                                        n_channels, channels,
1064                                        request->no_cck,
1065                                        request->rates);
1066         if (ret) {
1067                 ath6kl_err("failed to start scan: %d\n", ret);
1068                 vif->scan_req = NULL;
1069         }
1070 
1071         kfree(channels);
1072 
1073         return ret;
1074 }
1075 
1076 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1077 {
1078         struct ath6kl *ar = vif->ar;
1079         struct cfg80211_scan_info info = {
1080                 .aborted = aborted,
1081         };
1082         int i;
1083 
1084         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1085                    aborted ? " aborted" : "");
1086 
1087         if (!vif->scan_req)
1088                 return;
1089 
1090         if (aborted)
1091                 goto out;
1092 
1093         if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1094                 for (i = 0; i < vif->scan_req->n_ssids; i++) {
1095                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1096                                                   i, DISABLE_SSID_FLAG,
1097                                                   0, NULL);
1098                 }
1099         }
1100 
1101 out:
1102         cfg80211_scan_done(vif->scan_req, &info);
1103         vif->scan_req = NULL;
1104 }
1105 
1106 void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1107                                       enum wmi_phy_mode mode)
1108 {
1109         struct cfg80211_chan_def chandef;
1110 
1111         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1112                    "channel switch notify nw_type %d freq %d mode %d\n",
1113                    vif->nw_type, freq, mode);
1114 
1115         cfg80211_chandef_create(&chandef,
1116                                 ieee80211_get_channel(vif->ar->wiphy, freq),
1117                                 (mode == WMI_11G_HT20 &&
1118                                  ath6kl_band_2ghz.ht_cap.ht_supported) ?
1119                                         NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1120 
1121         mutex_lock(&vif->wdev.mtx);
1122         cfg80211_ch_switch_notify(vif->ndev, &chandef);
1123         mutex_unlock(&vif->wdev.mtx);
1124 }
1125 
1126 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1127                                    u8 key_index, bool pairwise,
1128                                    const u8 *mac_addr,
1129                                    struct key_params *params)
1130 {
1131         struct ath6kl *ar = ath6kl_priv(ndev);
1132         struct ath6kl_vif *vif = netdev_priv(ndev);
1133         struct ath6kl_key *key = NULL;
1134         int seq_len;
1135         u8 key_usage;
1136         u8 key_type;
1137 
1138         if (!ath6kl_cfg80211_ready(vif))
1139                 return -EIO;
1140 
1141         if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1142                 if (params->key_len != WMI_KRK_LEN)
1143                         return -EINVAL;
1144                 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1145                                               params->key);
1146         }
1147 
1148         if (key_index > WMI_MAX_KEY_INDEX) {
1149                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1150                            "%s: key index %d out of bounds\n", __func__,
1151                            key_index);
1152                 return -ENOENT;
1153         }
1154 
1155         key = &vif->keys[key_index];
1156         memset(key, 0, sizeof(struct ath6kl_key));
1157 
1158         if (pairwise)
1159                 key_usage = PAIRWISE_USAGE;
1160         else
1161                 key_usage = GROUP_USAGE;
1162 
1163         seq_len = params->seq_len;
1164         if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1165             seq_len > ATH6KL_KEY_SEQ_LEN) {
1166                 /* Only first half of the WPI PN is configured */
1167                 seq_len = ATH6KL_KEY_SEQ_LEN;
1168         }
1169         if (params->key_len > WLAN_MAX_KEY_LEN ||
1170             seq_len > sizeof(key->seq))
1171                 return -EINVAL;
1172 
1173         key->key_len = params->key_len;
1174         memcpy(key->key, params->key, key->key_len);
1175         key->seq_len = seq_len;
1176         memcpy(key->seq, params->seq, key->seq_len);
1177         key->cipher = params->cipher;
1178 
1179         switch (key->cipher) {
1180         case WLAN_CIPHER_SUITE_WEP40:
1181         case WLAN_CIPHER_SUITE_WEP104:
1182                 key_type = WEP_CRYPT;
1183                 break;
1184 
1185         case WLAN_CIPHER_SUITE_TKIP:
1186                 key_type = TKIP_CRYPT;
1187                 break;
1188 
1189         case WLAN_CIPHER_SUITE_CCMP:
1190                 key_type = AES_CRYPT;
1191                 break;
1192         case WLAN_CIPHER_SUITE_SMS4:
1193                 key_type = WAPI_CRYPT;
1194                 break;
1195 
1196         default:
1197                 return -ENOTSUPP;
1198         }
1199 
1200         if (((vif->auth_mode == WPA_PSK_AUTH) ||
1201              (vif->auth_mode == WPA2_PSK_AUTH)) &&
1202             (key_usage & GROUP_USAGE))
1203                 del_timer(&vif->disconnect_timer);
1204 
1205         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1206                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1207                    __func__, key_index, key->key_len, key_type,
1208                    key_usage, key->seq_len);
1209 
1210         if (vif->nw_type == AP_NETWORK && !pairwise &&
1211             (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1212              key_type == WAPI_CRYPT)) {
1213                 ar->ap_mode_bkey.valid = true;
1214                 ar->ap_mode_bkey.key_index = key_index;
1215                 ar->ap_mode_bkey.key_type = key_type;
1216                 ar->ap_mode_bkey.key_len = key->key_len;
1217                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1218                 if (!test_bit(CONNECTED, &vif->flags)) {
1219                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1220                                    "Delay initial group key configuration until AP mode has been started\n");
1221                         /*
1222                          * The key will be set in ath6kl_connect_ap_mode() once
1223                          * the connected event is received from the target.
1224                          */
1225                         return 0;
1226                 }
1227         }
1228 
1229         if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1230             !test_bit(CONNECTED, &vif->flags)) {
1231                 /*
1232                  * Store the key locally so that it can be re-configured after
1233                  * the AP mode has properly started
1234                  * (ath6kl_install_statioc_wep_keys).
1235                  */
1236                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1237                            "Delay WEP key configuration until AP mode has been started\n");
1238                 vif->wep_key_list[key_index].key_len = key->key_len;
1239                 memcpy(vif->wep_key_list[key_index].key, key->key,
1240                        key->key_len);
1241                 return 0;
1242         }
1243 
1244         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1245                                      key_type, key_usage, key->key_len,
1246                                      key->seq, key->seq_len, key->key,
1247                                      KEY_OP_INIT_VAL,
1248                                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1249 }
1250 
1251 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1252                                    u8 key_index, bool pairwise,
1253                                    const u8 *mac_addr)
1254 {
1255         struct ath6kl *ar = ath6kl_priv(ndev);
1256         struct ath6kl_vif *vif = netdev_priv(ndev);
1257 
1258         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1259 
1260         if (!ath6kl_cfg80211_ready(vif))
1261                 return -EIO;
1262 
1263         if (key_index > WMI_MAX_KEY_INDEX) {
1264                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1265                            "%s: key index %d out of bounds\n", __func__,
1266                            key_index);
1267                 return -ENOENT;
1268         }
1269 
1270         if (!vif->keys[key_index].key_len) {
1271                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1272                            "%s: index %d is empty\n", __func__, key_index);
1273                 return 0;
1274         }
1275 
1276         vif->keys[key_index].key_len = 0;
1277 
1278         return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1279 }
1280 
1281 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1282                                    u8 key_index, bool pairwise,
1283                                    const u8 *mac_addr, void *cookie,
1284                                    void (*callback) (void *cookie,
1285                                                      struct key_params *))
1286 {
1287         struct ath6kl_vif *vif = netdev_priv(ndev);
1288         struct ath6kl_key *key = NULL;
1289         struct key_params params;
1290 
1291         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1292 
1293         if (!ath6kl_cfg80211_ready(vif))
1294                 return -EIO;
1295 
1296         if (key_index > WMI_MAX_KEY_INDEX) {
1297                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1298                            "%s: key index %d out of bounds\n", __func__,
1299                            key_index);
1300                 return -ENOENT;
1301         }
1302 
1303         key = &vif->keys[key_index];
1304         memset(&params, 0, sizeof(params));
1305         params.cipher = key->cipher;
1306         params.key_len = key->key_len;
1307         params.seq_len = key->seq_len;
1308         params.seq = key->seq;
1309         params.key = key->key;
1310 
1311         callback(cookie, &params);
1312 
1313         return key->key_len ? 0 : -ENOENT;
1314 }
1315 
1316 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1317                                            struct net_device *ndev,
1318                                            u8 key_index, bool unicast,
1319                                            bool multicast)
1320 {
1321         struct ath6kl *ar = ath6kl_priv(ndev);
1322         struct ath6kl_vif *vif = netdev_priv(ndev);
1323         struct ath6kl_key *key = NULL;
1324         u8 key_usage;
1325         enum ath6kl_crypto_type key_type = NONE_CRYPT;
1326 
1327         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1328 
1329         if (!ath6kl_cfg80211_ready(vif))
1330                 return -EIO;
1331 
1332         if (key_index > WMI_MAX_KEY_INDEX) {
1333                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1334                            "%s: key index %d out of bounds\n",
1335                            __func__, key_index);
1336                 return -ENOENT;
1337         }
1338 
1339         if (!vif->keys[key_index].key_len) {
1340                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1341                            __func__, key_index);
1342                 return -EINVAL;
1343         }
1344 
1345         vif->def_txkey_index = key_index;
1346         key = &vif->keys[vif->def_txkey_index];
1347         key_usage = GROUP_USAGE;
1348         if (vif->prwise_crypto == WEP_CRYPT)
1349                 key_usage |= TX_USAGE;
1350         if (unicast)
1351                 key_type = vif->prwise_crypto;
1352         if (multicast)
1353                 key_type = vif->grp_crypto;
1354 
1355         if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1356                 return 0; /* Delay until AP mode has been started */
1357 
1358         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1359                                      vif->def_txkey_index,
1360                                      key_type, key_usage,
1361                                      key->key_len, key->seq, key->seq_len,
1362                                      key->key,
1363                                      KEY_OP_INIT_VAL, NULL,
1364                                      SYNC_BOTH_WMIFLAG);
1365 }
1366 
1367 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1368                                        bool ismcast)
1369 {
1370         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1371                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1372 
1373         cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1374                                      (ismcast ? NL80211_KEYTYPE_GROUP :
1375                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1376                                      GFP_KERNEL);
1377 }
1378 
1379 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1380 {
1381         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1382         struct ath6kl_vif *vif;
1383         int ret;
1384 
1385         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1386                    changed);
1387 
1388         vif = ath6kl_vif_first(ar);
1389         if (!vif)
1390                 return -EIO;
1391 
1392         if (!ath6kl_cfg80211_ready(vif))
1393                 return -EIO;
1394 
1395         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1396                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1397                 if (ret != 0) {
1398                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1399                         return -EIO;
1400                 }
1401         }
1402 
1403         return 0;
1404 }
1405 
1406 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1407                                        struct wireless_dev *wdev,
1408                                        enum nl80211_tx_power_setting type,
1409                                        int mbm)
1410 {
1411         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1412         struct ath6kl_vif *vif;
1413         int dbm = MBM_TO_DBM(mbm);
1414 
1415         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1416                    type, dbm);
1417 
1418         vif = ath6kl_vif_first(ar);
1419         if (!vif)
1420                 return -EIO;
1421 
1422         if (!ath6kl_cfg80211_ready(vif))
1423                 return -EIO;
1424 
1425         switch (type) {
1426         case NL80211_TX_POWER_AUTOMATIC:
1427                 return 0;
1428         case NL80211_TX_POWER_LIMITED:
1429                 ar->tx_pwr = dbm;
1430                 break;
1431         default:
1432                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1433                            __func__, type);
1434                 return -EOPNOTSUPP;
1435         }
1436 
1437         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1438 
1439         return 0;
1440 }
1441 
1442 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1443                                        struct wireless_dev *wdev,
1444                                        int *dbm)
1445 {
1446         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1447         struct ath6kl_vif *vif;
1448 
1449         vif = ath6kl_vif_first(ar);
1450         if (!vif)
1451                 return -EIO;
1452 
1453         if (!ath6kl_cfg80211_ready(vif))
1454                 return -EIO;
1455 
1456         if (test_bit(CONNECTED, &vif->flags)) {
1457                 ar->tx_pwr = 255;
1458 
1459                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1460                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1461                         return -EIO;
1462                 }
1463 
1464                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1465                                                  5 * HZ);
1466 
1467                 if (signal_pending(current)) {
1468                         ath6kl_err("target did not respond\n");
1469                         return -EINTR;
1470                 }
1471         }
1472 
1473         *dbm = ar->tx_pwr;
1474         return 0;
1475 }
1476 
1477 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1478                                           struct net_device *dev,
1479                                           bool pmgmt, int timeout)
1480 {
1481         struct ath6kl *ar = ath6kl_priv(dev);
1482         struct wmi_power_mode_cmd mode;
1483         struct ath6kl_vif *vif = netdev_priv(dev);
1484 
1485         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1486                    __func__, pmgmt, timeout);
1487 
1488         if (!ath6kl_cfg80211_ready(vif))
1489                 return -EIO;
1490 
1491         if (pmgmt) {
1492                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1493                 mode.pwr_mode = REC_POWER;
1494         } else {
1495                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1496                 mode.pwr_mode = MAX_PERF_POWER;
1497         }
1498 
1499         if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1500                                      mode.pwr_mode) != 0) {
1501                 ath6kl_err("wmi_powermode_cmd failed\n");
1502                 return -EIO;
1503         }
1504 
1505         return 0;
1506 }
1507 
1508 static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1509                                                       const char *name,
1510                                                       unsigned char name_assign_type,
1511                                                       enum nl80211_iftype type,
1512                                                       struct vif_params *params)
1513 {
1514         struct ath6kl *ar = wiphy_priv(wiphy);
1515         struct wireless_dev *wdev;
1516         u8 if_idx, nw_type;
1517 
1518         if (ar->num_vif == ar->vif_max) {
1519                 ath6kl_err("Reached maximum number of supported vif\n");
1520                 return ERR_PTR(-EINVAL);
1521         }
1522 
1523         if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1524                 ath6kl_err("Not a supported interface type\n");
1525                 return ERR_PTR(-EINVAL);
1526         }
1527 
1528         wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
1529         if (!wdev)
1530                 return ERR_PTR(-ENOMEM);
1531 
1532         ar->num_vif++;
1533 
1534         return wdev;
1535 }
1536 
1537 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1538                                      struct wireless_dev *wdev)
1539 {
1540         struct ath6kl *ar = wiphy_priv(wiphy);
1541         struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1542 
1543         spin_lock_bh(&ar->list_lock);
1544         list_del(&vif->list);
1545         spin_unlock_bh(&ar->list_lock);
1546 
1547         ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1548 
1549         rtnl_lock();
1550         ath6kl_cfg80211_vif_cleanup(vif);
1551         rtnl_unlock();
1552 
1553         return 0;
1554 }
1555 
1556 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1557                                         struct net_device *ndev,
1558                                         enum nl80211_iftype type,
1559                                         struct vif_params *params)
1560 {
1561         struct ath6kl_vif *vif = netdev_priv(ndev);
1562         int i;
1563 
1564         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1565 
1566         /*
1567          * Don't bring up p2p on an interface which is not initialized
1568          * for p2p operation where fw does not have capability to switch
1569          * dynamically between non-p2p and p2p type interface.
1570          */
1571         if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1572                       vif->ar->fw_capabilities) &&
1573             (type == NL80211_IFTYPE_P2P_CLIENT ||
1574              type == NL80211_IFTYPE_P2P_GO)) {
1575                 if (vif->ar->vif_max == 1) {
1576                         if (vif->fw_vif_idx != 0)
1577                                 return -EINVAL;
1578                         else
1579                                 goto set_iface_type;
1580                 }
1581 
1582                 for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1583                         if (i == vif->fw_vif_idx)
1584                                 break;
1585                 }
1586 
1587                 if (i == vif->ar->vif_max) {
1588                         ath6kl_err("Invalid interface to bring up P2P\n");
1589                         return -EINVAL;
1590                 }
1591         }
1592 
1593         /* need to clean up enhanced bmiss detection fw state */
1594         ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1595 
1596 set_iface_type:
1597         switch (type) {
1598         case NL80211_IFTYPE_STATION:
1599         case NL80211_IFTYPE_P2P_CLIENT:
1600                 vif->next_mode = INFRA_NETWORK;
1601                 break;
1602         case NL80211_IFTYPE_ADHOC:
1603                 vif->next_mode = ADHOC_NETWORK;
1604                 break;
1605         case NL80211_IFTYPE_AP:
1606         case NL80211_IFTYPE_P2P_GO:
1607                 vif->next_mode = AP_NETWORK;
1608                 break;
1609         default:
1610                 ath6kl_err("invalid interface type %u\n", type);
1611                 return -EOPNOTSUPP;
1612         }
1613 
1614         vif->wdev.iftype = type;
1615 
1616         return 0;
1617 }
1618 
1619 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1620                                      struct net_device *dev,
1621                                      struct cfg80211_ibss_params *ibss_param)
1622 {
1623         struct ath6kl *ar = ath6kl_priv(dev);
1624         struct ath6kl_vif *vif = netdev_priv(dev);
1625         int status;
1626 
1627         if (!ath6kl_cfg80211_ready(vif))
1628                 return -EIO;
1629 
1630         vif->ssid_len = ibss_param->ssid_len;
1631         memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1632 
1633         if (ibss_param->chandef.chan)
1634                 vif->ch_hint = ibss_param->chandef.chan->center_freq;
1635 
1636         if (ibss_param->channel_fixed) {
1637                 /*
1638                  * TODO: channel_fixed: The channel should be fixed, do not
1639                  * search for IBSSs to join on other channels. Target
1640                  * firmware does not support this feature, needs to be
1641                  * updated.
1642                  */
1643                 return -EOPNOTSUPP;
1644         }
1645 
1646         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1647         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1648                 memcpy(vif->req_bssid, ibss_param->bssid,
1649                        sizeof(vif->req_bssid));
1650 
1651         ath6kl_set_wpa_version(vif, 0);
1652 
1653         status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1654         if (status)
1655                 return status;
1656 
1657         if (ibss_param->privacy) {
1658                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1659                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1660         } else {
1661                 ath6kl_set_cipher(vif, 0, true);
1662                 ath6kl_set_cipher(vif, 0, false);
1663         }
1664 
1665         vif->nw_type = vif->next_mode;
1666 
1667         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1668                    "%s: connect called with authmode %d dot11 auth %d"
1669                    " PW crypto %d PW crypto len %d GRP crypto %d"
1670                    " GRP crypto len %d channel hint %u\n",
1671                    __func__,
1672                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1673                    vif->prwise_crypto_len, vif->grp_crypto,
1674                    vif->grp_crypto_len, vif->ch_hint);
1675 
1676         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1677                                         vif->dot11_auth_mode, vif->auth_mode,
1678                                         vif->prwise_crypto,
1679                                         vif->prwise_crypto_len,
1680                                         vif->grp_crypto, vif->grp_crypto_len,
1681                                         vif->ssid_len, vif->ssid,
1682                                         vif->req_bssid, vif->ch_hint,
1683                                         ar->connect_ctrl_flags, SUBTYPE_NONE);
1684         set_bit(CONNECT_PEND, &vif->flags);
1685 
1686         return 0;
1687 }
1688 
1689 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1690                                       struct net_device *dev)
1691 {
1692         struct ath6kl_vif *vif = netdev_priv(dev);
1693 
1694         if (!ath6kl_cfg80211_ready(vif))
1695                 return -EIO;
1696 
1697         ath6kl_disconnect(vif);
1698         memset(vif->ssid, 0, sizeof(vif->ssid));
1699         vif->ssid_len = 0;
1700 
1701         return 0;
1702 }
1703 
1704 static const u32 cipher_suites[] = {
1705         WLAN_CIPHER_SUITE_WEP40,
1706         WLAN_CIPHER_SUITE_WEP104,
1707         WLAN_CIPHER_SUITE_TKIP,
1708         WLAN_CIPHER_SUITE_CCMP,
1709         CCKM_KRK_CIPHER_SUITE,
1710         WLAN_CIPHER_SUITE_SMS4,
1711 };
1712 
1713 static bool is_rate_legacy(s32 rate)
1714 {
1715         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1716                 6000, 9000, 12000, 18000, 24000,
1717                 36000, 48000, 54000
1718         };
1719         u8 i;
1720 
1721         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1722                 if (rate == legacy[i])
1723                         return true;
1724 
1725         return false;
1726 }
1727 
1728 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1729 {
1730         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1731                 52000, 58500, 65000, 72200
1732         };
1733         u8 i;
1734 
1735         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1736                 if (rate == ht20[i]) {
1737                         if (i == ARRAY_SIZE(ht20) - 1)
1738                                 /* last rate uses sgi */
1739                                 *sgi = true;
1740                         else
1741                                 *sgi = false;
1742 
1743                         *mcs = i;
1744                         return true;
1745                 }
1746         }
1747         return false;
1748 }
1749 
1750 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1751 {
1752         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1753                 81000, 108000, 121500, 135000,
1754                 150000
1755         };
1756         u8 i;
1757 
1758         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1759                 if (rate == ht40[i]) {
1760                         if (i == ARRAY_SIZE(ht40) - 1)
1761                                 /* last rate uses sgi */
1762                                 *sgi = true;
1763                         else
1764                                 *sgi = false;
1765 
1766                         *mcs = i;
1767                         return true;
1768                 }
1769         }
1770 
1771         return false;
1772 }
1773 
1774 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1775                               const u8 *mac, struct station_info *sinfo)
1776 {
1777         struct ath6kl *ar = ath6kl_priv(dev);
1778         struct ath6kl_vif *vif = netdev_priv(dev);
1779         long left;
1780         bool sgi;
1781         s32 rate;
1782         int ret;
1783         u8 mcs;
1784 
1785         if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1786                 return -ENOENT;
1787 
1788         if (down_interruptible(&ar->sem))
1789                 return -EBUSY;
1790 
1791         set_bit(STATS_UPDATE_PEND, &vif->flags);
1792 
1793         ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1794 
1795         if (ret != 0) {
1796                 up(&ar->sem);
1797                 return -EIO;
1798         }
1799 
1800         left = wait_event_interruptible_timeout(ar->event_wq,
1801                                                 !test_bit(STATS_UPDATE_PEND,
1802                                                           &vif->flags),
1803                                                 WMI_TIMEOUT);
1804 
1805         up(&ar->sem);
1806 
1807         if (left == 0)
1808                 return -ETIMEDOUT;
1809         else if (left < 0)
1810                 return left;
1811 
1812         if (vif->target_stats.rx_byte) {
1813                 sinfo->rx_bytes = vif->target_stats.rx_byte;
1814                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
1815                 sinfo->rx_packets = vif->target_stats.rx_pkt;
1816                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
1817         }
1818 
1819         if (vif->target_stats.tx_byte) {
1820                 sinfo->tx_bytes = vif->target_stats.tx_byte;
1821                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
1822                 sinfo->tx_packets = vif->target_stats.tx_pkt;
1823                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
1824         }
1825 
1826         sinfo->signal = vif->target_stats.cs_rssi;
1827         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1828 
1829         rate = vif->target_stats.tx_ucast_rate;
1830 
1831         if (is_rate_legacy(rate)) {
1832                 sinfo->txrate.legacy = rate / 100;
1833         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1834                 if (sgi) {
1835                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1836                         sinfo->txrate.mcs = mcs - 1;
1837                 } else {
1838                         sinfo->txrate.mcs = mcs;
1839                 }
1840 
1841                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1842                 sinfo->txrate.bw = RATE_INFO_BW_20;
1843         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1844                 if (sgi) {
1845                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1846                         sinfo->txrate.mcs = mcs - 1;
1847                 } else {
1848                         sinfo->txrate.mcs = mcs;
1849                 }
1850 
1851                 sinfo->txrate.bw = RATE_INFO_BW_40;
1852                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1853         } else {
1854                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1855                            "invalid rate from stats: %d\n", rate);
1856                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1857                 return 0;
1858         }
1859 
1860         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
1861 
1862         if (test_bit(CONNECTED, &vif->flags) &&
1863             test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1864             vif->nw_type == INFRA_NETWORK) {
1865                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
1866                 sinfo->bss_param.flags = 0;
1867                 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1868                 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1869         }
1870 
1871         return 0;
1872 }
1873 
1874 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1875                             struct cfg80211_pmksa *pmksa)
1876 {
1877         struct ath6kl *ar = ath6kl_priv(netdev);
1878         struct ath6kl_vif *vif = netdev_priv(netdev);
1879 
1880         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1881                                        pmksa->pmkid, true);
1882 }
1883 
1884 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1885                             struct cfg80211_pmksa *pmksa)
1886 {
1887         struct ath6kl *ar = ath6kl_priv(netdev);
1888         struct ath6kl_vif *vif = netdev_priv(netdev);
1889 
1890         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1891                                        pmksa->pmkid, false);
1892 }
1893 
1894 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1895 {
1896         struct ath6kl *ar = ath6kl_priv(netdev);
1897         struct ath6kl_vif *vif = netdev_priv(netdev);
1898 
1899         if (test_bit(CONNECTED, &vif->flags))
1900                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1901                                                vif->bssid, NULL, false);
1902         return 0;
1903 }
1904 
1905 static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1906                           struct cfg80211_wowlan *wow, u32 *filter)
1907 {
1908         int ret, pos;
1909         u8 mask[WOW_PATTERN_SIZE];
1910         u16 i;
1911 
1912         /* Configure the patterns that we received from the user. */
1913         for (i = 0; i < wow->n_patterns; i++) {
1914                 /*
1915                  * Convert given nl80211 specific mask value to equivalent
1916                  * driver specific mask value and send it to the chip along
1917                  * with patterns. For example, If the mask value defined in
1918                  * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1919                  * then equivalent driver specific mask value is
1920                  * "0xFF 0x00 0xFF 0x00".
1921                  */
1922                 memset(&mask, 0, sizeof(mask));
1923                 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1924                         if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1925                                 mask[pos] = 0xFF;
1926                 }
1927                 /*
1928                  * Note: Pattern's offset is not passed as part of wowlan
1929                  * parameter from CFG layer. So it's always passed as ZERO
1930                  * to the firmware. It means, given WOW patterns are always
1931                  * matched from the first byte of received pkt in the firmware.
1932                  */
1933                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1934                                 vif->fw_vif_idx, WOW_LIST_ID,
1935                                 wow->patterns[i].pattern_len,
1936                                 0 /* pattern offset */,
1937                                 wow->patterns[i].pattern, mask);
1938                 if (ret)
1939                         return ret;
1940         }
1941 
1942         if (wow->disconnect)
1943                 *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1944 
1945         if (wow->magic_pkt)
1946                 *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1947 
1948         if (wow->gtk_rekey_failure)
1949                 *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1950 
1951         if (wow->eap_identity_req)
1952                 *filter |= WOW_FILTER_OPTION_EAP_REQ;
1953 
1954         if (wow->four_way_handshake)
1955                 *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1956 
1957         return 0;
1958 }
1959 
1960 static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1961 {
1962         static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1963                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1964                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965                 0x00, 0x08 };
1966         static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1967                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969                 0x00, 0x7f };
1970         u8 unicst_offset = 0;
1971         static const u8 arp_pattern[] = { 0x08, 0x06 };
1972         static const u8 arp_mask[] = { 0xff, 0xff };
1973         u8 arp_offset = 20;
1974         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1975         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1976         u8 discvr_offset = 38;
1977         static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1978                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1979                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1980                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1981                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1982                 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1983         static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1984                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1985                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1986                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988                 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1989         u8 dhcp_offset = 0;
1990         int ret;
1991 
1992         /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1993         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1994                         vif->fw_vif_idx, WOW_LIST_ID,
1995                         sizeof(unicst_pattern), unicst_offset,
1996                         unicst_pattern, unicst_mask);
1997         if (ret) {
1998                 ath6kl_err("failed to add WOW unicast IP pattern\n");
1999                 return ret;
2000         }
2001 
2002         /* Setup all ARP pkt pattern */
2003         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2004                         vif->fw_vif_idx, WOW_LIST_ID,
2005                         sizeof(arp_pattern), arp_offset,
2006                         arp_pattern, arp_mask);
2007         if (ret) {
2008                 ath6kl_err("failed to add WOW ARP pattern\n");
2009                 return ret;
2010         }
2011 
2012         /*
2013          * Setup multicast pattern for mDNS 224.0.0.251,
2014          * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2015          */
2016         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2017                         vif->fw_vif_idx, WOW_LIST_ID,
2018                         sizeof(discvr_pattern), discvr_offset,
2019                         discvr_pattern, discvr_mask);
2020         if (ret) {
2021                 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2022                 return ret;
2023         }
2024 
2025         /* Setup all DHCP broadcast pkt pattern */
2026         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2027                         vif->fw_vif_idx, WOW_LIST_ID,
2028                         sizeof(dhcp_pattern), dhcp_offset,
2029                         dhcp_pattern, dhcp_mask);
2030         if (ret) {
2031                 ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2032                 return ret;
2033         }
2034 
2035         return 0;
2036 }
2037 
2038 static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2039 {
2040         struct net_device *ndev = vif->ndev;
2041         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2042         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2043         u8 discvr_offset = 38;
2044         u8 mac_mask[ETH_ALEN];
2045         int ret;
2046 
2047         /* Setup unicast pkt pattern */
2048         eth_broadcast_addr(mac_mask);
2049         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2050                                 vif->fw_vif_idx, WOW_LIST_ID,
2051                                 ETH_ALEN, 0, ndev->dev_addr,
2052                                 mac_mask);
2053         if (ret) {
2054                 ath6kl_err("failed to add WOW unicast pattern\n");
2055                 return ret;
2056         }
2057 
2058         /*
2059          * Setup multicast pattern for mDNS 224.0.0.251,
2060          * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2061          */
2062         if ((ndev->flags & IFF_ALLMULTI) ||
2063             (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2064                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2065                                 vif->fw_vif_idx, WOW_LIST_ID,
2066                                 sizeof(discvr_pattern), discvr_offset,
2067                                 discvr_pattern, discvr_mask);
2068                 if (ret) {
2069                         ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2070                         return ret;
2071                 }
2072         }
2073 
2074         return 0;
2075 }
2076 
2077 static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2078 {
2079         return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2080 }
2081 
2082 static bool is_ctrl_ep_empty(struct ath6kl *ar)
2083 {
2084         return !ar->tx_pending[ar->ctrl_ep];
2085 }
2086 
2087 static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2088 {
2089         int ret, left;
2090 
2091         clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2092 
2093         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2094                                                  ATH6KL_HOST_MODE_ASLEEP);
2095         if (ret)
2096                 return ret;
2097 
2098         left = wait_event_interruptible_timeout(ar->event_wq,
2099                                                 is_hsleep_mode_procsed(vif),
2100                                                 WMI_TIMEOUT);
2101         if (left == 0) {
2102                 ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2103                 ret = -ETIMEDOUT;
2104         } else if (left < 0) {
2105                 ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2106                             left);
2107                 ret = left;
2108         }
2109 
2110         if (ar->tx_pending[ar->ctrl_ep]) {
2111                 left = wait_event_interruptible_timeout(ar->event_wq,
2112                                                         is_ctrl_ep_empty(ar),
2113                                                         WMI_TIMEOUT);
2114                 if (left == 0) {
2115                         ath6kl_warn("clear wmi ctrl data timeout\n");
2116                         ret = -ETIMEDOUT;
2117                 } else if (left < 0) {
2118                         ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2119                         ret = left;
2120                 }
2121         }
2122 
2123         return ret;
2124 }
2125 
2126 static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2127                                   struct cfg80211_wowlan *wow, u32 *filter)
2128 {
2129         struct ath6kl *ar = vif->ar;
2130         struct in_device *in_dev;
2131         struct in_ifaddr *ifa;
2132         int ret;
2133         u16 i, bmiss_time;
2134         __be32 ips[MAX_IP_ADDRS];
2135         u8 index = 0;
2136 
2137         if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2138             test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2139                      ar->fw_capabilities)) {
2140                 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2141                                                 vif->fw_vif_idx, false);
2142                 if (ret)
2143                         return ret;
2144         }
2145 
2146         /* Clear existing WOW patterns */
2147         for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2148                 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2149                                                WOW_LIST_ID, i);
2150 
2151         /*
2152          * Skip the default WOW pattern configuration
2153          * if the driver receives any WOW patterns from
2154          * the user.
2155          */
2156         if (wow)
2157                 ret = ath6kl_wow_usr(ar, vif, wow, filter);
2158         else if (vif->nw_type == AP_NETWORK)
2159                 ret = ath6kl_wow_ap(ar, vif);
2160         else
2161                 ret = ath6kl_wow_sta(ar, vif);
2162 
2163         if (ret)
2164                 return ret;
2165 
2166         netif_stop_queue(vif->ndev);
2167 
2168         if (vif->nw_type != AP_NETWORK) {
2169                 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2170                                                     ATH6KL_MAX_WOW_LISTEN_INTL,
2171                                                     0);
2172                 if (ret)
2173                         return ret;
2174 
2175                 /* Set listen interval x 15 times as bmiss time */
2176                 bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2177                 if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2178                         bmiss_time = ATH6KL_MAX_BMISS_TIME;
2179 
2180                 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2181                                                bmiss_time, 0);
2182                 if (ret)
2183                         return ret;
2184 
2185                 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2186                                                 0xFFFF, 0, 0xFFFF, 0, 0, 0,
2187                                                 0, 0, 0, 0);
2188                 if (ret)
2189                         return ret;
2190         }
2191 
2192         /* Setup own IP addr for ARP agent. */
2193         in_dev = __in_dev_get_rtnl(vif->ndev);
2194         if (!in_dev)
2195                 return 0;
2196 
2197         ifa = rtnl_dereference(in_dev->ifa_list);
2198         memset(&ips, 0, sizeof(ips));
2199 
2200         /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2201         while (index < MAX_IP_ADDRS && ifa) {
2202                 ips[index] = ifa->ifa_local;
2203                 ifa = rtnl_dereference(ifa->ifa_next);
2204                 index++;
2205         }
2206 
2207         if (ifa) {
2208                 ath6kl_err("total IP addr count is exceeding fw limit\n");
2209                 return -EINVAL;
2210         }
2211 
2212         ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2213         if (ret) {
2214                 ath6kl_err("fail to setup ip for arp agent\n");
2215                 return ret;
2216         }
2217 
2218         return ret;
2219 }
2220 
2221 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2222 {
2223         struct ath6kl_vif *first_vif, *vif;
2224         int ret = 0;
2225         u32 filter = 0;
2226         bool connected = false;
2227 
2228         /* enter / leave wow suspend on first vif always */
2229         first_vif = ath6kl_vif_first(ar);
2230         if (WARN_ON(!first_vif) ||
2231             !ath6kl_cfg80211_ready(first_vif))
2232                 return -EIO;
2233 
2234         if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2235                 return -EINVAL;
2236 
2237         /* install filters for each connected vif */
2238         spin_lock_bh(&ar->list_lock);
2239         list_for_each_entry(vif, &ar->vif_list, list) {
2240                 if (!test_bit(CONNECTED, &vif->flags) ||
2241                     !ath6kl_cfg80211_ready(vif))
2242                         continue;
2243                 connected = true;
2244 
2245                 ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2246                 if (ret)
2247                         break;
2248         }
2249         spin_unlock_bh(&ar->list_lock);
2250 
2251         if (!connected)
2252                 return -ENOTCONN;
2253         else if (ret)
2254                 return ret;
2255 
2256         ar->state = ATH6KL_STATE_SUSPENDING;
2257 
2258         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2259                                           ATH6KL_WOW_MODE_ENABLE,
2260                                           filter,
2261                                           WOW_HOST_REQ_DELAY);
2262         if (ret)
2263                 return ret;
2264 
2265         return ath6kl_cfg80211_host_sleep(ar, first_vif);
2266 }
2267 
2268 static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2269 {
2270         struct ath6kl *ar = vif->ar;
2271         int ret;
2272 
2273         if (vif->nw_type != AP_NETWORK) {
2274                 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2275                                                 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2276                 if (ret)
2277                         return ret;
2278 
2279                 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2280                                                     vif->listen_intvl_t, 0);
2281                 if (ret)
2282                         return ret;
2283 
2284                 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2285                                                vif->bmiss_time_t, 0);
2286                 if (ret)
2287                         return ret;
2288         }
2289 
2290         if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2291             test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2292                      ar->fw_capabilities)) {
2293                 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2294                                                   vif->fw_vif_idx, true);
2295                 if (ret)
2296                         return ret;
2297         }
2298 
2299         netif_wake_queue(vif->ndev);
2300 
2301         return 0;
2302 }
2303 
2304 static int ath6kl_wow_resume(struct ath6kl *ar)
2305 {
2306         struct ath6kl_vif *vif;
2307         int ret;
2308 
2309         vif = ath6kl_vif_first(ar);
2310         if (WARN_ON(!vif) ||
2311             !ath6kl_cfg80211_ready(vif))
2312                 return -EIO;
2313 
2314         ar->state = ATH6KL_STATE_RESUMING;
2315 
2316         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2317                                                  ATH6KL_HOST_MODE_AWAKE);
2318         if (ret) {
2319                 ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2320                             ret);
2321                 goto cleanup;
2322         }
2323 
2324         spin_lock_bh(&ar->list_lock);
2325         list_for_each_entry(vif, &ar->vif_list, list) {
2326                 if (!test_bit(CONNECTED, &vif->flags) ||
2327                     !ath6kl_cfg80211_ready(vif))
2328                         continue;
2329                 ret = ath6kl_wow_resume_vif(vif);
2330                 if (ret)
2331                         break;
2332         }
2333         spin_unlock_bh(&ar->list_lock);
2334 
2335         if (ret)
2336                 goto cleanup;
2337 
2338         ar->state = ATH6KL_STATE_ON;
2339         return 0;
2340 
2341 cleanup:
2342         ar->state = ATH6KL_STATE_WOW;
2343         return ret;
2344 }
2345 
2346 static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2347 {
2348         struct ath6kl_vif *vif;
2349         int ret;
2350 
2351         vif = ath6kl_vif_first(ar);
2352         if (!vif)
2353                 return -EIO;
2354 
2355         if (!test_bit(WMI_READY, &ar->flag)) {
2356                 ath6kl_err("deepsleep failed as wmi is not ready\n");
2357                 return -EIO;
2358         }
2359 
2360         ath6kl_cfg80211_stop_all(ar);
2361 
2362         /* Save the current power mode before enabling power save */
2363         ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2364 
2365         ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2366         if (ret)
2367                 return ret;
2368 
2369         /* Disable WOW mode */
2370         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2371                                           ATH6KL_WOW_MODE_DISABLE,
2372                                           0, 0);
2373         if (ret)
2374                 return ret;
2375 
2376         /* Flush all non control pkts in TX path */
2377         ath6kl_tx_data_cleanup(ar);
2378 
2379         ret = ath6kl_cfg80211_host_sleep(ar, vif);
2380         if (ret)
2381                 return ret;
2382 
2383         return 0;
2384 }
2385 
2386 static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2387 {
2388         struct ath6kl_vif *vif;
2389         int ret;
2390 
2391         vif = ath6kl_vif_first(ar);
2392 
2393         if (!vif)
2394                 return -EIO;
2395 
2396         if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2397                 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2398                                                ar->wmi->saved_pwr_mode);
2399                 if (ret)
2400                         return ret;
2401         }
2402 
2403         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2404                                                  ATH6KL_HOST_MODE_AWAKE);
2405         if (ret)
2406                 return ret;
2407 
2408         ar->state = ATH6KL_STATE_ON;
2409 
2410         /* Reset scan parameter to default values */
2411         ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2412                                         0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2413         if (ret)
2414                 return ret;
2415 
2416         return 0;
2417 }
2418 
2419 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2420                             enum ath6kl_cfg_suspend_mode mode,
2421                             struct cfg80211_wowlan *wow)
2422 {
2423         struct ath6kl_vif *vif;
2424         enum ath6kl_state prev_state;
2425         int ret;
2426 
2427         switch (mode) {
2428         case ATH6KL_CFG_SUSPEND_WOW:
2429 
2430                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2431 
2432                 /* Flush all non control pkts in TX path */
2433                 ath6kl_tx_data_cleanup(ar);
2434 
2435                 prev_state = ar->state;
2436 
2437                 ret = ath6kl_wow_suspend(ar, wow);
2438                 if (ret) {
2439                         ar->state = prev_state;
2440                         return ret;
2441                 }
2442 
2443                 ar->state = ATH6KL_STATE_WOW;
2444                 break;
2445 
2446         case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2447 
2448                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2449 
2450                 ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2451                 if (ret) {
2452                         ath6kl_err("deepsleep suspend failed: %d\n", ret);
2453                         return ret;
2454                 }
2455 
2456                 ar->state = ATH6KL_STATE_DEEPSLEEP;
2457 
2458                 break;
2459 
2460         case ATH6KL_CFG_SUSPEND_CUTPOWER:
2461 
2462                 ath6kl_cfg80211_stop_all(ar);
2463 
2464                 if (ar->state == ATH6KL_STATE_OFF) {
2465                         ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2466                                    "suspend hw off, no action for cutpower\n");
2467                         break;
2468                 }
2469 
2470                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2471 
2472                 ret = ath6kl_init_hw_stop(ar);
2473                 if (ret) {
2474                         ath6kl_warn("failed to stop hw during suspend: %d\n",
2475                                     ret);
2476                 }
2477 
2478                 ar->state = ATH6KL_STATE_CUTPOWER;
2479 
2480                 break;
2481 
2482         default:
2483                 break;
2484         }
2485 
2486         list_for_each_entry(vif, &ar->vif_list, list)
2487                 ath6kl_cfg80211_scan_complete_event(vif, true);
2488 
2489         return 0;
2490 }
2491 EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2492 
2493 int ath6kl_cfg80211_resume(struct ath6kl *ar)
2494 {
2495         int ret;
2496 
2497         switch (ar->state) {
2498         case  ATH6KL_STATE_WOW:
2499                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2500 
2501                 ret = ath6kl_wow_resume(ar);
2502                 if (ret) {
2503                         ath6kl_warn("wow mode resume failed: %d\n", ret);
2504                         return ret;
2505                 }
2506 
2507                 break;
2508 
2509         case ATH6KL_STATE_DEEPSLEEP:
2510                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2511 
2512                 ret = ath6kl_cfg80211_deepsleep_resume(ar);
2513                 if (ret) {
2514                         ath6kl_warn("deep sleep resume failed: %d\n", ret);
2515                         return ret;
2516                 }
2517                 break;
2518 
2519         case ATH6KL_STATE_CUTPOWER:
2520                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2521 
2522                 ret = ath6kl_init_hw_start(ar);
2523                 if (ret) {
2524                         ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2525                         return ret;
2526                 }
2527                 break;
2528 
2529         default:
2530                 break;
2531         }
2532 
2533         return 0;
2534 }
2535 EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2536 
2537 #ifdef CONFIG_PM
2538 
2539 /* hif layer decides what suspend mode to use */
2540 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2541                                  struct cfg80211_wowlan *wow)
2542 {
2543         struct ath6kl *ar = wiphy_priv(wiphy);
2544 
2545         ath6kl_recovery_suspend(ar);
2546 
2547         return ath6kl_hif_suspend(ar, wow);
2548 }
2549 
2550 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2551 {
2552         struct ath6kl *ar = wiphy_priv(wiphy);
2553         int err;
2554 
2555         err = ath6kl_hif_resume(ar);
2556         if (err)
2557                 return err;
2558 
2559         ath6kl_recovery_resume(ar);
2560 
2561         return 0;
2562 }
2563 
2564 /*
2565  * FIXME: WOW suspend mode is selected if the host sdio controller supports
2566  * both sdio irq wake up and keep power. The target pulls sdio data line to
2567  * wake up the host when WOW pattern matches. This causes sdio irq handler
2568  * is being called in the host side which internally hits ath6kl's RX path.
2569  *
2570  * Since sdio interrupt is not disabled, RX path executes even before
2571  * the host executes the actual resume operation from PM module.
2572  *
2573  * In the current scenario, WOW resume should happen before start processing
2574  * any data from the target. So It's required to perform WOW resume in RX path.
2575  * Ideally we should perform WOW resume only in the actual platform
2576  * resume path. This area needs bit rework to avoid WOW resume in RX path.
2577  *
2578  * ath6kl_check_wow_status() is called from ath6kl_rx().
2579  */
2580 void ath6kl_check_wow_status(struct ath6kl *ar)
2581 {
2582         if (ar->state == ATH6KL_STATE_SUSPENDING)
2583                 return;
2584 
2585         if (ar->state == ATH6KL_STATE_WOW)
2586                 ath6kl_cfg80211_resume(ar);
2587 }
2588 
2589 #else
2590 
2591 void ath6kl_check_wow_status(struct ath6kl *ar)
2592 {
2593 }
2594 #endif
2595 
2596 static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum nl80211_band band,
2597                             bool ht_enable)
2598 {
2599         struct ath6kl_htcap *htcap = &vif->htcap[band];
2600 
2601         if (htcap->ht_enable == ht_enable)
2602                 return 0;
2603 
2604         if (ht_enable) {
2605                 /* Set default ht capabilities */
2606                 htcap->ht_enable = true;
2607                 htcap->cap_info = (band == NL80211_BAND_2GHZ) ?
2608                                    ath6kl_g_htcap : ath6kl_a_htcap;
2609                 htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2610         } else /* Disable ht */
2611                 memset(htcap, 0, sizeof(*htcap));
2612 
2613         return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2614                                         band, htcap);
2615 }
2616 
2617 static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2618 {
2619         struct wiphy *wiphy = vif->ar->wiphy;
2620         int band, ret = 0;
2621 
2622         for (band = 0; band < NUM_NL80211_BANDS; band++) {
2623                 if (!wiphy->bands[band])
2624                         continue;
2625 
2626                 ret = ath6kl_set_htcap(vif, band,
2627                                 wiphy->bands[band]->ht_cap.ht_supported);
2628                 if (ret)
2629                         return ret;
2630         }
2631 
2632         return ret;
2633 }
2634 
2635 static bool ath6kl_is_p2p_ie(const u8 *pos)
2636 {
2637         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2638                 pos[2] == 0x50 && pos[3] == 0x6f &&
2639                 pos[4] == 0x9a && pos[5] == 0x09;
2640 }
2641 
2642 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2643                                         const u8 *ies, size_t ies_len)
2644 {
2645         struct ath6kl *ar = vif->ar;
2646         const u8 *pos;
2647         u8 *buf = NULL;
2648         size_t len = 0;
2649         int ret;
2650 
2651         /*
2652          * Filter out P2P IE(s) since they will be included depending on
2653          * the Probe Request frame in ath6kl_send_go_probe_resp().
2654          */
2655 
2656         if (ies && ies_len) {
2657                 buf = kmalloc(ies_len, GFP_KERNEL);
2658                 if (buf == NULL)
2659                         return -ENOMEM;
2660                 pos = ies;
2661                 while (pos + 1 < ies + ies_len) {
2662                         if (pos + 2 + pos[1] > ies + ies_len)
2663                                 break;
2664                         if (!ath6kl_is_p2p_ie(pos)) {
2665                                 memcpy(buf + len, pos, 2 + pos[1]);
2666                                 len += 2 + pos[1];
2667                         }
2668                         pos += 2 + pos[1];
2669                 }
2670         }
2671 
2672         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2673                                        WMI_FRAME_PROBE_RESP, buf, len);
2674         kfree(buf);
2675         return ret;
2676 }
2677 
2678 static int ath6kl_set_ies(struct ath6kl_vif *vif,
2679                           struct cfg80211_beacon_data *info)
2680 {
2681         struct ath6kl *ar = vif->ar;
2682         int res;
2683 
2684         /* this also clears IE in fw if it's not set */
2685         res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2686                                        WMI_FRAME_BEACON,
2687                                        info->beacon_ies,
2688                                        info->beacon_ies_len);
2689         if (res)
2690                 return res;
2691 
2692         /* this also clears IE in fw if it's not set */
2693         res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2694                                            info->proberesp_ies_len);
2695         if (res)
2696                 return res;
2697 
2698         /* this also clears IE in fw if it's not set */
2699         res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2700                                        WMI_FRAME_ASSOC_RESP,
2701                                        info->assocresp_ies,
2702                                        info->assocresp_ies_len);
2703         if (res)
2704                 return res;
2705 
2706         return 0;
2707 }
2708 
2709 static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2710                                 u8 *rsn_capab)
2711 {
2712         const u8 *rsn_ie;
2713         size_t rsn_ie_len;
2714         u16 cnt;
2715 
2716         if (!beacon->tail)
2717                 return -EINVAL;
2718 
2719         rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2720         if (!rsn_ie)
2721                 return -EINVAL;
2722 
2723         rsn_ie_len = *(rsn_ie + 1);
2724         /* skip element id and length */
2725         rsn_ie += 2;
2726 
2727         /* skip version */
2728         if (rsn_ie_len < 2)
2729                 return -EINVAL;
2730         rsn_ie +=  2;
2731         rsn_ie_len -= 2;
2732 
2733         /* skip group cipher suite */
2734         if (rsn_ie_len < 4)
2735                 return 0;
2736         rsn_ie +=  4;
2737         rsn_ie_len -= 4;
2738 
2739         /* skip pairwise cipher suite */
2740         if (rsn_ie_len < 2)
2741                 return 0;
2742         cnt = get_unaligned_le16(rsn_ie);
2743         rsn_ie += (2 + cnt * 4);
2744         rsn_ie_len -= (2 + cnt * 4);
2745 
2746         /* skip akm suite */
2747         if (rsn_ie_len < 2)
2748                 return 0;
2749         cnt = get_unaligned_le16(rsn_ie);
2750         rsn_ie += (2 + cnt * 4);
2751         rsn_ie_len -= (2 + cnt * 4);
2752 
2753         if (rsn_ie_len < 2)
2754                 return 0;
2755 
2756         memcpy(rsn_capab, rsn_ie, 2);
2757 
2758         return 0;
2759 }
2760 
2761 static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2762                            struct cfg80211_ap_settings *info)
2763 {
2764         struct ath6kl *ar = ath6kl_priv(dev);
2765         struct ath6kl_vif *vif = netdev_priv(dev);
2766         struct ieee80211_mgmt *mgmt;
2767         bool hidden = false;
2768         u8 *ies;
2769         struct wmi_connect_cmd p;
2770         int res;
2771         int i, ret;
2772         u16 rsn_capab = 0;
2773         int inactivity_timeout = 0;
2774 
2775         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2776 
2777         if (!ath6kl_cfg80211_ready(vif))
2778                 return -EIO;
2779 
2780         if (vif->next_mode != AP_NETWORK)
2781                 return -EOPNOTSUPP;
2782 
2783         res = ath6kl_set_ies(vif, &info->beacon);
2784 
2785         ar->ap_mode_bkey.valid = false;
2786 
2787         ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2788                                                  info->beacon_interval);
2789 
2790         if (ret)
2791                 ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2792 
2793         ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2794                                          info->dtim_period);
2795 
2796         /* ignore error, just print a warning and continue normally */
2797         if (ret)
2798                 ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2799 
2800         if (info->beacon.head == NULL)
2801                 return -EINVAL;
2802         mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2803         ies = mgmt->u.beacon.variable;
2804         if (ies > info->beacon.head + info->beacon.head_len)
2805                 return -EINVAL;
2806 
2807         if (info->ssid == NULL)
2808                 return -EINVAL;
2809         memcpy(vif->ssid, info->ssid, info->ssid_len);
2810         vif->ssid_len = info->ssid_len;
2811         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2812                 hidden = true;
2813 
2814         res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2815         if (res)
2816                 return res;
2817 
2818         ret = ath6kl_set_auth_type(vif, info->auth_type);
2819         if (ret)
2820                 return ret;
2821 
2822         memset(&p, 0, sizeof(p));
2823 
2824         for (i = 0; i < info->crypto.n_akm_suites; i++) {
2825                 switch (info->crypto.akm_suites[i]) {
2826                 case WLAN_AKM_SUITE_8021X:
2827                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2828                                 p.auth_mode |= WPA_AUTH;
2829                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2830                                 p.auth_mode |= WPA2_AUTH;
2831                         break;
2832                 case WLAN_AKM_SUITE_PSK:
2833                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2834                                 p.auth_mode |= WPA_PSK_AUTH;
2835                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2836                                 p.auth_mode |= WPA2_PSK_AUTH;
2837                         break;
2838                 }
2839         }
2840         if (p.auth_mode == 0)
2841                 p.auth_mode = NONE_AUTH;
2842         vif->auth_mode = p.auth_mode;
2843 
2844         for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2845                 switch (info->crypto.ciphers_pairwise[i]) {
2846                 case WLAN_CIPHER_SUITE_WEP40:
2847                 case WLAN_CIPHER_SUITE_WEP104:
2848                         p.prwise_crypto_type |= WEP_CRYPT;
2849                         break;
2850                 case WLAN_CIPHER_SUITE_TKIP:
2851                         p.prwise_crypto_type |= TKIP_CRYPT;
2852                         break;
2853                 case WLAN_CIPHER_SUITE_CCMP:
2854                         p.prwise_crypto_type |= AES_CRYPT;
2855                         break;
2856                 case WLAN_CIPHER_SUITE_SMS4:
2857                         p.prwise_crypto_type |= WAPI_CRYPT;
2858                         break;
2859                 }
2860         }
2861         if (p.prwise_crypto_type == 0) {
2862                 p.prwise_crypto_type = NONE_CRYPT;
2863                 ath6kl_set_cipher(vif, 0, true);
2864         } else if (info->crypto.n_ciphers_pairwise == 1) {
2865                 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2866         }
2867 
2868         switch (info->crypto.cipher_group) {
2869         case WLAN_CIPHER_SUITE_WEP40:
2870         case WLAN_CIPHER_SUITE_WEP104:
2871                 p.grp_crypto_type = WEP_CRYPT;
2872                 break;
2873         case WLAN_CIPHER_SUITE_TKIP:
2874                 p.grp_crypto_type = TKIP_CRYPT;
2875                 break;
2876         case WLAN_CIPHER_SUITE_CCMP:
2877                 p.grp_crypto_type = AES_CRYPT;
2878                 break;
2879         case WLAN_CIPHER_SUITE_SMS4:
2880                 p.grp_crypto_type = WAPI_CRYPT;
2881                 break;
2882         default:
2883                 p.grp_crypto_type = NONE_CRYPT;
2884                 break;
2885         }
2886         ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2887 
2888         p.nw_type = AP_NETWORK;
2889         vif->nw_type = vif->next_mode;
2890 
2891         p.ssid_len = vif->ssid_len;
2892         memcpy(p.ssid, vif->ssid, vif->ssid_len);
2893         p.dot11_auth_mode = vif->dot11_auth_mode;
2894         p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2895 
2896         /* Enable uAPSD support by default */
2897         res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2898         if (res < 0)
2899                 return res;
2900 
2901         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2902                 p.nw_subtype = SUBTYPE_P2PGO;
2903         } else {
2904                 /*
2905                  * Due to firmware limitation, it is not possible to
2906                  * do P2P mgmt operations in AP mode
2907                  */
2908                 p.nw_subtype = SUBTYPE_NONE;
2909         }
2910 
2911         if (info->inactivity_timeout) {
2912                 inactivity_timeout = info->inactivity_timeout;
2913 
2914                 if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2915                              ar->fw_capabilities))
2916                         inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2917                                                           60);
2918 
2919                 res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2920                                                   inactivity_timeout);
2921                 if (res < 0)
2922                         return res;
2923         }
2924 
2925         if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2926                              cfg80211_get_chandef_type(&info->chandef)
2927                                         != NL80211_CHAN_NO_HT))
2928                 return -EIO;
2929 
2930         /*
2931          * Get the PTKSA replay counter in the RSN IE. Supplicant
2932          * will use the RSN IE in M3 message and firmware has to
2933          * advertise the same in beacon/probe response. Send
2934          * the complete RSN IE capability field to firmware
2935          */
2936         if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2937             test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2938                      ar->fw_capabilities)) {
2939                 res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2940                                             WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2941                                             (const u8 *) &rsn_capab,
2942                                             sizeof(rsn_capab));
2943                 vif->rsn_capab = rsn_capab;
2944                 if (res < 0)
2945                         return res;
2946         }
2947 
2948         memcpy(&vif->profile, &p, sizeof(p));
2949         res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2950         if (res < 0)
2951                 return res;
2952 
2953         return 0;
2954 }
2955 
2956 static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2957                                 struct cfg80211_beacon_data *beacon)
2958 {
2959         struct ath6kl_vif *vif = netdev_priv(dev);
2960 
2961         if (!ath6kl_cfg80211_ready(vif))
2962                 return -EIO;
2963 
2964         if (vif->next_mode != AP_NETWORK)
2965                 return -EOPNOTSUPP;
2966 
2967         return ath6kl_set_ies(vif, beacon);
2968 }
2969 
2970 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2971 {
2972         struct ath6kl *ar = ath6kl_priv(dev);
2973         struct ath6kl_vif *vif = netdev_priv(dev);
2974 
2975         if (vif->nw_type != AP_NETWORK)
2976                 return -EOPNOTSUPP;
2977         if (!test_bit(CONNECTED, &vif->flags))
2978                 return -ENOTCONN;
2979 
2980         ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2981         clear_bit(CONNECTED, &vif->flags);
2982         netif_carrier_off(vif->ndev);
2983 
2984         /* Restore ht setting in firmware */
2985         return ath6kl_restore_htcap(vif);
2986 }
2987 
2988 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2989 
2990 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2991                               struct station_del_parameters *params)
2992 {
2993         struct ath6kl *ar = ath6kl_priv(dev);
2994         struct ath6kl_vif *vif = netdev_priv(dev);
2995         const u8 *addr = params->mac ? params->mac : bcast_addr;
2996 
2997         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2998                                       addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2999 }
3000 
3001 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3002                                  const u8 *mac,
3003                                  struct station_parameters *params)
3004 {
3005         struct ath6kl *ar = ath6kl_priv(dev);
3006         struct ath6kl_vif *vif = netdev_priv(dev);
3007         int err;
3008 
3009         if (vif->nw_type != AP_NETWORK)
3010                 return -EOPNOTSUPP;
3011 
3012         err = cfg80211_check_station_change(wiphy, params,
3013                                             CFG80211_STA_AP_MLME_CLIENT);
3014         if (err)
3015                 return err;
3016 
3017         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3018                 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3019                                               WMI_AP_MLME_AUTHORIZE, mac, 0);
3020         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3021                                       WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3022 }
3023 
3024 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3025                                     struct wireless_dev *wdev,
3026                                     struct ieee80211_channel *chan,
3027                                     unsigned int duration,
3028                                     u64 *cookie)
3029 {
3030         struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3031         struct ath6kl *ar = ath6kl_priv(vif->ndev);
3032         u32 id;
3033 
3034         /* TODO: if already pending or ongoing remain-on-channel,
3035          * return -EBUSY */
3036         id = ++vif->last_roc_id;
3037         if (id == 0) {
3038                 /* Do not use 0 as the cookie value */
3039                 id = ++vif->last_roc_id;
3040         }
3041         *cookie = id;
3042 
3043         return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3044                                              chan->center_freq, duration);
3045 }
3046 
3047 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3048                                            struct wireless_dev *wdev,
3049                                            u64 cookie)
3050 {
3051         struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3052         struct ath6kl *ar = ath6kl_priv(vif->ndev);
3053 
3054         if (cookie != vif->last_roc_id)
3055                 return -ENOENT;
3056         vif->last_cancel_roc_id = cookie;
3057 
3058         return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3059 }
3060 
3061 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3062                                      const u8 *buf, size_t len,
3063                                      unsigned int freq)
3064 {
3065         struct ath6kl *ar = vif->ar;
3066         const u8 *pos;
3067         u8 *p2p;
3068         int p2p_len;
3069         int ret;
3070         const struct ieee80211_mgmt *mgmt;
3071 
3072         mgmt = (const struct ieee80211_mgmt *) buf;
3073 
3074         /* Include P2P IE(s) from the frame generated in user space. */
3075 
3076         p2p = kmalloc(len, GFP_KERNEL);
3077         if (p2p == NULL)
3078                 return -ENOMEM;
3079         p2p_len = 0;
3080 
3081         pos = mgmt->u.probe_resp.variable;
3082         while (pos + 1 < buf + len) {
3083                 if (pos + 2 + pos[1] > buf + len)
3084                         break;
3085                 if (ath6kl_is_p2p_ie(pos)) {
3086                         memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3087                         p2p_len += 2 + pos[1];
3088                 }
3089                 pos += 2 + pos[1];
3090         }
3091 
3092         ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3093                                                  mgmt->da, p2p, p2p_len);
3094         kfree(p2p);
3095         return ret;
3096 }
3097 
3098 static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3099                                      u32 id,
3100                                      u32 freq,
3101                                      u32 wait,
3102                                      const u8 *buf,
3103                                      size_t len,
3104                                      bool *more_data,
3105                                      bool no_cck)
3106 {
3107         struct ieee80211_mgmt *mgmt;
3108         struct ath6kl_sta *conn;
3109         bool is_psq_empty = false;
3110         struct ath6kl_mgmt_buff *mgmt_buf;
3111         size_t mgmt_buf_size;
3112         struct ath6kl *ar = vif->ar;
3113 
3114         mgmt = (struct ieee80211_mgmt *) buf;
3115         if (is_multicast_ether_addr(mgmt->da))
3116                 return false;
3117 
3118         conn = ath6kl_find_sta(vif, mgmt->da);
3119         if (!conn)
3120                 return false;
3121 
3122         if (conn->sta_flags & STA_PS_SLEEP) {
3123                 if (!(conn->sta_flags & STA_PS_POLLED)) {
3124                         /* Queue the frames if the STA is sleeping */
3125                         mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3126                         mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3127                         if (!mgmt_buf)
3128                                 return false;
3129 
3130                         INIT_LIST_HEAD(&mgmt_buf->list);
3131                         mgmt_buf->id = id;
3132                         mgmt_buf->freq = freq;
3133                         mgmt_buf->wait = wait;
3134                         mgmt_buf->len = len;
3135                         mgmt_buf->no_cck = no_cck;
3136                         memcpy(mgmt_buf->buf, buf, len);
3137                         spin_lock_bh(&conn->psq_lock);
3138                         is_psq_empty = skb_queue_empty(&conn->psq) &&
3139                                         (conn->mgmt_psq_len == 0);
3140                         list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3141                         conn->mgmt_psq_len++;
3142                         spin_unlock_bh(&conn->psq_lock);
3143 
3144                         /*
3145                          * If this is the first pkt getting queued
3146                          * for this STA, update the PVB for this
3147                          * STA.
3148                          */
3149                         if (is_psq_empty)
3150                                 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3151                                                        conn->aid, 1);
3152                         return true;
3153                 }
3154 
3155                 /*
3156                  * This tx is because of a PsPoll.
3157                  * Determine if MoreData bit has to be set.
3158                  */
3159                 spin_lock_bh(&conn->psq_lock);
3160                 if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3161                         *more_data = true;
3162                 spin_unlock_bh(&conn->psq_lock);
3163         }
3164 
3165         return false;
3166 }
3167 
3168 /* Check if SSID length is greater than DIRECT- */
3169 static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3170 {
3171         const struct ieee80211_mgmt *mgmt;
3172         mgmt = (const struct ieee80211_mgmt *) buf;
3173 
3174         /* variable[1] contains the SSID tag length */
3175         if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3176             (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3177                 return true;
3178         }
3179 
3180         return false;
3181 }
3182 
3183 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3184                           struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3185 {
3186         struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3187         struct ath6kl *ar = ath6kl_priv(vif->ndev);
3188         struct ieee80211_channel *chan = params->chan;
3189         const u8 *buf = params->buf;
3190         size_t len = params->len;
3191         unsigned int wait = params->wait;
3192         bool no_cck = params->no_cck;
3193         u32 id, freq;
3194         const struct ieee80211_mgmt *mgmt;
3195         bool more_data, queued;
3196 
3197         /* default to the current channel, but use the one specified as argument
3198          * if any
3199          */
3200         freq = vif->ch_hint;
3201         if (chan)
3202                 freq = chan->center_freq;
3203 
3204         /* never send freq zero to the firmware */
3205         if (WARN_ON(freq == 0))
3206                 return -EINVAL;
3207 
3208         mgmt = (const struct ieee80211_mgmt *) buf;
3209         if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3210             ieee80211_is_probe_resp(mgmt->frame_control) &&
3211             ath6kl_is_p2p_go_ssid(buf, len)) {
3212                 /*
3213                  * Send Probe Response frame in GO mode using a separate WMI
3214                  * command to allow the target to fill in the generic IEs.
3215                  */
3216                 *cookie = 0; /* TX status not supported */
3217                 return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3218         }
3219 
3220         id = vif->send_action_id++;
3221         if (id == 0) {
3222                 /*
3223                  * 0 is a reserved value in the WMI command and shall not be
3224                  * used for the command.
3225                  */
3226                 id = vif->send_action_id++;
3227         }
3228 
3229         *cookie = id;
3230 
3231         /* AP mode Power saving processing */
3232         if (vif->nw_type == AP_NETWORK) {
3233                 queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3234                                                   &more_data, no_cck);
3235                 if (queued)
3236                         return 0;
3237         }
3238 
3239         return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3240                                         wait, buf, len, no_cck);
3241 }
3242 
3243 static int ath6kl_get_antenna(struct wiphy *wiphy,
3244                               u32 *tx_ant, u32 *rx_ant)
3245 {
3246         struct ath6kl *ar = wiphy_priv(wiphy);
3247         *tx_ant = ar->hw.tx_ant;
3248         *rx_ant = ar->hw.rx_ant;
3249         return 0;
3250 }
3251 
3252 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
3253                                        struct wireless_dev *wdev,
3254                                        u16 frame_type, bool reg)
3255 {
3256         struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3257 
3258         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3259                    __func__, frame_type, reg);
3260         if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3261                 /*
3262                  * Note: This notification callback is not allowed to sleep, so
3263                  * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3264                  * hardcode target to report Probe Request frames all the time.
3265                  */
3266                 vif->probe_req_report = reg;
3267         }
3268 }
3269 
3270 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3271                         struct net_device *dev,
3272                         struct cfg80211_sched_scan_request *request)
3273 {
3274         struct ath6kl *ar = ath6kl_priv(dev);
3275         struct ath6kl_vif *vif = netdev_priv(dev);
3276         u16 interval;
3277         int ret, rssi_thold;
3278         int n_match_sets = request->n_match_sets;
3279 
3280         /*
3281          * If there's a matchset w/o an SSID, then assume it's just for
3282          * the RSSI (nothing else is currently supported) and ignore it.
3283          * The device only supports a global RSSI filter that we set below.
3284          */
3285         if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3286                 n_match_sets = 0;
3287 
3288         if (ar->state != ATH6KL_STATE_ON)
3289                 return -EIO;
3290 
3291         if (vif->sme_state != SME_DISCONNECTED)
3292                 return -EBUSY;
3293 
3294         ath6kl_cfg80211_scan_complete_event(vif, true);
3295 
3296         ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3297                                       request->n_ssids,
3298                                       request->match_sets,
3299                                       n_match_sets);
3300         if (ret < 0)
3301                 return ret;
3302 
3303         if (!n_match_sets) {
3304                 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3305                                                ALL_BSS_FILTER, 0);
3306                 if (ret < 0)
3307                         return ret;
3308         } else {
3309                  ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3310                                                 MATCHED_SSID_FILTER, 0);
3311                 if (ret < 0)
3312                         return ret;
3313         }
3314 
3315         if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3316                      ar->fw_capabilities)) {
3317                 if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3318                         rssi_thold = 0;
3319                 else if (request->min_rssi_thold < -127)
3320                         rssi_thold = -127;
3321                 else
3322                         rssi_thold = request->min_rssi_thold;
3323 
3324                 ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3325                                                      rssi_thold);
3326                 if (ret) {
3327                         ath6kl_err("failed to set RSSI threshold for scan\n");
3328                         return ret;
3329                 }
3330         }
3331 
3332         /* fw uses seconds, also make sure that it's >0 */
3333         interval = max_t(u16, 1, request->scan_plans[0].interval);
3334 
3335         ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3336                                   interval, interval,
3337                                   vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3338 
3339         /* this also clears IE in fw if it's not set */
3340         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3341                                        WMI_FRAME_PROBE_REQ,
3342                                        request->ie, request->ie_len);
3343         if (ret) {
3344                 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3345                             ret);
3346                 return ret;
3347         }
3348 
3349         ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3350         if (ret)
3351                 return ret;
3352 
3353         set_bit(SCHED_SCANNING, &vif->flags);
3354 
3355         return 0;
3356 }
3357 
3358 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3359                                       struct net_device *dev, u64 reqid)
3360 {
3361         struct ath6kl_vif *vif = netdev_priv(dev);
3362         bool stopped;
3363 
3364         stopped = __ath6kl_cfg80211_sscan_stop(vif);
3365 
3366         if (!stopped)
3367                 return -EIO;
3368 
3369         return 0;
3370 }
3371 
3372 static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3373                                        struct net_device *dev,
3374                                        const u8 *addr,
3375                                        const struct cfg80211_bitrate_mask *mask)
3376 {
3377         struct ath6kl *ar = ath6kl_priv(dev);
3378         struct ath6kl_vif *vif = netdev_priv(dev);
3379 
3380         return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3381                                            mask);
3382 }
3383 
3384 static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3385                                           struct net_device *dev,
3386                                           u32 rate, u32 pkts, u32 intvl)
3387 {
3388         struct ath6kl *ar = ath6kl_priv(dev);
3389         struct ath6kl_vif *vif = netdev_priv(dev);
3390 
3391         if (vif->nw_type != INFRA_NETWORK ||
3392             !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3393                 return -EOPNOTSUPP;
3394 
3395         if (vif->sme_state != SME_CONNECTED)
3396                 return -ENOTCONN;
3397 
3398         /* save this since the firmware won't report the interval */
3399         vif->txe_intvl = intvl;
3400 
3401         return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3402                                          rate, pkts, intvl);
3403 }
3404 
3405 static const struct ieee80211_txrx_stypes
3406 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3407         [NL80211_IFTYPE_STATION] = {
3408                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3409                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3410                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3411                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3412         },
3413         [NL80211_IFTYPE_AP] = {
3414                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3415                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3416                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3417                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3418         },
3419         [NL80211_IFTYPE_P2P_CLIENT] = {
3420                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3421                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3422                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3423                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3424         },
3425         [NL80211_IFTYPE_P2P_GO] = {
3426                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3427                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3428                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3429                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3430         },
3431 };
3432 
3433 static struct cfg80211_ops ath6kl_cfg80211_ops = {
3434         .add_virtual_intf = ath6kl_cfg80211_add_iface,
3435         .del_virtual_intf = ath6kl_cfg80211_del_iface,
3436         .change_virtual_intf = ath6kl_cfg80211_change_iface,
3437         .scan = ath6kl_cfg80211_scan,
3438         .connect = ath6kl_cfg80211_connect,
3439         .disconnect = ath6kl_cfg80211_disconnect,
3440         .add_key = ath6kl_cfg80211_add_key,
3441         .get_key = ath6kl_cfg80211_get_key,
3442         .del_key = ath6kl_cfg80211_del_key,
3443         .set_default_key = ath6kl_cfg80211_set_default_key,
3444         .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3445         .set_tx_power = ath6kl_cfg80211_set_txpower,
3446         .get_tx_power = ath6kl_cfg80211_get_txpower,
3447         .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3448         .join_ibss = ath6kl_cfg80211_join_ibss,
3449         .leave_ibss = ath6kl_cfg80211_leave_ibss,
3450         .get_station = ath6kl_get_station,
3451         .set_pmksa = ath6kl_set_pmksa,
3452         .del_pmksa = ath6kl_del_pmksa,
3453         .flush_pmksa = ath6kl_flush_pmksa,
3454         CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3455 #ifdef CONFIG_PM
3456         .suspend = __ath6kl_cfg80211_suspend,
3457         .resume = __ath6kl_cfg80211_resume,
3458 #endif
3459         .start_ap = ath6kl_start_ap,
3460         .change_beacon = ath6kl_change_beacon,
3461         .stop_ap = ath6kl_stop_ap,
3462         .del_station = ath6kl_del_station,
3463         .change_station = ath6kl_change_station,
3464         .remain_on_channel = ath6kl_remain_on_channel,
3465         .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3466         .mgmt_tx = ath6kl_mgmt_tx,
3467         .mgmt_frame_register = ath6kl_mgmt_frame_register,
3468         .get_antenna = ath6kl_get_antenna,
3469         .sched_scan_start = ath6kl_cfg80211_sscan_start,
3470         .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3471         .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3472         .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3473 };
3474 
3475 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3476 {
3477         ath6kl_cfg80211_sscan_disable(vif);
3478 
3479         switch (vif->sme_state) {
3480         case SME_DISCONNECTED:
3481                 break;
3482         case SME_CONNECTING:
3483                 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3484                                         NULL, 0,
3485                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
3486                                         GFP_KERNEL);
3487                 break;
3488         case SME_CONNECTED:
3489                 cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3490                 break;
3491         }
3492 
3493         if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3494             (test_bit(CONNECTED, &vif->flags) ||
3495             test_bit(CONNECT_PEND, &vif->flags)))
3496                 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3497 
3498         vif->sme_state = SME_DISCONNECTED;
3499         clear_bit(CONNECTED, &vif->flags);
3500         clear_bit(CONNECT_PEND, &vif->flags);
3501 
3502         /* Stop netdev queues, needed during recovery */
3503         netif_stop_queue(vif->ndev);
3504         netif_carrier_off(vif->ndev);
3505 
3506         /* disable scanning */
3507         if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3508             ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3509                                       0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3510                 ath6kl_warn("failed to disable scan during stop\n");
3511 
3512         ath6kl_cfg80211_scan_complete_event(vif, true);
3513 }
3514 
3515 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3516 {
3517         struct ath6kl_vif *vif;
3518 
3519         vif = ath6kl_vif_first(ar);
3520         if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3521                 /* save the current power mode before enabling power save */
3522                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3523 
3524                 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3525                         ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3526                 return;
3527         }
3528 
3529         /*
3530          * FIXME: we should take ar->list_lock to protect changes in the
3531          * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3532          * sleeps.
3533          */
3534         list_for_each_entry(vif, &ar->vif_list, list)
3535                 ath6kl_cfg80211_stop(vif);
3536 }
3537 
3538 static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3539                                        struct regulatory_request *request)
3540 {
3541         struct ath6kl *ar = wiphy_priv(wiphy);
3542         u32 rates[NUM_NL80211_BANDS];
3543         int ret, i;
3544 
3545         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3546                    "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3547                    request->alpha2[0], request->alpha2[1],
3548                    request->intersect ? " intersect" : "",
3549                    request->processed ? " processed" : "",
3550                    request->initiator, request->user_reg_hint_type);
3551 
3552         if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3553                 return;
3554 
3555         ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3556         if (ret) {
3557                 ath6kl_err("failed to set regdomain: %d\n", ret);
3558                 return;
3559         }
3560 
3561         /*
3562          * Firmware will apply the regdomain change only after a scan is
3563          * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3564          * changed.
3565          */
3566 
3567         for (i = 0; i < NUM_NL80211_BANDS; i++)
3568                 if (wiphy->bands[i])
3569                         rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3570 
3571 
3572         ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3573                                        false, 0, ATH6KL_FG_SCAN_INTERVAL,
3574                                        0, NULL, false, rates);
3575         if (ret) {
3576                 ath6kl_err("failed to start scan for a regdomain change: %d\n",
3577                            ret);
3578                 return;
3579         }
3580 }
3581 
3582 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3583 {
3584         vif->aggr_cntxt = aggr_init(vif);
3585         if (!vif->aggr_cntxt) {
3586                 ath6kl_err("failed to initialize aggr\n");
3587                 return -ENOMEM;
3588         }
3589 
3590         timer_setup(&vif->disconnect_timer, disconnect_timer_handler, 0);
3591         timer_setup(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer, 0);
3592 
3593         set_bit(WMM_ENABLED, &vif->flags);
3594         spin_lock_init(&vif->if_lock);
3595 
3596         INIT_LIST_HEAD(&vif->mc_filter);
3597 
3598         return 0;
3599 }
3600 
3601 void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3602 {
3603         static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3604         bool discon_issued;
3605 
3606         netif_stop_queue(vif->ndev);
3607 
3608         clear_bit(WLAN_ENABLED, &vif->flags);
3609 
3610         if (wmi_ready) {
3611                 discon_issued = test_bit(CONNECTED, &vif->flags) ||
3612                                 test_bit(CONNECT_PEND, &vif->flags);
3613                 ath6kl_disconnect(vif);
3614                 del_timer(&vif->disconnect_timer);
3615 
3616                 if (discon_issued)
3617                         ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3618                                                 (vif->nw_type & AP_NETWORK) ?
3619                                                 bcast_mac : vif->bssid,
3620                                                 0, NULL, 0);
3621         }
3622 
3623         if (vif->scan_req) {
3624                 struct cfg80211_scan_info info = {
3625                         .aborted = true,
3626                 };
3627 
3628                 cfg80211_scan_done(vif->scan_req, &info);
3629                 vif->scan_req = NULL;
3630         }
3631 
3632         /* need to clean up enhanced bmiss detection fw state */
3633         ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3634 }
3635 
3636 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3637 {
3638         struct ath6kl *ar = vif->ar;
3639         struct ath6kl_mc_filter *mc_filter, *tmp;
3640 
3641         aggr_module_destroy(vif->aggr_cntxt);
3642 
3643         ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3644 
3645         if (vif->nw_type == ADHOC_NETWORK)
3646                 ar->ibss_if_active = false;
3647 
3648         list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3649                 list_del(&mc_filter->list);
3650                 kfree(mc_filter);
3651         }
3652 
3653         unregister_netdevice(vif->ndev);
3654 
3655         ar->num_vif--;
3656 }
3657 
3658 static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3659         /* Common stats names used by many drivers. */
3660         "tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3661 
3662         /* TX stats. */
3663         "d_tx_ucast_pkts", "d_tx_bcast_pkts",
3664         "d_tx_ucast_bytes", "d_tx_bcast_bytes",
3665         "d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3666         "d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3667         "d_tx_tkip_counter_measures",
3668 
3669         /* RX Stats. */
3670         "d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3671         "d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3672         "d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3673         "d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3674         "d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3675         "d_rx_ccmp_replay_err",
3676 
3677         /* Misc stats. */
3678         "d_beacon_miss", "d_num_connects", "d_num_disconnects",
3679         "d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3680         "d_arp_replied"
3681 };
3682 
3683 #define ATH6KL_STATS_LEN        ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3684 
3685 static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3686 {
3687         int rv = 0;
3688 
3689         if (sset == ETH_SS_STATS)
3690                 rv += ATH6KL_STATS_LEN;
3691 
3692         if (rv == 0)
3693                 return -EOPNOTSUPP;
3694         return rv;
3695 }
3696 
3697 static void ath6kl_get_stats(struct net_device *dev,
3698                             struct ethtool_stats *stats,
3699                             u64 *data)
3700 {
3701         struct ath6kl_vif *vif = netdev_priv(dev);
3702         struct ath6kl *ar = vif->ar;
3703         int i = 0;
3704         struct target_stats *tgt_stats;
3705 
3706         memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3707 
3708         ath6kl_read_tgt_stats(ar, vif);
3709 
3710         tgt_stats = &vif->target_stats;
3711 
3712         data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3713         data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3714         data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3715         data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3716 
3717         data[i++] = tgt_stats->tx_ucast_pkt;
3718         data[i++] = tgt_stats->tx_bcast_pkt;
3719         data[i++] = tgt_stats->tx_ucast_byte;
3720         data[i++] = tgt_stats->tx_bcast_byte;
3721         data[i++] = tgt_stats->tx_rts_success_cnt;
3722         data[i++] = tgt_stats->tx_err;
3723         data[i++] = tgt_stats->tx_fail_cnt;
3724         data[i++] = tgt_stats->tx_retry_cnt;
3725         data[i++] = tgt_stats->tx_mult_retry_cnt;
3726         data[i++] = tgt_stats->tx_rts_fail_cnt;
3727         data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3728 
3729         data[i++] = tgt_stats->rx_ucast_pkt;
3730         data[i++] = tgt_stats->rx_ucast_rate;
3731         data[i++] = tgt_stats->rx_bcast_pkt;
3732         data[i++] = tgt_stats->rx_ucast_byte;
3733         data[i++] = tgt_stats->rx_bcast_byte;
3734         data[i++] = tgt_stats->rx_frgment_pkt;
3735         data[i++] = tgt_stats->rx_err;
3736         data[i++] = tgt_stats->rx_crc_err;
3737         data[i++] = tgt_stats->rx_key_cache_miss;
3738         data[i++] = tgt_stats->rx_decrypt_err;
3739         data[i++] = tgt_stats->rx_dupl_frame;
3740         data[i++] = tgt_stats->tkip_local_mic_fail;
3741         data[i++] = tgt_stats->tkip_fmt_err;
3742         data[i++] = tgt_stats->ccmp_fmt_err;
3743         data[i++] = tgt_stats->ccmp_replays;
3744 
3745         data[i++] = tgt_stats->cs_bmiss_cnt;
3746         data[i++] = tgt_stats->cs_connect_cnt;
3747         data[i++] = tgt_stats->cs_discon_cnt;
3748         data[i++] = tgt_stats->cs_ave_beacon_rssi;
3749         data[i++] = tgt_stats->arp_received;
3750         data[i++] = tgt_stats->arp_matched;
3751         data[i++] = tgt_stats->arp_replied;
3752 
3753         if (i !=  ATH6KL_STATS_LEN) {
3754                 WARN_ON_ONCE(1);
3755                 ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3756                            i, (int)ATH6KL_STATS_LEN);
3757         }
3758 }
3759 
3760 /* These stats are per NIC, not really per vdev, so we just ignore dev. */
3761 static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3762 {
3763         int sz_sta_stats = 0;
3764 
3765         if (sset == ETH_SS_STATS) {
3766                 sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3767                 memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3768         }
3769 }
3770 
3771 static const struct ethtool_ops ath6kl_ethtool_ops = {
3772         .get_drvinfo = cfg80211_get_drvinfo,
3773         .get_link = ethtool_op_get_link,
3774         .get_strings = ath6kl_get_strings,
3775         .get_ethtool_stats = ath6kl_get_stats,
3776         .get_sset_count = ath6kl_get_sset_count,
3777 };
3778 
3779 struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3780                                           unsigned char name_assign_type,
3781                                           enum nl80211_iftype type,
3782                                           u8 fw_vif_idx, u8 nw_type)
3783 {
3784         struct net_device *ndev;
3785         struct ath6kl_vif *vif;
3786 
3787         ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3788         if (!ndev)
3789                 return NULL;
3790 
3791         vif = netdev_priv(ndev);
3792         ndev->ieee80211_ptr = &vif->wdev;
3793         vif->wdev.wiphy = ar->wiphy;
3794         vif->ar = ar;
3795         vif->ndev = ndev;
3796         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3797         vif->wdev.netdev = ndev;
3798         vif->wdev.iftype = type;
3799         vif->fw_vif_idx = fw_vif_idx;
3800         vif->nw_type = nw_type;
3801         vif->next_mode = nw_type;
3802         vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3803         vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3804         vif->bg_scan_period = 0;
3805         vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3806         vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3807 
3808         memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3809         if (fw_vif_idx != 0) {
3810                 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3811                                      0x2;
3812                 if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3813                              ar->fw_capabilities))
3814                         ndev->dev_addr[4] ^= 0x80;
3815         }
3816 
3817         init_netdev(ndev);
3818 
3819         ath6kl_init_control_info(vif);
3820 
3821         if (ath6kl_cfg80211_vif_init(vif))
3822                 goto err;
3823 
3824         netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3825 
3826         if (register_netdevice(ndev))
3827                 goto err;
3828 
3829         ar->avail_idx_map &= ~BIT(fw_vif_idx);
3830         vif->sme_state = SME_DISCONNECTED;
3831         set_bit(WLAN_ENABLED, &vif->flags);
3832         ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3833 
3834         if (type == NL80211_IFTYPE_ADHOC)
3835                 ar->ibss_if_active = true;
3836 
3837         spin_lock_bh(&ar->list_lock);
3838         list_add_tail(&vif->list, &ar->vif_list);
3839         spin_unlock_bh(&ar->list_lock);
3840 
3841         return &vif->wdev;
3842 
3843 err:
3844         aggr_module_destroy(vif->aggr_cntxt);
3845         free_netdev(ndev);
3846         return NULL;
3847 }
3848 
3849 #ifdef CONFIG_PM
3850 static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3851         .flags = WIPHY_WOWLAN_MAGIC_PKT |
3852                  WIPHY_WOWLAN_DISCONNECT |
3853                  WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3854                  WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3855                  WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3856                  WIPHY_WOWLAN_4WAY_HANDSHAKE,
3857         .n_patterns = WOW_MAX_FILTERS_PER_LIST,
3858         .pattern_min_len = 1,
3859         .pattern_max_len = WOW_PATTERN_SIZE,
3860 };
3861 #endif
3862 
3863 int ath6kl_cfg80211_init(struct ath6kl *ar)
3864 {
3865         struct wiphy *wiphy = ar->wiphy;
3866         bool band_2gig = false, band_5gig = false, ht = false;
3867         int ret;
3868 
3869         wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3870 
3871         wiphy->max_remain_on_channel_duration = 5000;
3872 
3873         /* set device pointer for wiphy */
3874         set_wiphy_dev(wiphy, ar->dev);
3875 
3876         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3877                                  BIT(NL80211_IFTYPE_ADHOC) |
3878                                  BIT(NL80211_IFTYPE_AP);
3879         if (ar->p2p) {
3880                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3881                                           BIT(NL80211_IFTYPE_P2P_CLIENT);
3882         }
3883 
3884         if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3885             test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3886                 wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3887                 ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3888         }
3889 
3890         /* max num of ssids that can be probed during scanning */
3891         wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3892 
3893         /* max num of ssids that can be matched after scan */
3894         if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3895                      ar->fw_capabilities))
3896                 wiphy->max_match_sets = MAX_PROBED_SSIDS;
3897 
3898         wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3899         switch (ar->hw.cap) {
3900         case WMI_11AN_CAP:
3901                 ht = true;
3902                 /* fall through */
3903         case WMI_11A_CAP:
3904                 band_5gig = true;
3905                 break;
3906         case WMI_11GN_CAP:
3907                 ht = true;
3908                 /* fall through */
3909         case WMI_11G_CAP:
3910                 band_2gig = true;
3911                 break;
3912         case WMI_11AGN_CAP:
3913                 ht = true;
3914                 /* fall through */
3915         case WMI_11AG_CAP:
3916                 band_2gig = true;
3917                 band_5gig = true;
3918                 break;
3919         default:
3920                 ath6kl_err("invalid phy capability!\n");
3921                 return -EINVAL;
3922         }
3923 
3924         /*
3925          * Even if the fw has HT support, advertise HT cap only when
3926          * the firmware has support to override RSN capability, otherwise
3927          * 4-way handshake would fail.
3928          */
3929         if (!(ht &&
3930               test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3931                        ar->fw_capabilities))) {
3932                 ath6kl_band_2ghz.ht_cap.cap = 0;
3933                 ath6kl_band_2ghz.ht_cap.ht_supported = false;
3934                 ath6kl_band_5ghz.ht_cap.cap = 0;
3935                 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3936 
3937                 if (ht)
3938                         ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3939         }
3940 
3941         if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3942                      ar->fw_capabilities)) {
3943                 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3944                 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3945                 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3946                 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3947                 ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3948                 ar->hw.rx_ant = 0x3;
3949         } else {
3950                 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3951                 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3952                 ar->hw.tx_ant = 1;
3953                 ar->hw.rx_ant = 1;
3954         }
3955 
3956         wiphy->available_antennas_tx = ar->hw.tx_ant;
3957         wiphy->available_antennas_rx = ar->hw.rx_ant;
3958 
3959         if (band_2gig)
3960                 wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3961         if (band_5gig)
3962                 wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3963 
3964         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3965 
3966         wiphy->cipher_suites = cipher_suites;
3967         wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3968 
3969 #ifdef CONFIG_PM
3970         wiphy->wowlan = &ath6kl_wowlan_support;
3971 #endif
3972 
3973         wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3974 
3975         ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3976                             WIPHY_FLAG_HAVE_AP_SME |
3977                             WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3978                             WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3979 
3980         if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3981                 ar->wiphy->max_sched_scan_reqs = 1;
3982 
3983         if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3984                      ar->fw_capabilities))
3985                 ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3986 
3987         ar->wiphy->probe_resp_offload =
3988                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3989                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3990                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3991 
3992         ret = wiphy_register(wiphy);
3993         if (ret < 0) {
3994                 ath6kl_err("couldn't register wiphy device\n");
3995                 return ret;
3996         }
3997 
3998         ar->wiphy_registered = true;
3999 
4000         return 0;
4001 }
4002 
4003 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4004 {
4005         wiphy_unregister(ar->wiphy);
4006 
4007         ar->wiphy_registered = false;
4008 }
4009 
4010 struct ath6kl *ath6kl_cfg80211_create(void)
4011 {
4012         struct ath6kl *ar;
4013         struct wiphy *wiphy;
4014 
4015         /* create a new wiphy for use with cfg80211 */
4016         wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4017 
4018         if (!wiphy) {
4019                 ath6kl_err("couldn't allocate wiphy device\n");
4020                 return NULL;
4021         }
4022 
4023         ar = wiphy_priv(wiphy);
4024         ar->wiphy = wiphy;
4025 
4026         return ar;
4027 }
4028 
4029 /* Note: ar variable must not be accessed after calling this! */
4030 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4031 {
4032         int i;
4033 
4034         for (i = 0; i < AP_MAX_NUM_STA; i++)
4035                 kfree(ar->sta_list[i].aggr_conn);
4036 
4037         wiphy_free(ar->wiphy);
4038 }
4039 

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