root/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c

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

DEFINITIONS

This source file includes following definitions.
  1. check_vif_up
  2. nl80211_band_to_fwil
  3. chandef_to_chanspec
  4. channel_to_chanspec
  5. brcmf_parse_tlvs
  6. brcmf_tlv_has_ie
  7. brcmf_find_wpaie
  8. brcmf_find_wpsie
  9. brcmf_vif_change_validate
  10. brcmf_vif_add_validate
  11. convert_key_from_CPU
  12. send_key_to_dongle
  13. brcmf_cfg80211_update_proto_addr_mode
  14. brcmf_get_first_free_bsscfgidx
  15. brcmf_cfg80211_request_ap_if
  16. brcmf_ap_add_vif
  17. brcmf_is_apmode
  18. brcmf_is_ibssmode
  19. brcmf_cfg80211_add_iface
  20. brcmf_scan_config_mpc
  21. brcmf_set_mpc
  22. brcmf_notify_escan_complete
  23. brcmf_cfg80211_del_ap_iface
  24. brcmf_cfg80211_del_iface
  25. brcmf_cfg80211_change_iface
  26. brcmf_escan_prep
  27. brcmf_run_escan
  28. brcmf_do_escan
  29. brcmf_cfg80211_scan
  30. brcmf_set_rts
  31. brcmf_set_frag
  32. brcmf_set_retry
  33. brcmf_cfg80211_set_wiphy_params
  34. brcmf_init_prof
  35. brcmf_map_fw_linkdown_reason
  36. brcmf_set_pmk
  37. brcmf_link_down
  38. brcmf_cfg80211_join_ibss
  39. brcmf_cfg80211_leave_ibss
  40. brcmf_set_wpa_version
  41. brcmf_set_auth_type
  42. brcmf_set_wsec_mode
  43. brcmf_set_key_mgmt
  44. brcmf_set_sharedkey
  45. brcmf_war_auth_type
  46. brcmf_set_join_pref
  47. brcmf_cfg80211_connect
  48. brcmf_cfg80211_disconnect
  49. brcmf_cfg80211_set_tx_power
  50. brcmf_cfg80211_get_tx_power
  51. brcmf_cfg80211_config_default_key
  52. brcmf_cfg80211_del_key
  53. brcmf_cfg80211_add_key
  54. brcmf_cfg80211_get_key
  55. brcmf_cfg80211_config_default_mgmt_key
  56. brcmf_cfg80211_reconfigure_wep
  57. brcmf_convert_sta_flags
  58. brcmf_fill_bss_param
  59. brcmf_cfg80211_get_station_ibss
  60. brcmf_cfg80211_get_station
  61. brcmf_cfg80211_dump_station
  62. brcmf_cfg80211_set_power_mgmt
  63. brcmf_inform_single_bss
  64. next_bss_le
  65. brcmf_inform_bss
  66. brcmf_inform_ibss
  67. brcmf_update_bss_info
  68. brcmf_abort_scanning
  69. brcmf_cfg80211_escan_timeout_worker
  70. brcmf_escan_timeout
  71. brcmf_compare_update_same_bss
  72. brcmf_cfg80211_escan_handler
  73. brcmf_init_escan
  74. brcmf_alloc_internal_escan_request
  75. brcmf_internal_escan_add_info
  76. brcmf_start_internal_escan
  77. brcmf_get_netinfo_array
  78. brcmf_notify_sched_scan_results
  79. brcmf_cfg80211_sched_scan_start
  80. brcmf_cfg80211_sched_scan_stop
  81. brcmf_delay
  82. brcmf_config_wowl_pattern
  83. brcmf_wowl_nd_results
  84. brcmf_report_wowl_wakeind
  85. brcmf_report_wowl_wakeind
  86. brcmf_cfg80211_resume
  87. brcmf_configure_wowl
  88. brcmf_cfg80211_suspend
  89. brcmf_update_pmklist
  90. brcmf_cfg80211_set_pmksa
  91. brcmf_cfg80211_del_pmksa
  92. brcmf_cfg80211_flush_pmksa
  93. brcmf_configure_opensecurity
  94. brcmf_valid_wpa_oui
  95. brcmf_configure_wpaie
  96. brcmf_parse_vndr_ies
  97. brcmf_vndr_ie
  98. brcmf_vif_set_mgmt_ie
  99. brcmf_vif_clear_mgmt_ies
  100. brcmf_config_ap_mgmt_ie
  101. brcmf_cfg80211_start_ap
  102. brcmf_cfg80211_stop_ap
  103. brcmf_cfg80211_change_beacon
  104. brcmf_cfg80211_del_station
  105. brcmf_cfg80211_change_station
  106. brcmf_cfg80211_mgmt_frame_register
  107. brcmf_cfg80211_mgmt_tx
  108. brcmf_cfg80211_cancel_remain_on_channel
  109. brcmf_cfg80211_get_channel
  110. brcmf_cfg80211_crit_proto_start
  111. brcmf_cfg80211_crit_proto_stop
  112. brcmf_notify_tdls_peer_event
  113. brcmf_convert_nl80211_tdls_oper
  114. brcmf_cfg80211_tdls_oper
  115. brcmf_cfg80211_update_conn_params
  116. brcmf_cfg80211_set_rekey_data
  117. brcmf_cfg80211_set_pmk
  118. brcmf_cfg80211_del_pmk
  119. brcmf_cfg80211_get_ops
  120. brcmf_alloc_vif
  121. brcmf_free_vif
  122. brcmf_cfg80211_free_netdev
  123. brcmf_is_linkup
  124. brcmf_is_linkdown
  125. brcmf_is_nonetwork
  126. brcmf_clear_assoc_ies
  127. brcmf_get_assoc_ies
  128. brcmf_bss_roaming_done
  129. brcmf_bss_connect_done
  130. brcmf_notify_connect_status_ap
  131. brcmf_notify_connect_status
  132. brcmf_notify_roaming_status
  133. brcmf_notify_mic_status
  134. brcmf_notify_vif_event
  135. brcmf_init_conf
  136. brcmf_register_event_handlers
  137. brcmf_deinit_priv_mem
  138. brcmf_init_priv_mem
  139. wl_init_priv
  140. wl_deinit_priv
  141. init_vif_event
  142. brcmf_dongle_roam
  143. brcmf_dongle_scantime
  144. brcmf_update_bw40_channel_flag
  145. brcmf_construct_chaninfo
  146. brcmf_enable_bw40_2g
  147. brcmf_get_bwcap
  148. brcmf_update_ht_cap
  149. brcmf_get_mcs_map
  150. brcmf_update_vht_cap
  151. brcmf_setup_wiphybands
  152. brcmf_setup_ifmodes
  153. brcmf_wiphy_wowl_params
  154. brcmf_setup_wiphy
  155. brcmf_config_dongle
  156. __brcmf_cfg80211_up
  157. __brcmf_cfg80211_down
  158. brcmf_cfg80211_up
  159. brcmf_cfg80211_down
  160. brcmf_cfg80211_get_iftype
  161. brcmf_get_vif_state_any
  162. vif_event_equals
  163. brcmf_cfg80211_arm_vif_event
  164. brcmf_cfg80211_vif_event_armed
  165. brcmf_cfg80211_wait_vif_event
  166. brcmf_translate_country_code
  167. brcmf_cfg80211_reg_notifier
  168. brcmf_free_wiphy
  169. brcmf_cfg80211_attach
  170. brcmf_cfg80211_detach

   1 // SPDX-License-Identifier: ISC
   2 /*
   3  * Copyright (c) 2010 Broadcom Corporation
   4  */
   5 
   6 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/etherdevice.h>
  10 #include <linux/module.h>
  11 #include <linux/vmalloc.h>
  12 #include <net/cfg80211.h>
  13 #include <net/netlink.h>
  14 
  15 #include <brcmu_utils.h>
  16 #include <defs.h>
  17 #include <brcmu_wifi.h>
  18 #include "core.h"
  19 #include "debug.h"
  20 #include "tracepoint.h"
  21 #include "fwil_types.h"
  22 #include "p2p.h"
  23 #include "btcoex.h"
  24 #include "pno.h"
  25 #include "cfg80211.h"
  26 #include "feature.h"
  27 #include "fwil.h"
  28 #include "proto.h"
  29 #include "vendor.h"
  30 #include "bus.h"
  31 #include "common.h"
  32 
  33 #define BRCMF_SCAN_IE_LEN_MAX           2048
  34 
  35 #define WPA_OUI                         "\x00\x50\xF2"  /* WPA OUI */
  36 #define WPA_OUI_TYPE                    1
  37 #define RSN_OUI                         "\x00\x0F\xAC"  /* RSN OUI */
  38 #define WME_OUI_TYPE                    2
  39 #define WPS_OUI_TYPE                    4
  40 
  41 #define VS_IE_FIXED_HDR_LEN             6
  42 #define WPA_IE_VERSION_LEN              2
  43 #define WPA_IE_MIN_OUI_LEN              4
  44 #define WPA_IE_SUITE_COUNT_LEN          2
  45 
  46 #define WPA_CIPHER_NONE                 0       /* None */
  47 #define WPA_CIPHER_WEP_40               1       /* WEP (40-bit) */
  48 #define WPA_CIPHER_TKIP                 2       /* TKIP: default for WPA */
  49 #define WPA_CIPHER_AES_CCM              4       /* AES (CCM) */
  50 #define WPA_CIPHER_WEP_104              5       /* WEP (104-bit) */
  51 
  52 #define RSN_AKM_NONE                    0       /* None (IBSS) */
  53 #define RSN_AKM_UNSPECIFIED             1       /* Over 802.1x */
  54 #define RSN_AKM_PSK                     2       /* Pre-shared Key */
  55 #define RSN_AKM_SHA256_1X               5       /* SHA256, 802.1X */
  56 #define RSN_AKM_SHA256_PSK              6       /* SHA256, Pre-shared Key */
  57 #define RSN_CAP_LEN                     2       /* Length of RSN capabilities */
  58 #define RSN_CAP_PTK_REPLAY_CNTR_MASK    (BIT(2) | BIT(3))
  59 #define RSN_CAP_MFPR_MASK               BIT(6)
  60 #define RSN_CAP_MFPC_MASK               BIT(7)
  61 #define RSN_PMKID_COUNT_LEN             2
  62 
  63 #define VNDR_IE_CMD_LEN                 4       /* length of the set command
  64                                                  * string :"add", "del" (+ NUL)
  65                                                  */
  66 #define VNDR_IE_COUNT_OFFSET            4
  67 #define VNDR_IE_PKTFLAG_OFFSET          8
  68 #define VNDR_IE_VSIE_OFFSET             12
  69 #define VNDR_IE_HDR_SIZE                12
  70 #define VNDR_IE_PARSE_LIMIT             5
  71 
  72 #define DOT11_MGMT_HDR_LEN              24      /* d11 management header len */
  73 #define DOT11_BCN_PRB_FIXED_LEN         12      /* beacon/probe fixed length */
  74 
  75 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS    320
  76 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS   400
  77 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS       20
  78 
  79 #define BRCMF_SCAN_CHANNEL_TIME         40
  80 #define BRCMF_SCAN_UNASSOC_TIME         40
  81 #define BRCMF_SCAN_PASSIVE_TIME         120
  82 
  83 #define BRCMF_ND_INFO_TIMEOUT           msecs_to_jiffies(2000)
  84 
  85 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
  86         (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
  87 
  88 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
  89 {
  90         if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
  91                 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
  92                           vif->sme_state);
  93                 return false;
  94         }
  95         return true;
  96 }
  97 
  98 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
  99 #define RATETAB_ENT(_rateid, _flags) \
 100         {                                                               \
 101                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
 102                 .hw_value       = (_rateid),                            \
 103                 .flags          = (_flags),                             \
 104         }
 105 
 106 static struct ieee80211_rate __wl_rates[] = {
 107         RATETAB_ENT(BRCM_RATE_1M, 0),
 108         RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
 109         RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
 110         RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
 111         RATETAB_ENT(BRCM_RATE_6M, 0),
 112         RATETAB_ENT(BRCM_RATE_9M, 0),
 113         RATETAB_ENT(BRCM_RATE_12M, 0),
 114         RATETAB_ENT(BRCM_RATE_18M, 0),
 115         RATETAB_ENT(BRCM_RATE_24M, 0),
 116         RATETAB_ENT(BRCM_RATE_36M, 0),
 117         RATETAB_ENT(BRCM_RATE_48M, 0),
 118         RATETAB_ENT(BRCM_RATE_54M, 0),
 119 };
 120 
 121 #define wl_g_rates              (__wl_rates + 0)
 122 #define wl_g_rates_size         ARRAY_SIZE(__wl_rates)
 123 #define wl_a_rates              (__wl_rates + 4)
 124 #define wl_a_rates_size         (wl_g_rates_size - 4)
 125 
 126 #define CHAN2G(_channel, _freq) {                               \
 127         .band                   = NL80211_BAND_2GHZ,            \
 128         .center_freq            = (_freq),                      \
 129         .hw_value               = (_channel),                   \
 130         .max_antenna_gain       = 0,                            \
 131         .max_power              = 30,                           \
 132 }
 133 
 134 #define CHAN5G(_channel) {                                      \
 135         .band                   = NL80211_BAND_5GHZ,            \
 136         .center_freq            = 5000 + (5 * (_channel)),      \
 137         .hw_value               = (_channel),                   \
 138         .max_antenna_gain       = 0,                            \
 139         .max_power              = 30,                           \
 140 }
 141 
 142 static struct ieee80211_channel __wl_2ghz_channels[] = {
 143         CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
 144         CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
 145         CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
 146         CHAN2G(13, 2472), CHAN2G(14, 2484)
 147 };
 148 
 149 static struct ieee80211_channel __wl_5ghz_channels[] = {
 150         CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
 151         CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
 152         CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
 153         CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
 154         CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
 155         CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
 156 };
 157 
 158 /* Band templates duplicated per wiphy. The channel info
 159  * above is added to the band during setup.
 160  */
 161 static const struct ieee80211_supported_band __wl_band_2ghz = {
 162         .band = NL80211_BAND_2GHZ,
 163         .bitrates = wl_g_rates,
 164         .n_bitrates = wl_g_rates_size,
 165 };
 166 
 167 static const struct ieee80211_supported_band __wl_band_5ghz = {
 168         .band = NL80211_BAND_5GHZ,
 169         .bitrates = wl_a_rates,
 170         .n_bitrates = wl_a_rates_size,
 171 };
 172 
 173 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
 174  * By default world regulatory domain defined in reg.c puts the flags
 175  * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
 176  * With respect to these flags, wpa_supplicant doesn't * start p2p
 177  * operations on 5GHz channels. All the changes in world regulatory
 178  * domain are to be done here.
 179  */
 180 static const struct ieee80211_regdomain brcmf_regdom = {
 181         .n_reg_rules = 4,
 182         .alpha2 =  "99",
 183         .reg_rules = {
 184                 /* IEEE 802.11b/g, channels 1..11 */
 185                 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
 186                 /* If any */
 187                 /* IEEE 802.11 channel 14 - Only JP enables
 188                  * this and for 802.11b only
 189                  */
 190                 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
 191                 /* IEEE 802.11a, channel 36..64 */
 192                 REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
 193                 /* IEEE 802.11a, channel 100..165 */
 194                 REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
 195 };
 196 
 197 /* Note: brcmf_cipher_suites is an array of int defining which cipher suites
 198  * are supported. A pointer to this array and the number of entries is passed
 199  * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
 200  * So the cipher suite AES_CMAC has to be the last one in the array, and when
 201  * device does not support MFP then the number of suites will be decreased by 1
 202  */
 203 static const u32 brcmf_cipher_suites[] = {
 204         WLAN_CIPHER_SUITE_WEP40,
 205         WLAN_CIPHER_SUITE_WEP104,
 206         WLAN_CIPHER_SUITE_TKIP,
 207         WLAN_CIPHER_SUITE_CCMP,
 208         /* Keep as last entry: */
 209         WLAN_CIPHER_SUITE_AES_CMAC
 210 };
 211 
 212 /* Vendor specific ie. id = 221, oui and type defines exact ie */
 213 struct brcmf_vs_tlv {
 214         u8 id;
 215         u8 len;
 216         u8 oui[3];
 217         u8 oui_type;
 218 };
 219 
 220 struct parsed_vndr_ie_info {
 221         u8 *ie_ptr;
 222         u32 ie_len;     /* total length including id & length field */
 223         struct brcmf_vs_tlv vndrie;
 224 };
 225 
 226 struct parsed_vndr_ies {
 227         u32 count;
 228         struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
 229 };
 230 
 231 static u8 nl80211_band_to_fwil(enum nl80211_band band)
 232 {
 233         switch (band) {
 234         case NL80211_BAND_2GHZ:
 235                 return WLC_BAND_2G;
 236         case NL80211_BAND_5GHZ:
 237                 return WLC_BAND_5G;
 238         default:
 239                 WARN_ON(1);
 240                 break;
 241         }
 242         return 0;
 243 }
 244 
 245 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
 246                                struct cfg80211_chan_def *ch)
 247 {
 248         struct brcmu_chan ch_inf;
 249         s32 primary_offset;
 250 
 251         brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
 252                   ch->chan->center_freq, ch->center_freq1, ch->width);
 253         ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
 254         primary_offset = ch->chan->center_freq - ch->center_freq1;
 255         switch (ch->width) {
 256         case NL80211_CHAN_WIDTH_20:
 257         case NL80211_CHAN_WIDTH_20_NOHT:
 258                 ch_inf.bw = BRCMU_CHAN_BW_20;
 259                 WARN_ON(primary_offset != 0);
 260                 break;
 261         case NL80211_CHAN_WIDTH_40:
 262                 ch_inf.bw = BRCMU_CHAN_BW_40;
 263                 if (primary_offset > 0)
 264                         ch_inf.sb = BRCMU_CHAN_SB_U;
 265                 else
 266                         ch_inf.sb = BRCMU_CHAN_SB_L;
 267                 break;
 268         case NL80211_CHAN_WIDTH_80:
 269                 ch_inf.bw = BRCMU_CHAN_BW_80;
 270                 if (primary_offset == -30)
 271                         ch_inf.sb = BRCMU_CHAN_SB_LL;
 272                 else if (primary_offset == -10)
 273                         ch_inf.sb = BRCMU_CHAN_SB_LU;
 274                 else if (primary_offset == 10)
 275                         ch_inf.sb = BRCMU_CHAN_SB_UL;
 276                 else
 277                         ch_inf.sb = BRCMU_CHAN_SB_UU;
 278                 break;
 279         case NL80211_CHAN_WIDTH_160:
 280                 ch_inf.bw = BRCMU_CHAN_BW_160;
 281                 if (primary_offset == -70)
 282                         ch_inf.sb = BRCMU_CHAN_SB_LLL;
 283                 else if (primary_offset == -50)
 284                         ch_inf.sb = BRCMU_CHAN_SB_LLU;
 285                 else if (primary_offset == -30)
 286                         ch_inf.sb = BRCMU_CHAN_SB_LUL;
 287                 else if (primary_offset == -10)
 288                         ch_inf.sb = BRCMU_CHAN_SB_LUU;
 289                 else if (primary_offset == 10)
 290                         ch_inf.sb = BRCMU_CHAN_SB_ULL;
 291                 else if (primary_offset == 30)
 292                         ch_inf.sb = BRCMU_CHAN_SB_ULU;
 293                 else if (primary_offset == 50)
 294                         ch_inf.sb = BRCMU_CHAN_SB_UUL;
 295                 else
 296                         ch_inf.sb = BRCMU_CHAN_SB_UUU;
 297                 break;
 298         case NL80211_CHAN_WIDTH_80P80:
 299         case NL80211_CHAN_WIDTH_5:
 300         case NL80211_CHAN_WIDTH_10:
 301         default:
 302                 WARN_ON_ONCE(1);
 303         }
 304         switch (ch->chan->band) {
 305         case NL80211_BAND_2GHZ:
 306                 ch_inf.band = BRCMU_CHAN_BAND_2G;
 307                 break;
 308         case NL80211_BAND_5GHZ:
 309                 ch_inf.band = BRCMU_CHAN_BAND_5G;
 310                 break;
 311         case NL80211_BAND_60GHZ:
 312         default:
 313                 WARN_ON_ONCE(1);
 314         }
 315         d11inf->encchspec(&ch_inf);
 316 
 317         brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
 318         return ch_inf.chspec;
 319 }
 320 
 321 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
 322                         struct ieee80211_channel *ch)
 323 {
 324         struct brcmu_chan ch_inf;
 325 
 326         ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
 327         ch_inf.bw = BRCMU_CHAN_BW_20;
 328         d11inf->encchspec(&ch_inf);
 329 
 330         return ch_inf.chspec;
 331 }
 332 
 333 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
 334  * triples, returning a pointer to the substring whose first element
 335  * matches tag
 336  */
 337 static const struct brcmf_tlv *
 338 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
 339 {
 340         const struct brcmf_tlv *elt = buf;
 341         int totlen = buflen;
 342 
 343         /* find tagged parameter */
 344         while (totlen >= TLV_HDR_LEN) {
 345                 int len = elt->len;
 346 
 347                 /* validate remaining totlen */
 348                 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
 349                         return elt;
 350 
 351                 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
 352                 totlen -= (len + TLV_HDR_LEN);
 353         }
 354 
 355         return NULL;
 356 }
 357 
 358 /* Is any of the tlvs the expected entry? If
 359  * not update the tlvs buffer pointer/length.
 360  */
 361 static bool
 362 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
 363                  const u8 *oui, u32 oui_len, u8 type)
 364 {
 365         /* If the contents match the OUI and the type */
 366         if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
 367             !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
 368             type == ie[TLV_BODY_OFF + oui_len]) {
 369                 return true;
 370         }
 371 
 372         if (tlvs == NULL)
 373                 return false;
 374         /* point to the next ie */
 375         ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
 376         /* calculate the length of the rest of the buffer */
 377         *tlvs_len -= (int)(ie - *tlvs);
 378         /* update the pointer to the start of the buffer */
 379         *tlvs = ie;
 380 
 381         return false;
 382 }
 383 
 384 static struct brcmf_vs_tlv *
 385 brcmf_find_wpaie(const u8 *parse, u32 len)
 386 {
 387         const struct brcmf_tlv *ie;
 388 
 389         while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
 390                 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
 391                                      WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
 392                         return (struct brcmf_vs_tlv *)ie;
 393         }
 394         return NULL;
 395 }
 396 
 397 static struct brcmf_vs_tlv *
 398 brcmf_find_wpsie(const u8 *parse, u32 len)
 399 {
 400         const struct brcmf_tlv *ie;
 401 
 402         while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
 403                 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
 404                                      WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
 405                         return (struct brcmf_vs_tlv *)ie;
 406         }
 407         return NULL;
 408 }
 409 
 410 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
 411                                      struct brcmf_cfg80211_vif *vif,
 412                                      enum nl80211_iftype new_type)
 413 {
 414         struct brcmf_cfg80211_vif *pos;
 415         bool check_combos = false;
 416         int ret = 0;
 417         struct iface_combination_params params = {
 418                 .num_different_channels = 1,
 419         };
 420 
 421         list_for_each_entry(pos, &cfg->vif_list, list)
 422                 if (pos == vif) {
 423                         params.iftype_num[new_type]++;
 424                 } else {
 425                         /* concurrent interfaces so need check combinations */
 426                         check_combos = true;
 427                         params.iftype_num[pos->wdev.iftype]++;
 428                 }
 429 
 430         if (check_combos)
 431                 ret = cfg80211_check_combinations(cfg->wiphy, &params);
 432 
 433         return ret;
 434 }
 435 
 436 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
 437                                   enum nl80211_iftype new_type)
 438 {
 439         struct brcmf_cfg80211_vif *pos;
 440         struct iface_combination_params params = {
 441                 .num_different_channels = 1,
 442         };
 443 
 444         list_for_each_entry(pos, &cfg->vif_list, list)
 445                 params.iftype_num[pos->wdev.iftype]++;
 446 
 447         params.iftype_num[new_type]++;
 448         return cfg80211_check_combinations(cfg->wiphy, &params);
 449 }
 450 
 451 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
 452                                  struct brcmf_wsec_key_le *key_le)
 453 {
 454         key_le->index = cpu_to_le32(key->index);
 455         key_le->len = cpu_to_le32(key->len);
 456         key_le->algo = cpu_to_le32(key->algo);
 457         key_le->flags = cpu_to_le32(key->flags);
 458         key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
 459         key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
 460         key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
 461         memcpy(key_le->data, key->data, sizeof(key->data));
 462         memcpy(key_le->ea, key->ea, sizeof(key->ea));
 463 }
 464 
 465 static int
 466 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
 467 {
 468         struct brcmf_pub *drvr = ifp->drvr;
 469         int err;
 470         struct brcmf_wsec_key_le key_le;
 471 
 472         convert_key_from_CPU(key, &key_le);
 473 
 474         brcmf_netdev_wait_pend8021x(ifp);
 475 
 476         err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
 477                                         sizeof(key_le));
 478 
 479         if (err)
 480                 bphy_err(drvr, "wsec_key error (%d)\n", err);
 481         return err;
 482 }
 483 
 484 static void
 485 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
 486 {
 487         struct brcmf_cfg80211_vif *vif;
 488         struct brcmf_if *ifp;
 489 
 490         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
 491         ifp = vif->ifp;
 492 
 493         if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
 494             (wdev->iftype == NL80211_IFTYPE_AP) ||
 495             (wdev->iftype == NL80211_IFTYPE_P2P_GO))
 496                 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
 497                                                 ADDR_DIRECT);
 498         else
 499                 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
 500                                                 ADDR_INDIRECT);
 501 }
 502 
 503 static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
 504 {
 505         int bsscfgidx;
 506 
 507         for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
 508                 /* bsscfgidx 1 is reserved for legacy P2P */
 509                 if (bsscfgidx == 1)
 510                         continue;
 511                 if (!drvr->iflist[bsscfgidx])
 512                         return bsscfgidx;
 513         }
 514 
 515         return -ENOMEM;
 516 }
 517 
 518 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
 519 {
 520         struct brcmf_pub *drvr = ifp->drvr;
 521         struct brcmf_mbss_ssid_le mbss_ssid_le;
 522         int bsscfgidx;
 523         int err;
 524 
 525         memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
 526         bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
 527         if (bsscfgidx < 0)
 528                 return bsscfgidx;
 529 
 530         mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
 531         mbss_ssid_le.SSID_len = cpu_to_le32(5);
 532         sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
 533 
 534         err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
 535                                         sizeof(mbss_ssid_le));
 536         if (err < 0)
 537                 bphy_err(drvr, "setting ssid failed %d\n", err);
 538 
 539         return err;
 540 }
 541 
 542 /**
 543  * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
 544  *
 545  * @wiphy: wiphy device of new interface.
 546  * @name: name of the new interface.
 547  * @params: contains mac address for AP device.
 548  */
 549 static
 550 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
 551                                       struct vif_params *params)
 552 {
 553         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 554         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
 555         struct brcmf_pub *drvr = cfg->pub;
 556         struct brcmf_cfg80211_vif *vif;
 557         int err;
 558 
 559         if (brcmf_cfg80211_vif_event_armed(cfg))
 560                 return ERR_PTR(-EBUSY);
 561 
 562         brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
 563 
 564         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
 565         if (IS_ERR(vif))
 566                 return (struct wireless_dev *)vif;
 567 
 568         brcmf_cfg80211_arm_vif_event(cfg, vif);
 569 
 570         err = brcmf_cfg80211_request_ap_if(ifp);
 571         if (err) {
 572                 brcmf_cfg80211_arm_vif_event(cfg, NULL);
 573                 goto fail;
 574         }
 575 
 576         /* wait for firmware event */
 577         err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
 578                                             BRCMF_VIF_EVENT_TIMEOUT);
 579         brcmf_cfg80211_arm_vif_event(cfg, NULL);
 580         if (!err) {
 581                 bphy_err(drvr, "timeout occurred\n");
 582                 err = -EIO;
 583                 goto fail;
 584         }
 585 
 586         /* interface created in firmware */
 587         ifp = vif->ifp;
 588         if (!ifp) {
 589                 bphy_err(drvr, "no if pointer provided\n");
 590                 err = -ENOENT;
 591                 goto fail;
 592         }
 593 
 594         strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
 595         err = brcmf_net_attach(ifp, true);
 596         if (err) {
 597                 bphy_err(drvr, "Registering netdevice failed\n");
 598                 free_netdev(ifp->ndev);
 599                 goto fail;
 600         }
 601 
 602         return &ifp->vif->wdev;
 603 
 604 fail:
 605         brcmf_free_vif(vif);
 606         return ERR_PTR(err);
 607 }
 608 
 609 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
 610 {
 611         enum nl80211_iftype iftype;
 612 
 613         iftype = vif->wdev.iftype;
 614         return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
 615 }
 616 
 617 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
 618 {
 619         return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
 620 }
 621 
 622 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
 623                                                      const char *name,
 624                                                      unsigned char name_assign_type,
 625                                                      enum nl80211_iftype type,
 626                                                      struct vif_params *params)
 627 {
 628         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 629         struct brcmf_pub *drvr = cfg->pub;
 630         struct wireless_dev *wdev;
 631         int err;
 632 
 633         brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
 634         err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
 635         if (err) {
 636                 bphy_err(drvr, "iface validation failed: err=%d\n", err);
 637                 return ERR_PTR(err);
 638         }
 639         switch (type) {
 640         case NL80211_IFTYPE_ADHOC:
 641         case NL80211_IFTYPE_STATION:
 642         case NL80211_IFTYPE_AP_VLAN:
 643         case NL80211_IFTYPE_WDS:
 644         case NL80211_IFTYPE_MONITOR:
 645         case NL80211_IFTYPE_MESH_POINT:
 646                 return ERR_PTR(-EOPNOTSUPP);
 647         case NL80211_IFTYPE_AP:
 648                 wdev = brcmf_ap_add_vif(wiphy, name, params);
 649                 break;
 650         case NL80211_IFTYPE_P2P_CLIENT:
 651         case NL80211_IFTYPE_P2P_GO:
 652         case NL80211_IFTYPE_P2P_DEVICE:
 653                 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
 654                 break;
 655         case NL80211_IFTYPE_UNSPECIFIED:
 656         default:
 657                 return ERR_PTR(-EINVAL);
 658         }
 659 
 660         if (IS_ERR(wdev))
 661                 bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
 662                          type, (int)PTR_ERR(wdev));
 663         else
 664                 brcmf_cfg80211_update_proto_addr_mode(wdev);
 665 
 666         return wdev;
 667 }
 668 
 669 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
 670 {
 671         if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
 672                 brcmf_set_mpc(ifp, mpc);
 673 }
 674 
 675 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
 676 {
 677         struct brcmf_pub *drvr = ifp->drvr;
 678         s32 err = 0;
 679 
 680         if (check_vif_up(ifp->vif)) {
 681                 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
 682                 if (err) {
 683                         bphy_err(drvr, "fail to set mpc\n");
 684                         return;
 685                 }
 686                 brcmf_dbg(INFO, "MPC : %d\n", mpc);
 687         }
 688 }
 689 
 690 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
 691                                 struct brcmf_if *ifp, bool aborted,
 692                                 bool fw_abort)
 693 {
 694         struct brcmf_pub *drvr = cfg->pub;
 695         struct brcmf_scan_params_le params_le;
 696         struct cfg80211_scan_request *scan_request;
 697         u64 reqid;
 698         u32 bucket;
 699         s32 err = 0;
 700 
 701         brcmf_dbg(SCAN, "Enter\n");
 702 
 703         /* clear scan request, because the FW abort can cause a second call */
 704         /* to this functon and might cause a double cfg80211_scan_done      */
 705         scan_request = cfg->scan_request;
 706         cfg->scan_request = NULL;
 707 
 708         if (timer_pending(&cfg->escan_timeout))
 709                 del_timer_sync(&cfg->escan_timeout);
 710 
 711         if (fw_abort) {
 712                 /* Do a scan abort to stop the driver's scan engine */
 713                 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
 714                 memset(&params_le, 0, sizeof(params_le));
 715                 eth_broadcast_addr(params_le.bssid);
 716                 params_le.bss_type = DOT11_BSSTYPE_ANY;
 717                 params_le.scan_type = 0;
 718                 params_le.channel_num = cpu_to_le32(1);
 719                 params_le.nprobes = cpu_to_le32(1);
 720                 params_le.active_time = cpu_to_le32(-1);
 721                 params_le.passive_time = cpu_to_le32(-1);
 722                 params_le.home_time = cpu_to_le32(-1);
 723                 /* Scan is aborted by setting channel_list[0] to -1 */
 724                 params_le.channel_list[0] = cpu_to_le16(-1);
 725                 /* E-Scan (or anyother type) can be aborted by SCAN */
 726                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
 727                                              &params_le, sizeof(params_le));
 728                 if (err)
 729                         bphy_err(drvr, "Scan abort failed\n");
 730         }
 731 
 732         brcmf_scan_config_mpc(ifp, 1);
 733 
 734         /*
 735          * e-scan can be initiated internally
 736          * which takes precedence.
 737          */
 738         if (cfg->int_escan_map) {
 739                 brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
 740                           cfg->int_escan_map);
 741                 while (cfg->int_escan_map) {
 742                         bucket = __ffs(cfg->int_escan_map);
 743                         cfg->int_escan_map &= ~BIT(bucket);
 744                         reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
 745                                                                bucket);
 746                         if (!aborted) {
 747                                 brcmf_dbg(SCAN, "report results: reqid=%llu\n",
 748                                           reqid);
 749                                 cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
 750                                                             reqid);
 751                         }
 752                 }
 753         } else if (scan_request) {
 754                 struct cfg80211_scan_info info = {
 755                         .aborted = aborted,
 756                 };
 757 
 758                 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
 759                           aborted ? "Aborted" : "Done");
 760                 cfg80211_scan_done(scan_request, &info);
 761         }
 762         if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
 763                 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
 764 
 765         return err;
 766 }
 767 
 768 static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
 769                                        struct wireless_dev *wdev)
 770 {
 771         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 772         struct net_device *ndev = wdev->netdev;
 773         struct brcmf_if *ifp = netdev_priv(ndev);
 774         struct brcmf_pub *drvr = cfg->pub;
 775         int ret;
 776         int err;
 777 
 778         brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
 779 
 780         err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
 781         if (err) {
 782                 bphy_err(drvr, "interface_remove failed %d\n", err);
 783                 goto err_unarm;
 784         }
 785 
 786         /* wait for firmware event */
 787         ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
 788                                             BRCMF_VIF_EVENT_TIMEOUT);
 789         if (!ret) {
 790                 bphy_err(drvr, "timeout occurred\n");
 791                 err = -EIO;
 792                 goto err_unarm;
 793         }
 794 
 795         brcmf_remove_interface(ifp, true);
 796 
 797 err_unarm:
 798         brcmf_cfg80211_arm_vif_event(cfg, NULL);
 799         return err;
 800 }
 801 
 802 static
 803 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
 804 {
 805         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 806         struct net_device *ndev = wdev->netdev;
 807 
 808         if (ndev && ndev == cfg_to_ndev(cfg))
 809                 return -ENOTSUPP;
 810 
 811         /* vif event pending in firmware */
 812         if (brcmf_cfg80211_vif_event_armed(cfg))
 813                 return -EBUSY;
 814 
 815         if (ndev) {
 816                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
 817                     cfg->escan_info.ifp == netdev_priv(ndev))
 818                         brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
 819                                                     true, true);
 820 
 821                 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
 822         }
 823 
 824         switch (wdev->iftype) {
 825         case NL80211_IFTYPE_ADHOC:
 826         case NL80211_IFTYPE_STATION:
 827         case NL80211_IFTYPE_AP_VLAN:
 828         case NL80211_IFTYPE_WDS:
 829         case NL80211_IFTYPE_MONITOR:
 830         case NL80211_IFTYPE_MESH_POINT:
 831                 return -EOPNOTSUPP;
 832         case NL80211_IFTYPE_AP:
 833                 return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
 834         case NL80211_IFTYPE_P2P_CLIENT:
 835         case NL80211_IFTYPE_P2P_GO:
 836         case NL80211_IFTYPE_P2P_DEVICE:
 837                 return brcmf_p2p_del_vif(wiphy, wdev);
 838         case NL80211_IFTYPE_UNSPECIFIED:
 839         default:
 840                 return -EINVAL;
 841         }
 842         return -EOPNOTSUPP;
 843 }
 844 
 845 static s32
 846 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
 847                          enum nl80211_iftype type,
 848                          struct vif_params *params)
 849 {
 850         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 851         struct brcmf_if *ifp = netdev_priv(ndev);
 852         struct brcmf_cfg80211_vif *vif = ifp->vif;
 853         struct brcmf_pub *drvr = cfg->pub;
 854         s32 infra = 0;
 855         s32 ap = 0;
 856         s32 err = 0;
 857 
 858         brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
 859                   type);
 860 
 861         /* WAR: There are a number of p2p interface related problems which
 862          * need to be handled initially (before doing the validate).
 863          * wpa_supplicant tends to do iface changes on p2p device/client/go
 864          * which are not always possible/allowed. However we need to return
 865          * OK otherwise the wpa_supplicant wont start. The situation differs
 866          * on configuration and setup (p2pon=1 module param). The first check
 867          * is to see if the request is a change to station for p2p iface.
 868          */
 869         if ((type == NL80211_IFTYPE_STATION) &&
 870             ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
 871              (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
 872              (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
 873                 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
 874                 /* Now depending on whether module param p2pon=1 was used the
 875                  * response needs to be either 0 or EOPNOTSUPP. The reason is
 876                  * that if p2pon=1 is used, but a newer supplicant is used then
 877                  * we should return an error, as this combination wont work.
 878                  * In other situations 0 is returned and supplicant will start
 879                  * normally. It will give a trace in cfg80211, but it is the
 880                  * only way to get it working. Unfortunately this will result
 881                  * in situation where we wont support new supplicant in
 882                  * combination with module param p2pon=1, but that is the way
 883                  * it is. If the user tries this then unloading of driver might
 884                  * fail/lock.
 885                  */
 886                 if (cfg->p2p.p2pdev_dynamically)
 887                         return -EOPNOTSUPP;
 888                 else
 889                         return 0;
 890         }
 891         err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
 892         if (err) {
 893                 bphy_err(drvr, "iface validation failed: err=%d\n", err);
 894                 return err;
 895         }
 896         switch (type) {
 897         case NL80211_IFTYPE_MONITOR:
 898         case NL80211_IFTYPE_WDS:
 899                 bphy_err(drvr, "type (%d) : currently we do not support this type\n",
 900                          type);
 901                 return -EOPNOTSUPP;
 902         case NL80211_IFTYPE_ADHOC:
 903                 infra = 0;
 904                 break;
 905         case NL80211_IFTYPE_STATION:
 906                 infra = 1;
 907                 break;
 908         case NL80211_IFTYPE_AP:
 909         case NL80211_IFTYPE_P2P_GO:
 910                 ap = 1;
 911                 break;
 912         default:
 913                 err = -EINVAL;
 914                 goto done;
 915         }
 916 
 917         if (ap) {
 918                 if (type == NL80211_IFTYPE_P2P_GO) {
 919                         brcmf_dbg(INFO, "IF Type = P2P GO\n");
 920                         err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
 921                 }
 922                 if (!err) {
 923                         brcmf_dbg(INFO, "IF Type = AP\n");
 924                 }
 925         } else {
 926                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
 927                 if (err) {
 928                         bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
 929                         err = -EAGAIN;
 930                         goto done;
 931                 }
 932                 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
 933                           "Adhoc" : "Infra");
 934         }
 935         ndev->ieee80211_ptr->iftype = type;
 936 
 937         brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
 938 
 939 done:
 940         brcmf_dbg(TRACE, "Exit\n");
 941 
 942         return err;
 943 }
 944 
 945 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
 946                              struct brcmf_scan_params_le *params_le,
 947                              struct cfg80211_scan_request *request)
 948 {
 949         u32 n_ssids;
 950         u32 n_channels;
 951         s32 i;
 952         s32 offset;
 953         u16 chanspec;
 954         char *ptr;
 955         struct brcmf_ssid_le ssid_le;
 956 
 957         eth_broadcast_addr(params_le->bssid);
 958         params_le->bss_type = DOT11_BSSTYPE_ANY;
 959         params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
 960         params_le->channel_num = 0;
 961         params_le->nprobes = cpu_to_le32(-1);
 962         params_le->active_time = cpu_to_le32(-1);
 963         params_le->passive_time = cpu_to_le32(-1);
 964         params_le->home_time = cpu_to_le32(-1);
 965         memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
 966 
 967         n_ssids = request->n_ssids;
 968         n_channels = request->n_channels;
 969 
 970         /* Copy channel array if applicable */
 971         brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
 972                   n_channels);
 973         if (n_channels > 0) {
 974                 for (i = 0; i < n_channels; i++) {
 975                         chanspec = channel_to_chanspec(&cfg->d11inf,
 976                                                        request->channels[i]);
 977                         brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
 978                                   request->channels[i]->hw_value, chanspec);
 979                         params_le->channel_list[i] = cpu_to_le16(chanspec);
 980                 }
 981         } else {
 982                 brcmf_dbg(SCAN, "Scanning all channels\n");
 983         }
 984         /* Copy ssid array if applicable */
 985         brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
 986         if (n_ssids > 0) {
 987                 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
 988                                 n_channels * sizeof(u16);
 989                 offset = roundup(offset, sizeof(u32));
 990                 ptr = (char *)params_le + offset;
 991                 for (i = 0; i < n_ssids; i++) {
 992                         memset(&ssid_le, 0, sizeof(ssid_le));
 993                         ssid_le.SSID_len =
 994                                         cpu_to_le32(request->ssids[i].ssid_len);
 995                         memcpy(ssid_le.SSID, request->ssids[i].ssid,
 996                                request->ssids[i].ssid_len);
 997                         if (!ssid_le.SSID_len)
 998                                 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
 999                         else
1000                                 brcmf_dbg(SCAN, "%d: scan for  %.32s size=%d\n",
1001                                           i, ssid_le.SSID, ssid_le.SSID_len);
1002                         memcpy(ptr, &ssid_le, sizeof(ssid_le));
1003                         ptr += sizeof(ssid_le);
1004                 }
1005         } else {
1006                 brcmf_dbg(SCAN, "Performing passive scan\n");
1007                 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
1008         }
1009         /* Adding mask to channel numbers */
1010         params_le->channel_num =
1011                 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1012                         (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1013 }
1014 
1015 static s32
1016 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1017                 struct cfg80211_scan_request *request)
1018 {
1019         struct brcmf_pub *drvr = cfg->pub;
1020         s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1021                           offsetof(struct brcmf_escan_params_le, params_le);
1022         struct brcmf_escan_params_le *params;
1023         s32 err = 0;
1024 
1025         brcmf_dbg(SCAN, "E-SCAN START\n");
1026 
1027         if (request != NULL) {
1028                 /* Allocate space for populating ssids in struct */
1029                 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1030 
1031                 /* Allocate space for populating ssids in struct */
1032                 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1033         }
1034 
1035         params = kzalloc(params_size, GFP_KERNEL);
1036         if (!params) {
1037                 err = -ENOMEM;
1038                 goto exit;
1039         }
1040         BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1041         brcmf_escan_prep(cfg, &params->params_le, request);
1042         params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1043         params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1044         params->sync_id = cpu_to_le16(0x1234);
1045 
1046         err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1047         if (err) {
1048                 if (err == -EBUSY)
1049                         brcmf_dbg(INFO, "system busy : escan canceled\n");
1050                 else
1051                         bphy_err(drvr, "error (%d)\n", err);
1052         }
1053 
1054         kfree(params);
1055 exit:
1056         return err;
1057 }
1058 
1059 static s32
1060 brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1061 {
1062         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1063         s32 err;
1064         struct brcmf_scan_results *results;
1065         struct escan_info *escan = &cfg->escan_info;
1066 
1067         brcmf_dbg(SCAN, "Enter\n");
1068         escan->ifp = ifp;
1069         escan->wiphy = cfg->wiphy;
1070         escan->escan_state = WL_ESCAN_STATE_SCANNING;
1071 
1072         brcmf_scan_config_mpc(ifp, 0);
1073         results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1074         results->version = 0;
1075         results->count = 0;
1076         results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1077 
1078         err = escan->run(cfg, ifp, request);
1079         if (err)
1080                 brcmf_scan_config_mpc(ifp, 1);
1081         return err;
1082 }
1083 
1084 static s32
1085 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1086 {
1087         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1088         struct brcmf_pub *drvr = cfg->pub;
1089         struct brcmf_cfg80211_vif *vif;
1090         s32 err = 0;
1091 
1092         brcmf_dbg(TRACE, "Enter\n");
1093         vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1094         if (!check_vif_up(vif))
1095                 return -EIO;
1096 
1097         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1098                 bphy_err(drvr, "Scanning already: status (%lu)\n",
1099                          cfg->scan_status);
1100                 return -EAGAIN;
1101         }
1102         if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1103                 bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
1104                          cfg->scan_status);
1105                 return -EAGAIN;
1106         }
1107         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1108                 bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
1109                          cfg->scan_status);
1110                 return -EAGAIN;
1111         }
1112         if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1113                 bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
1114                 return -EAGAIN;
1115         }
1116 
1117         /* If scan req comes for p2p0, send it over primary I/F */
1118         if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1119                 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1120 
1121         brcmf_dbg(SCAN, "START ESCAN\n");
1122 
1123         cfg->scan_request = request;
1124         set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1125 
1126         cfg->escan_info.run = brcmf_run_escan;
1127         err = brcmf_p2p_scan_prep(wiphy, request, vif);
1128         if (err)
1129                 goto scan_out;
1130 
1131         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1132                                     request->ie, request->ie_len);
1133         if (err)
1134                 goto scan_out;
1135 
1136         err = brcmf_do_escan(vif->ifp, request);
1137         if (err)
1138                 goto scan_out;
1139 
1140         /* Arm scan timeout timer */
1141         mod_timer(&cfg->escan_timeout,
1142                   jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1143 
1144         return 0;
1145 
1146 scan_out:
1147         bphy_err(drvr, "scan error (%d)\n", err);
1148         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1149         cfg->scan_request = NULL;
1150         return err;
1151 }
1152 
1153 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1154 {
1155         struct brcmf_if *ifp = netdev_priv(ndev);
1156         struct brcmf_pub *drvr = ifp->drvr;
1157         s32 err = 0;
1158 
1159         err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
1160         if (err)
1161                 bphy_err(drvr, "Error (%d)\n", err);
1162 
1163         return err;
1164 }
1165 
1166 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1167 {
1168         struct brcmf_if *ifp = netdev_priv(ndev);
1169         struct brcmf_pub *drvr = ifp->drvr;
1170         s32 err = 0;
1171 
1172         err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
1173                                       frag_threshold);
1174         if (err)
1175                 bphy_err(drvr, "Error (%d)\n", err);
1176 
1177         return err;
1178 }
1179 
1180 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1181 {
1182         struct brcmf_if *ifp = netdev_priv(ndev);
1183         struct brcmf_pub *drvr = ifp->drvr;
1184         s32 err = 0;
1185         u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1186 
1187         err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
1188         if (err) {
1189                 bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
1190                 return err;
1191         }
1192         return err;
1193 }
1194 
1195 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1196 {
1197         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1198         struct net_device *ndev = cfg_to_ndev(cfg);
1199         struct brcmf_if *ifp = netdev_priv(ndev);
1200         s32 err = 0;
1201 
1202         brcmf_dbg(TRACE, "Enter\n");
1203         if (!check_vif_up(ifp->vif))
1204                 return -EIO;
1205 
1206         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1207             (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1208                 cfg->conf->rts_threshold = wiphy->rts_threshold;
1209                 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1210                 if (!err)
1211                         goto done;
1212         }
1213         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1214             (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1215                 cfg->conf->frag_threshold = wiphy->frag_threshold;
1216                 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1217                 if (!err)
1218                         goto done;
1219         }
1220         if (changed & WIPHY_PARAM_RETRY_LONG
1221             && (cfg->conf->retry_long != wiphy->retry_long)) {
1222                 cfg->conf->retry_long = wiphy->retry_long;
1223                 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1224                 if (!err)
1225                         goto done;
1226         }
1227         if (changed & WIPHY_PARAM_RETRY_SHORT
1228             && (cfg->conf->retry_short != wiphy->retry_short)) {
1229                 cfg->conf->retry_short = wiphy->retry_short;
1230                 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1231                 if (!err)
1232                         goto done;
1233         }
1234 
1235 done:
1236         brcmf_dbg(TRACE, "Exit\n");
1237         return err;
1238 }
1239 
1240 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1241 {
1242         memset(prof, 0, sizeof(*prof));
1243 }
1244 
1245 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1246 {
1247         u16 reason;
1248 
1249         switch (e->event_code) {
1250         case BRCMF_E_DEAUTH:
1251         case BRCMF_E_DEAUTH_IND:
1252         case BRCMF_E_DISASSOC_IND:
1253                 reason = e->reason;
1254                 break;
1255         case BRCMF_E_LINK:
1256         default:
1257                 reason = 0;
1258                 break;
1259         }
1260         return reason;
1261 }
1262 
1263 static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1264 {
1265         struct brcmf_pub *drvr = ifp->drvr;
1266         struct brcmf_wsec_pmk_le pmk;
1267         int i, err;
1268 
1269         /* convert to firmware key format */
1270         pmk.key_len = cpu_to_le16(pmk_len << 1);
1271         pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
1272         for (i = 0; i < pmk_len; i++)
1273                 snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
1274 
1275         /* store psk in firmware */
1276         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1277                                      &pmk, sizeof(pmk));
1278         if (err < 0)
1279                 bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
1280                          pmk_len);
1281 
1282         return err;
1283 }
1284 
1285 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1286 {
1287         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1288         struct brcmf_pub *drvr = cfg->pub;
1289         bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP;
1290         s32 err = 0;
1291 
1292         brcmf_dbg(TRACE, "Enter\n");
1293 
1294         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1295                 if (bus_up) {
1296                         brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n");
1297                         err = brcmf_fil_cmd_data_set(vif->ifp,
1298                                                      BRCMF_C_DISASSOC, NULL, 0);
1299                         if (err)
1300                                 bphy_err(drvr, "WLC_DISASSOC failed (%d)\n",
1301                                          err);
1302                 }
1303 
1304                 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1305                     (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1306                         cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1307                                               true, GFP_KERNEL);
1308         }
1309         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1310         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1311         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1312         if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1313                 if (bus_up)
1314                         brcmf_set_pmk(vif->ifp, NULL, 0);
1315                 vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1316         }
1317         brcmf_dbg(TRACE, "Exit\n");
1318 }
1319 
1320 static s32
1321 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1322                       struct cfg80211_ibss_params *params)
1323 {
1324         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1325         struct brcmf_if *ifp = netdev_priv(ndev);
1326         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1327         struct brcmf_pub *drvr = cfg->pub;
1328         struct brcmf_join_params join_params;
1329         size_t join_params_size = 0;
1330         s32 err = 0;
1331         s32 wsec = 0;
1332         s32 bcnprd;
1333         u16 chanspec;
1334         u32 ssid_len;
1335 
1336         brcmf_dbg(TRACE, "Enter\n");
1337         if (!check_vif_up(ifp->vif))
1338                 return -EIO;
1339 
1340         if (params->ssid)
1341                 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1342         else {
1343                 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1344                 return -EOPNOTSUPP;
1345         }
1346 
1347         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1348 
1349         if (params->bssid)
1350                 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1351         else
1352                 brcmf_dbg(CONN, "No BSSID specified\n");
1353 
1354         if (params->chandef.chan)
1355                 brcmf_dbg(CONN, "channel: %d\n",
1356                           params->chandef.chan->center_freq);
1357         else
1358                 brcmf_dbg(CONN, "no channel specified\n");
1359 
1360         if (params->channel_fixed)
1361                 brcmf_dbg(CONN, "fixed channel required\n");
1362         else
1363                 brcmf_dbg(CONN, "no fixed channel required\n");
1364 
1365         if (params->ie && params->ie_len)
1366                 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1367         else
1368                 brcmf_dbg(CONN, "no ie specified\n");
1369 
1370         if (params->beacon_interval)
1371                 brcmf_dbg(CONN, "beacon interval: %d\n",
1372                           params->beacon_interval);
1373         else
1374                 brcmf_dbg(CONN, "no beacon interval specified\n");
1375 
1376         if (params->basic_rates)
1377                 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1378         else
1379                 brcmf_dbg(CONN, "no basic rates specified\n");
1380 
1381         if (params->privacy)
1382                 brcmf_dbg(CONN, "privacy required\n");
1383         else
1384                 brcmf_dbg(CONN, "no privacy required\n");
1385 
1386         /* Configure Privacy for starter */
1387         if (params->privacy)
1388                 wsec |= WEP_ENABLED;
1389 
1390         err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1391         if (err) {
1392                 bphy_err(drvr, "wsec failed (%d)\n", err);
1393                 goto done;
1394         }
1395 
1396         /* Configure Beacon Interval for starter */
1397         if (params->beacon_interval)
1398                 bcnprd = params->beacon_interval;
1399         else
1400                 bcnprd = 100;
1401 
1402         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1403         if (err) {
1404                 bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
1405                 goto done;
1406         }
1407 
1408         /* Configure required join parameter */
1409         memset(&join_params, 0, sizeof(struct brcmf_join_params));
1410 
1411         /* SSID */
1412         ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1413         memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1414         join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1415         join_params_size = sizeof(join_params.ssid_le);
1416 
1417         /* BSSID */
1418         if (params->bssid) {
1419                 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1420                 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1421                 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1422         } else {
1423                 eth_broadcast_addr(join_params.params_le.bssid);
1424                 eth_zero_addr(profile->bssid);
1425         }
1426 
1427         /* Channel */
1428         if (params->chandef.chan) {
1429                 u32 target_channel;
1430 
1431                 cfg->channel =
1432                         ieee80211_frequency_to_channel(
1433                                 params->chandef.chan->center_freq);
1434                 if (params->channel_fixed) {
1435                         /* adding chanspec */
1436                         chanspec = chandef_to_chanspec(&cfg->d11inf,
1437                                                        &params->chandef);
1438                         join_params.params_le.chanspec_list[0] =
1439                                 cpu_to_le16(chanspec);
1440                         join_params.params_le.chanspec_num = cpu_to_le32(1);
1441                         join_params_size += sizeof(join_params.params_le);
1442                 }
1443 
1444                 /* set channel for starter */
1445                 target_channel = cfg->channel;
1446                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1447                                             target_channel);
1448                 if (err) {
1449                         bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
1450                         goto done;
1451                 }
1452         } else
1453                 cfg->channel = 0;
1454 
1455         cfg->ibss_starter = false;
1456 
1457 
1458         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1459                                      &join_params, join_params_size);
1460         if (err) {
1461                 bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
1462                 goto done;
1463         }
1464 
1465 done:
1466         if (err)
1467                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1468         brcmf_dbg(TRACE, "Exit\n");
1469         return err;
1470 }
1471 
1472 static s32
1473 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1474 {
1475         struct brcmf_if *ifp = netdev_priv(ndev);
1476 
1477         brcmf_dbg(TRACE, "Enter\n");
1478         if (!check_vif_up(ifp->vif)) {
1479                 /* When driver is being unloaded, it can end up here. If an
1480                  * error is returned then later on a debug trace in the wireless
1481                  * core module will be printed. To avoid this 0 is returned.
1482                  */
1483                 return 0;
1484         }
1485 
1486         brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1487         brcmf_net_setcarrier(ifp, false);
1488 
1489         brcmf_dbg(TRACE, "Exit\n");
1490 
1491         return 0;
1492 }
1493 
1494 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1495                                  struct cfg80211_connect_params *sme)
1496 {
1497         struct brcmf_if *ifp = netdev_priv(ndev);
1498         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1499         struct brcmf_pub *drvr = ifp->drvr;
1500         struct brcmf_cfg80211_security *sec;
1501         s32 val = 0;
1502         s32 err = 0;
1503 
1504         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1505                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1506         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1507                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1508         else
1509                 val = WPA_AUTH_DISABLED;
1510         brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1511         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
1512         if (err) {
1513                 bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
1514                 return err;
1515         }
1516         sec = &profile->sec;
1517         sec->wpa_versions = sme->crypto.wpa_versions;
1518         return err;
1519 }
1520 
1521 static s32 brcmf_set_auth_type(struct net_device *ndev,
1522                                struct cfg80211_connect_params *sme)
1523 {
1524         struct brcmf_if *ifp = netdev_priv(ndev);
1525         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1526         struct brcmf_pub *drvr = ifp->drvr;
1527         struct brcmf_cfg80211_security *sec;
1528         s32 val = 0;
1529         s32 err = 0;
1530 
1531         switch (sme->auth_type) {
1532         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1533                 val = 0;
1534                 brcmf_dbg(CONN, "open system\n");
1535                 break;
1536         case NL80211_AUTHTYPE_SHARED_KEY:
1537                 val = 1;
1538                 brcmf_dbg(CONN, "shared key\n");
1539                 break;
1540         default:
1541                 val = 2;
1542                 brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
1543                 break;
1544         }
1545 
1546         err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1547         if (err) {
1548                 bphy_err(drvr, "set auth failed (%d)\n", err);
1549                 return err;
1550         }
1551         sec = &profile->sec;
1552         sec->auth_type = sme->auth_type;
1553         return err;
1554 }
1555 
1556 static s32
1557 brcmf_set_wsec_mode(struct net_device *ndev,
1558                     struct cfg80211_connect_params *sme)
1559 {
1560         struct brcmf_if *ifp = netdev_priv(ndev);
1561         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1562         struct brcmf_pub *drvr = ifp->drvr;
1563         struct brcmf_cfg80211_security *sec;
1564         s32 pval = 0;
1565         s32 gval = 0;
1566         s32 wsec;
1567         s32 err = 0;
1568 
1569         if (sme->crypto.n_ciphers_pairwise) {
1570                 switch (sme->crypto.ciphers_pairwise[0]) {
1571                 case WLAN_CIPHER_SUITE_WEP40:
1572                 case WLAN_CIPHER_SUITE_WEP104:
1573                         pval = WEP_ENABLED;
1574                         break;
1575                 case WLAN_CIPHER_SUITE_TKIP:
1576                         pval = TKIP_ENABLED;
1577                         break;
1578                 case WLAN_CIPHER_SUITE_CCMP:
1579                         pval = AES_ENABLED;
1580                         break;
1581                 case WLAN_CIPHER_SUITE_AES_CMAC:
1582                         pval = AES_ENABLED;
1583                         break;
1584                 default:
1585                         bphy_err(drvr, "invalid cipher pairwise (%d)\n",
1586                                  sme->crypto.ciphers_pairwise[0]);
1587                         return -EINVAL;
1588                 }
1589         }
1590         if (sme->crypto.cipher_group) {
1591                 switch (sme->crypto.cipher_group) {
1592                 case WLAN_CIPHER_SUITE_WEP40:
1593                 case WLAN_CIPHER_SUITE_WEP104:
1594                         gval = WEP_ENABLED;
1595                         break;
1596                 case WLAN_CIPHER_SUITE_TKIP:
1597                         gval = TKIP_ENABLED;
1598                         break;
1599                 case WLAN_CIPHER_SUITE_CCMP:
1600                         gval = AES_ENABLED;
1601                         break;
1602                 case WLAN_CIPHER_SUITE_AES_CMAC:
1603                         gval = AES_ENABLED;
1604                         break;
1605                 default:
1606                         bphy_err(drvr, "invalid cipher group (%d)\n",
1607                                  sme->crypto.cipher_group);
1608                         return -EINVAL;
1609                 }
1610         }
1611 
1612         brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1613         /* In case of privacy, but no security and WPS then simulate */
1614         /* setting AES. WPS-2.0 allows no security                   */
1615         if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1616             sme->privacy)
1617                 pval = AES_ENABLED;
1618 
1619         wsec = pval | gval;
1620         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1621         if (err) {
1622                 bphy_err(drvr, "error (%d)\n", err);
1623                 return err;
1624         }
1625 
1626         sec = &profile->sec;
1627         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1628         sec->cipher_group = sme->crypto.cipher_group;
1629 
1630         return err;
1631 }
1632 
1633 static s32
1634 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1635 {
1636         struct brcmf_if *ifp = netdev_priv(ndev);
1637         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1638         struct brcmf_pub *drvr = ifp->drvr;
1639         s32 val;
1640         s32 err;
1641         const struct brcmf_tlv *rsn_ie;
1642         const u8 *ie;
1643         u32 ie_len;
1644         u32 offset;
1645         u16 rsn_cap;
1646         u32 mfp;
1647         u16 count;
1648 
1649         profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1650 
1651         if (!sme->crypto.n_akm_suites)
1652                 return 0;
1653 
1654         err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1655         if (err) {
1656                 bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
1657                 return err;
1658         }
1659         if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1660                 switch (sme->crypto.akm_suites[0]) {
1661                 case WLAN_AKM_SUITE_8021X:
1662                         val = WPA_AUTH_UNSPECIFIED;
1663                         if (sme->want_1x)
1664                                 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1665                         break;
1666                 case WLAN_AKM_SUITE_PSK:
1667                         val = WPA_AUTH_PSK;
1668                         break;
1669                 default:
1670                         bphy_err(drvr, "invalid cipher group (%d)\n",
1671                                  sme->crypto.cipher_group);
1672                         return -EINVAL;
1673                 }
1674         } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1675                 switch (sme->crypto.akm_suites[0]) {
1676                 case WLAN_AKM_SUITE_8021X:
1677                         val = WPA2_AUTH_UNSPECIFIED;
1678                         if (sme->want_1x)
1679                                 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1680                         break;
1681                 case WLAN_AKM_SUITE_8021X_SHA256:
1682                         val = WPA2_AUTH_1X_SHA256;
1683                         if (sme->want_1x)
1684                                 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1685                         break;
1686                 case WLAN_AKM_SUITE_PSK_SHA256:
1687                         val = WPA2_AUTH_PSK_SHA256;
1688                         break;
1689                 case WLAN_AKM_SUITE_PSK:
1690                         val = WPA2_AUTH_PSK;
1691                         break;
1692                 case WLAN_AKM_SUITE_FT_8021X:
1693                         val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
1694                         if (sme->want_1x)
1695                                 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1696                         break;
1697                 case WLAN_AKM_SUITE_FT_PSK:
1698                         val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
1699                         break;
1700                 default:
1701                         bphy_err(drvr, "invalid cipher group (%d)\n",
1702                                  sme->crypto.cipher_group);
1703                         return -EINVAL;
1704                 }
1705         }
1706 
1707         if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
1708                 brcmf_dbg(INFO, "using 1X offload\n");
1709 
1710         if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1711                 goto skip_mfp_config;
1712         /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
1713          * IE will not be verified, just a quick search for MFP config
1714          */
1715         rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1716                                   WLAN_EID_RSN);
1717         if (!rsn_ie)
1718                 goto skip_mfp_config;
1719         ie = (const u8 *)rsn_ie;
1720         ie_len = rsn_ie->len + TLV_HDR_LEN;
1721         /* Skip unicast suite */
1722         offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1723         if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1724                 goto skip_mfp_config;
1725         /* Skip multicast suite */
1726         count = ie[offset] + (ie[offset + 1] << 8);
1727         offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1728         if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1729                 goto skip_mfp_config;
1730         /* Skip auth key management suite(s) */
1731         count = ie[offset] + (ie[offset + 1] << 8);
1732         offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1733         if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1734                 goto skip_mfp_config;
1735         /* Ready to read capabilities */
1736         mfp = BRCMF_MFP_NONE;
1737         rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1738         if (rsn_cap & RSN_CAP_MFPR_MASK)
1739                 mfp = BRCMF_MFP_REQUIRED;
1740         else if (rsn_cap & RSN_CAP_MFPC_MASK)
1741                 mfp = BRCMF_MFP_CAPABLE;
1742         brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1743 
1744 skip_mfp_config:
1745         brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1746         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1747         if (err) {
1748                 bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
1749                 return err;
1750         }
1751 
1752         return err;
1753 }
1754 
1755 static s32
1756 brcmf_set_sharedkey(struct net_device *ndev,
1757                     struct cfg80211_connect_params *sme)
1758 {
1759         struct brcmf_if *ifp = netdev_priv(ndev);
1760         struct brcmf_pub *drvr = ifp->drvr;
1761         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1762         struct brcmf_cfg80211_security *sec;
1763         struct brcmf_wsec_key key;
1764         s32 val;
1765         s32 err = 0;
1766 
1767         brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1768 
1769         if (sme->key_len == 0)
1770                 return 0;
1771 
1772         sec = &profile->sec;
1773         brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1774                   sec->wpa_versions, sec->cipher_pairwise);
1775 
1776         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1777                 return 0;
1778 
1779         if (!(sec->cipher_pairwise &
1780             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1781                 return 0;
1782 
1783         memset(&key, 0, sizeof(key));
1784         key.len = (u32) sme->key_len;
1785         key.index = (u32) sme->key_idx;
1786         if (key.len > sizeof(key.data)) {
1787                 bphy_err(drvr, "Too long key length (%u)\n", key.len);
1788                 return -EINVAL;
1789         }
1790         memcpy(key.data, sme->key, key.len);
1791         key.flags = BRCMF_PRIMARY_KEY;
1792         switch (sec->cipher_pairwise) {
1793         case WLAN_CIPHER_SUITE_WEP40:
1794                 key.algo = CRYPTO_ALGO_WEP1;
1795                 break;
1796         case WLAN_CIPHER_SUITE_WEP104:
1797                 key.algo = CRYPTO_ALGO_WEP128;
1798                 break;
1799         default:
1800                 bphy_err(drvr, "Invalid algorithm (%d)\n",
1801                          sme->crypto.ciphers_pairwise[0]);
1802                 return -EINVAL;
1803         }
1804         /* Set the new key/index */
1805         brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1806                   key.len, key.index, key.algo);
1807         brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1808         err = send_key_to_dongle(ifp, &key);
1809         if (err)
1810                 return err;
1811 
1812         if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1813                 brcmf_dbg(CONN, "set auth_type to shared key\n");
1814                 val = WL_AUTH_SHARED_KEY;       /* shared key */
1815                 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1816                 if (err)
1817                         bphy_err(drvr, "set auth failed (%d)\n", err);
1818         }
1819         return err;
1820 }
1821 
1822 static
1823 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1824                                            enum nl80211_auth_type type)
1825 {
1826         if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1827             brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1828                 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1829                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1830         }
1831         return type;
1832 }
1833 
1834 static void brcmf_set_join_pref(struct brcmf_if *ifp,
1835                                 struct cfg80211_bss_selection *bss_select)
1836 {
1837         struct brcmf_pub *drvr = ifp->drvr;
1838         struct brcmf_join_pref_params join_pref_params[2];
1839         enum nl80211_band band;
1840         int err, i = 0;
1841 
1842         join_pref_params[i].len = 2;
1843         join_pref_params[i].rssi_gain = 0;
1844 
1845         if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
1846                 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
1847 
1848         switch (bss_select->behaviour) {
1849         case __NL80211_BSS_SELECT_ATTR_INVALID:
1850                 brcmf_c_set_joinpref_default(ifp);
1851                 return;
1852         case NL80211_BSS_SELECT_ATTR_BAND_PREF:
1853                 join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
1854                 band = bss_select->param.band_pref;
1855                 join_pref_params[i].band = nl80211_band_to_fwil(band);
1856                 i++;
1857                 break;
1858         case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
1859                 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
1860                 band = bss_select->param.adjust.band;
1861                 join_pref_params[i].band = nl80211_band_to_fwil(band);
1862                 join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
1863                 i++;
1864                 break;
1865         case NL80211_BSS_SELECT_ATTR_RSSI:
1866         default:
1867                 break;
1868         }
1869         join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
1870         join_pref_params[i].len = 2;
1871         join_pref_params[i].rssi_gain = 0;
1872         join_pref_params[i].band = 0;
1873         err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
1874                                        sizeof(join_pref_params));
1875         if (err)
1876                 bphy_err(drvr, "Set join_pref error (%d)\n", err);
1877 }
1878 
1879 static s32
1880 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1881                        struct cfg80211_connect_params *sme)
1882 {
1883         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1884         struct brcmf_if *ifp = netdev_priv(ndev);
1885         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1886         struct ieee80211_channel *chan = sme->channel;
1887         struct brcmf_pub *drvr = ifp->drvr;
1888         struct brcmf_join_params join_params;
1889         size_t join_params_size;
1890         const struct brcmf_tlv *rsn_ie;
1891         const struct brcmf_vs_tlv *wpa_ie;
1892         const void *ie;
1893         u32 ie_len;
1894         struct brcmf_ext_join_params_le *ext_join_params;
1895         u16 chanspec;
1896         s32 err = 0;
1897         u32 ssid_len;
1898 
1899         brcmf_dbg(TRACE, "Enter\n");
1900         if (!check_vif_up(ifp->vif))
1901                 return -EIO;
1902 
1903         if (!sme->ssid) {
1904                 bphy_err(drvr, "Invalid ssid\n");
1905                 return -EOPNOTSUPP;
1906         }
1907 
1908         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1909                 /* A normal (non P2P) connection request setup. */
1910                 ie = NULL;
1911                 ie_len = 0;
1912                 /* find the WPA_IE */
1913                 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1914                 if (wpa_ie) {
1915                         ie = wpa_ie;
1916                         ie_len = wpa_ie->len + TLV_HDR_LEN;
1917                 } else {
1918                         /* find the RSN_IE */
1919                         rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1920                                                   sme->ie_len,
1921                                                   WLAN_EID_RSN);
1922                         if (rsn_ie) {
1923                                 ie = rsn_ie;
1924                                 ie_len = rsn_ie->len + TLV_HDR_LEN;
1925                         }
1926                 }
1927                 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1928         }
1929 
1930         err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1931                                     sme->ie, sme->ie_len);
1932         if (err)
1933                 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
1934         else
1935                 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1936 
1937         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1938 
1939         if (chan) {
1940                 cfg->channel =
1941                         ieee80211_frequency_to_channel(chan->center_freq);
1942                 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1943                 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1944                           cfg->channel, chan->center_freq, chanspec);
1945         } else {
1946                 cfg->channel = 0;
1947                 chanspec = 0;
1948         }
1949 
1950         brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1951 
1952         err = brcmf_set_wpa_version(ndev, sme);
1953         if (err) {
1954                 bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
1955                 goto done;
1956         }
1957 
1958         sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1959         err = brcmf_set_auth_type(ndev, sme);
1960         if (err) {
1961                 bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
1962                 goto done;
1963         }
1964 
1965         err = brcmf_set_wsec_mode(ndev, sme);
1966         if (err) {
1967                 bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
1968                 goto done;
1969         }
1970 
1971         err = brcmf_set_key_mgmt(ndev, sme);
1972         if (err) {
1973                 bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
1974                 goto done;
1975         }
1976 
1977         err = brcmf_set_sharedkey(ndev, sme);
1978         if (err) {
1979                 bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
1980                 goto done;
1981         }
1982 
1983         if (sme->crypto.psk) {
1984                 if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
1985                         err = -EINVAL;
1986                         goto done;
1987                 }
1988                 brcmf_dbg(INFO, "using PSK offload\n");
1989                 profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
1990         }
1991 
1992         if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1993                 /* enable firmware supplicant for this interface */
1994                 err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
1995                 if (err < 0) {
1996                         bphy_err(drvr, "failed to enable fw supplicant\n");
1997                         goto done;
1998                 }
1999         }
2000 
2001         if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) {
2002                 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2003                                     BRCMF_WSEC_MAX_PSK_LEN);
2004                 if (err)
2005                         goto done;
2006         }
2007 
2008         /* Join with specific BSSID and cached SSID
2009          * If SSID is zero join based on BSSID only
2010          */
2011         join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2012                 offsetof(struct brcmf_assoc_params_le, chanspec_list);
2013         if (cfg->channel)
2014                 join_params_size += sizeof(u16);
2015         ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
2016         if (ext_join_params == NULL) {
2017                 err = -ENOMEM;
2018                 goto done;
2019         }
2020         ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2021         ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2022         memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2023         if (ssid_len < IEEE80211_MAX_SSID_LEN)
2024                 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2025                           ext_join_params->ssid_le.SSID, ssid_len);
2026 
2027         /* Set up join scan parameters */
2028         ext_join_params->scan_le.scan_type = -1;
2029         ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2030 
2031         if (sme->bssid)
2032                 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2033         else
2034                 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2035 
2036         if (cfg->channel) {
2037                 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2038 
2039                 ext_join_params->assoc_le.chanspec_list[0] =
2040                         cpu_to_le16(chanspec);
2041                 /* Increase dwell time to receive probe response or detect
2042                  * beacon from target AP at a noisy air only during connect
2043                  * command.
2044                  */
2045                 ext_join_params->scan_le.active_time =
2046                         cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2047                 ext_join_params->scan_le.passive_time =
2048                         cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2049                 /* To sync with presence period of VSDB GO send probe request
2050                  * more frequently. Probe request will be stopped when it gets
2051                  * probe response from target AP/GO.
2052                  */
2053                 ext_join_params->scan_le.nprobes =
2054                         cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2055                                     BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2056         } else {
2057                 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2058                 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2059                 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2060         }
2061 
2062         brcmf_set_join_pref(ifp, &sme->bss_select);
2063 
2064         err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2065                                          join_params_size);
2066         kfree(ext_join_params);
2067         if (!err)
2068                 /* This is it. join command worked, we are done */
2069                 goto done;
2070 
2071         /* join command failed, fallback to set ssid */
2072         memset(&join_params, 0, sizeof(join_params));
2073         join_params_size = sizeof(join_params.ssid_le);
2074 
2075         memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2076         join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2077 
2078         if (sme->bssid)
2079                 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2080         else
2081                 eth_broadcast_addr(join_params.params_le.bssid);
2082 
2083         if (cfg->channel) {
2084                 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2085                 join_params.params_le.chanspec_num = cpu_to_le32(1);
2086                 join_params_size += sizeof(join_params.params_le);
2087         }
2088         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2089                                      &join_params, join_params_size);
2090         if (err)
2091                 bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
2092 
2093 done:
2094         if (err)
2095                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2096         brcmf_dbg(TRACE, "Exit\n");
2097         return err;
2098 }
2099 
2100 static s32
2101 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2102                        u16 reason_code)
2103 {
2104         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2105         struct brcmf_if *ifp = netdev_priv(ndev);
2106         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2107         struct brcmf_pub *drvr = cfg->pub;
2108         struct brcmf_scb_val_le scbval;
2109         s32 err = 0;
2110 
2111         brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2112         if (!check_vif_up(ifp->vif))
2113                 return -EIO;
2114 
2115         clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2116         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2117         cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2118 
2119         memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2120         scbval.val = cpu_to_le32(reason_code);
2121         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2122                                      &scbval, sizeof(scbval));
2123         if (err)
2124                 bphy_err(drvr, "error (%d)\n", err);
2125 
2126         brcmf_dbg(TRACE, "Exit\n");
2127         return err;
2128 }
2129 
2130 static s32
2131 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2132                             enum nl80211_tx_power_setting type, s32 mbm)
2133 {
2134         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2135         struct net_device *ndev = cfg_to_ndev(cfg);
2136         struct brcmf_if *ifp = netdev_priv(ndev);
2137         struct brcmf_pub *drvr = cfg->pub;
2138         s32 err;
2139         s32 disable;
2140         u32 qdbm = 127;
2141 
2142         brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2143         if (!check_vif_up(ifp->vif))
2144                 return -EIO;
2145 
2146         switch (type) {
2147         case NL80211_TX_POWER_AUTOMATIC:
2148                 break;
2149         case NL80211_TX_POWER_LIMITED:
2150         case NL80211_TX_POWER_FIXED:
2151                 if (mbm < 0) {
2152                         bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
2153                         err = -EINVAL;
2154                         goto done;
2155                 }
2156                 qdbm =  MBM_TO_DBM(4 * mbm);
2157                 if (qdbm > 127)
2158                         qdbm = 127;
2159                 qdbm |= WL_TXPWR_OVERRIDE;
2160                 break;
2161         default:
2162                 bphy_err(drvr, "Unsupported type %d\n", type);
2163                 err = -EINVAL;
2164                 goto done;
2165         }
2166         /* Make sure radio is off or on as far as software is concerned */
2167         disable = WL_RADIO_SW_DISABLE << 16;
2168         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2169         if (err)
2170                 bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
2171 
2172         err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2173         if (err)
2174                 bphy_err(drvr, "qtxpower error (%d)\n", err);
2175 
2176 done:
2177         brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2178         return err;
2179 }
2180 
2181 static s32
2182 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2183                             s32 *dbm)
2184 {
2185         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2186         struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2187         struct brcmf_pub *drvr = cfg->pub;
2188         s32 qdbm = 0;
2189         s32 err;
2190 
2191         brcmf_dbg(TRACE, "Enter\n");
2192         if (!check_vif_up(vif))
2193                 return -EIO;
2194 
2195         err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2196         if (err) {
2197                 bphy_err(drvr, "error (%d)\n", err);
2198                 goto done;
2199         }
2200         *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2201 
2202 done:
2203         brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2204         return err;
2205 }
2206 
2207 static s32
2208 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2209                                   u8 key_idx, bool unicast, bool multicast)
2210 {
2211         struct brcmf_if *ifp = netdev_priv(ndev);
2212         struct brcmf_pub *drvr = ifp->drvr;
2213         u32 index;
2214         u32 wsec;
2215         s32 err = 0;
2216 
2217         brcmf_dbg(TRACE, "Enter\n");
2218         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2219         if (!check_vif_up(ifp->vif))
2220                 return -EIO;
2221 
2222         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2223         if (err) {
2224                 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2225                 goto done;
2226         }
2227 
2228         if (wsec & WEP_ENABLED) {
2229                 /* Just select a new current key */
2230                 index = key_idx;
2231                 err = brcmf_fil_cmd_int_set(ifp,
2232                                             BRCMF_C_SET_KEY_PRIMARY, index);
2233                 if (err)
2234                         bphy_err(drvr, "error (%d)\n", err);
2235         }
2236 done:
2237         brcmf_dbg(TRACE, "Exit\n");
2238         return err;
2239 }
2240 
2241 static s32
2242 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2243                        u8 key_idx, bool pairwise, const u8 *mac_addr)
2244 {
2245         struct brcmf_if *ifp = netdev_priv(ndev);
2246         struct brcmf_wsec_key *key;
2247         s32 err;
2248 
2249         brcmf_dbg(TRACE, "Enter\n");
2250         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2251 
2252         if (!check_vif_up(ifp->vif))
2253                 return -EIO;
2254 
2255         if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2256                 /* we ignore this key index in this case */
2257                 return -EINVAL;
2258         }
2259 
2260         key = &ifp->vif->profile.key[key_idx];
2261 
2262         if (key->algo == CRYPTO_ALGO_OFF) {
2263                 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2264                 return -EINVAL;
2265         }
2266 
2267         memset(key, 0, sizeof(*key));
2268         key->index = (u32)key_idx;
2269         key->flags = BRCMF_PRIMARY_KEY;
2270 
2271         /* Clear the key/index */
2272         err = send_key_to_dongle(ifp, key);
2273 
2274         brcmf_dbg(TRACE, "Exit\n");
2275         return err;
2276 }
2277 
2278 static s32
2279 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2280                        u8 key_idx, bool pairwise, const u8 *mac_addr,
2281                        struct key_params *params)
2282 {
2283         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2284         struct brcmf_if *ifp = netdev_priv(ndev);
2285         struct brcmf_pub *drvr = cfg->pub;
2286         struct brcmf_wsec_key *key;
2287         s32 val;
2288         s32 wsec;
2289         s32 err;
2290         u8 keybuf[8];
2291         bool ext_key;
2292 
2293         brcmf_dbg(TRACE, "Enter\n");
2294         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2295         if (!check_vif_up(ifp->vif))
2296                 return -EIO;
2297 
2298         if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2299                 /* we ignore this key index in this case */
2300                 bphy_err(drvr, "invalid key index (%d)\n", key_idx);
2301                 return -EINVAL;
2302         }
2303 
2304         if (params->key_len == 0)
2305                 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2306                                               mac_addr);
2307 
2308         if (params->key_len > sizeof(key->data)) {
2309                 bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
2310                 return -EINVAL;
2311         }
2312 
2313         ext_key = false;
2314         if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2315             (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2316                 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2317                 ext_key = true;
2318         }
2319 
2320         key = &ifp->vif->profile.key[key_idx];
2321         memset(key, 0, sizeof(*key));
2322         if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2323                 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2324         key->len = params->key_len;
2325         key->index = key_idx;
2326         memcpy(key->data, params->key, key->len);
2327         if (!ext_key)
2328                 key->flags = BRCMF_PRIMARY_KEY;
2329 
2330         switch (params->cipher) {
2331         case WLAN_CIPHER_SUITE_WEP40:
2332                 key->algo = CRYPTO_ALGO_WEP1;
2333                 val = WEP_ENABLED;
2334                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2335                 break;
2336         case WLAN_CIPHER_SUITE_WEP104:
2337                 key->algo = CRYPTO_ALGO_WEP128;
2338                 val = WEP_ENABLED;
2339                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2340                 break;
2341         case WLAN_CIPHER_SUITE_TKIP:
2342                 if (!brcmf_is_apmode(ifp->vif)) {
2343                         brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2344                         memcpy(keybuf, &key->data[24], sizeof(keybuf));
2345                         memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2346                         memcpy(&key->data[16], keybuf, sizeof(keybuf));
2347                 }
2348                 key->algo = CRYPTO_ALGO_TKIP;
2349                 val = TKIP_ENABLED;
2350                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2351                 break;
2352         case WLAN_CIPHER_SUITE_AES_CMAC:
2353                 key->algo = CRYPTO_ALGO_AES_CCM;
2354                 val = AES_ENABLED;
2355                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2356                 break;
2357         case WLAN_CIPHER_SUITE_CCMP:
2358                 key->algo = CRYPTO_ALGO_AES_CCM;
2359                 val = AES_ENABLED;
2360                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2361                 break;
2362         default:
2363                 bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
2364                 err = -EINVAL;
2365                 goto done;
2366         }
2367 
2368         err = send_key_to_dongle(ifp, key);
2369         if (ext_key || err)
2370                 goto done;
2371 
2372         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2373         if (err) {
2374                 bphy_err(drvr, "get wsec error (%d)\n", err);
2375                 goto done;
2376         }
2377         wsec |= val;
2378         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2379         if (err) {
2380                 bphy_err(drvr, "set wsec error (%d)\n", err);
2381                 goto done;
2382         }
2383 
2384 done:
2385         brcmf_dbg(TRACE, "Exit\n");
2386         return err;
2387 }
2388 
2389 static s32
2390 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2391                        bool pairwise, const u8 *mac_addr, void *cookie,
2392                        void (*callback)(void *cookie,
2393                                         struct key_params *params))
2394 {
2395         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2396         struct key_params params;
2397         struct brcmf_if *ifp = netdev_priv(ndev);
2398         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2399         struct brcmf_pub *drvr = cfg->pub;
2400         struct brcmf_cfg80211_security *sec;
2401         s32 wsec;
2402         s32 err = 0;
2403 
2404         brcmf_dbg(TRACE, "Enter\n");
2405         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2406         if (!check_vif_up(ifp->vif))
2407                 return -EIO;
2408 
2409         memset(&params, 0, sizeof(params));
2410 
2411         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2412         if (err) {
2413                 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2414                 /* Ignore this error, may happen during DISASSOC */
2415                 err = -EAGAIN;
2416                 goto done;
2417         }
2418         if (wsec & WEP_ENABLED) {
2419                 sec = &profile->sec;
2420                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2421                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
2422                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2423                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2424                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
2425                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2426                 }
2427         } else if (wsec & TKIP_ENABLED) {
2428                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2429                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2430         } else if (wsec & AES_ENABLED) {
2431                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2432                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2433         } else  {
2434                 bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
2435                 err = -EINVAL;
2436                 goto done;
2437         }
2438         callback(cookie, &params);
2439 
2440 done:
2441         brcmf_dbg(TRACE, "Exit\n");
2442         return err;
2443 }
2444 
2445 static s32
2446 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2447                                        struct net_device *ndev, u8 key_idx)
2448 {
2449         struct brcmf_if *ifp = netdev_priv(ndev);
2450 
2451         brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2452 
2453         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2454                 return 0;
2455 
2456         brcmf_dbg(INFO, "Not supported\n");
2457 
2458         return -EOPNOTSUPP;
2459 }
2460 
2461 static void
2462 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2463 {
2464         struct brcmf_pub *drvr = ifp->drvr;
2465         s32 err;
2466         u8 key_idx;
2467         struct brcmf_wsec_key *key;
2468         s32 wsec;
2469 
2470         for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2471                 key = &ifp->vif->profile.key[key_idx];
2472                 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2473                     (key->algo == CRYPTO_ALGO_WEP128))
2474                         break;
2475         }
2476         if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2477                 return;
2478 
2479         err = send_key_to_dongle(ifp, key);
2480         if (err) {
2481                 bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
2482                 return;
2483         }
2484         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2485         if (err) {
2486                 bphy_err(drvr, "get wsec error (%d)\n", err);
2487                 return;
2488         }
2489         wsec |= WEP_ENABLED;
2490         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2491         if (err)
2492                 bphy_err(drvr, "set wsec error (%d)\n", err);
2493 }
2494 
2495 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2496 {
2497         struct nl80211_sta_flag_update *sfu;
2498 
2499         brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2500         si->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS);
2501         sfu = &si->sta_flags;
2502         sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2503                     BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2504                     BIT(NL80211_STA_FLAG_ASSOCIATED) |
2505                     BIT(NL80211_STA_FLAG_AUTHORIZED);
2506         if (fw_sta_flags & BRCMF_STA_WME)
2507                 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2508         if (fw_sta_flags & BRCMF_STA_AUTHE)
2509                 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2510         if (fw_sta_flags & BRCMF_STA_ASSOC)
2511                 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2512         if (fw_sta_flags & BRCMF_STA_AUTHO)
2513                 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2514 }
2515 
2516 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2517 {
2518         struct brcmf_pub *drvr = ifp->drvr;
2519         struct {
2520                 __le32 len;
2521                 struct brcmf_bss_info_le bss_le;
2522         } *buf;
2523         u16 capability;
2524         int err;
2525 
2526         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2527         if (!buf)
2528                 return;
2529 
2530         buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2531         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2532                                      WL_BSS_INFO_MAX);
2533         if (err) {
2534                 bphy_err(drvr, "Failed to get bss info (%d)\n", err);
2535                 goto out_kfree;
2536         }
2537         si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
2538         si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2539         si->bss_param.dtim_period = buf->bss_le.dtim_period;
2540         capability = le16_to_cpu(buf->bss_le.capability);
2541         if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2542                 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2543         if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2544                 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2545         if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2546                 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2547 
2548 out_kfree:
2549         kfree(buf);
2550 }
2551 
2552 static s32
2553 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2554                                 struct station_info *sinfo)
2555 {
2556         struct brcmf_pub *drvr = ifp->drvr;
2557         struct brcmf_scb_val_le scbval;
2558         struct brcmf_pktcnt_le pktcnt;
2559         s32 err;
2560         u32 rate;
2561         u32 rssi;
2562 
2563         /* Get the current tx rate */
2564         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2565         if (err < 0) {
2566                 bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
2567                 return err;
2568         }
2569         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2570         sinfo->txrate.legacy = rate * 5;
2571 
2572         memset(&scbval, 0, sizeof(scbval));
2573         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2574                                      sizeof(scbval));
2575         if (err) {
2576                 bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
2577                 return err;
2578         }
2579         rssi = le32_to_cpu(scbval.val);
2580         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2581         sinfo->signal = rssi;
2582 
2583         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2584                                      sizeof(pktcnt));
2585         if (err) {
2586                 bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2587                 return err;
2588         }
2589         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
2590                          BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
2591                          BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
2592                          BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2593         sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2594         sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2595         sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2596         sinfo->tx_failed  = le32_to_cpu(pktcnt.tx_bad_pkt);
2597 
2598         return 0;
2599 }
2600 
2601 static s32
2602 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2603                            const u8 *mac, struct station_info *sinfo)
2604 {
2605         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2606         struct brcmf_if *ifp = netdev_priv(ndev);
2607         struct brcmf_pub *drvr = cfg->pub;
2608         struct brcmf_scb_val_le scb_val;
2609         s32 err = 0;
2610         struct brcmf_sta_info_le sta_info_le;
2611         u32 sta_flags;
2612         u32 is_tdls_peer;
2613         s32 total_rssi;
2614         s32 count_rssi;
2615         int rssi;
2616         u32 i;
2617 
2618         brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2619         if (!check_vif_up(ifp->vif))
2620                 return -EIO;
2621 
2622         if (brcmf_is_ibssmode(ifp->vif))
2623                 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2624 
2625         memset(&sta_info_le, 0, sizeof(sta_info_le));
2626         memcpy(&sta_info_le, mac, ETH_ALEN);
2627         err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2628                                        &sta_info_le,
2629                                        sizeof(sta_info_le));
2630         is_tdls_peer = !err;
2631         if (err) {
2632                 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2633                                                &sta_info_le,
2634                                                sizeof(sta_info_le));
2635                 if (err < 0) {
2636                         bphy_err(drvr, "GET STA INFO failed, %d\n", err);
2637                         goto done;
2638                 }
2639         }
2640         brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2641         sinfo->filled = BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
2642         sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2643         sta_flags = le32_to_cpu(sta_info_le.flags);
2644         brcmf_convert_sta_flags(sta_flags, sinfo);
2645         sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2646         if (is_tdls_peer)
2647                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2648         else
2649                 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2650         if (sta_flags & BRCMF_STA_ASSOC) {
2651                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME);
2652                 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2653                 brcmf_fill_bss_param(ifp, sinfo);
2654         }
2655         if (sta_flags & BRCMF_STA_SCBSTATS) {
2656                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2657                 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2658                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
2659                 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2660                 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2661                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
2662                 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2663                 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2664                 if (sinfo->tx_packets) {
2665                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2666                         sinfo->txrate.legacy =
2667                                 le32_to_cpu(sta_info_le.tx_rate) / 100;
2668                 }
2669                 if (sinfo->rx_packets) {
2670                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
2671                         sinfo->rxrate.legacy =
2672                                 le32_to_cpu(sta_info_le.rx_rate) / 100;
2673                 }
2674                 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2675                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
2676                         sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2677                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
2678                         sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2679                 }
2680                 total_rssi = 0;
2681                 count_rssi = 0;
2682                 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2683                         if (sta_info_le.rssi[i]) {
2684                                 sinfo->chain_signal_avg[count_rssi] =
2685                                         sta_info_le.rssi[i];
2686                                 sinfo->chain_signal[count_rssi] =
2687                                         sta_info_le.rssi[i];
2688                                 total_rssi += sta_info_le.rssi[i];
2689                                 count_rssi++;
2690                         }
2691                 }
2692                 if (count_rssi) {
2693                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
2694                         sinfo->chains = count_rssi;
2695 
2696                         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2697                         total_rssi /= count_rssi;
2698                         sinfo->signal = total_rssi;
2699                 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2700                         &ifp->vif->sme_state)) {
2701                         memset(&scb_val, 0, sizeof(scb_val));
2702                         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2703                                                      &scb_val, sizeof(scb_val));
2704                         if (err) {
2705                                 bphy_err(drvr, "Could not get rssi (%d)\n",
2706                                          err);
2707                                 goto done;
2708                         } else {
2709                                 rssi = le32_to_cpu(scb_val.val);
2710                                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2711                                 sinfo->signal = rssi;
2712                                 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2713                         }
2714                 }
2715         }
2716 done:
2717         brcmf_dbg(TRACE, "Exit\n");
2718         return err;
2719 }
2720 
2721 static int
2722 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2723                             int idx, u8 *mac, struct station_info *sinfo)
2724 {
2725         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2726         struct brcmf_if *ifp = netdev_priv(ndev);
2727         struct brcmf_pub *drvr = cfg->pub;
2728         s32 err;
2729 
2730         brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2731 
2732         if (idx == 0) {
2733                 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2734                 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2735                                              &cfg->assoclist,
2736                                              sizeof(cfg->assoclist));
2737                 if (err) {
2738                         bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2739                                  err);
2740                         cfg->assoclist.count = 0;
2741                         return -EOPNOTSUPP;
2742                 }
2743         }
2744         if (idx < le32_to_cpu(cfg->assoclist.count)) {
2745                 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2746                 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2747         }
2748         return -ENOENT;
2749 }
2750 
2751 static s32
2752 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2753                            bool enabled, s32 timeout)
2754 {
2755         s32 pm;
2756         s32 err = 0;
2757         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2758         struct brcmf_if *ifp = netdev_priv(ndev);
2759         struct brcmf_pub *drvr = cfg->pub;
2760 
2761         brcmf_dbg(TRACE, "Enter\n");
2762 
2763         /*
2764          * Powersave enable/disable request is coming from the
2765          * cfg80211 even before the interface is up. In that
2766          * scenario, driver will be storing the power save
2767          * preference in cfg struct to apply this to
2768          * FW later while initializing the dongle
2769          */
2770         cfg->pwr_save = enabled;
2771         if (!check_vif_up(ifp->vif)) {
2772 
2773                 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2774                 goto done;
2775         }
2776 
2777         pm = enabled ? PM_FAST : PM_OFF;
2778         /* Do not enable the power save after assoc if it is a p2p interface */
2779         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2780                 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2781                 pm = PM_OFF;
2782         }
2783         brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2784 
2785         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2786         if (err) {
2787                 if (err == -ENODEV)
2788                         bphy_err(drvr, "net_device is not ready yet\n");
2789                 else
2790                         bphy_err(drvr, "error (%d)\n", err);
2791         }
2792 done:
2793         brcmf_dbg(TRACE, "Exit\n");
2794         return err;
2795 }
2796 
2797 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2798                                    struct brcmf_bss_info_le *bi)
2799 {
2800         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2801         struct brcmf_pub *drvr = cfg->pub;
2802         struct cfg80211_bss *bss;
2803         enum nl80211_band band;
2804         struct brcmu_chan ch;
2805         u16 channel;
2806         u32 freq;
2807         u16 notify_capability;
2808         u16 notify_interval;
2809         u8 *notify_ie;
2810         size_t notify_ielen;
2811         struct cfg80211_inform_bss bss_data = {};
2812 
2813         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2814                 bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
2815                 return 0;
2816         }
2817 
2818         if (!bi->ctl_ch) {
2819                 ch.chspec = le16_to_cpu(bi->chanspec);
2820                 cfg->d11inf.decchspec(&ch);
2821                 bi->ctl_ch = ch.control_ch_num;
2822         }
2823         channel = bi->ctl_ch;
2824 
2825         if (channel <= CH_MAX_2G_CHANNEL)
2826                 band = NL80211_BAND_2GHZ;
2827         else
2828                 band = NL80211_BAND_5GHZ;
2829 
2830         freq = ieee80211_channel_to_frequency(channel, band);
2831         bss_data.chan = ieee80211_get_channel(wiphy, freq);
2832         bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
2833         bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
2834 
2835         notify_capability = le16_to_cpu(bi->capability);
2836         notify_interval = le16_to_cpu(bi->beacon_period);
2837         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2838         notify_ielen = le32_to_cpu(bi->ie_length);
2839         bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2840 
2841         brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2842         brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2843         brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2844         brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2845         brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal);
2846 
2847         bss = cfg80211_inform_bss_data(wiphy, &bss_data,
2848                                        CFG80211_BSS_FTYPE_UNKNOWN,
2849                                        (const u8 *)bi->BSSID,
2850                                        0, notify_capability,
2851                                        notify_interval, notify_ie,
2852                                        notify_ielen, GFP_KERNEL);
2853 
2854         if (!bss)
2855                 return -ENOMEM;
2856 
2857         cfg80211_put_bss(wiphy, bss);
2858 
2859         return 0;
2860 }
2861 
2862 static struct brcmf_bss_info_le *
2863 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2864 {
2865         if (bss == NULL)
2866                 return list->bss_info_le;
2867         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2868                                             le32_to_cpu(bss->length));
2869 }
2870 
2871 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2872 {
2873         struct brcmf_pub *drvr = cfg->pub;
2874         struct brcmf_scan_results *bss_list;
2875         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2876         s32 err = 0;
2877         int i;
2878 
2879         bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2880         if (bss_list->count != 0 &&
2881             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2882                 bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
2883                          bss_list->version);
2884                 return -EOPNOTSUPP;
2885         }
2886         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2887         for (i = 0; i < bss_list->count; i++) {
2888                 bi = next_bss_le(bss_list, bi);
2889                 err = brcmf_inform_single_bss(cfg, bi);
2890                 if (err)
2891                         break;
2892         }
2893         return err;
2894 }
2895 
2896 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
2897                              struct net_device *ndev, const u8 *bssid)
2898 {
2899         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2900         struct brcmf_pub *drvr = cfg->pub;
2901         struct ieee80211_channel *notify_channel;
2902         struct brcmf_bss_info_le *bi = NULL;
2903         struct ieee80211_supported_band *band;
2904         struct cfg80211_bss *bss;
2905         struct brcmu_chan ch;
2906         u8 *buf = NULL;
2907         s32 err = 0;
2908         u32 freq;
2909         u16 notify_capability;
2910         u16 notify_interval;
2911         u8 *notify_ie;
2912         size_t notify_ielen;
2913         s32 notify_signal;
2914 
2915         brcmf_dbg(TRACE, "Enter\n");
2916 
2917         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2918         if (buf == NULL) {
2919                 err = -ENOMEM;
2920                 goto CleanUp;
2921         }
2922 
2923         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2924 
2925         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2926                                      buf, WL_BSS_INFO_MAX);
2927         if (err) {
2928                 bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
2929                 goto CleanUp;
2930         }
2931 
2932         bi = (struct brcmf_bss_info_le *)(buf + 4);
2933 
2934         ch.chspec = le16_to_cpu(bi->chanspec);
2935         cfg->d11inf.decchspec(&ch);
2936 
2937         if (ch.band == BRCMU_CHAN_BAND_2G)
2938                 band = wiphy->bands[NL80211_BAND_2GHZ];
2939         else
2940                 band = wiphy->bands[NL80211_BAND_5GHZ];
2941 
2942         freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
2943         cfg->channel = freq;
2944         notify_channel = ieee80211_get_channel(wiphy, freq);
2945 
2946         notify_capability = le16_to_cpu(bi->capability);
2947         notify_interval = le16_to_cpu(bi->beacon_period);
2948         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2949         notify_ielen = le32_to_cpu(bi->ie_length);
2950         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2951 
2952         brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
2953         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2954         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2955         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2956 
2957         bss = cfg80211_inform_bss(wiphy, notify_channel,
2958                                   CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2959                                   notify_capability, notify_interval,
2960                                   notify_ie, notify_ielen, notify_signal,
2961                                   GFP_KERNEL);
2962 
2963         if (!bss) {
2964                 err = -ENOMEM;
2965                 goto CleanUp;
2966         }
2967 
2968         cfg80211_put_bss(wiphy, bss);
2969 
2970 CleanUp:
2971 
2972         kfree(buf);
2973 
2974         brcmf_dbg(TRACE, "Exit\n");
2975 
2976         return err;
2977 }
2978 
2979 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2980                                  struct brcmf_if *ifp)
2981 {
2982         struct brcmf_pub *drvr = cfg->pub;
2983         struct brcmf_bss_info_le *bi;
2984         const struct brcmf_tlv *tim;
2985         size_t ie_len;
2986         u8 *ie;
2987         s32 err = 0;
2988 
2989         brcmf_dbg(TRACE, "Enter\n");
2990         if (brcmf_is_ibssmode(ifp->vif))
2991                 return err;
2992 
2993         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2994         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2995                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2996         if (err) {
2997                 bphy_err(drvr, "Could not get bss info %d\n", err);
2998                 goto update_bss_info_out;
2999         }
3000 
3001         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
3002         err = brcmf_inform_single_bss(cfg, bi);
3003         if (err)
3004                 goto update_bss_info_out;
3005 
3006         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
3007         ie_len = le32_to_cpu(bi->ie_length);
3008 
3009         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
3010         if (!tim) {
3011                 /*
3012                 * active scan was done so we could not get dtim
3013                 * information out of probe response.
3014                 * so we speficially query dtim information to dongle.
3015                 */
3016                 u32 var;
3017                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
3018                 if (err) {
3019                         bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err);
3020                         goto update_bss_info_out;
3021                 }
3022         }
3023 
3024 update_bss_info_out:
3025         brcmf_dbg(TRACE, "Exit");
3026         return err;
3027 }
3028 
3029 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3030 {
3031         struct escan_info *escan = &cfg->escan_info;
3032 
3033         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3034         if (cfg->int_escan_map || cfg->scan_request) {
3035                 escan->escan_state = WL_ESCAN_STATE_IDLE;
3036                 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3037         }
3038         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3039         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3040 }
3041 
3042 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3043 {
3044         struct brcmf_cfg80211_info *cfg =
3045                         container_of(work, struct brcmf_cfg80211_info,
3046                                      escan_timeout_work);
3047 
3048         brcmf_inform_bss(cfg);
3049         brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3050 }
3051 
3052 static void brcmf_escan_timeout(struct timer_list *t)
3053 {
3054         struct brcmf_cfg80211_info *cfg =
3055                         from_timer(cfg, t, escan_timeout);
3056         struct brcmf_pub *drvr = cfg->pub;
3057 
3058         if (cfg->int_escan_map || cfg->scan_request) {
3059                 bphy_err(drvr, "timer expired\n");
3060                 schedule_work(&cfg->escan_timeout_work);
3061         }
3062 }
3063 
3064 static s32
3065 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3066                               struct brcmf_bss_info_le *bss,
3067                               struct brcmf_bss_info_le *bss_info_le)
3068 {
3069         struct brcmu_chan ch_bss, ch_bss_info_le;
3070 
3071         ch_bss.chspec = le16_to_cpu(bss->chanspec);
3072         cfg->d11inf.decchspec(&ch_bss);
3073         ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3074         cfg->d11inf.decchspec(&ch_bss_info_le);
3075 
3076         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3077                 ch_bss.band == ch_bss_info_le.band &&
3078                 bss_info_le->SSID_len == bss->SSID_len &&
3079                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3080                 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3081                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3082                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
3083                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3084 
3085                         /* preserve max RSSI if the measurements are
3086                         * both on-channel or both off-channel
3087                         */
3088                         if (bss_info_rssi > bss_rssi)
3089                                 bss->RSSI = bss_info_le->RSSI;
3090                 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3091                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3092                         /* preserve the on-channel rssi measurement
3093                         * if the new measurement is off channel
3094                         */
3095                         bss->RSSI = bss_info_le->RSSI;
3096                         bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3097                 }
3098                 return 1;
3099         }
3100         return 0;
3101 }
3102 
3103 static s32
3104 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3105                              const struct brcmf_event_msg *e, void *data)
3106 {
3107         struct brcmf_pub *drvr = ifp->drvr;
3108         struct brcmf_cfg80211_info *cfg = drvr->config;
3109         s32 status;
3110         struct brcmf_escan_result_le *escan_result_le;
3111         u32 escan_buflen;
3112         struct brcmf_bss_info_le *bss_info_le;
3113         struct brcmf_bss_info_le *bss = NULL;
3114         u32 bi_length;
3115         struct brcmf_scan_results *list;
3116         u32 i;
3117         bool aborted;
3118 
3119         status = e->status;
3120 
3121         if (status == BRCMF_E_STATUS_ABORT)
3122                 goto exit;
3123 
3124         if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3125                 bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
3126                          ifp->bsscfgidx);
3127                 return -EPERM;
3128         }
3129 
3130         if (status == BRCMF_E_STATUS_PARTIAL) {
3131                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3132                 if (e->datalen < sizeof(*escan_result_le)) {
3133                         bphy_err(drvr, "invalid event data length\n");
3134                         goto exit;
3135                 }
3136                 escan_result_le = (struct brcmf_escan_result_le *) data;
3137                 if (!escan_result_le) {
3138                         bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
3139                         goto exit;
3140                 }
3141                 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3142                 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3143                     escan_buflen > e->datalen ||
3144                     escan_buflen < sizeof(*escan_result_le)) {
3145                         bphy_err(drvr, "Invalid escan buffer length: %d\n",
3146                                  escan_buflen);
3147                         goto exit;
3148                 }
3149                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3150                         bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
3151                                  escan_result_le->bss_count);
3152                         goto exit;
3153                 }
3154                 bss_info_le = &escan_result_le->bss_info_le;
3155 
3156                 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3157                         goto exit;
3158 
3159                 if (!cfg->int_escan_map && !cfg->scan_request) {
3160                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
3161                         goto exit;
3162                 }
3163 
3164                 bi_length = le32_to_cpu(bss_info_le->length);
3165                 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3166                         bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
3167                                  bi_length);
3168                         goto exit;
3169                 }
3170 
3171                 if (!(cfg_to_wiphy(cfg)->interface_modes &
3172                                         BIT(NL80211_IFTYPE_ADHOC))) {
3173                         if (le16_to_cpu(bss_info_le->capability) &
3174                                                 WLAN_CAPABILITY_IBSS) {
3175                                 bphy_err(drvr, "Ignoring IBSS result\n");
3176                                 goto exit;
3177                         }
3178                 }
3179 
3180                 list = (struct brcmf_scan_results *)
3181                                 cfg->escan_info.escan_buf;
3182                 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3183                         bphy_err(drvr, "Buffer is too small: ignoring\n");
3184                         goto exit;
3185                 }
3186 
3187                 for (i = 0; i < list->count; i++) {
3188                         bss = bss ? (struct brcmf_bss_info_le *)
3189                                 ((unsigned char *)bss +
3190                                 le32_to_cpu(bss->length)) : list->bss_info_le;
3191                         if (brcmf_compare_update_same_bss(cfg, bss,
3192                                                           bss_info_le))
3193                                 goto exit;
3194                 }
3195                 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3196                        bi_length);
3197                 list->version = le32_to_cpu(bss_info_le->version);
3198                 list->buflen += bi_length;
3199                 list->count++;
3200         } else {
3201                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3202                 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3203                         goto exit;
3204                 if (cfg->int_escan_map || cfg->scan_request) {
3205                         brcmf_inform_bss(cfg);
3206                         aborted = status != BRCMF_E_STATUS_SUCCESS;
3207                         brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3208                 } else
3209                         brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3210                                   status);
3211         }
3212 exit:
3213         return 0;
3214 }
3215 
3216 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3217 {
3218         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3219                             brcmf_cfg80211_escan_handler);
3220         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3221         /* Init scan_timeout timer */
3222         timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3223         INIT_WORK(&cfg->escan_timeout_work,
3224                   brcmf_cfg80211_escan_timeout_worker);
3225 }
3226 
3227 static struct cfg80211_scan_request *
3228 brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3229         struct cfg80211_scan_request *req;
3230         size_t req_size;
3231 
3232         req_size = sizeof(*req) +
3233                    n_netinfo * sizeof(req->channels[0]) +
3234                    n_netinfo * sizeof(*req->ssids);
3235 
3236         req = kzalloc(req_size, GFP_KERNEL);
3237         if (req) {
3238                 req->wiphy = wiphy;
3239                 req->ssids = (void *)(&req->channels[0]) +
3240                              n_netinfo * sizeof(req->channels[0]);
3241         }
3242         return req;
3243 }
3244 
3245 static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3246                                          u8 *ssid, u8 ssid_len, u8 channel)
3247 {
3248         struct ieee80211_channel *chan;
3249         enum nl80211_band band;
3250         int freq, i;
3251 
3252         if (channel <= CH_MAX_2G_CHANNEL)
3253                 band = NL80211_BAND_2GHZ;
3254         else
3255                 band = NL80211_BAND_5GHZ;
3256 
3257         freq = ieee80211_channel_to_frequency(channel, band);
3258         if (!freq)
3259                 return -EINVAL;
3260 
3261         chan = ieee80211_get_channel(req->wiphy, freq);
3262         if (!chan)
3263                 return -EINVAL;
3264 
3265         for (i = 0; i < req->n_channels; i++) {
3266                 if (req->channels[i] == chan)
3267                         break;
3268         }
3269         if (i == req->n_channels)
3270                 req->channels[req->n_channels++] = chan;
3271 
3272         for (i = 0; i < req->n_ssids; i++) {
3273                 if (req->ssids[i].ssid_len == ssid_len &&
3274                     !memcmp(req->ssids[i].ssid, ssid, ssid_len))
3275                         break;
3276         }
3277         if (i == req->n_ssids) {
3278                 memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3279                 req->ssids[req->n_ssids++].ssid_len = ssid_len;
3280         }
3281         return 0;
3282 }
3283 
3284 static int brcmf_start_internal_escan(struct brcmf_if *ifp, u32 fwmap,
3285                                       struct cfg80211_scan_request *request)
3286 {
3287         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3288         int err;
3289 
3290         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3291                 if (cfg->int_escan_map)
3292                         brcmf_dbg(SCAN, "aborting internal scan: map=%u\n",
3293                                   cfg->int_escan_map);
3294                 /* Abort any on-going scan */
3295                 brcmf_abort_scanning(cfg);
3296         }
3297 
3298         brcmf_dbg(SCAN, "start internal scan: map=%u\n", fwmap);
3299         set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3300         cfg->escan_info.run = brcmf_run_escan;
3301         err = brcmf_do_escan(ifp, request);
3302         if (err) {
3303                 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3304                 return err;
3305         }
3306         cfg->int_escan_map = fwmap;
3307         return 0;
3308 }
3309 
3310 static struct brcmf_pno_net_info_le *
3311 brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3312 {
3313         struct brcmf_pno_scanresults_v2_le *pfn_v2;
3314         struct brcmf_pno_net_info_le *netinfo;
3315 
3316         switch (pfn_v1->version) {
3317         default:
3318                 WARN_ON(1);
3319                 /* fall-thru */
3320         case cpu_to_le32(1):
3321                 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3322                 break;
3323         case cpu_to_le32(2):
3324                 pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3325                 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3326                 break;
3327         }
3328 
3329         return netinfo;
3330 }
3331 
3332 /* PFN result doesn't have all the info which are required by the supplicant
3333  * (For e.g IEs) Do a target Escan so that sched scan results are reported
3334  * via wl_inform_single_bss in the required format. Escan does require the
3335  * scan request in the form of cfg80211_scan_request. For timebeing, create
3336  * cfg80211_scan_request one out of the received PNO event.
3337  */
3338 static s32
3339 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3340                                 const struct brcmf_event_msg *e, void *data)
3341 {
3342         struct brcmf_pub *drvr = ifp->drvr;
3343         struct brcmf_cfg80211_info *cfg = drvr->config;
3344         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3345         struct cfg80211_scan_request *request = NULL;
3346         struct wiphy *wiphy = cfg_to_wiphy(cfg);
3347         int i, err = 0;
3348         struct brcmf_pno_scanresults_le *pfn_result;
3349         u32 bucket_map;
3350         u32 result_count;
3351         u32 status;
3352         u32 datalen;
3353 
3354         brcmf_dbg(SCAN, "Enter\n");
3355 
3356         if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3357                 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3358                 return 0;
3359         }
3360 
3361         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3362                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3363                 return 0;
3364         }
3365 
3366         pfn_result = (struct brcmf_pno_scanresults_le *)data;
3367         result_count = le32_to_cpu(pfn_result->count);
3368         status = le32_to_cpu(pfn_result->status);
3369 
3370         /* PFN event is limited to fit 512 bytes so we may get
3371          * multiple NET_FOUND events. For now place a warning here.
3372          */
3373         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3374         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3375         if (!result_count) {
3376                 bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n");
3377                 goto out_err;
3378         }
3379 
3380         netinfo_start = brcmf_get_netinfo_array(pfn_result);
3381         datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3382         if (datalen < result_count * sizeof(*netinfo)) {
3383                 bphy_err(drvr, "insufficient event data\n");
3384                 goto out_err;
3385         }
3386 
3387         request = brcmf_alloc_internal_escan_request(wiphy,
3388                                                      result_count);
3389         if (!request) {
3390                 err = -ENOMEM;
3391                 goto out_err;
3392         }
3393 
3394         bucket_map = 0;
3395         for (i = 0; i < result_count; i++) {
3396                 netinfo = &netinfo_start[i];
3397 
3398                 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3399                         netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3400                 brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3401                           netinfo->SSID, netinfo->channel);
3402                 bucket_map |= brcmf_pno_get_bucket_map(cfg->pno, netinfo);
3403                 err = brcmf_internal_escan_add_info(request,
3404                                                     netinfo->SSID,
3405                                                     netinfo->SSID_len,
3406                                                     netinfo->channel);
3407                 if (err)
3408                         goto out_err;
3409         }
3410 
3411         if (!bucket_map)
3412                 goto free_req;
3413 
3414         err = brcmf_start_internal_escan(ifp, bucket_map, request);
3415         if (!err)
3416                 goto free_req;
3417 
3418 out_err:
3419         cfg80211_sched_scan_stopped(wiphy, 0);
3420 free_req:
3421         kfree(request);
3422         return err;
3423 }
3424 
3425 static int
3426 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3427                                 struct net_device *ndev,
3428                                 struct cfg80211_sched_scan_request *req)
3429 {
3430         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3431         struct brcmf_if *ifp = netdev_priv(ndev);
3432         struct brcmf_pub *drvr = cfg->pub;
3433 
3434         brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
3435                   req->n_match_sets, req->n_ssids);
3436 
3437         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3438                 bphy_err(drvr, "Scanning suppressed: status=%lu\n",
3439                          cfg->scan_status);
3440                 return -EAGAIN;
3441         }
3442 
3443         if (req->n_match_sets <= 0) {
3444                 brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3445                           req->n_match_sets);
3446                 return -EINVAL;
3447         }
3448 
3449         return brcmf_pno_start_sched_scan(ifp, req);
3450 }
3451 
3452 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3453                                           struct net_device *ndev, u64 reqid)
3454 {
3455         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3456         struct brcmf_if *ifp = netdev_priv(ndev);
3457 
3458         brcmf_dbg(SCAN, "enter\n");
3459         brcmf_pno_stop_sched_scan(ifp, reqid);
3460         if (cfg->int_escan_map)
3461                 brcmf_notify_escan_complete(cfg, ifp, true, true);
3462         return 0;
3463 }
3464 
3465 static __always_inline void brcmf_delay(u32 ms)
3466 {
3467         if (ms < 1000 / HZ) {
3468                 cond_resched();
3469                 mdelay(ms);
3470         } else {
3471                 msleep(ms);
3472         }
3473 }
3474 
3475 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3476                                      u8 *pattern, u32 patternsize, u8 *mask,
3477                                      u32 packet_offset)
3478 {
3479         struct brcmf_fil_wowl_pattern_le *filter;
3480         u32 masksize;
3481         u32 patternoffset;
3482         u8 *buf;
3483         u32 bufsize;
3484         s32 ret;
3485 
3486         masksize = (patternsize + 7) / 8;
3487         patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3488 
3489         bufsize = sizeof(*filter) + patternsize + masksize;
3490         buf = kzalloc(bufsize, GFP_KERNEL);
3491         if (!buf)
3492                 return -ENOMEM;
3493         filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3494 
3495         memcpy(filter->cmd, cmd, 4);
3496         filter->masksize = cpu_to_le32(masksize);
3497         filter->offset = cpu_to_le32(packet_offset);
3498         filter->patternoffset = cpu_to_le32(patternoffset);
3499         filter->patternsize = cpu_to_le32(patternsize);
3500         filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3501 
3502         if ((mask) && (masksize))
3503                 memcpy(buf + sizeof(*filter), mask, masksize);
3504         if ((pattern) && (patternsize))
3505                 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3506 
3507         ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3508 
3509         kfree(buf);
3510         return ret;
3511 }
3512 
3513 static s32
3514 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3515                       void *data)
3516 {
3517         struct brcmf_pub *drvr = ifp->drvr;
3518         struct brcmf_cfg80211_info *cfg = drvr->config;
3519         struct brcmf_pno_scanresults_le *pfn_result;
3520         struct brcmf_pno_net_info_le *netinfo;
3521 
3522         brcmf_dbg(SCAN, "Enter\n");
3523 
3524         if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3525                 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3526                 return 0;
3527         }
3528 
3529         pfn_result = (struct brcmf_pno_scanresults_le *)data;
3530 
3531         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3532                 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3533                 return 0;
3534         }
3535 
3536         if (le32_to_cpu(pfn_result->count) < 1) {
3537                 bphy_err(drvr, "Invalid result count, expected 1 (%d)\n",
3538                          le32_to_cpu(pfn_result->count));
3539                 return -EINVAL;
3540         }
3541 
3542         netinfo = brcmf_get_netinfo_array(pfn_result);
3543         if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3544                 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3545         memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3546         cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3547         cfg->wowl.nd->n_channels = 1;
3548         cfg->wowl.nd->channels[0] =
3549                 ieee80211_channel_to_frequency(netinfo->channel,
3550                         netinfo->channel <= CH_MAX_2G_CHANNEL ?
3551                                         NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3552         cfg->wowl.nd_info->n_matches = 1;
3553         cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3554 
3555         /* Inform (the resume task) that the net detect information was recvd */
3556         cfg->wowl.nd_data_completed = true;
3557         wake_up(&cfg->wowl.nd_data_wait);
3558 
3559         return 0;
3560 }
3561 
3562 #ifdef CONFIG_PM
3563 
3564 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3565 {
3566         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3567         struct brcmf_pub *drvr = cfg->pub;
3568         struct brcmf_wowl_wakeind_le wake_ind_le;
3569         struct cfg80211_wowlan_wakeup wakeup_data;
3570         struct cfg80211_wowlan_wakeup *wakeup;
3571         u32 wakeind;
3572         s32 err;
3573         int timeout;
3574 
3575         err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3576                                        sizeof(wake_ind_le));
3577         if (err) {
3578                 bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err);
3579                 return;
3580         }
3581 
3582         wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3583         if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3584                        BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3585                        BRCMF_WOWL_PFN_FOUND)) {
3586                 wakeup = &wakeup_data;
3587                 memset(&wakeup_data, 0, sizeof(wakeup_data));
3588                 wakeup_data.pattern_idx = -1;
3589 
3590                 if (wakeind & BRCMF_WOWL_MAGIC) {
3591                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3592                         wakeup_data.magic_pkt = true;
3593                 }
3594                 if (wakeind & BRCMF_WOWL_DIS) {
3595                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3596                         wakeup_data.disconnect = true;
3597                 }
3598                 if (wakeind & BRCMF_WOWL_BCN) {
3599                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3600                         wakeup_data.disconnect = true;
3601                 }
3602                 if (wakeind & BRCMF_WOWL_RETR) {
3603                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3604                         wakeup_data.disconnect = true;
3605                 }
3606                 if (wakeind & BRCMF_WOWL_NET) {
3607                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3608                         /* For now always map to pattern 0, no API to get
3609                          * correct information available at the moment.
3610                          */
3611                         wakeup_data.pattern_idx = 0;
3612                 }
3613                 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3614                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3615                         timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3616                                 cfg->wowl.nd_data_completed,
3617                                 BRCMF_ND_INFO_TIMEOUT);
3618                         if (!timeout)
3619                                 bphy_err(drvr, "No result for wowl net detect\n");
3620                         else
3621                                 wakeup_data.net_detect = cfg->wowl.nd_info;
3622                 }
3623                 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3624                         brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3625                         wakeup_data.gtk_rekey_failure = true;
3626                 }
3627         } else {
3628                 wakeup = NULL;
3629         }
3630         cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3631 }
3632 
3633 #else
3634 
3635 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3636 {
3637 }
3638 
3639 #endif /* CONFIG_PM */
3640 
3641 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3642 {
3643         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3644         struct net_device *ndev = cfg_to_ndev(cfg);
3645         struct brcmf_if *ifp = netdev_priv(ndev);
3646 
3647         brcmf_dbg(TRACE, "Enter\n");
3648 
3649         if (cfg->wowl.active) {
3650                 brcmf_report_wowl_wakeind(wiphy, ifp);
3651                 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3652                 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3653                 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3654                         brcmf_configure_arp_nd_offload(ifp, true);
3655                 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3656                                       cfg->wowl.pre_pmmode);
3657                 cfg->wowl.active = false;
3658                 if (cfg->wowl.nd_enabled) {
3659                         brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
3660                         brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3661                         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3662                                             brcmf_notify_sched_scan_results);
3663                         cfg->wowl.nd_enabled = false;
3664                 }
3665         }
3666         return 0;
3667 }
3668 
3669 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3670                                  struct brcmf_if *ifp,
3671                                  struct cfg80211_wowlan *wowl)
3672 {
3673         u32 wowl_config;
3674         struct brcmf_wowl_wakeind_le wowl_wakeind;
3675         u32 i;
3676 
3677         brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3678 
3679         if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3680                 brcmf_configure_arp_nd_offload(ifp, false);
3681         brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3682         brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3683 
3684         wowl_config = 0;
3685         if (wowl->disconnect)
3686                 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3687         if (wowl->magic_pkt)
3688                 wowl_config |= BRCMF_WOWL_MAGIC;
3689         if ((wowl->patterns) && (wowl->n_patterns)) {
3690                 wowl_config |= BRCMF_WOWL_NET;
3691                 for (i = 0; i < wowl->n_patterns; i++) {
3692                         brcmf_config_wowl_pattern(ifp, "add",
3693                                 (u8 *)wowl->patterns[i].pattern,
3694                                 wowl->patterns[i].pattern_len,
3695                                 (u8 *)wowl->patterns[i].mask,
3696                                 wowl->patterns[i].pkt_offset);
3697                 }
3698         }
3699         if (wowl->nd_config) {
3700                 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3701                                                 wowl->nd_config);
3702                 wowl_config |= BRCMF_WOWL_PFN_FOUND;
3703 
3704                 cfg->wowl.nd_data_completed = false;
3705                 cfg->wowl.nd_enabled = true;
3706                 /* Now reroute the event for PFN to the wowl function. */
3707                 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3708                 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3709                                     brcmf_wowl_nd_results);
3710         }
3711         if (wowl->gtk_rekey_failure)
3712                 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3713         if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3714                 wowl_config |= BRCMF_WOWL_UNASSOC;
3715 
3716         memcpy(&wowl_wakeind, "clear", 6);
3717         brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
3718                                  sizeof(wowl_wakeind));
3719         brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3720         brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3721         brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3722         cfg->wowl.active = true;
3723 }
3724 
3725 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3726                                   struct cfg80211_wowlan *wowl)
3727 {
3728         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3729         struct net_device *ndev = cfg_to_ndev(cfg);
3730         struct brcmf_if *ifp = netdev_priv(ndev);
3731         struct brcmf_cfg80211_vif *vif;
3732 
3733         brcmf_dbg(TRACE, "Enter\n");
3734 
3735         /* if the primary net_device is not READY there is nothing
3736          * we can do but pray resume goes smoothly.
3737          */
3738         if (!check_vif_up(ifp->vif))
3739                 goto exit;
3740 
3741         /* Stop scheduled scan */
3742         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3743                 brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
3744 
3745         /* end any scanning */
3746         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3747                 brcmf_abort_scanning(cfg);
3748 
3749         if (wowl == NULL) {
3750                 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3751                 list_for_each_entry(vif, &cfg->vif_list, list) {
3752                         if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3753                                 continue;
3754                         /* While going to suspend if associated with AP
3755                          * disassociate from AP to save power while system is
3756                          * in suspended state
3757                          */
3758                         brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3759                         /* Make sure WPA_Supplicant receives all the event
3760                          * generated due to DISASSOC call to the fw to keep
3761                          * the state fw and WPA_Supplicant state consistent
3762                          */
3763                         brcmf_delay(500);
3764                 }
3765                 /* Configure MPC */
3766                 brcmf_set_mpc(ifp, 1);
3767 
3768         } else {
3769                 /* Configure WOWL paramaters */
3770                 brcmf_configure_wowl(cfg, ifp, wowl);
3771         }
3772 
3773 exit:
3774         brcmf_dbg(TRACE, "Exit\n");
3775         /* clear any scanning activity */
3776         cfg->scan_status = 0;
3777         return 0;
3778 }
3779 
3780 static __used s32
3781 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3782 {
3783         struct brcmf_pmk_list_le *pmk_list;
3784         int i;
3785         u32 npmk;
3786         s32 err;
3787 
3788         pmk_list = &cfg->pmk_list;
3789         npmk = le32_to_cpu(pmk_list->npmk);
3790 
3791         brcmf_dbg(CONN, "No of elements %d\n", npmk);
3792         for (i = 0; i < npmk; i++)
3793                 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3794 
3795         err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3796                                        sizeof(*pmk_list));
3797 
3798         return err;
3799 }
3800 
3801 static s32
3802 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3803                          struct cfg80211_pmksa *pmksa)
3804 {
3805         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3806         struct brcmf_if *ifp = netdev_priv(ndev);
3807         struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3808         struct brcmf_pub *drvr = cfg->pub;
3809         s32 err;
3810         u32 npmk, i;
3811 
3812         brcmf_dbg(TRACE, "Enter\n");
3813         if (!check_vif_up(ifp->vif))
3814                 return -EIO;
3815 
3816         npmk = le32_to_cpu(cfg->pmk_list.npmk);
3817         for (i = 0; i < npmk; i++)
3818                 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3819                         break;
3820         if (i < BRCMF_MAXPMKID) {
3821                 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
3822                 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
3823                 if (i == npmk) {
3824                         npmk++;
3825                         cfg->pmk_list.npmk = cpu_to_le32(npmk);
3826                 }
3827         } else {
3828                 bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk);
3829                 return -EINVAL;
3830         }
3831 
3832         brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
3833         for (i = 0; i < WLAN_PMKID_LEN; i += 4)
3834                 brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
3835                           pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
3836                           pmk[npmk].pmkid[i + 3]);
3837 
3838         err = brcmf_update_pmklist(cfg, ifp);
3839 
3840         brcmf_dbg(TRACE, "Exit\n");
3841         return err;
3842 }
3843 
3844 static s32
3845 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3846                          struct cfg80211_pmksa *pmksa)
3847 {
3848         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3849         struct brcmf_if *ifp = netdev_priv(ndev);
3850         struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3851         struct brcmf_pub *drvr = cfg->pub;
3852         s32 err;
3853         u32 npmk, i;
3854 
3855         brcmf_dbg(TRACE, "Enter\n");
3856         if (!check_vif_up(ifp->vif))
3857                 return -EIO;
3858 
3859         brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
3860 
3861         npmk = le32_to_cpu(cfg->pmk_list.npmk);
3862         for (i = 0; i < npmk; i++)
3863                 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3864                         break;
3865 
3866         if ((npmk > 0) && (i < npmk)) {
3867                 for (; i < (npmk - 1); i++) {
3868                         memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
3869                         memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
3870                                WLAN_PMKID_LEN);
3871                 }
3872                 memset(&pmk[i], 0, sizeof(*pmk));
3873                 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
3874         } else {
3875                 bphy_err(drvr, "Cache entry not found\n");
3876                 return -EINVAL;
3877         }
3878 
3879         err = brcmf_update_pmklist(cfg, ifp);
3880 
3881         brcmf_dbg(TRACE, "Exit\n");
3882         return err;
3883 
3884 }
3885 
3886 static s32
3887 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3888 {
3889         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3890         struct brcmf_if *ifp = netdev_priv(ndev);
3891         s32 err;
3892 
3893         brcmf_dbg(TRACE, "Enter\n");
3894         if (!check_vif_up(ifp->vif))
3895                 return -EIO;
3896 
3897         memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
3898         err = brcmf_update_pmklist(cfg, ifp);
3899 
3900         brcmf_dbg(TRACE, "Exit\n");
3901         return err;
3902 
3903 }
3904 
3905 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3906 {
3907         struct brcmf_pub *drvr = ifp->drvr;
3908         s32 err;
3909         s32 wpa_val;
3910 
3911         /* set auth */
3912         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3913         if (err < 0) {
3914                 bphy_err(drvr, "auth error %d\n", err);
3915                 return err;
3916         }
3917         /* set wsec */
3918         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3919         if (err < 0) {
3920                 bphy_err(drvr, "wsec error %d\n", err);
3921                 return err;
3922         }
3923         /* set upper-layer auth */
3924         if (brcmf_is_ibssmode(ifp->vif))
3925                 wpa_val = WPA_AUTH_NONE;
3926         else
3927                 wpa_val = WPA_AUTH_DISABLED;
3928         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
3929         if (err < 0) {
3930                 bphy_err(drvr, "wpa_auth error %d\n", err);
3931                 return err;
3932         }
3933 
3934         return 0;
3935 }
3936 
3937 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3938 {
3939         if (is_rsn_ie)
3940                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3941 
3942         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3943 }
3944 
3945 static s32
3946 brcmf_configure_wpaie(struct brcmf_if *ifp,
3947                       const struct brcmf_vs_tlv *wpa_ie,
3948                       bool is_rsn_ie)
3949 {
3950         struct brcmf_pub *drvr = ifp->drvr;
3951         u32 auth = 0; /* d11 open authentication */
3952         u16 count;
3953         s32 err = 0;
3954         s32 len;
3955         u32 i;
3956         u32 wsec;
3957         u32 pval = 0;
3958         u32 gval = 0;
3959         u32 wpa_auth = 0;
3960         u32 offset;
3961         u8 *data;
3962         u16 rsn_cap;
3963         u32 wme_bss_disable;
3964         u32 mfp;
3965 
3966         brcmf_dbg(TRACE, "Enter\n");
3967         if (wpa_ie == NULL)
3968                 goto exit;
3969 
3970         len = wpa_ie->len + TLV_HDR_LEN;
3971         data = (u8 *)wpa_ie;
3972         offset = TLV_HDR_LEN;
3973         if (!is_rsn_ie)
3974                 offset += VS_IE_FIXED_HDR_LEN;
3975         else
3976                 offset += WPA_IE_VERSION_LEN;
3977 
3978         /* check for multicast cipher suite */
3979         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3980                 err = -EINVAL;
3981                 bphy_err(drvr, "no multicast cipher suite\n");
3982                 goto exit;
3983         }
3984 
3985         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3986                 err = -EINVAL;
3987                 bphy_err(drvr, "ivalid OUI\n");
3988                 goto exit;
3989         }
3990         offset += TLV_OUI_LEN;
3991 
3992         /* pick up multicast cipher */
3993         switch (data[offset]) {
3994         case WPA_CIPHER_NONE:
3995                 gval = 0;
3996                 break;
3997         case WPA_CIPHER_WEP_40:
3998         case WPA_CIPHER_WEP_104:
3999                 gval = WEP_ENABLED;
4000                 break;
4001         case WPA_CIPHER_TKIP:
4002                 gval = TKIP_ENABLED;
4003                 break;
4004         case WPA_CIPHER_AES_CCM:
4005                 gval = AES_ENABLED;
4006                 break;
4007         default:
4008                 err = -EINVAL;
4009                 bphy_err(drvr, "Invalid multi cast cipher info\n");
4010                 goto exit;
4011         }
4012 
4013         offset++;
4014         /* walk thru unicast cipher list and pick up what we recognize */
4015         count = data[offset] + (data[offset + 1] << 8);
4016         offset += WPA_IE_SUITE_COUNT_LEN;
4017         /* Check for unicast suite(s) */
4018         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4019                 err = -EINVAL;
4020                 bphy_err(drvr, "no unicast cipher suite\n");
4021                 goto exit;
4022         }
4023         for (i = 0; i < count; i++) {
4024                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4025                         err = -EINVAL;
4026                         bphy_err(drvr, "ivalid OUI\n");
4027                         goto exit;
4028                 }
4029                 offset += TLV_OUI_LEN;
4030                 switch (data[offset]) {
4031                 case WPA_CIPHER_NONE:
4032                         break;
4033                 case WPA_CIPHER_WEP_40:
4034                 case WPA_CIPHER_WEP_104:
4035                         pval |= WEP_ENABLED;
4036                         break;
4037                 case WPA_CIPHER_TKIP:
4038                         pval |= TKIP_ENABLED;
4039                         break;
4040                 case WPA_CIPHER_AES_CCM:
4041                         pval |= AES_ENABLED;
4042                         break;
4043                 default:
4044                         bphy_err(drvr, "Invalid unicast security info\n");
4045                 }
4046                 offset++;
4047         }
4048         /* walk thru auth management suite list and pick up what we recognize */
4049         count = data[offset] + (data[offset + 1] << 8);
4050         offset += WPA_IE_SUITE_COUNT_LEN;
4051         /* Check for auth key management suite(s) */
4052         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4053                 err = -EINVAL;
4054                 bphy_err(drvr, "no auth key mgmt suite\n");
4055                 goto exit;
4056         }
4057         for (i = 0; i < count; i++) {
4058                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4059                         err = -EINVAL;
4060                         bphy_err(drvr, "ivalid OUI\n");
4061                         goto exit;
4062                 }
4063                 offset += TLV_OUI_LEN;
4064                 switch (data[offset]) {
4065                 case RSN_AKM_NONE:
4066                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
4067                         wpa_auth |= WPA_AUTH_NONE;
4068                         break;
4069                 case RSN_AKM_UNSPECIFIED:
4070                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
4071                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
4072                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
4073                         break;
4074                 case RSN_AKM_PSK:
4075                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
4076                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
4077                                     (wpa_auth |= WPA_AUTH_PSK);
4078                         break;
4079                 case RSN_AKM_SHA256_PSK:
4080                         brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4081                         wpa_auth |= WPA2_AUTH_PSK_SHA256;
4082                         break;
4083                 case RSN_AKM_SHA256_1X:
4084                         brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4085                         wpa_auth |= WPA2_AUTH_1X_SHA256;
4086                         break;
4087                 default:
4088                         bphy_err(drvr, "Invalid key mgmt info\n");
4089                 }
4090                 offset++;
4091         }
4092 
4093         mfp = BRCMF_MFP_NONE;
4094         if (is_rsn_ie) {
4095                 wme_bss_disable = 1;
4096                 if ((offset + RSN_CAP_LEN) <= len) {
4097                         rsn_cap = data[offset] + (data[offset + 1] << 8);
4098                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4099                                 wme_bss_disable = 0;
4100                         if (rsn_cap & RSN_CAP_MFPR_MASK) {
4101                                 brcmf_dbg(TRACE, "MFP Required\n");
4102                                 mfp = BRCMF_MFP_REQUIRED;
4103                                 /* Firmware only supports mfp required in
4104                                  * combination with WPA2_AUTH_PSK_SHA256 or
4105                                  * WPA2_AUTH_1X_SHA256.
4106                                  */
4107                                 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4108                                                   WPA2_AUTH_1X_SHA256))) {
4109                                         err = -EINVAL;
4110                                         goto exit;
4111                                 }
4112                                 /* Firmware has requirement that WPA2_AUTH_PSK/
4113                                  * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4114                                  * is to be included in the rsn ie.
4115                                  */
4116                                 if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4117                                         wpa_auth |= WPA2_AUTH_PSK;
4118                                 else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4119                                         wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4120                         } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4121                                 brcmf_dbg(TRACE, "MFP Capable\n");
4122                                 mfp = BRCMF_MFP_CAPABLE;
4123                         }
4124                 }
4125                 offset += RSN_CAP_LEN;
4126                 /* set wme_bss_disable to sync RSN Capabilities */
4127                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4128                                                wme_bss_disable);
4129                 if (err < 0) {
4130                         bphy_err(drvr, "wme_bss_disable error %d\n", err);
4131                         goto exit;
4132                 }
4133 
4134                 /* Skip PMKID cnt as it is know to be 0 for AP. */
4135                 offset += RSN_PMKID_COUNT_LEN;
4136 
4137                 /* See if there is BIP wpa suite left for MFP */
4138                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4139                     ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4140                         err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4141                                                         &data[offset],
4142                                                         WPA_IE_MIN_OUI_LEN);
4143                         if (err < 0) {
4144                                 bphy_err(drvr, "bip error %d\n", err);
4145                                 goto exit;
4146                         }
4147                 }
4148         }
4149         /* FOR WPS , set SES_OW_ENABLED */
4150         wsec = (pval | gval | SES_OW_ENABLED);
4151 
4152         /* set auth */
4153         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4154         if (err < 0) {
4155                 bphy_err(drvr, "auth error %d\n", err);
4156                 goto exit;
4157         }
4158         /* set wsec */
4159         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4160         if (err < 0) {
4161                 bphy_err(drvr, "wsec error %d\n", err);
4162                 goto exit;
4163         }
4164         /* Configure MFP, this needs to go after wsec otherwise the wsec command
4165          * will overwrite the values set by MFP
4166          */
4167         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4168                 err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4169                 if (err < 0) {
4170                         bphy_err(drvr, "mfp error %d\n", err);
4171                         goto exit;
4172                 }
4173         }
4174         /* set upper-layer auth */
4175         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4176         if (err < 0) {
4177                 bphy_err(drvr, "wpa_auth error %d\n", err);
4178                 goto exit;
4179         }
4180 
4181 exit:
4182         return err;
4183 }
4184 
4185 static s32
4186 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4187                      struct parsed_vndr_ies *vndr_ies)
4188 {
4189         struct brcmf_vs_tlv *vndrie;
4190         struct brcmf_tlv *ie;
4191         struct parsed_vndr_ie_info *parsed_info;
4192         s32 remaining_len;
4193 
4194         remaining_len = (s32)vndr_ie_len;
4195         memset(vndr_ies, 0, sizeof(*vndr_ies));
4196 
4197         ie = (struct brcmf_tlv *)vndr_ie_buf;
4198         while (ie) {
4199                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4200                         goto next;
4201                 vndrie = (struct brcmf_vs_tlv *)ie;
4202                 /* len should be bigger than OUI length + one */
4203                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4204                         brcmf_err("invalid vndr ie. length is too small %d\n",
4205                                   vndrie->len);
4206                         goto next;
4207                 }
4208                 /* if wpa or wme ie, do not add ie */
4209                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4210                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
4211                     (vndrie->oui_type == WME_OUI_TYPE))) {
4212                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4213                         goto next;
4214                 }
4215 
4216                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4217 
4218                 /* save vndr ie information */
4219                 parsed_info->ie_ptr = (char *)vndrie;
4220                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4221                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4222 
4223                 vndr_ies->count++;
4224 
4225                 brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n",
4226                           parsed_info->vndrie.oui,
4227                           parsed_info->vndrie.oui_type);
4228 
4229                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4230                         break;
4231 next:
4232                 remaining_len -= (ie->len + TLV_HDR_LEN);
4233                 if (remaining_len <= TLV_HDR_LEN)
4234                         ie = NULL;
4235                 else
4236                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4237                                 TLV_HDR_LEN);
4238         }
4239         return 0;
4240 }
4241 
4242 static u32
4243 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4244 {
4245         strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN);
4246 
4247         put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4248 
4249         put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4250 
4251         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4252 
4253         return ie_len + VNDR_IE_HDR_SIZE;
4254 }
4255 
4256 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4257                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
4258 {
4259         struct brcmf_pub *drvr;
4260         struct brcmf_if *ifp;
4261         struct vif_saved_ie *saved_ie;
4262         s32 err = 0;
4263         u8  *iovar_ie_buf;
4264         u8  *curr_ie_buf;
4265         u8  *mgmt_ie_buf = NULL;
4266         int mgmt_ie_buf_len;
4267         u32 *mgmt_ie_len;
4268         u32 del_add_ie_buf_len = 0;
4269         u32 total_ie_buf_len = 0;
4270         u32 parsed_ie_buf_len = 0;
4271         struct parsed_vndr_ies old_vndr_ies;
4272         struct parsed_vndr_ies new_vndr_ies;
4273         struct parsed_vndr_ie_info *vndrie_info;
4274         s32 i;
4275         u8 *ptr;
4276         int remained_buf_len;
4277 
4278         if (!vif)
4279                 return -ENODEV;
4280         ifp = vif->ifp;
4281         drvr = ifp->drvr;
4282         saved_ie = &vif->saved_ie;
4283 
4284         brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4285                   pktflag);
4286         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4287         if (!iovar_ie_buf)
4288                 return -ENOMEM;
4289         curr_ie_buf = iovar_ie_buf;
4290         switch (pktflag) {
4291         case BRCMF_VNDR_IE_PRBREQ_FLAG:
4292                 mgmt_ie_buf = saved_ie->probe_req_ie;
4293                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4294                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4295                 break;
4296         case BRCMF_VNDR_IE_PRBRSP_FLAG:
4297                 mgmt_ie_buf = saved_ie->probe_res_ie;
4298                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4299                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4300                 break;
4301         case BRCMF_VNDR_IE_BEACON_FLAG:
4302                 mgmt_ie_buf = saved_ie->beacon_ie;
4303                 mgmt_ie_len = &saved_ie->beacon_ie_len;
4304                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4305                 break;
4306         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4307                 mgmt_ie_buf = saved_ie->assoc_req_ie;
4308                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4309                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4310                 break;
4311         default:
4312                 err = -EPERM;
4313                 bphy_err(drvr, "not suitable type\n");
4314                 goto exit;
4315         }
4316 
4317         if (vndr_ie_len > mgmt_ie_buf_len) {
4318                 err = -ENOMEM;
4319                 bphy_err(drvr, "extra IE size too big\n");
4320                 goto exit;
4321         }
4322 
4323         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4324         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4325                 ptr = curr_ie_buf;
4326                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4327                 for (i = 0; i < new_vndr_ies.count; i++) {
4328                         vndrie_info = &new_vndr_ies.ie_info[i];
4329                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4330                                vndrie_info->ie_len);
4331                         parsed_ie_buf_len += vndrie_info->ie_len;
4332                 }
4333         }
4334 
4335         if (mgmt_ie_buf && *mgmt_ie_len) {
4336                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4337                     (memcmp(mgmt_ie_buf, curr_ie_buf,
4338                             parsed_ie_buf_len) == 0)) {
4339                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4340                         goto exit;
4341                 }
4342 
4343                 /* parse old vndr_ie */
4344                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4345 
4346                 /* make a command to delete old ie */
4347                 for (i = 0; i < old_vndr_ies.count; i++) {
4348                         vndrie_info = &old_vndr_ies.ie_info[i];
4349 
4350                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n",
4351                                   vndrie_info->vndrie.id,
4352                                   vndrie_info->vndrie.len,
4353                                   vndrie_info->vndrie.oui);
4354 
4355                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4356                                                            vndrie_info->ie_ptr,
4357                                                            vndrie_info->ie_len,
4358                                                            "del");
4359                         curr_ie_buf += del_add_ie_buf_len;
4360                         total_ie_buf_len += del_add_ie_buf_len;
4361                 }
4362         }
4363 
4364         *mgmt_ie_len = 0;
4365         /* Add if there is any extra IE */
4366         if (mgmt_ie_buf && parsed_ie_buf_len) {
4367                 ptr = mgmt_ie_buf;
4368 
4369                 remained_buf_len = mgmt_ie_buf_len;
4370 
4371                 /* make a command to add new ie */
4372                 for (i = 0; i < new_vndr_ies.count; i++) {
4373                         vndrie_info = &new_vndr_ies.ie_info[i];
4374 
4375                         /* verify remained buf size before copy data */
4376                         if (remained_buf_len < (vndrie_info->vndrie.len +
4377                                                         VNDR_IE_VSIE_OFFSET)) {
4378                                 bphy_err(drvr, "no space in mgmt_ie_buf: len left %d",
4379                                          remained_buf_len);
4380                                 break;
4381                         }
4382                         remained_buf_len -= (vndrie_info->ie_len +
4383                                              VNDR_IE_VSIE_OFFSET);
4384 
4385                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n",
4386                                   vndrie_info->vndrie.id,
4387                                   vndrie_info->vndrie.len,
4388                                   vndrie_info->vndrie.oui);
4389 
4390                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4391                                                            vndrie_info->ie_ptr,
4392                                                            vndrie_info->ie_len,
4393                                                            "add");
4394 
4395                         /* save the parsed IE in wl struct */
4396                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4397                                vndrie_info->ie_len);
4398                         *mgmt_ie_len += vndrie_info->ie_len;
4399 
4400                         curr_ie_buf += del_add_ie_buf_len;
4401                         total_ie_buf_len += del_add_ie_buf_len;
4402                 }
4403         }
4404         if (total_ie_buf_len) {
4405                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4406                                                  total_ie_buf_len);
4407                 if (err)
4408                         bphy_err(drvr, "vndr ie set error : %d\n", err);
4409         }
4410 
4411 exit:
4412         kfree(iovar_ie_buf);
4413         return err;
4414 }
4415 
4416 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4417 {
4418         s32 pktflags[] = {
4419                 BRCMF_VNDR_IE_PRBREQ_FLAG,
4420                 BRCMF_VNDR_IE_PRBRSP_FLAG,
4421                 BRCMF_VNDR_IE_BEACON_FLAG
4422         };
4423         int i;
4424 
4425         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4426                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4427 
4428         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4429         return 0;
4430 }
4431 
4432 static s32
4433 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4434                         struct cfg80211_beacon_data *beacon)
4435 {
4436         struct brcmf_pub *drvr = vif->ifp->drvr;
4437         s32 err;
4438 
4439         /* Set Beacon IEs to FW */
4440         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4441                                     beacon->tail, beacon->tail_len);
4442         if (err) {
4443                 bphy_err(drvr, "Set Beacon IE Failed\n");
4444                 return err;
4445         }
4446         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4447 
4448         /* Set Probe Response IEs to FW */
4449         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4450                                     beacon->proberesp_ies,
4451                                     beacon->proberesp_ies_len);
4452         if (err)
4453                 bphy_err(drvr, "Set Probe Resp IE Failed\n");
4454         else
4455                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4456 
4457         return err;
4458 }
4459 
4460 static s32
4461 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4462                         struct cfg80211_ap_settings *settings)
4463 {
4464         s32 ie_offset;
4465         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4466         struct brcmf_if *ifp = netdev_priv(ndev);
4467         struct brcmf_pub *drvr = cfg->pub;
4468         const struct brcmf_tlv *ssid_ie;
4469         const struct brcmf_tlv *country_ie;
4470         struct brcmf_ssid_le ssid_le;
4471         s32 err = -EPERM;
4472         const struct brcmf_tlv *rsn_ie;
4473         const struct brcmf_vs_tlv *wpa_ie;
4474         struct brcmf_join_params join_params;
4475         enum nl80211_iftype dev_role;
4476         struct brcmf_fil_bss_enable_le bss_enable;
4477         u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
4478         bool mbss;
4479         int is_11d;
4480         bool supports_11d;
4481 
4482         brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4483                   settings->chandef.chan->hw_value,
4484                   settings->chandef.center_freq1, settings->chandef.width,
4485                   settings->beacon_interval, settings->dtim_period);
4486         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4487                   settings->ssid, settings->ssid_len, settings->auth_type,
4488                   settings->inactivity_timeout);
4489         dev_role = ifp->vif->wdev.iftype;
4490         mbss = ifp->vif->mbss;
4491 
4492         /* store current 11d setting */
4493         if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
4494                                   &ifp->vif->is_11d)) {
4495                 is_11d = supports_11d = false;
4496         } else {
4497                 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4498                                               settings->beacon.tail_len,
4499                                               WLAN_EID_COUNTRY);
4500                 is_11d = country_ie ? 1 : 0;
4501                 supports_11d = true;
4502         }
4503 
4504         memset(&ssid_le, 0, sizeof(ssid_le));
4505         if (settings->ssid == NULL || settings->ssid_len == 0) {
4506                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4507                 ssid_ie = brcmf_parse_tlvs(
4508                                 (u8 *)&settings->beacon.head[ie_offset],
4509                                 settings->beacon.head_len - ie_offset,
4510                                 WLAN_EID_SSID);
4511                 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4512                         return -EINVAL;
4513 
4514                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4515                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4516                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4517         } else {
4518                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4519                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4520         }
4521 
4522         if (!mbss) {
4523                 brcmf_set_mpc(ifp, 0);
4524                 brcmf_configure_arp_nd_offload(ifp, false);
4525         }
4526 
4527         /* find the RSN_IE */
4528         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4529                                   settings->beacon.tail_len, WLAN_EID_RSN);
4530 
4531         /* find the WPA_IE */
4532         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4533                                   settings->beacon.tail_len);
4534 
4535         if ((wpa_ie != NULL || rsn_ie != NULL)) {
4536                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4537                 if (wpa_ie != NULL) {
4538                         /* WPA IE */
4539                         err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4540                         if (err < 0)
4541                                 goto exit;
4542                 } else {
4543                         struct brcmf_vs_tlv *tmp_ie;
4544 
4545                         tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4546 
4547                         /* RSN IE */
4548                         err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4549                         if (err < 0)
4550                                 goto exit;
4551                 }
4552         } else {
4553                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4554                 brcmf_configure_opensecurity(ifp);
4555         }
4556 
4557         /* Parameters shared by all radio interfaces */
4558         if (!mbss) {
4559                 if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
4560                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4561                                                     is_11d);
4562                         if (err < 0) {
4563                                 bphy_err(drvr, "Regulatory Set Error, %d\n",
4564                                          err);
4565                                 goto exit;
4566                         }
4567                 }
4568                 if (settings->beacon_interval) {
4569                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4570                                                     settings->beacon_interval);
4571                         if (err < 0) {
4572                                 bphy_err(drvr, "Beacon Interval Set Error, %d\n",
4573                                          err);
4574                                 goto exit;
4575                         }
4576                 }
4577                 if (settings->dtim_period) {
4578                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4579                                                     settings->dtim_period);
4580                         if (err < 0) {
4581                                 bphy_err(drvr, "DTIM Interval Set Error, %d\n",
4582                                          err);
4583                                 goto exit;
4584                         }
4585                 }
4586 
4587                 if ((dev_role == NL80211_IFTYPE_AP) &&
4588                     ((ifp->ifidx == 0) ||
4589                      !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
4590                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4591                         if (err < 0) {
4592                                 bphy_err(drvr, "BRCMF_C_DOWN error %d\n",
4593                                          err);
4594                                 goto exit;
4595                         }
4596                         brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4597                 }
4598 
4599                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4600                 if (err < 0) {
4601                         bphy_err(drvr, "SET INFRA error %d\n", err);
4602                         goto exit;
4603                 }
4604         } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
4605                 /* Multiple-BSS should use same 11d configuration */
4606                 err = -EINVAL;
4607                 goto exit;
4608         }
4609 
4610         /* Interface specific setup */
4611         if (dev_role == NL80211_IFTYPE_AP) {
4612                 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4613                         brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4614 
4615                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4616                 if (err < 0) {
4617                         bphy_err(drvr, "setting AP mode failed %d\n",
4618                                  err);
4619                         goto exit;
4620                 }
4621                 if (!mbss) {
4622                         /* Firmware 10.x requires setting channel after enabling
4623                          * AP and before bringing interface up.
4624                          */
4625                         err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4626                         if (err < 0) {
4627                                 bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
4628                                          chanspec, err);
4629                                 goto exit;
4630                         }
4631                 }
4632                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4633                 if (err < 0) {
4634                         bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
4635                         goto exit;
4636                 }
4637                 /* On DOWN the firmware removes the WEP keys, reconfigure
4638                  * them if they were set.
4639                  */
4640                 brcmf_cfg80211_reconfigure_wep(ifp);
4641 
4642                 memset(&join_params, 0, sizeof(join_params));
4643                 /* join parameters starts with ssid */
4644                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4645                 /* create softap */
4646                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4647                                              &join_params, sizeof(join_params));
4648                 if (err < 0) {
4649                         bphy_err(drvr, "SET SSID error (%d)\n", err);
4650                         goto exit;
4651                 }
4652 
4653                 if (settings->hidden_ssid) {
4654                         err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
4655                         if (err) {
4656                                 bphy_err(drvr, "closednet error (%d)\n", err);
4657                                 goto exit;
4658                         }
4659                 }
4660 
4661                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4662         } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
4663                 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4664                 if (err < 0) {
4665                         bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
4666                                  chanspec, err);
4667                         goto exit;
4668                 }
4669                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4670                                                 sizeof(ssid_le));
4671                 if (err < 0) {
4672                         bphy_err(drvr, "setting ssid failed %d\n", err);
4673                         goto exit;
4674                 }
4675                 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4676                 bss_enable.enable = cpu_to_le32(1);
4677                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4678                                                sizeof(bss_enable));
4679                 if (err < 0) {
4680                         bphy_err(drvr, "bss_enable config failed %d\n", err);
4681                         goto exit;
4682                 }
4683 
4684                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4685         } else {
4686                 WARN_ON(1);
4687         }
4688 
4689         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4690         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4691         brcmf_net_setcarrier(ifp, true);
4692 
4693 exit:
4694         if ((err) && (!mbss)) {
4695                 brcmf_set_mpc(ifp, 1);
4696                 brcmf_configure_arp_nd_offload(ifp, true);
4697         }
4698         return err;
4699 }
4700 
4701 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4702 {
4703         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4704         struct brcmf_if *ifp = netdev_priv(ndev);
4705         struct brcmf_pub *drvr = cfg->pub;
4706         s32 err;
4707         struct brcmf_fil_bss_enable_le bss_enable;
4708         struct brcmf_join_params join_params;
4709 
4710         brcmf_dbg(TRACE, "Enter\n");
4711 
4712         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4713                 /* Due to most likely deauths outstanding we sleep */
4714                 /* first to make sure they get processed by fw. */
4715                 msleep(400);
4716 
4717                 if (ifp->vif->mbss) {
4718                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4719                         return err;
4720                 }
4721 
4722                 /* First BSS doesn't get a full reset */
4723                 if (ifp->bsscfgidx == 0)
4724                         brcmf_fil_iovar_int_set(ifp, "closednet", 0);
4725 
4726                 memset(&join_params, 0, sizeof(join_params));
4727                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4728                                              &join_params, sizeof(join_params));
4729                 if (err < 0)
4730                         bphy_err(drvr, "SET SSID error (%d)\n", err);
4731                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4732                 if (err < 0)
4733                         bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
4734                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4735                 if (err < 0)
4736                         bphy_err(drvr, "setting AP mode failed %d\n", err);
4737                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4738                         brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4739                 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4740                                       ifp->vif->is_11d);
4741                 /* Bring device back up so it can be used again */
4742                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4743                 if (err < 0)
4744                         bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
4745 
4746                 brcmf_vif_clear_mgmt_ies(ifp->vif);
4747         } else {
4748                 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4749                 bss_enable.enable = cpu_to_le32(0);
4750                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4751                                                sizeof(bss_enable));
4752                 if (err < 0)
4753                         bphy_err(drvr, "bss_enable config failed %d\n", err);
4754         }
4755         brcmf_set_mpc(ifp, 1);
4756         brcmf_configure_arp_nd_offload(ifp, true);
4757         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4758         brcmf_net_setcarrier(ifp, false);
4759 
4760         return err;
4761 }
4762 
4763 static s32
4764 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4765                              struct cfg80211_beacon_data *info)
4766 {
4767         struct brcmf_if *ifp = netdev_priv(ndev);
4768         s32 err;
4769 
4770         brcmf_dbg(TRACE, "Enter\n");
4771 
4772         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4773 
4774         return err;
4775 }
4776 
4777 static int
4778 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4779                            struct station_del_parameters *params)
4780 {
4781         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4782         struct brcmf_pub *drvr = cfg->pub;
4783         struct brcmf_scb_val_le scbval;
4784         struct brcmf_if *ifp = netdev_priv(ndev);
4785         s32 err;
4786 
4787         if (!params->mac)
4788                 return -EFAULT;
4789 
4790         brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4791 
4792         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4793                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4794         if (!check_vif_up(ifp->vif))
4795                 return -EIO;
4796 
4797         memcpy(&scbval.ea, params->mac, ETH_ALEN);
4798         scbval.val = cpu_to_le32(params->reason_code);
4799         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4800                                      &scbval, sizeof(scbval));
4801         if (err)
4802                 bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
4803                          err);
4804 
4805         brcmf_dbg(TRACE, "Exit\n");
4806         return err;
4807 }
4808 
4809 static int
4810 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4811                               const u8 *mac, struct station_parameters *params)
4812 {
4813         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4814         struct brcmf_pub *drvr = cfg->pub;
4815         struct brcmf_if *ifp = netdev_priv(ndev);
4816         s32 err;
4817 
4818         brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4819                   params->sta_flags_mask, params->sta_flags_set);
4820 
4821         /* Ignore all 00 MAC */
4822         if (is_zero_ether_addr(mac))
4823                 return 0;
4824 
4825         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4826                 return 0;
4827 
4828         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4829                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4830                                              (void *)mac, ETH_ALEN);
4831         else
4832                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4833                                              (void *)mac, ETH_ALEN);
4834         if (err < 0)
4835                 bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
4836 
4837         return err;
4838 }
4839 
4840 static void
4841 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4842                                    struct wireless_dev *wdev,
4843                                    u16 frame_type, bool reg)
4844 {
4845         struct brcmf_cfg80211_vif *vif;
4846         u16 mgmt_type;
4847 
4848         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4849 
4850         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4851         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4852         if (reg)
4853                 vif->mgmt_rx_reg |= BIT(mgmt_type);
4854         else
4855                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4856 }
4857 
4858 
4859 static int
4860 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4861                        struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4862 {
4863         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4864         struct ieee80211_channel *chan = params->chan;
4865         struct brcmf_pub *drvr = cfg->pub;
4866         const u8 *buf = params->buf;
4867         size_t len = params->len;
4868         const struct ieee80211_mgmt *mgmt;
4869         struct brcmf_cfg80211_vif *vif;
4870         s32 err = 0;
4871         s32 ie_offset;
4872         s32 ie_len;
4873         struct brcmf_fil_action_frame_le *action_frame;
4874         struct brcmf_fil_af_params_le *af_params;
4875         bool ack;
4876         s32 chan_nr;
4877         u32 freq;
4878 
4879         brcmf_dbg(TRACE, "Enter\n");
4880 
4881         *cookie = 0;
4882 
4883         mgmt = (const struct ieee80211_mgmt *)buf;
4884 
4885         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4886                 bphy_err(drvr, "Driver only allows MGMT packet type\n");
4887                 return -EPERM;
4888         }
4889 
4890         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4891 
4892         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4893                 /* Right now the only reason to get a probe response */
4894                 /* is for p2p listen response or for p2p GO from     */
4895                 /* wpa_supplicant. Unfortunately the probe is send   */
4896                 /* on primary ndev, while dongle wants it on the p2p */
4897                 /* vif. Since this is only reason for a probe        */
4898                 /* response to be sent, the vif is taken from cfg.   */
4899                 /* If ever desired to send proberesp for non p2p     */
4900                 /* response then data should be checked for          */
4901                 /* "DIRECT-". Note in future supplicant will take    */
4902                 /* dedicated p2p wdev to do this and then this 'hack'*/
4903                 /* is not needed anymore.                            */
4904                 ie_offset =  DOT11_MGMT_HDR_LEN +
4905                              DOT11_BCN_PRB_FIXED_LEN;
4906                 ie_len = len - ie_offset;
4907                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4908                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4909                 err = brcmf_vif_set_mgmt_ie(vif,
4910                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
4911                                             &buf[ie_offset],
4912                                             ie_len);
4913                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4914                                         GFP_KERNEL);
4915         } else if (ieee80211_is_action(mgmt->frame_control)) {
4916                 if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
4917                         bphy_err(drvr, "invalid action frame length\n");
4918                         err = -EINVAL;
4919                         goto exit;
4920                 }
4921                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4922                 if (af_params == NULL) {
4923                         bphy_err(drvr, "unable to allocate frame\n");
4924                         err = -ENOMEM;
4925                         goto exit;
4926                 }
4927                 action_frame = &af_params->action_frame;
4928                 /* Add the packet Id */
4929                 action_frame->packet_id = cpu_to_le32(*cookie);
4930                 /* Add BSSID */
4931                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4932                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4933                 /* Add the length exepted for 802.11 header  */
4934                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4935                 /* Add the channel. Use the one specified as parameter if any or
4936                  * the current one (got from the firmware) otherwise
4937                  */
4938                 if (chan)
4939                         freq = chan->center_freq;
4940                 else
4941                         brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4942                                               &freq);
4943                 chan_nr = ieee80211_frequency_to_channel(freq);
4944                 af_params->channel = cpu_to_le32(chan_nr);
4945 
4946                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4947                        le16_to_cpu(action_frame->len));
4948 
4949                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4950                           *cookie, le16_to_cpu(action_frame->len), freq);
4951 
4952                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4953                                                   af_params);
4954 
4955                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4956                                         GFP_KERNEL);
4957                 kfree(af_params);
4958         } else {
4959                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4960                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
4961         }
4962 
4963 exit:
4964         return err;
4965 }
4966 
4967 
4968 static int
4969 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4970                                         struct wireless_dev *wdev,
4971                                         u64 cookie)
4972 {
4973         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4974         struct brcmf_pub *drvr = cfg->pub;
4975         struct brcmf_cfg80211_vif *vif;
4976         int err = 0;
4977 
4978         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4979 
4980         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4981         if (vif == NULL) {
4982                 bphy_err(drvr, "No p2p device available for probe response\n");
4983                 err = -ENODEV;
4984                 goto exit;
4985         }
4986         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4987 exit:
4988         return err;
4989 }
4990 
4991 static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
4992                                       struct wireless_dev *wdev,
4993                                       struct cfg80211_chan_def *chandef)
4994 {
4995         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4996         struct net_device *ndev = wdev->netdev;
4997         struct brcmf_pub *drvr = cfg->pub;
4998         struct brcmu_chan ch;
4999         enum nl80211_band band = 0;
5000         enum nl80211_chan_width width = 0;
5001         u32 chanspec;
5002         int freq, err;
5003 
5004         if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP)
5005                 return -ENODEV;
5006 
5007         err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec);
5008         if (err) {
5009                 bphy_err(drvr, "chanspec failed (%d)\n", err);
5010                 return err;
5011         }
5012 
5013         ch.chspec = chanspec;
5014         cfg->d11inf.decchspec(&ch);
5015 
5016         switch (ch.band) {
5017         case BRCMU_CHAN_BAND_2G:
5018                 band = NL80211_BAND_2GHZ;
5019                 break;
5020         case BRCMU_CHAN_BAND_5G:
5021                 band = NL80211_BAND_5GHZ;
5022                 break;
5023         }
5024 
5025         switch (ch.bw) {
5026         case BRCMU_CHAN_BW_80:
5027                 width = NL80211_CHAN_WIDTH_80;
5028                 break;
5029         case BRCMU_CHAN_BW_40:
5030                 width = NL80211_CHAN_WIDTH_40;
5031                 break;
5032         case BRCMU_CHAN_BW_20:
5033                 width = NL80211_CHAN_WIDTH_20;
5034                 break;
5035         case BRCMU_CHAN_BW_80P80:
5036                 width = NL80211_CHAN_WIDTH_80P80;
5037                 break;
5038         case BRCMU_CHAN_BW_160:
5039                 width = NL80211_CHAN_WIDTH_160;
5040                 break;
5041         }
5042 
5043         freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
5044         chandef->chan = ieee80211_get_channel(wiphy, freq);
5045         chandef->width = width;
5046         chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
5047         chandef->center_freq2 = 0;
5048 
5049         return 0;
5050 }
5051 
5052 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
5053                                            struct wireless_dev *wdev,
5054                                            enum nl80211_crit_proto_id proto,
5055                                            u16 duration)
5056 {
5057         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5058         struct brcmf_cfg80211_vif *vif;
5059 
5060         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5061 
5062         /* only DHCP support for now */
5063         if (proto != NL80211_CRIT_PROTO_DHCP)
5064                 return -EINVAL;
5065 
5066         /* suppress and abort scanning */
5067         set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5068         brcmf_abort_scanning(cfg);
5069 
5070         return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
5071 }
5072 
5073 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
5074                                            struct wireless_dev *wdev)
5075 {
5076         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5077         struct brcmf_cfg80211_vif *vif;
5078 
5079         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5080 
5081         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
5082         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5083 }
5084 
5085 static s32
5086 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
5087                              const struct brcmf_event_msg *e, void *data)
5088 {
5089         switch (e->reason) {
5090         case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5091                 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5092                 break;
5093         case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5094                 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5095                 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5096                 break;
5097         case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5098                 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5099                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5100                 break;
5101         }
5102 
5103         return 0;
5104 }
5105 
5106 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5107 {
5108         int ret;
5109 
5110         switch (oper) {
5111         case NL80211_TDLS_DISCOVERY_REQ:
5112                 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5113                 break;
5114         case NL80211_TDLS_SETUP:
5115                 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5116                 break;
5117         case NL80211_TDLS_TEARDOWN:
5118                 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5119                 break;
5120         default:
5121                 brcmf_err("unsupported operation: %d\n", oper);
5122                 ret = -EOPNOTSUPP;
5123         }
5124         return ret;
5125 }
5126 
5127 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5128                                     struct net_device *ndev, const u8 *peer,
5129                                     enum nl80211_tdls_operation oper)
5130 {
5131         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5132         struct brcmf_pub *drvr = cfg->pub;
5133         struct brcmf_if *ifp;
5134         struct brcmf_tdls_iovar_le info;
5135         int ret = 0;
5136 
5137         ret = brcmf_convert_nl80211_tdls_oper(oper);
5138         if (ret < 0)
5139                 return ret;
5140 
5141         ifp = netdev_priv(ndev);
5142         memset(&info, 0, sizeof(info));
5143         info.mode = (u8)ret;
5144         if (peer)
5145                 memcpy(info.ea, peer, ETH_ALEN);
5146 
5147         ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5148                                        &info, sizeof(info));
5149         if (ret < 0)
5150                 bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
5151 
5152         return ret;
5153 }
5154 
5155 static int
5156 brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
5157                                   struct net_device *ndev,
5158                                   struct cfg80211_connect_params *sme,
5159                                   u32 changed)
5160 {
5161         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5162         struct brcmf_pub *drvr = cfg->pub;
5163         struct brcmf_if *ifp;
5164         int err;
5165 
5166         if (!(changed & UPDATE_ASSOC_IES))
5167                 return 0;
5168 
5169         ifp = netdev_priv(ndev);
5170         err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
5171                                     sme->ie, sme->ie_len);
5172         if (err)
5173                 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
5174         else
5175                 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
5176 
5177         return err;
5178 }
5179 
5180 #ifdef CONFIG_PM
5181 static int
5182 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5183                               struct cfg80211_gtk_rekey_data *gtk)
5184 {
5185         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5186         struct brcmf_pub *drvr = cfg->pub;
5187         struct brcmf_if *ifp = netdev_priv(ndev);
5188         struct brcmf_gtk_keyinfo_le gtk_le;
5189         int ret;
5190 
5191         brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5192 
5193         memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5194         memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5195         memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5196                sizeof(gtk_le.replay_counter));
5197 
5198         ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
5199                                        sizeof(gtk_le));
5200         if (ret < 0)
5201                 bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
5202 
5203         return ret;
5204 }
5205 #endif
5206 
5207 static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
5208                                   const struct cfg80211_pmk_conf *conf)
5209 {
5210         struct brcmf_if *ifp;
5211 
5212         brcmf_dbg(TRACE, "enter\n");
5213 
5214         /* expect using firmware supplicant for 1X */
5215         ifp = netdev_priv(dev);
5216         if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5217                 return -EINVAL;
5218 
5219         if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
5220                 return -ERANGE;
5221 
5222         return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
5223 }
5224 
5225 static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
5226                                   const u8 *aa)
5227 {
5228         struct brcmf_if *ifp;
5229 
5230         brcmf_dbg(TRACE, "enter\n");
5231         ifp = netdev_priv(dev);
5232         if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5233                 return -EINVAL;
5234 
5235         return brcmf_set_pmk(ifp, NULL, 0);
5236 }
5237 
5238 static struct cfg80211_ops brcmf_cfg80211_ops = {
5239         .add_virtual_intf = brcmf_cfg80211_add_iface,
5240         .del_virtual_intf = brcmf_cfg80211_del_iface,
5241         .change_virtual_intf = brcmf_cfg80211_change_iface,
5242         .scan = brcmf_cfg80211_scan,
5243         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5244         .join_ibss = brcmf_cfg80211_join_ibss,
5245         .leave_ibss = brcmf_cfg80211_leave_ibss,
5246         .get_station = brcmf_cfg80211_get_station,
5247         .dump_station = brcmf_cfg80211_dump_station,
5248         .set_tx_power = brcmf_cfg80211_set_tx_power,
5249         .get_tx_power = brcmf_cfg80211_get_tx_power,
5250         .add_key = brcmf_cfg80211_add_key,
5251         .del_key = brcmf_cfg80211_del_key,
5252         .get_key = brcmf_cfg80211_get_key,
5253         .set_default_key = brcmf_cfg80211_config_default_key,
5254         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5255         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
5256         .connect = brcmf_cfg80211_connect,
5257         .disconnect = brcmf_cfg80211_disconnect,
5258         .suspend = brcmf_cfg80211_suspend,
5259         .resume = brcmf_cfg80211_resume,
5260         .set_pmksa = brcmf_cfg80211_set_pmksa,
5261         .del_pmksa = brcmf_cfg80211_del_pmksa,
5262         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
5263         .start_ap = brcmf_cfg80211_start_ap,
5264         .stop_ap = brcmf_cfg80211_stop_ap,
5265         .change_beacon = brcmf_cfg80211_change_beacon,
5266         .del_station = brcmf_cfg80211_del_station,
5267         .change_station = brcmf_cfg80211_change_station,
5268         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
5269         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
5270         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
5271         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
5272         .remain_on_channel = brcmf_p2p_remain_on_channel,
5273         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
5274         .get_channel = brcmf_cfg80211_get_channel,
5275         .start_p2p_device = brcmf_p2p_start_device,
5276         .stop_p2p_device = brcmf_p2p_stop_device,
5277         .crit_proto_start = brcmf_cfg80211_crit_proto_start,
5278         .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
5279         .tdls_oper = brcmf_cfg80211_tdls_oper,
5280         .update_connect_params = brcmf_cfg80211_update_conn_params,
5281         .set_pmk = brcmf_cfg80211_set_pmk,
5282         .del_pmk = brcmf_cfg80211_del_pmk,
5283 };
5284 
5285 struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
5286 {
5287         struct cfg80211_ops *ops;
5288 
5289         ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
5290                        GFP_KERNEL);
5291 
5292         if (ops && settings->roamoff)
5293                 ops->update_connect_params = NULL;
5294 
5295         return ops;
5296 }
5297 
5298 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
5299                                            enum nl80211_iftype type)
5300 {
5301         struct brcmf_cfg80211_vif *vif_walk;
5302         struct brcmf_cfg80211_vif *vif;
5303         bool mbss;
5304 
5305         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
5306                   sizeof(*vif));
5307         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
5308         if (!vif)
5309                 return ERR_PTR(-ENOMEM);
5310 
5311         vif->wdev.wiphy = cfg->wiphy;
5312         vif->wdev.iftype = type;
5313 
5314         brcmf_init_prof(&vif->profile);
5315 
5316         if (type == NL80211_IFTYPE_AP) {
5317                 mbss = false;
5318                 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
5319                         if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
5320                                 mbss = true;
5321                                 break;
5322                         }
5323                 }
5324                 vif->mbss = mbss;
5325         }
5326 
5327         list_add_tail(&vif->list, &cfg->vif_list);
5328         return vif;
5329 }
5330 
5331 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
5332 {
5333         list_del(&vif->list);
5334         kfree(vif);
5335 }
5336 
5337 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
5338 {
5339         struct brcmf_cfg80211_vif *vif;
5340         struct brcmf_if *ifp;
5341 
5342         ifp = netdev_priv(ndev);
5343         vif = ifp->vif;
5344 
5345         if (vif)
5346                 brcmf_free_vif(vif);
5347 }
5348 
5349 static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
5350                             const struct brcmf_event_msg *e)
5351 {
5352         u32 event = e->event_code;
5353         u32 status = e->status;
5354 
5355         if (vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK &&
5356             event == BRCMF_E_PSK_SUP &&
5357             status == BRCMF_E_STATUS_FWSUP_COMPLETED)
5358                 set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5359         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
5360                 brcmf_dbg(CONN, "Processing set ssid\n");
5361                 memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
5362                 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK)
5363                         return true;
5364 
5365                 set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5366         }
5367 
5368         if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
5369             test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
5370                 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5371                 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5372                 return true;
5373         }
5374         return false;
5375 }
5376 
5377 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
5378 {
5379         u32 event = e->event_code;
5380         u16 flags = e->flags;
5381 
5382         if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
5383             (event == BRCMF_E_DISASSOC_IND) ||
5384             ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
5385                 brcmf_dbg(CONN, "Processing link down\n");
5386                 return true;
5387         }
5388         return false;
5389 }
5390 
5391 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
5392                                const struct brcmf_event_msg *e)
5393 {
5394         u32 event = e->event_code;
5395         u32 status = e->status;
5396 
5397         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
5398                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
5399                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
5400                 return true;
5401         }
5402 
5403         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
5404                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
5405                 return true;
5406         }
5407 
5408         if (event == BRCMF_E_PSK_SUP &&
5409             status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
5410                 brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
5411                           status);
5412                 return true;
5413         }
5414 
5415         return false;
5416 }
5417 
5418 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
5419 {
5420         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5421 
5422         kfree(conn_info->req_ie);
5423         conn_info->req_ie = NULL;
5424         conn_info->req_ie_len = 0;
5425         kfree(conn_info->resp_ie);
5426         conn_info->resp_ie = NULL;
5427         conn_info->resp_ie_len = 0;
5428 }
5429 
5430 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
5431                                struct brcmf_if *ifp)
5432 {
5433         struct brcmf_pub *drvr = cfg->pub;
5434         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
5435         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5436         u32 req_len;
5437         u32 resp_len;
5438         s32 err = 0;
5439 
5440         brcmf_clear_assoc_ies(cfg);
5441 
5442         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5443                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
5444         if (err) {
5445                 bphy_err(drvr, "could not get assoc info (%d)\n", err);
5446                 return err;
5447         }
5448         assoc_info =
5449                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5450         req_len = le32_to_cpu(assoc_info->req_len);
5451         resp_len = le32_to_cpu(assoc_info->resp_len);
5452         if (req_len) {
5453                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5454                                                cfg->extra_buf,
5455                                                WL_ASSOC_INFO_MAX);
5456                 if (err) {
5457                         bphy_err(drvr, "could not get assoc req (%d)\n", err);
5458                         return err;
5459                 }
5460                 conn_info->req_ie_len = req_len;
5461                 conn_info->req_ie =
5462                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5463                             GFP_KERNEL);
5464                 if (!conn_info->req_ie)
5465                         conn_info->req_ie_len = 0;
5466         } else {
5467                 conn_info->req_ie_len = 0;
5468                 conn_info->req_ie = NULL;
5469         }
5470         if (resp_len) {
5471                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5472                                                cfg->extra_buf,
5473                                                WL_ASSOC_INFO_MAX);
5474                 if (err) {
5475                         bphy_err(drvr, "could not get assoc resp (%d)\n", err);
5476                         return err;
5477                 }
5478                 conn_info->resp_ie_len = resp_len;
5479                 conn_info->resp_ie =
5480                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5481                             GFP_KERNEL);
5482                 if (!conn_info->resp_ie)
5483                         conn_info->resp_ie_len = 0;
5484         } else {
5485                 conn_info->resp_ie_len = 0;
5486                 conn_info->resp_ie = NULL;
5487         }
5488         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5489                   conn_info->req_ie_len, conn_info->resp_ie_len);
5490 
5491         return err;
5492 }
5493 
5494 static s32
5495 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5496                        struct net_device *ndev,
5497                        const struct brcmf_event_msg *e)
5498 {
5499         struct brcmf_if *ifp = netdev_priv(ndev);
5500         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5501         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5502         struct wiphy *wiphy = cfg_to_wiphy(cfg);
5503         struct ieee80211_channel *notify_channel = NULL;
5504         struct ieee80211_supported_band *band;
5505         struct brcmf_bss_info_le *bi;
5506         struct brcmu_chan ch;
5507         struct cfg80211_roam_info roam_info = {};
5508         u32 freq;
5509         s32 err = 0;
5510         u8 *buf;
5511 
5512         brcmf_dbg(TRACE, "Enter\n");
5513 
5514         brcmf_get_assoc_ies(cfg, ifp);
5515         memcpy(profile->bssid, e->addr, ETH_ALEN);
5516         brcmf_update_bss_info(cfg, ifp);
5517 
5518         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5519         if (buf == NULL) {
5520                 err = -ENOMEM;
5521                 goto done;
5522         }
5523 
5524         /* data sent to dongle has to be little endian */
5525         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5526         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
5527                                      buf, WL_BSS_INFO_MAX);
5528 
5529         if (err)
5530                 goto done;
5531 
5532         bi = (struct brcmf_bss_info_le *)(buf + 4);
5533         ch.chspec = le16_to_cpu(bi->chanspec);
5534         cfg->d11inf.decchspec(&ch);
5535 
5536         if (ch.band == BRCMU_CHAN_BAND_2G)
5537                 band = wiphy->bands[NL80211_BAND_2GHZ];
5538         else
5539                 band = wiphy->bands[NL80211_BAND_5GHZ];
5540 
5541         freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
5542         notify_channel = ieee80211_get_channel(wiphy, freq);
5543 
5544 done:
5545         kfree(buf);
5546 
5547         roam_info.channel = notify_channel;
5548         roam_info.bssid = profile->bssid;
5549         roam_info.req_ie = conn_info->req_ie;
5550         roam_info.req_ie_len = conn_info->req_ie_len;
5551         roam_info.resp_ie = conn_info->resp_ie;
5552         roam_info.resp_ie_len = conn_info->resp_ie_len;
5553 
5554         cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
5555         brcmf_dbg(CONN, "Report roaming result\n");
5556 
5557         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
5558         brcmf_dbg(TRACE, "Exit\n");
5559         return err;
5560 }
5561 
5562 static s32
5563 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
5564                        struct net_device *ndev, const struct brcmf_event_msg *e,
5565                        bool completed)
5566 {
5567         struct brcmf_if *ifp = netdev_priv(ndev);
5568         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5569         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5570         struct cfg80211_connect_resp_params conn_params;
5571 
5572         brcmf_dbg(TRACE, "Enter\n");
5573 
5574         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5575                                &ifp->vif->sme_state)) {
5576                 memset(&conn_params, 0, sizeof(conn_params));
5577                 if (completed) {
5578                         brcmf_get_assoc_ies(cfg, ifp);
5579                         brcmf_update_bss_info(cfg, ifp);
5580                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
5581                                 &ifp->vif->sme_state);
5582                         conn_params.status = WLAN_STATUS_SUCCESS;
5583                 } else {
5584                         conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
5585                 }
5586                 conn_params.bssid = profile->bssid;
5587                 conn_params.req_ie = conn_info->req_ie;
5588                 conn_params.req_ie_len = conn_info->req_ie_len;
5589                 conn_params.resp_ie = conn_info->resp_ie;
5590                 conn_params.resp_ie_len = conn_info->resp_ie_len;
5591                 cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
5592                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
5593                           completed ? "succeeded" : "failed");
5594         }
5595         brcmf_dbg(TRACE, "Exit\n");
5596         return 0;
5597 }
5598 
5599 static s32
5600 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
5601                                struct net_device *ndev,
5602                                const struct brcmf_event_msg *e, void *data)
5603 {
5604         struct brcmf_pub *drvr = cfg->pub;
5605         static int generation;
5606         u32 event = e->event_code;
5607         u32 reason = e->reason;
5608         struct station_info *sinfo;
5609 
5610         brcmf_dbg(CONN, "event %s (%u), reason %d\n",
5611                   brcmf_fweh_event_name(event), event, reason);
5612         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5613             ndev != cfg_to_ndev(cfg)) {
5614                 brcmf_dbg(CONN, "AP mode link down\n");
5615                 complete(&cfg->vif_disabled);
5616                 return 0;
5617         }
5618 
5619         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5620             (reason == BRCMF_E_STATUS_SUCCESS)) {
5621                 if (!data) {
5622                         bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
5623                         return -EINVAL;
5624                 }
5625 
5626                 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
5627                 if (!sinfo)
5628                         return -ENOMEM;
5629 
5630                 sinfo->assoc_req_ies = data;
5631                 sinfo->assoc_req_ies_len = e->datalen;
5632                 generation++;
5633                 sinfo->generation = generation;
5634                 cfg80211_new_sta(ndev, e->addr, sinfo, GFP_KERNEL);
5635 
5636                 kfree(sinfo);
5637         } else if ((event == BRCMF_E_DISASSOC_IND) ||
5638                    (event == BRCMF_E_DEAUTH_IND) ||
5639                    (event == BRCMF_E_DEAUTH)) {
5640                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5641         }
5642         return 0;
5643 }
5644 
5645 static s32
5646 brcmf_notify_connect_status(struct brcmf_if *ifp,
5647                             const struct brcmf_event_msg *e, void *data)
5648 {
5649         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5650         struct net_device *ndev = ifp->ndev;
5651         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5652         struct ieee80211_channel *chan;
5653         s32 err = 0;
5654 
5655         if ((e->event_code == BRCMF_E_DEAUTH) ||
5656             (e->event_code == BRCMF_E_DEAUTH_IND) ||
5657             (e->event_code == BRCMF_E_DISASSOC_IND) ||
5658             ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5659                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5660         }
5661 
5662         if (brcmf_is_apmode(ifp->vif)) {
5663                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5664         } else if (brcmf_is_linkup(ifp->vif, e)) {
5665                 brcmf_dbg(CONN, "Linkup\n");
5666                 if (brcmf_is_ibssmode(ifp->vif)) {
5667                         brcmf_inform_ibss(cfg, ndev, e->addr);
5668                         chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5669                         memcpy(profile->bssid, e->addr, ETH_ALEN);
5670                         cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5671                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5672                                   &ifp->vif->sme_state);
5673                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
5674                                 &ifp->vif->sme_state);
5675                 } else
5676                         brcmf_bss_connect_done(cfg, ndev, e, true);
5677                 brcmf_net_setcarrier(ifp, true);
5678         } else if (brcmf_is_linkdown(e)) {
5679                 brcmf_dbg(CONN, "Linkdown\n");
5680                 if (!brcmf_is_ibssmode(ifp->vif)) {
5681                         brcmf_bss_connect_done(cfg, ndev, e, false);
5682                         brcmf_link_down(ifp->vif,
5683                                         brcmf_map_fw_linkdown_reason(e));
5684                         brcmf_init_prof(ndev_to_prof(ndev));
5685                         if (ndev != cfg_to_ndev(cfg))
5686                                 complete(&cfg->vif_disabled);
5687                         brcmf_net_setcarrier(ifp, false);
5688                 }
5689         } else if (brcmf_is_nonetwork(cfg, e)) {
5690                 if (brcmf_is_ibssmode(ifp->vif))
5691                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5692                                   &ifp->vif->sme_state);
5693                 else
5694                         brcmf_bss_connect_done(cfg, ndev, e, false);
5695         }
5696 
5697         return err;
5698 }
5699 
5700 static s32
5701 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5702                             const struct brcmf_event_msg *e, void *data)
5703 {
5704         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5705         u32 event = e->event_code;
5706         u32 status = e->status;
5707 
5708         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5709                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
5710                              &ifp->vif->sme_state)) {
5711                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5712                 } else {
5713                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5714                         brcmf_net_setcarrier(ifp, true);
5715                 }
5716         }
5717 
5718         return 0;
5719 }
5720 
5721 static s32
5722 brcmf_notify_mic_status(struct brcmf_if *ifp,
5723                         const struct brcmf_event_msg *e, void *data)
5724 {
5725         u16 flags = e->flags;
5726         enum nl80211_key_type key_type;
5727 
5728         if (flags & BRCMF_EVENT_MSG_GROUP)
5729                 key_type = NL80211_KEYTYPE_GROUP;
5730         else
5731                 key_type = NL80211_KEYTYPE_PAIRWISE;
5732 
5733         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5734                                      NULL, GFP_KERNEL);
5735 
5736         return 0;
5737 }
5738 
5739 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5740                                   const struct brcmf_event_msg *e, void *data)
5741 {
5742         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5743         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5744         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5745         struct brcmf_cfg80211_vif *vif;
5746 
5747         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5748                   ifevent->action, ifevent->flags, ifevent->ifidx,
5749                   ifevent->bsscfgidx);
5750 
5751         spin_lock(&event->vif_event_lock);
5752         event->action = ifevent->action;
5753         vif = event->vif;
5754 
5755         switch (ifevent->action) {
5756         case BRCMF_E_IF_ADD:
5757                 /* waiting process may have timed out */
5758                 if (!cfg->vif_event.vif) {
5759                         spin_unlock(&event->vif_event_lock);
5760                         return -EBADF;
5761                 }
5762 
5763                 ifp->vif = vif;
5764                 vif->ifp = ifp;
5765                 if (ifp->ndev) {
5766                         vif->wdev.netdev = ifp->ndev;
5767                         ifp->ndev->ieee80211_ptr = &vif->wdev;
5768                         SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5769                 }
5770                 spin_unlock(&event->vif_event_lock);
5771                 wake_up(&event->vif_wq);
5772                 return 0;
5773 
5774         case BRCMF_E_IF_DEL:
5775                 spin_unlock(&event->vif_event_lock);
5776                 /* event may not be upon user request */
5777                 if (brcmf_cfg80211_vif_event_armed(cfg))
5778                         wake_up(&event->vif_wq);
5779                 return 0;
5780 
5781         case BRCMF_E_IF_CHANGE:
5782                 spin_unlock(&event->vif_event_lock);
5783                 wake_up(&event->vif_wq);
5784                 return 0;
5785 
5786         default:
5787                 spin_unlock(&event->vif_event_lock);
5788                 break;
5789         }
5790         return -EINVAL;
5791 }
5792 
5793 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5794 {
5795         conf->frag_threshold = (u32)-1;
5796         conf->rts_threshold = (u32)-1;
5797         conf->retry_short = (u32)-1;
5798         conf->retry_long = (u32)-1;
5799 }
5800 
5801 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5802 {
5803         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5804                             brcmf_notify_connect_status);
5805         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5806                             brcmf_notify_connect_status);
5807         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5808                             brcmf_notify_connect_status);
5809         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5810                             brcmf_notify_connect_status);
5811         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5812                             brcmf_notify_connect_status);
5813         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5814                             brcmf_notify_connect_status);
5815         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5816                             brcmf_notify_roaming_status);
5817         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5818                             brcmf_notify_mic_status);
5819         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5820                             brcmf_notify_connect_status);
5821         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5822                             brcmf_notify_sched_scan_results);
5823         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5824                             brcmf_notify_vif_event);
5825         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5826                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5827         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5828                             brcmf_p2p_notify_listen_complete);
5829         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5830                             brcmf_p2p_notify_action_frame_rx);
5831         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5832                             brcmf_p2p_notify_action_tx_complete);
5833         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5834                             brcmf_p2p_notify_action_tx_complete);
5835         brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
5836                             brcmf_notify_connect_status);
5837 }
5838 
5839 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5840 {
5841         kfree(cfg->conf);
5842         cfg->conf = NULL;
5843         kfree(cfg->extra_buf);
5844         cfg->extra_buf = NULL;
5845         kfree(cfg->wowl.nd);
5846         cfg->wowl.nd = NULL;
5847         kfree(cfg->wowl.nd_info);
5848         cfg->wowl.nd_info = NULL;
5849         kfree(cfg->escan_info.escan_buf);
5850         cfg->escan_info.escan_buf = NULL;
5851 }
5852 
5853 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5854 {
5855         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5856         if (!cfg->conf)
5857                 goto init_priv_mem_out;
5858         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5859         if (!cfg->extra_buf)
5860                 goto init_priv_mem_out;
5861         cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
5862         if (!cfg->wowl.nd)
5863                 goto init_priv_mem_out;
5864         cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
5865                                     sizeof(struct cfg80211_wowlan_nd_match *),
5866                                     GFP_KERNEL);
5867         if (!cfg->wowl.nd_info)
5868                 goto init_priv_mem_out;
5869         cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
5870         if (!cfg->escan_info.escan_buf)
5871                 goto init_priv_mem_out;
5872 
5873         return 0;
5874 
5875 init_priv_mem_out:
5876         brcmf_deinit_priv_mem(cfg);
5877 
5878         return -ENOMEM;
5879 }
5880 
5881 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5882 {
5883         s32 err = 0;
5884 
5885         cfg->scan_request = NULL;
5886         cfg->pwr_save = true;
5887         cfg->dongle_up = false;         /* dongle is not up yet */
5888         err = brcmf_init_priv_mem(cfg);
5889         if (err)
5890                 return err;
5891         brcmf_register_event_handlers(cfg);
5892         mutex_init(&cfg->usr_sync);
5893         brcmf_init_escan(cfg);
5894         brcmf_init_conf(cfg->conf);
5895         init_completion(&cfg->vif_disabled);
5896         return err;
5897 }
5898 
5899 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5900 {
5901         cfg->dongle_up = false; /* dongle down */
5902         brcmf_abort_scanning(cfg);
5903         brcmf_deinit_priv_mem(cfg);
5904 }
5905 
5906 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5907 {
5908         init_waitqueue_head(&event->vif_wq);
5909         spin_lock_init(&event->vif_event_lock);
5910 }
5911 
5912 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
5913 {
5914         struct brcmf_pub *drvr = ifp->drvr;
5915         s32 err;
5916         u32 bcn_timeout;
5917         __le32 roamtrigger[2];
5918         __le32 roam_delta[2];
5919 
5920         /* Configure beacon timeout value based upon roaming setting */
5921         if (ifp->drvr->settings->roamoff)
5922                 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
5923         else
5924                 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
5925         err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5926         if (err) {
5927                 bphy_err(drvr, "bcn_timeout error (%d)\n", err);
5928                 goto roam_setup_done;
5929         }
5930 
5931         /* Enable/Disable built-in roaming to allow supplicant to take care of
5932          * roaming.
5933          */
5934         brcmf_dbg(INFO, "Internal Roaming = %s\n",
5935                   ifp->drvr->settings->roamoff ? "Off" : "On");
5936         err = brcmf_fil_iovar_int_set(ifp, "roam_off",
5937                                       ifp->drvr->settings->roamoff);
5938         if (err) {
5939                 bphy_err(drvr, "roam_off error (%d)\n", err);
5940                 goto roam_setup_done;
5941         }
5942 
5943         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5944         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5945         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5946                                      (void *)roamtrigger, sizeof(roamtrigger));
5947         if (err) {
5948                 bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5949                 goto roam_setup_done;
5950         }
5951 
5952         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5953         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5954         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5955                                      (void *)roam_delta, sizeof(roam_delta));
5956         if (err) {
5957                 bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
5958                 goto roam_setup_done;
5959         }
5960 
5961 roam_setup_done:
5962         return err;
5963 }
5964 
5965 static s32
5966 brcmf_dongle_scantime(struct brcmf_if *ifp)
5967 {
5968         struct brcmf_pub *drvr = ifp->drvr;
5969         s32 err = 0;
5970 
5971         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5972                                     BRCMF_SCAN_CHANNEL_TIME);
5973         if (err) {
5974                 bphy_err(drvr, "Scan assoc time error (%d)\n", err);
5975                 goto dongle_scantime_out;
5976         }
5977         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5978                                     BRCMF_SCAN_UNASSOC_TIME);
5979         if (err) {
5980                 bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
5981                 goto dongle_scantime_out;
5982         }
5983 
5984         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5985                                     BRCMF_SCAN_PASSIVE_TIME);
5986         if (err) {
5987                 bphy_err(drvr, "Scan passive time error (%d)\n", err);
5988                 goto dongle_scantime_out;
5989         }
5990 
5991 dongle_scantime_out:
5992         return err;
5993 }
5994 
5995 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5996                                            struct brcmu_chan *ch)
5997 {
5998         u32 ht40_flag;
5999 
6000         ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
6001         if (ch->sb == BRCMU_CHAN_SB_U) {
6002                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6003                         channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6004                 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
6005         } else {
6006                 /* It should be one of
6007                  * IEEE80211_CHAN_NO_HT40 or
6008                  * IEEE80211_CHAN_NO_HT40PLUS
6009                  */
6010                 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6011                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6012                         channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
6013         }
6014 }
6015 
6016 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
6017                                     u32 bw_cap[])
6018 {
6019         struct wiphy *wiphy = cfg_to_wiphy(cfg);
6020         struct brcmf_pub *drvr = cfg->pub;
6021         struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6022         struct ieee80211_supported_band *band;
6023         struct ieee80211_channel *channel;
6024         struct brcmf_chanspec_list *list;
6025         struct brcmu_chan ch;
6026         int err;
6027         u8 *pbuf;
6028         u32 i, j;
6029         u32 total;
6030         u32 chaninfo;
6031 
6032         pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6033 
6034         if (pbuf == NULL)
6035                 return -ENOMEM;
6036 
6037         list = (struct brcmf_chanspec_list *)pbuf;
6038 
6039         err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6040                                        BRCMF_DCMD_MEDLEN);
6041         if (err) {
6042                 bphy_err(drvr, "get chanspecs error (%d)\n", err);
6043                 goto fail_pbuf;
6044         }
6045 
6046         band = wiphy->bands[NL80211_BAND_2GHZ];
6047         if (band)
6048                 for (i = 0; i < band->n_channels; i++)
6049                         band->channels[i].flags = IEEE80211_CHAN_DISABLED;
6050         band = wiphy->bands[NL80211_BAND_5GHZ];
6051         if (band)
6052                 for (i = 0; i < band->n_channels; i++)
6053                         band->channels[i].flags = IEEE80211_CHAN_DISABLED;
6054 
6055         total = le32_to_cpu(list->count);
6056         for (i = 0; i < total; i++) {
6057                 ch.chspec = (u16)le32_to_cpu(list->element[i]);
6058                 cfg->d11inf.decchspec(&ch);
6059 
6060                 if (ch.band == BRCMU_CHAN_BAND_2G) {
6061                         band = wiphy->bands[NL80211_BAND_2GHZ];
6062                 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
6063                         band = wiphy->bands[NL80211_BAND_5GHZ];
6064                 } else {
6065                         bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
6066                                  ch.chspec);
6067                         continue;
6068                 }
6069                 if (!band)
6070                         continue;
6071                 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
6072                     ch.bw == BRCMU_CHAN_BW_40)
6073                         continue;
6074                 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
6075                     ch.bw == BRCMU_CHAN_BW_80)
6076                         continue;
6077 
6078                 channel = NULL;
6079                 for (j = 0; j < band->n_channels; j++) {
6080                         if (band->channels[j].hw_value == ch.control_ch_num) {
6081                                 channel = &band->channels[j];
6082                                 break;
6083                         }
6084                 }
6085                 if (!channel) {
6086                         /* It seems firmware supports some channel we never
6087                          * considered. Something new in IEEE standard?
6088                          */
6089                         bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
6090                                  ch.control_ch_num);
6091                         continue;
6092                 }
6093 
6094                 if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
6095                         continue;
6096 
6097                 /* assuming the chanspecs order is HT20,
6098                  * HT40 upper, HT40 lower, and VHT80.
6099                  */
6100                 switch (ch.bw) {
6101                 case BRCMU_CHAN_BW_160:
6102                         channel->flags &= ~IEEE80211_CHAN_NO_160MHZ;
6103                         break;
6104                 case BRCMU_CHAN_BW_80:
6105                         channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
6106                         break;
6107                 case BRCMU_CHAN_BW_40:
6108                         brcmf_update_bw40_channel_flag(channel, &ch);
6109                         break;
6110                 default:
6111                         wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n",
6112                                    ch.bw);
6113                         /* fall through */
6114                 case BRCMU_CHAN_BW_20:
6115                         /* enable the channel and disable other bandwidths
6116                          * for now as mentioned order assure they are enabled
6117                          * for subsequent chanspecs.
6118                          */
6119                         channel->flags = IEEE80211_CHAN_NO_HT40 |
6120                                          IEEE80211_CHAN_NO_80MHZ |
6121                                          IEEE80211_CHAN_NO_160MHZ;
6122                         ch.bw = BRCMU_CHAN_BW_20;
6123                         cfg->d11inf.encchspec(&ch);
6124                         chaninfo = ch.chspec;
6125                         err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
6126                                                        &chaninfo);
6127                         if (!err) {
6128                                 if (chaninfo & WL_CHAN_RADAR)
6129                                         channel->flags |=
6130                                                 (IEEE80211_CHAN_RADAR |
6131                                                  IEEE80211_CHAN_NO_IR);
6132                                 if (chaninfo & WL_CHAN_PASSIVE)
6133                                         channel->flags |=
6134                                                 IEEE80211_CHAN_NO_IR;
6135                         }
6136                 }
6137         }
6138 
6139 fail_pbuf:
6140         kfree(pbuf);
6141         return err;
6142 }
6143 
6144 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
6145 {
6146         struct brcmf_pub *drvr = cfg->pub;
6147         struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6148         struct ieee80211_supported_band *band;
6149         struct brcmf_fil_bwcap_le band_bwcap;
6150         struct brcmf_chanspec_list *list;
6151         u8 *pbuf;
6152         u32 val;
6153         int err;
6154         struct brcmu_chan ch;
6155         u32 num_chan;
6156         int i, j;
6157 
6158         /* verify support for bw_cap command */
6159         val = WLC_BAND_5G;
6160         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
6161 
6162         if (!err) {
6163                 /* only set 2G bandwidth using bw_cap command */
6164                 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
6165                 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
6166                 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
6167                                                sizeof(band_bwcap));
6168         } else {
6169                 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
6170                 val = WLC_N_BW_40ALL;
6171                 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
6172         }
6173 
6174         if (!err) {
6175                 /* update channel info in 2G band */
6176                 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6177 
6178                 if (pbuf == NULL)
6179                         return -ENOMEM;
6180 
6181                 ch.band = BRCMU_CHAN_BAND_2G;
6182                 ch.bw = BRCMU_CHAN_BW_40;
6183                 ch.sb = BRCMU_CHAN_SB_NONE;
6184                 ch.chnum = 0;
6185                 cfg->d11inf.encchspec(&ch);
6186 
6187                 /* pass encoded chanspec in query */
6188                 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
6189 
6190                 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6191                                                BRCMF_DCMD_MEDLEN);
6192                 if (err) {
6193                         bphy_err(drvr, "get chanspecs error (%d)\n", err);
6194                         kfree(pbuf);
6195                         return err;
6196                 }
6197 
6198                 band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
6199                 list = (struct brcmf_chanspec_list *)pbuf;
6200                 num_chan = le32_to_cpu(list->count);
6201                 for (i = 0; i < num_chan; i++) {
6202                         ch.chspec = (u16)le32_to_cpu(list->element[i]);
6203                         cfg->d11inf.decchspec(&ch);
6204                         if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
6205                                 continue;
6206                         if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
6207                                 continue;
6208                         for (j = 0; j < band->n_channels; j++) {
6209                                 if (band->channels[j].hw_value == ch.control_ch_num)
6210                                         break;
6211                         }
6212                         if (WARN_ON(j == band->n_channels))
6213                                 continue;
6214 
6215                         brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
6216                 }
6217                 kfree(pbuf);
6218         }
6219         return err;
6220 }
6221 
6222 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
6223 {
6224         struct brcmf_pub *drvr = ifp->drvr;
6225         u32 band, mimo_bwcap;
6226         int err;
6227 
6228         band = WLC_BAND_2G;
6229         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6230         if (!err) {
6231                 bw_cap[NL80211_BAND_2GHZ] = band;
6232                 band = WLC_BAND_5G;
6233                 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6234                 if (!err) {
6235                         bw_cap[NL80211_BAND_5GHZ] = band;
6236                         return;
6237                 }
6238                 WARN_ON(1);
6239                 return;
6240         }
6241         brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
6242         mimo_bwcap = 0;
6243         err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
6244         if (err)
6245                 /* assume 20MHz if firmware does not give a clue */
6246                 mimo_bwcap = WLC_N_BW_20ALL;
6247 
6248         switch (mimo_bwcap) {
6249         case WLC_N_BW_40ALL:
6250                 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
6251                 /* fall-thru */
6252         case WLC_N_BW_20IN2G_40IN5G:
6253                 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
6254                 /* fall-thru */
6255         case WLC_N_BW_20ALL:
6256                 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
6257                 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
6258                 break;
6259         default:
6260                 bphy_err(drvr, "invalid mimo_bw_cap value\n");
6261         }
6262 }
6263 
6264 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
6265                                 u32 bw_cap[2], u32 nchain)
6266 {
6267         band->ht_cap.ht_supported = true;
6268         if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
6269                 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6270                 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6271         }
6272         band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6273         band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6274         band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6275         band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
6276         memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
6277         band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
6278 }
6279 
6280 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
6281 {
6282         u16 mcs_map;
6283         int i;
6284 
6285         for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
6286                 mcs_map = (mcs_map << 2) | supp;
6287 
6288         return cpu_to_le16(mcs_map);
6289 }
6290 
6291 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
6292                                  u32 bw_cap[2], u32 nchain, u32 txstreams,
6293                                  u32 txbf_bfe_cap, u32 txbf_bfr_cap)
6294 {
6295         __le16 mcs_map;
6296 
6297         /* not allowed in 2.4G band */
6298         if (band->band == NL80211_BAND_2GHZ)
6299                 return;
6300 
6301         band->vht_cap.vht_supported = true;
6302         /* 80MHz is mandatory */
6303         band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
6304         if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
6305                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
6306                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
6307         }
6308         /* all support 256-QAM */
6309         mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
6310         band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
6311         band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
6312 
6313         /* Beamforming support information */
6314         if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
6315                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
6316         if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
6317                 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
6318         if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
6319                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
6320         if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
6321                 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
6322 
6323         if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
6324                 band->vht_cap.cap |=
6325                         (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
6326                 band->vht_cap.cap |= ((txstreams - 1) <<
6327                                 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
6328                 band->vht_cap.cap |=
6329                         IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
6330         }
6331 }
6332 
6333 static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
6334 {
6335         struct brcmf_pub *drvr = cfg->pub;
6336         struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6337         struct wiphy *wiphy = cfg_to_wiphy(cfg);
6338         u32 nmode = 0;
6339         u32 vhtmode = 0;
6340         u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
6341         u32 rxchain;
6342         u32 nchain;
6343         int err;
6344         s32 i;
6345         struct ieee80211_supported_band *band;
6346         u32 txstreams = 0;
6347         u32 txbf_bfe_cap = 0;
6348         u32 txbf_bfr_cap = 0;
6349 
6350         (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
6351         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
6352         if (err) {
6353                 bphy_err(drvr, "nmode error (%d)\n", err);
6354         } else {
6355                 brcmf_get_bwcap(ifp, bw_cap);
6356         }
6357         brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
6358                   nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
6359                   bw_cap[NL80211_BAND_5GHZ]);
6360 
6361         err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
6362         if (err) {
6363                 bphy_err(drvr, "rxchain error (%d)\n", err);
6364                 nchain = 1;
6365         } else {
6366                 for (nchain = 0; rxchain; nchain++)
6367                         rxchain = rxchain & (rxchain - 1);
6368         }
6369         brcmf_dbg(INFO, "nchain=%d\n", nchain);
6370 
6371         err = brcmf_construct_chaninfo(cfg, bw_cap);
6372         if (err) {
6373                 bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
6374                 return err;
6375         }
6376 
6377         if (vhtmode) {
6378                 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
6379                 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
6380                                               &txbf_bfe_cap);
6381                 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
6382                                               &txbf_bfr_cap);
6383         }
6384 
6385         for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
6386                 band = wiphy->bands[i];
6387                 if (band == NULL)
6388                         continue;
6389 
6390                 if (nmode)
6391                         brcmf_update_ht_cap(band, bw_cap, nchain);
6392                 if (vhtmode)
6393                         brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
6394                                              txbf_bfe_cap, txbf_bfr_cap);
6395         }
6396 
6397         return 0;
6398 }
6399 
6400 static const struct ieee80211_txrx_stypes
6401 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
6402         [NL80211_IFTYPE_STATION] = {
6403                 .tx = 0xffff,
6404                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6405                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6406         },
6407         [NL80211_IFTYPE_P2P_CLIENT] = {
6408                 .tx = 0xffff,
6409                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6410                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6411         },
6412         [NL80211_IFTYPE_P2P_GO] = {
6413                 .tx = 0xffff,
6414                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6415                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6416                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6417                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6418                       BIT(IEEE80211_STYPE_AUTH >> 4) |
6419                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6420                       BIT(IEEE80211_STYPE_ACTION >> 4)
6421         },
6422         [NL80211_IFTYPE_P2P_DEVICE] = {
6423                 .tx = 0xffff,
6424                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6425                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6426         },
6427         [NL80211_IFTYPE_AP] = {
6428                 .tx = 0xffff,
6429                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6430                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6431                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6432                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6433                       BIT(IEEE80211_STYPE_AUTH >> 4) |
6434                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6435                       BIT(IEEE80211_STYPE_ACTION >> 4)
6436         }
6437 };
6438 
6439 /**
6440  * brcmf_setup_ifmodes() - determine interface modes and combinations.
6441  *
6442  * @wiphy: wiphy object.
6443  * @ifp: interface object needed for feat module api.
6444  *
6445  * The interface modes and combinations are determined dynamically here
6446  * based on firmware functionality.
6447  *
6448  * no p2p and no mbss:
6449  *
6450  *      #STA <= 1, #AP <= 1, channels = 1, 2 total
6451  *
6452  * no p2p and mbss:
6453  *
6454  *      #STA <= 1, #AP <= 1, channels = 1, 2 total
6455  *      #AP <= 4, matching BI, channels = 1, 4 total
6456  *
6457  * p2p, no mchan, and mbss:
6458  *
6459  *      #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
6460  *      #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6461  *      #AP <= 4, matching BI, channels = 1, 4 total
6462  *
6463  * p2p, mchan, and mbss:
6464  *
6465  *      #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6466  *      #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6467  *      #AP <= 4, matching BI, channels = 1, 4 total
6468  */
6469 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
6470 {
6471         struct ieee80211_iface_combination *combo = NULL;
6472         struct ieee80211_iface_limit *c0_limits = NULL;
6473         struct ieee80211_iface_limit *p2p_limits = NULL;
6474         struct ieee80211_iface_limit *mbss_limits = NULL;
6475         bool mbss, p2p;
6476         int i, c, n_combos;
6477 
6478         mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
6479         p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
6480 
6481         n_combos = 1 + !!p2p + !!mbss;
6482         combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
6483         if (!combo)
6484                 goto err;
6485 
6486         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6487                                  BIT(NL80211_IFTYPE_ADHOC) |
6488                                  BIT(NL80211_IFTYPE_AP);
6489 
6490         c = 0;
6491         i = 0;
6492         c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
6493         if (!c0_limits)
6494                 goto err;
6495         c0_limits[i].max = 1;
6496         c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6497         if (p2p) {
6498                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
6499                         combo[c].num_different_channels = 2;
6500                 else
6501                         combo[c].num_different_channels = 1;
6502                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
6503                                           BIT(NL80211_IFTYPE_P2P_GO) |
6504                                           BIT(NL80211_IFTYPE_P2P_DEVICE);
6505                 c0_limits[i].max = 1;
6506                 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6507                 c0_limits[i].max = 1;
6508                 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
6509                                        BIT(NL80211_IFTYPE_P2P_GO);
6510         } else {
6511                 combo[c].num_different_channels = 1;
6512                 c0_limits[i].max = 1;
6513                 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6514         }
6515         combo[c].max_interfaces = i;
6516         combo[c].n_limits = i;
6517         combo[c].limits = c0_limits;
6518 
6519         if (p2p) {
6520                 c++;
6521                 i = 0;
6522                 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
6523                 if (!p2p_limits)
6524                         goto err;
6525                 p2p_limits[i].max = 1;
6526                 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6527                 p2p_limits[i].max = 1;
6528                 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6529                 p2p_limits[i].max = 1;
6530                 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
6531                 p2p_limits[i].max = 1;
6532                 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6533                 combo[c].num_different_channels = 1;
6534                 combo[c].max_interfaces = i;
6535                 combo[c].n_limits = i;
6536                 combo[c].limits = p2p_limits;
6537         }
6538 
6539         if (mbss) {
6540                 c++;
6541                 i = 0;
6542                 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
6543                 if (!mbss_limits)
6544                         goto err;
6545                 mbss_limits[i].max = 4;
6546                 mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6547                 combo[c].beacon_int_infra_match = true;
6548                 combo[c].num_different_channels = 1;
6549                 combo[c].max_interfaces = 4;
6550                 combo[c].n_limits = i;
6551                 combo[c].limits = mbss_limits;
6552         }
6553 
6554         wiphy->n_iface_combinations = n_combos;
6555         wiphy->iface_combinations = combo;
6556         return 0;
6557 
6558 err:
6559         kfree(c0_limits);
6560         kfree(p2p_limits);
6561         kfree(mbss_limits);
6562         kfree(combo);
6563         return -ENOMEM;
6564 }
6565 
6566 #ifdef CONFIG_PM
6567 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
6568         .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
6569         .n_patterns = BRCMF_WOWL_MAXPATTERNS,
6570         .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
6571         .pattern_min_len = 1,
6572         .max_pkt_offset = 1500,
6573 };
6574 #endif
6575 
6576 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6577 {
6578 #ifdef CONFIG_PM
6579         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6580         struct brcmf_pub *drvr = cfg->pub;
6581         struct wiphy_wowlan_support *wowl;
6582 
6583         wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
6584                        GFP_KERNEL);
6585         if (!wowl) {
6586                 bphy_err(drvr, "only support basic wowlan features\n");
6587                 wiphy->wowlan = &brcmf_wowlan_support;
6588                 return;
6589         }
6590 
6591         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6592                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
6593                         wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
6594                         wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6595                         init_waitqueue_head(&cfg->wowl.nd_data_wait);
6596                 }
6597         }
6598         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
6599                 wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
6600                 wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
6601         }
6602 
6603         wiphy->wowlan = wowl;
6604 #endif
6605 }
6606 
6607 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6608 {
6609         struct brcmf_pub *drvr = ifp->drvr;
6610         const struct ieee80211_iface_combination *combo;
6611         struct ieee80211_supported_band *band;
6612         u16 max_interfaces = 0;
6613         bool gscan;
6614         __le32 bandlist[3];
6615         u32 n_bands;
6616         int err, i;
6617 
6618         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
6619         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6620         wiphy->max_num_pmkids = BRCMF_MAXPMKID;
6621 
6622         err = brcmf_setup_ifmodes(wiphy, ifp);
6623         if (err)
6624                 return err;
6625 
6626         for (i = 0, combo = wiphy->iface_combinations;
6627              i < wiphy->n_iface_combinations; i++, combo++) {
6628                 max_interfaces = max(max_interfaces, combo->max_interfaces);
6629         }
6630 
6631         for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
6632              i++) {
6633                 u8 *addr = drvr->addresses[i].addr;
6634 
6635                 memcpy(addr, drvr->mac, ETH_ALEN);
6636                 if (i) {
6637                         addr[0] |= BIT(1);
6638                         addr[ETH_ALEN - 1] ^= i;
6639                 }
6640         }
6641         wiphy->addresses = drvr->addresses;
6642         wiphy->n_addresses = i;
6643 
6644         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6645         wiphy->cipher_suites = brcmf_cipher_suites;
6646         wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
6647         if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
6648                 wiphy->n_cipher_suites--;
6649         wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
6650                                     BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
6651                                     BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
6652 
6653         wiphy->flags |= WIPHY_FLAG_NETNS_OK |
6654                         WIPHY_FLAG_PS_ON_BY_DEFAULT |
6655                         WIPHY_FLAG_HAVE_AP_SME |
6656                         WIPHY_FLAG_OFFCHAN_TX |
6657                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6658         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
6659                 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6660         if (!ifp->drvr->settings->roamoff)
6661                 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6662         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
6663                 wiphy_ext_feature_set(wiphy,
6664                                       NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
6665                 wiphy_ext_feature_set(wiphy,
6666                                       NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
6667         }
6668         wiphy->mgmt_stypes = brcmf_txrx_stypes;
6669         wiphy->max_remain_on_channel_duration = 5000;
6670         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6671                 gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
6672                 brcmf_pno_wiphy_params(wiphy, gscan);
6673         }
6674         /* vendor commands/events support */
6675         wiphy->vendor_commands = brcmf_vendor_cmds;
6676         wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
6677 
6678         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
6679                 brcmf_wiphy_wowl_params(wiphy, ifp);
6680         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
6681                                      sizeof(bandlist));
6682         if (err) {
6683                 bphy_err(drvr, "could not obtain band info: err=%d\n", err);
6684                 return err;
6685         }
6686         /* first entry in bandlist is number of bands */
6687         n_bands = le32_to_cpu(bandlist[0]);
6688         for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
6689                 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
6690                         band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
6691                                        GFP_KERNEL);
6692                         if (!band)
6693                                 return -ENOMEM;
6694 
6695                         band->channels = kmemdup(&__wl_2ghz_channels,
6696                                                  sizeof(__wl_2ghz_channels),
6697                                                  GFP_KERNEL);
6698                         if (!band->channels) {
6699                                 kfree(band);
6700                                 return -ENOMEM;
6701                         }
6702 
6703                         band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6704                         wiphy->bands[NL80211_BAND_2GHZ] = band;
6705                 }
6706                 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6707                         band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6708                                        GFP_KERNEL);
6709                         if (!band)
6710                                 return -ENOMEM;
6711 
6712                         band->channels = kmemdup(&__wl_5ghz_channels,
6713                                                  sizeof(__wl_5ghz_channels),
6714                                                  GFP_KERNEL);
6715                         if (!band->channels) {
6716                                 kfree(band);
6717                                 return -ENOMEM;
6718                         }
6719 
6720                         band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6721                         wiphy->bands[NL80211_BAND_5GHZ] = band;
6722                 }
6723         }
6724 
6725         if (wiphy->bands[NL80211_BAND_5GHZ] &&
6726             brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H))
6727                 wiphy_ext_feature_set(wiphy,
6728                                       NL80211_EXT_FEATURE_DFS_OFFLOAD);
6729 
6730         wiphy_read_of_freq_limits(wiphy);
6731 
6732         return 0;
6733 }
6734 
6735 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6736 {
6737         struct brcmf_pub *drvr = cfg->pub;
6738         struct net_device *ndev;
6739         struct wireless_dev *wdev;
6740         struct brcmf_if *ifp;
6741         s32 power_mode;
6742         s32 err = 0;
6743 
6744         if (cfg->dongle_up)
6745                 return err;
6746 
6747         ndev = cfg_to_ndev(cfg);
6748         wdev = ndev->ieee80211_ptr;
6749         ifp = netdev_priv(ndev);
6750 
6751         /* make sure RF is ready for work */
6752         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6753 
6754         brcmf_dongle_scantime(ifp);
6755 
6756         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6757         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6758         if (err)
6759                 goto default_conf_out;
6760         brcmf_dbg(INFO, "power save set to %s\n",
6761                   (power_mode ? "enabled" : "disabled"));
6762 
6763         err = brcmf_dongle_roam(ifp);
6764         if (err)
6765                 goto default_conf_out;
6766         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6767                                           NULL);
6768         if (err)
6769                 goto default_conf_out;
6770 
6771         brcmf_configure_arp_nd_offload(ifp, true);
6772 
6773         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
6774         if (err) {
6775                 bphy_err(drvr, "failed to set frameburst mode\n");
6776                 goto default_conf_out;
6777         }
6778 
6779         cfg->dongle_up = true;
6780 default_conf_out:
6781 
6782         return err;
6783 
6784 }
6785 
6786 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6787 {
6788         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6789 
6790         return brcmf_config_dongle(ifp->drvr->config);
6791 }
6792 
6793 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6794 {
6795         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6796 
6797         /*
6798          * While going down, if associated with AP disassociate
6799          * from AP to save power
6800          */
6801         if (check_vif_up(ifp->vif)) {
6802                 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6803 
6804                 /* Make sure WPA_Supplicant receives all the event
6805                    generated due to DISASSOC call to the fw to keep
6806                    the state fw and WPA_Supplicant state consistent
6807                  */
6808                 brcmf_delay(500);
6809         }
6810 
6811         brcmf_abort_scanning(cfg);
6812         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6813 
6814         return 0;
6815 }
6816 
6817 s32 brcmf_cfg80211_up(struct net_device *ndev)
6818 {
6819         struct brcmf_if *ifp = netdev_priv(ndev);
6820         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6821         s32 err = 0;
6822 
6823         mutex_lock(&cfg->usr_sync);
6824         err = __brcmf_cfg80211_up(ifp);
6825         mutex_unlock(&cfg->usr_sync);
6826 
6827         return err;
6828 }
6829 
6830 s32 brcmf_cfg80211_down(struct net_device *ndev)
6831 {
6832         struct brcmf_if *ifp = netdev_priv(ndev);
6833         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6834         s32 err = 0;
6835 
6836         mutex_lock(&cfg->usr_sync);
6837         err = __brcmf_cfg80211_down(ifp);
6838         mutex_unlock(&cfg->usr_sync);
6839 
6840         return err;
6841 }
6842 
6843 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6844 {
6845         struct wireless_dev *wdev = &ifp->vif->wdev;
6846 
6847         return wdev->iftype;
6848 }
6849 
6850 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6851                              unsigned long state)
6852 {
6853         struct brcmf_cfg80211_vif *vif;
6854 
6855         list_for_each_entry(vif, &cfg->vif_list, list) {
6856                 if (test_bit(state, &vif->sme_state))
6857                         return true;
6858         }
6859         return false;
6860 }
6861 
6862 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6863                                     u8 action)
6864 {
6865         u8 evt_action;
6866 
6867         spin_lock(&event->vif_event_lock);
6868         evt_action = event->action;
6869         spin_unlock(&event->vif_event_lock);
6870         return evt_action == action;
6871 }
6872 
6873 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6874                                   struct brcmf_cfg80211_vif *vif)
6875 {
6876         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6877 
6878         spin_lock(&event->vif_event_lock);
6879         event->vif = vif;
6880         event->action = 0;
6881         spin_unlock(&event->vif_event_lock);
6882 }
6883 
6884 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6885 {
6886         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6887         bool armed;
6888 
6889         spin_lock(&event->vif_event_lock);
6890         armed = event->vif != NULL;
6891         spin_unlock(&event->vif_event_lock);
6892 
6893         return armed;
6894 }
6895 
6896 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
6897                                   u8 action, ulong timeout)
6898 {
6899         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6900 
6901         return wait_event_timeout(event->vif_wq,
6902                                   vif_event_equals(event, action), timeout);
6903 }
6904 
6905 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6906                                         struct brcmf_fil_country_le *ccreq)
6907 {
6908         struct brcmfmac_pd_cc *country_codes;
6909         struct brcmfmac_pd_cc_entry *cc;
6910         s32 found_index;
6911         int i;
6912 
6913         country_codes = drvr->settings->country_codes;
6914         if (!country_codes) {
6915                 brcmf_dbg(TRACE, "No country codes configured for device\n");
6916                 return -EINVAL;
6917         }
6918 
6919         if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6920             (alpha2[1] == ccreq->country_abbrev[1])) {
6921                 brcmf_dbg(TRACE, "Country code already set\n");
6922                 return -EAGAIN;
6923         }
6924 
6925         found_index = -1;
6926         for (i = 0; i < country_codes->table_size; i++) {
6927                 cc = &country_codes->table[i];
6928                 if ((cc->iso3166[0] == '\0') && (found_index == -1))
6929                         found_index = i;
6930                 if ((cc->iso3166[0] == alpha2[0]) &&
6931                     (cc->iso3166[1] == alpha2[1])) {
6932                         found_index = i;
6933                         break;
6934                 }
6935         }
6936         if (found_index == -1) {
6937                 brcmf_dbg(TRACE, "No country code match found\n");
6938                 return -EINVAL;
6939         }
6940         memset(ccreq, 0, sizeof(*ccreq));
6941         ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6942         memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6943                BRCMF_COUNTRY_BUF_SZ);
6944         ccreq->country_abbrev[0] = alpha2[0];
6945         ccreq->country_abbrev[1] = alpha2[1];
6946         ccreq->country_abbrev[2] = 0;
6947 
6948         return 0;
6949 }
6950 
6951 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6952                                         struct regulatory_request *req)
6953 {
6954         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6955         struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6956         struct brcmf_pub *drvr = cfg->pub;
6957         struct brcmf_fil_country_le ccreq;
6958         s32 err;
6959         int i;
6960 
6961         /* The country code gets set to "00" by default at boot, ignore */
6962         if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
6963                 return;
6964 
6965         /* ignore non-ISO3166 country codes */
6966         for (i = 0; i < 2; i++)
6967                 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6968                         bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
6969                                  req->alpha2[0], req->alpha2[1]);
6970                         return;
6971                 }
6972 
6973         brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6974                   req->alpha2[0], req->alpha2[1]);
6975 
6976         err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6977         if (err) {
6978                 bphy_err(drvr, "Country code iovar returned err = %d\n", err);
6979                 return;
6980         }
6981 
6982         err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6983         if (err)
6984                 return;
6985 
6986         err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6987         if (err) {
6988                 bphy_err(drvr, "Firmware rejected country setting\n");
6989                 return;
6990         }
6991         brcmf_setup_wiphybands(cfg);
6992 }
6993 
6994 static void brcmf_free_wiphy(struct wiphy *wiphy)
6995 {
6996         int i;
6997 
6998         if (!wiphy)
6999                 return;
7000 
7001         if (wiphy->iface_combinations) {
7002                 for (i = 0; i < wiphy->n_iface_combinations; i++)
7003                         kfree(wiphy->iface_combinations[i].limits);
7004         }
7005         kfree(wiphy->iface_combinations);
7006         if (wiphy->bands[NL80211_BAND_2GHZ]) {
7007                 kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
7008                 kfree(wiphy->bands[NL80211_BAND_2GHZ]);
7009         }
7010         if (wiphy->bands[NL80211_BAND_5GHZ]) {
7011                 kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
7012                 kfree(wiphy->bands[NL80211_BAND_5GHZ]);
7013         }
7014 #if IS_ENABLED(CONFIG_PM)
7015         if (wiphy->wowlan != &brcmf_wowlan_support)
7016                 kfree(wiphy->wowlan);
7017 #endif
7018 }
7019 
7020 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
7021                                                   struct cfg80211_ops *ops,
7022                                                   bool p2pdev_forced)
7023 {
7024         struct wiphy *wiphy = drvr->wiphy;
7025         struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
7026         struct brcmf_cfg80211_info *cfg;
7027         struct brcmf_cfg80211_vif *vif;
7028         struct brcmf_if *ifp;
7029         s32 err = 0;
7030         s32 io_type;
7031         u16 *cap = NULL;
7032 
7033         if (!ndev) {
7034                 bphy_err(drvr, "ndev is invalid\n");
7035                 return NULL;
7036         }
7037 
7038         cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
7039         if (!cfg) {
7040                 bphy_err(drvr, "Could not allocate wiphy device\n");
7041                 return NULL;
7042         }
7043 
7044         cfg->wiphy = wiphy;
7045         cfg->pub = drvr;
7046         init_vif_event(&cfg->vif_event);
7047         INIT_LIST_HEAD(&cfg->vif_list);
7048 
7049         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
7050         if (IS_ERR(vif))
7051                 goto wiphy_out;
7052 
7053         ifp = netdev_priv(ndev);
7054         vif->ifp = ifp;
7055         vif->wdev.netdev = ndev;
7056         ndev->ieee80211_ptr = &vif->wdev;
7057         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
7058 
7059         err = wl_init_priv(cfg);
7060         if (err) {
7061                 bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
7062                 brcmf_free_vif(vif);
7063                 goto wiphy_out;
7064         }
7065         ifp->vif = vif;
7066 
7067         /* determine d11 io type before wiphy setup */
7068         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
7069         if (err) {
7070                 bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
7071                 goto priv_out;
7072         }
7073         cfg->d11inf.io_type = (u8)io_type;
7074         brcmu_d11_attach(&cfg->d11inf);
7075 
7076         /* regulatory notifer below needs access to cfg so
7077          * assign it now.
7078          */
7079         drvr->config = cfg;
7080 
7081         err = brcmf_setup_wiphy(wiphy, ifp);
7082         if (err < 0)
7083                 goto priv_out;
7084 
7085         brcmf_dbg(INFO, "Registering custom regulatory\n");
7086         wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
7087         wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
7088         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
7089 
7090         /* firmware defaults to 40MHz disabled in 2G band. We signal
7091          * cfg80211 here that we do and have it decide we can enable
7092          * it. But first check if device does support 2G operation.
7093          */
7094         if (wiphy->bands[NL80211_BAND_2GHZ]) {
7095                 cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
7096                 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7097         }
7098 #ifdef CONFIG_PM
7099         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
7100                 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
7101 #endif
7102         err = wiphy_register(wiphy);
7103         if (err < 0) {
7104                 bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
7105                 goto priv_out;
7106         }
7107 
7108         err = brcmf_setup_wiphybands(cfg);
7109         if (err) {
7110                 bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
7111                 goto wiphy_unreg_out;
7112         }
7113 
7114         /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
7115          * setup 40MHz in 2GHz band and enable OBSS scanning.
7116          */
7117         if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
7118                 err = brcmf_enable_bw40_2g(cfg);
7119                 if (!err)
7120                         err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
7121                                                       BRCMF_OBSS_COEX_AUTO);
7122                 else
7123                         *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7124         }
7125 
7126         err = brcmf_fweh_activate_events(ifp);
7127         if (err) {
7128                 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
7129                 goto wiphy_unreg_out;
7130         }
7131 
7132         err = brcmf_p2p_attach(cfg, p2pdev_forced);
7133         if (err) {
7134                 bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
7135                 goto wiphy_unreg_out;
7136         }
7137         err = brcmf_btcoex_attach(cfg);
7138         if (err) {
7139                 bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
7140                 brcmf_p2p_detach(&cfg->p2p);
7141                 goto wiphy_unreg_out;
7142         }
7143         err = brcmf_pno_attach(cfg);
7144         if (err) {
7145                 bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
7146                 brcmf_btcoex_detach(cfg);
7147                 brcmf_p2p_detach(&cfg->p2p);
7148                 goto wiphy_unreg_out;
7149         }
7150 
7151         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
7152                 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
7153                 if (err) {
7154                         brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
7155                         wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
7156                 } else {
7157                         brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
7158                                             brcmf_notify_tdls_peer_event);
7159                 }
7160         }
7161 
7162         /* (re-) activate FWEH event handling */
7163         err = brcmf_fweh_activate_events(ifp);
7164         if (err) {
7165                 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
7166                 goto detach;
7167         }
7168 
7169         /* Fill in some of the advertised nl80211 supported features */
7170         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
7171                 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7172 #ifdef CONFIG_PM
7173                 if (wiphy->wowlan &&
7174                     wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
7175                         wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7176 #endif
7177         }
7178 
7179         return cfg;
7180 
7181 detach:
7182         brcmf_pno_detach(cfg);
7183         brcmf_btcoex_detach(cfg);
7184         brcmf_p2p_detach(&cfg->p2p);
7185 wiphy_unreg_out:
7186         wiphy_unregister(cfg->wiphy);
7187 priv_out:
7188         wl_deinit_priv(cfg);
7189         brcmf_free_vif(vif);
7190         ifp->vif = NULL;
7191 wiphy_out:
7192         brcmf_free_wiphy(wiphy);
7193         kfree(cfg);
7194         return NULL;
7195 }
7196 
7197 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
7198 {
7199         if (!cfg)
7200                 return;
7201 
7202         brcmf_pno_detach(cfg);
7203         brcmf_btcoex_detach(cfg);
7204         wiphy_unregister(cfg->wiphy);
7205         wl_deinit_priv(cfg);
7206         brcmf_free_wiphy(cfg->wiphy);
7207         kfree(cfg);
7208 }

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