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

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

DEFINITIONS

This source file includes following definitions.
  1. wil_rx_cb_mode_to_n_bonded
  2. wil_tx_cb_mode_to_n_bonded
  3. wil_memdup_ie
  4. wil_num_supported_channels
  5. update_supported_bands
  6. wil_iftype_nl2wmi
  7. wil_spec2wmi_ch
  8. wil_wmi2spec_ch
  9. wil_cid_fill_sinfo
  10. wil_cfg80211_get_station
  11. wil_find_cid_by_idx
  12. wil_cfg80211_dump_station
  13. wil_cfg80211_start_p2p_device
  14. wil_cfg80211_stop_p2p_device
  15. wil_cfg80211_validate_add_iface
  16. wil_cfg80211_validate_change_iface
  17. wil_cfg80211_add_iface
  18. wil_vif_prepare_stop
  19. wil_cfg80211_del_iface
  20. wil_is_safe_switch
  21. wil_cfg80211_change_iface
  22. wil_cfg80211_scan
  23. wil_cfg80211_abort_scan
  24. wil_print_crypto
  25. wil_get_auth_type_name
  26. wil_print_connect_params
  27. wil_ft_connect
  28. wil_get_wmi_edmg_channel
  29. wil_cfg80211_connect
  30. wil_cfg80211_disconnect
  31. wil_cfg80211_set_wiphy_params
  32. wil_cfg80211_mgmt_tx
  33. wil_cfg80211_set_channel
  34. wil_detect_key_usage
  35. wil_find_sta_by_key_usage
  36. wil_set_crypto_rx
  37. wil_del_rx_key
  38. wil_cfg80211_add_key
  39. wil_cfg80211_del_key
  40. wil_cfg80211_set_default_key
  41. wil_remain_on_channel
  42. wil_cancel_remain_on_channel
  43. _wil_cfg80211_find_ie
  44. _wil_cfg80211_merge_extra_ies
  45. wil_print_bcon_data
  46. _wil_cfg80211_get_proberesp_ies
  47. _wil_cfg80211_set_ies
  48. _wil_cfg80211_start_ap
  49. wil_cfg80211_ap_recovery
  50. wil_cfg80211_change_beacon
  51. wil_cfg80211_start_ap
  52. wil_cfg80211_stop_ap
  53. wil_cfg80211_add_station
  54. wil_cfg80211_del_station
  55. wil_cfg80211_change_station
  56. wil_probe_client_handle
  57. next_probe_client
  58. wil_probe_client_worker
  59. wil_probe_client_flush
  60. wil_cfg80211_probe_client
  61. wil_cfg80211_change_bss
  62. wil_cfg80211_set_power_mgmt
  63. wil_cfg80211_suspend
  64. wil_cfg80211_resume
  65. wil_cfg80211_sched_scan_start
  66. wil_cfg80211_sched_scan_stop
  67. wil_cfg80211_update_ft_ies
  68. wil_wiphy_init
  69. wil_cfg80211_iface_combinations_from_fw
  70. wil_cfg80211_init
  71. wil_cfg80211_deinit
  72. wil_p2p_wdev_free
  73. wil_rf_sector_status_to_rc
  74. wil_rf_sector_get_cfg
  75. wil_rf_sector_set_cfg
  76. wil_rf_sector_get_selected
  77. wil_rf_sector_wmi_set_selected
  78. wil_rf_sector_set_selected

   1 /*
   2  * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
   3  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
   4  *
   5  * Permission to use, copy, modify, and/or distribute this software for any
   6  * purpose with or without fee is hereby granted, provided that the above
   7  * copyright notice and this permission notice appear in all copies.
   8  *
   9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16  */
  17 
  18 #include <linux/etherdevice.h>
  19 #include <linux/moduleparam.h>
  20 #include <net/netlink.h>
  21 #include <net/cfg80211.h>
  22 #include "wil6210.h"
  23 #include "wmi.h"
  24 #include "fw.h"
  25 
  26 #define WIL_MAX_ROC_DURATION_MS 5000
  27 
  28 #define WIL_EDMG_CHANNEL_9_SUBCHANNELS  (BIT(0) | BIT(1))
  29 #define WIL_EDMG_CHANNEL_10_SUBCHANNELS (BIT(1) | BIT(2))
  30 #define WIL_EDMG_CHANNEL_11_SUBCHANNELS (BIT(2) | BIT(3))
  31 
  32 /* WIL_EDMG_BW_CONFIGURATION define the allowed channel bandwidth
  33  * configurations as defined by IEEE 802.11 section 9.4.2.251, Table 13.
  34  * The value 5 allowing CB1 and CB2 of adjacent channels.
  35  */
  36 #define WIL_EDMG_BW_CONFIGURATION 5
  37 
  38 /* WIL_EDMG_CHANNELS is a bitmap that indicates the 2.16 GHz channel(s) that
  39  * are allowed to be used for EDMG transmissions in the BSS as defined by
  40  * IEEE 802.11 section 9.4.2.251.
  41  */
  42 #define WIL_EDMG_CHANNELS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
  43 
  44 bool disable_ap_sme;
  45 module_param(disable_ap_sme, bool, 0444);
  46 MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
  47 
  48 #ifdef CONFIG_PM
  49 static struct wiphy_wowlan_support wil_wowlan_support = {
  50         .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
  51 };
  52 #endif
  53 
  54 #define CHAN60G(_channel, _flags) {                             \
  55         .band                   = NL80211_BAND_60GHZ,           \
  56         .center_freq            = 56160 + (2160 * (_channel)),  \
  57         .hw_value               = (_channel),                   \
  58         .flags                  = (_flags),                     \
  59         .max_antenna_gain       = 0,                            \
  60         .max_power              = 40,                           \
  61 }
  62 
  63 static struct ieee80211_channel wil_60ghz_channels[] = {
  64         CHAN60G(1, 0),
  65         CHAN60G(2, 0),
  66         CHAN60G(3, 0),
  67         CHAN60G(4, 0),
  68 };
  69 
  70 /* Rx channel bonding mode */
  71 enum wil_rx_cb_mode {
  72         WIL_RX_CB_MODE_DMG,
  73         WIL_RX_CB_MODE_EDMG,
  74         WIL_RX_CB_MODE_WIDE,
  75 };
  76 
  77 static int wil_rx_cb_mode_to_n_bonded(u8 cb_mode)
  78 {
  79         switch (cb_mode) {
  80         case WIL_RX_CB_MODE_DMG:
  81         case WIL_RX_CB_MODE_EDMG:
  82                 return 1;
  83         case WIL_RX_CB_MODE_WIDE:
  84                 return 2;
  85         default:
  86                 return 1;
  87         }
  88 }
  89 
  90 static int wil_tx_cb_mode_to_n_bonded(u8 cb_mode)
  91 {
  92         switch (cb_mode) {
  93         case WMI_TX_MODE_DMG:
  94         case WMI_TX_MODE_EDMG_CB1:
  95                 return 1;
  96         case WMI_TX_MODE_EDMG_CB2:
  97                 return 2;
  98         default:
  99                 return 1;
 100         }
 101 }
 102 
 103 static void
 104 wil_memdup_ie(u8 **pdst, size_t *pdst_len, const u8 *src, size_t src_len)
 105 {
 106         kfree(*pdst);
 107         *pdst = NULL;
 108         *pdst_len = 0;
 109         if (src_len > 0) {
 110                 *pdst = kmemdup(src, src_len, GFP_KERNEL);
 111                 if (*pdst)
 112                         *pdst_len = src_len;
 113         }
 114 }
 115 
 116 static int wil_num_supported_channels(struct wil6210_priv *wil)
 117 {
 118         int num_channels = ARRAY_SIZE(wil_60ghz_channels);
 119 
 120         if (!test_bit(WMI_FW_CAPABILITY_CHANNEL_4, wil->fw_capabilities))
 121                 num_channels--;
 122 
 123         return num_channels;
 124 }
 125 
 126 void update_supported_bands(struct wil6210_priv *wil)
 127 {
 128         struct wiphy *wiphy = wil_to_wiphy(wil);
 129 
 130         wil_dbg_misc(wil, "update supported bands");
 131 
 132         wiphy->bands[NL80211_BAND_60GHZ]->n_channels =
 133                                                 wil_num_supported_channels(wil);
 134 
 135         if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) {
 136                 wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.channels =
 137                                                         WIL_EDMG_CHANNELS;
 138                 wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.bw_config =
 139                                                       WIL_EDMG_BW_CONFIGURATION;
 140         }
 141 }
 142 
 143 /* Vendor id to be used in vendor specific command and events
 144  * to user space.
 145  * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
 146  * vendor subcmd definitions prefixed with QCA_NL80211_VENDOR_SUBCMD, and
 147  * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in
 148  * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that
 149  */
 150 
 151 #define QCA_NL80211_VENDOR_ID   0x001374
 152 
 153 #define WIL_MAX_RF_SECTORS (128)
 154 #define WIL_CID_ALL (0xff)
 155 
 156 enum qca_wlan_vendor_attr_rf_sector {
 157         QCA_ATTR_MAC_ADDR = 6,
 158         QCA_ATTR_PAD = 13,
 159         QCA_ATTR_TSF = 29,
 160         QCA_ATTR_DMG_RF_SECTOR_INDEX = 30,
 161         QCA_ATTR_DMG_RF_SECTOR_TYPE = 31,
 162         QCA_ATTR_DMG_RF_MODULE_MASK = 32,
 163         QCA_ATTR_DMG_RF_SECTOR_CFG = 33,
 164         QCA_ATTR_DMG_RF_SECTOR_MAX,
 165 };
 166 
 167 enum qca_wlan_vendor_attr_dmg_rf_sector_type {
 168         QCA_ATTR_DMG_RF_SECTOR_TYPE_RX,
 169         QCA_ATTR_DMG_RF_SECTOR_TYPE_TX,
 170         QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
 171 };
 172 
 173 enum qca_wlan_vendor_attr_dmg_rf_sector_cfg {
 174         QCA_ATTR_DMG_RF_SECTOR_CFG_INVALID = 0,
 175         QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX,
 176         QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0,
 177         QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1,
 178         QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2,
 179         QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI,
 180         QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO,
 181         QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16,
 182 
 183         /* keep last */
 184         QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST,
 185         QCA_ATTR_DMG_RF_SECTOR_CFG_MAX =
 186         QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1
 187 };
 188 
 189 static const struct
 190 nla_policy wil_rf_sector_policy[QCA_ATTR_DMG_RF_SECTOR_MAX + 1] = {
 191         [QCA_ATTR_MAC_ADDR] = { .len = ETH_ALEN },
 192         [QCA_ATTR_DMG_RF_SECTOR_INDEX] = { .type = NLA_U16 },
 193         [QCA_ATTR_DMG_RF_SECTOR_TYPE] = { .type = NLA_U8 },
 194         [QCA_ATTR_DMG_RF_MODULE_MASK] = { .type = NLA_U32 },
 195         [QCA_ATTR_DMG_RF_SECTOR_CFG] = { .type = NLA_NESTED },
 196 };
 197 
 198 static const struct
 199 nla_policy wil_rf_sector_cfg_policy[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1] = {
 200         [QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX] = { .type = NLA_U8 },
 201         [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0] = { .type = NLA_U32 },
 202         [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1] = { .type = NLA_U32 },
 203         [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2] = { .type = NLA_U32 },
 204         [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI] = { .type = NLA_U32 },
 205         [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO] = { .type = NLA_U32 },
 206         [QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16] = { .type = NLA_U32 },
 207 };
 208 
 209 enum qca_nl80211_vendor_subcmds {
 210         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG = 139,
 211         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG = 140,
 212         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR = 141,
 213         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR = 142,
 214 };
 215 
 216 static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
 217                                  struct wireless_dev *wdev,
 218                                  const void *data, int data_len);
 219 static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
 220                                  struct wireless_dev *wdev,
 221                                  const void *data, int data_len);
 222 static int wil_rf_sector_get_selected(struct wiphy *wiphy,
 223                                       struct wireless_dev *wdev,
 224                                       const void *data, int data_len);
 225 static int wil_rf_sector_set_selected(struct wiphy *wiphy,
 226                                       struct wireless_dev *wdev,
 227                                       const void *data, int data_len);
 228 
 229 /* vendor specific commands */
 230 static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
 231         {
 232                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
 233                 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG,
 234                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
 235                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 236                 .policy = wil_rf_sector_policy,
 237                 .doit = wil_rf_sector_get_cfg
 238         },
 239         {
 240                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
 241                 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG,
 242                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
 243                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 244                 .policy = wil_rf_sector_policy,
 245                 .doit = wil_rf_sector_set_cfg
 246         },
 247         {
 248                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
 249                 .info.subcmd =
 250                         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR,
 251                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
 252                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 253                 .policy = wil_rf_sector_policy,
 254                 .doit = wil_rf_sector_get_selected
 255         },
 256         {
 257                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
 258                 .info.subcmd =
 259                         QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR,
 260                 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
 261                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 262                 .policy = wil_rf_sector_policy,
 263                 .doit = wil_rf_sector_set_selected
 264         },
 265 };
 266 
 267 static struct ieee80211_supported_band wil_band_60ghz = {
 268         .channels = wil_60ghz_channels,
 269         .n_channels = ARRAY_SIZE(wil_60ghz_channels),
 270         .ht_cap = {
 271                 .ht_supported = true,
 272                 .cap = 0, /* TODO */
 273                 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
 274                 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
 275                 .mcs = {
 276                                 /* MCS 1..12 - SC PHY */
 277                         .rx_mask = {0xfe, 0x1f}, /* 1..12 */
 278                         .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
 279                 },
 280         },
 281 };
 282 
 283 static const struct ieee80211_txrx_stypes
 284 wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 285         [NL80211_IFTYPE_STATION] = {
 286                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 287                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
 288                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 289                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 290         },
 291         [NL80211_IFTYPE_AP] = {
 292                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 293                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
 294                 BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
 295                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
 296                 BIT(IEEE80211_STYPE_AUTH >> 4) |
 297                 BIT(IEEE80211_STYPE_REASSOC_RESP >> 4),
 298                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 299                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
 300                 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
 301                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
 302                 BIT(IEEE80211_STYPE_AUTH >> 4) |
 303                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 304                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
 305         },
 306         [NL80211_IFTYPE_P2P_CLIENT] = {
 307                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 308                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
 309                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 310                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 311         },
 312         [NL80211_IFTYPE_P2P_GO] = {
 313                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 314                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
 315                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 316                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 317         },
 318         [NL80211_IFTYPE_P2P_DEVICE] = {
 319                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 320                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
 321                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 322                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 323         },
 324 };
 325 
 326 static const u32 wil_cipher_suites[] = {
 327         WLAN_CIPHER_SUITE_GCMP,
 328 };
 329 
 330 static const char * const key_usage_str[] = {
 331         [WMI_KEY_USE_PAIRWISE]  = "PTK",
 332         [WMI_KEY_USE_RX_GROUP]  = "RX_GTK",
 333         [WMI_KEY_USE_TX_GROUP]  = "TX_GTK",
 334         [WMI_KEY_USE_STORE_PTK] = "STORE_PTK",
 335         [WMI_KEY_USE_APPLY_PTK] = "APPLY_PTK",
 336 };
 337 
 338 int wil_iftype_nl2wmi(enum nl80211_iftype type)
 339 {
 340         static const struct {
 341                 enum nl80211_iftype nl;
 342                 enum wmi_network_type wmi;
 343         } __nl2wmi[] = {
 344                 {NL80211_IFTYPE_ADHOC,          WMI_NETTYPE_ADHOC},
 345                 {NL80211_IFTYPE_STATION,        WMI_NETTYPE_INFRA},
 346                 {NL80211_IFTYPE_AP,             WMI_NETTYPE_AP},
 347                 {NL80211_IFTYPE_P2P_CLIENT,     WMI_NETTYPE_P2P},
 348                 {NL80211_IFTYPE_P2P_GO,         WMI_NETTYPE_P2P},
 349                 {NL80211_IFTYPE_MONITOR,        WMI_NETTYPE_ADHOC}, /* FIXME */
 350         };
 351         uint i;
 352 
 353         for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
 354                 if (__nl2wmi[i].nl == type)
 355                         return __nl2wmi[i].wmi;
 356         }
 357 
 358         return -EOPNOTSUPP;
 359 }
 360 
 361 int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch)
 362 {
 363         switch (spec_ch) {
 364         case 1:
 365                 *wmi_ch = WMI_CHANNEL_1;
 366                 break;
 367         case 2:
 368                 *wmi_ch = WMI_CHANNEL_2;
 369                 break;
 370         case 3:
 371                 *wmi_ch = WMI_CHANNEL_3;
 372                 break;
 373         case 4:
 374                 *wmi_ch = WMI_CHANNEL_4;
 375                 break;
 376         case 5:
 377                 *wmi_ch = WMI_CHANNEL_5;
 378                 break;
 379         case 6:
 380                 *wmi_ch = WMI_CHANNEL_6;
 381                 break;
 382         case 9:
 383                 *wmi_ch = WMI_CHANNEL_9;
 384                 break;
 385         case 10:
 386                 *wmi_ch = WMI_CHANNEL_10;
 387                 break;
 388         case 11:
 389                 *wmi_ch = WMI_CHANNEL_11;
 390                 break;
 391         case 12:
 392                 *wmi_ch = WMI_CHANNEL_12;
 393                 break;
 394         default:
 395                 return -EINVAL;
 396         }
 397 
 398         return 0;
 399 }
 400 
 401 int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch)
 402 {
 403         switch (wmi_ch) {
 404         case WMI_CHANNEL_1:
 405                 *spec_ch = 1;
 406                 break;
 407         case WMI_CHANNEL_2:
 408                 *spec_ch = 2;
 409                 break;
 410         case WMI_CHANNEL_3:
 411                 *spec_ch = 3;
 412                 break;
 413         case WMI_CHANNEL_4:
 414                 *spec_ch = 4;
 415                 break;
 416         case WMI_CHANNEL_5:
 417                 *spec_ch = 5;
 418                 break;
 419         case WMI_CHANNEL_6:
 420                 *spec_ch = 6;
 421                 break;
 422         case WMI_CHANNEL_9:
 423                 *spec_ch = 9;
 424                 break;
 425         case WMI_CHANNEL_10:
 426                 *spec_ch = 10;
 427                 break;
 428         case WMI_CHANNEL_11:
 429                 *spec_ch = 11;
 430                 break;
 431         case WMI_CHANNEL_12:
 432                 *spec_ch = 12;
 433                 break;
 434         default:
 435                 return -EINVAL;
 436         }
 437 
 438         return 0;
 439 }
 440 
 441 int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
 442                        struct station_info *sinfo)
 443 {
 444         struct wil6210_priv *wil = vif_to_wil(vif);
 445         struct wmi_notify_req_cmd cmd = {
 446                 .cid = cid,
 447                 .interval_usec = 0,
 448         };
 449         struct {
 450                 struct wmi_cmd_hdr wmi;
 451                 struct wmi_notify_req_done_event evt;
 452         } __packed reply;
 453         struct wil_net_stats *stats = &wil->sta[cid].stats;
 454         int rc;
 455         u8 txflag = RATE_INFO_FLAGS_DMG;
 456 
 457         memset(&reply, 0, sizeof(reply));
 458 
 459         rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd),
 460                       WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply),
 461                       WIL_WMI_CALL_GENERAL_TO_MS);
 462         if (rc)
 463                 return rc;
 464 
 465         wil_dbg_wmi(wil, "Link status for CID %d MID %d: {\n"
 466                     "  MCS %d TSF 0x%016llx\n"
 467                     "  BF status 0x%08x RSSI %d SQI %d%%\n"
 468                     "  Tx Tpt %d goodput %d Rx goodput %d\n"
 469                     "  Sectors(rx:tx) my %d:%d peer %d:%d\n"
 470                     "  Tx mode %d}\n",
 471                     cid, vif->mid, le16_to_cpu(reply.evt.bf_mcs),
 472                     le64_to_cpu(reply.evt.tsf), reply.evt.status,
 473                     reply.evt.rssi,
 474                     reply.evt.sqi,
 475                     le32_to_cpu(reply.evt.tx_tpt),
 476                     le32_to_cpu(reply.evt.tx_goodput),
 477                     le32_to_cpu(reply.evt.rx_goodput),
 478                     le16_to_cpu(reply.evt.my_rx_sector),
 479                     le16_to_cpu(reply.evt.my_tx_sector),
 480                     le16_to_cpu(reply.evt.other_rx_sector),
 481                     le16_to_cpu(reply.evt.other_tx_sector),
 482                     reply.evt.tx_mode);
 483 
 484         sinfo->generation = wil->sinfo_gen;
 485 
 486         sinfo->filled = BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
 487                         BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
 488                         BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
 489                         BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
 490                         BIT_ULL(NL80211_STA_INFO_RX_BITRATE) |
 491                         BIT_ULL(NL80211_STA_INFO_TX_BITRATE) |
 492                         BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
 493                         BIT_ULL(NL80211_STA_INFO_TX_FAILED);
 494 
 495         if (wil->use_enhanced_dma_hw && reply.evt.tx_mode != WMI_TX_MODE_DMG)
 496                 txflag = RATE_INFO_FLAGS_EDMG;
 497 
 498         sinfo->txrate.flags = txflag;
 499         sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
 500         sinfo->rxrate.mcs = stats->last_mcs_rx;
 501         sinfo->txrate.n_bonded_ch =
 502                                   wil_tx_cb_mode_to_n_bonded(reply.evt.tx_mode);
 503         sinfo->rxrate.n_bonded_ch =
 504                              wil_rx_cb_mode_to_n_bonded(stats->last_cb_mode_rx);
 505         sinfo->rx_bytes = stats->rx_bytes;
 506         sinfo->rx_packets = stats->rx_packets;
 507         sinfo->rx_dropped_misc = stats->rx_dropped;
 508         sinfo->tx_bytes = stats->tx_bytes;
 509         sinfo->tx_packets = stats->tx_packets;
 510         sinfo->tx_failed = stats->tx_errors;
 511 
 512         if (test_bit(wil_vif_fwconnected, vif->status)) {
 513                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
 514                 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING,
 515                              wil->fw_capabilities))
 516                         sinfo->signal = reply.evt.rssi;
 517                 else
 518                         sinfo->signal = reply.evt.sqi;
 519         }
 520 
 521         return rc;
 522 }
 523 
 524 static int wil_cfg80211_get_station(struct wiphy *wiphy,
 525                                     struct net_device *ndev,
 526                                     const u8 *mac, struct station_info *sinfo)
 527 {
 528         struct wil6210_vif *vif = ndev_to_vif(ndev);
 529         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 530         int rc;
 531 
 532         int cid = wil_find_cid(wil, vif->mid, mac);
 533 
 534         wil_dbg_misc(wil, "get_station: %pM CID %d MID %d\n", mac, cid,
 535                      vif->mid);
 536         if (!wil_cid_valid(wil, cid))
 537                 return -ENOENT;
 538 
 539         rc = wil_cid_fill_sinfo(vif, cid, sinfo);
 540 
 541         return rc;
 542 }
 543 
 544 /*
 545  * Find @idx-th active STA for specific MID for station dump.
 546  */
 547 int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx)
 548 {
 549         int i;
 550 
 551         for (i = 0; i < wil->max_assoc_sta; i++) {
 552                 if (wil->sta[i].status == wil_sta_unused)
 553                         continue;
 554                 if (wil->sta[i].mid != mid)
 555                         continue;
 556                 if (idx == 0)
 557                         return i;
 558                 idx--;
 559         }
 560 
 561         return -ENOENT;
 562 }
 563 
 564 static int wil_cfg80211_dump_station(struct wiphy *wiphy,
 565                                      struct net_device *dev, int idx,
 566                                      u8 *mac, struct station_info *sinfo)
 567 {
 568         struct wil6210_vif *vif = ndev_to_vif(dev);
 569         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 570         int rc;
 571         int cid = wil_find_cid_by_idx(wil, vif->mid, idx);
 572 
 573         if (!wil_cid_valid(wil, cid))
 574                 return -ENOENT;
 575 
 576         ether_addr_copy(mac, wil->sta[cid].addr);
 577         wil_dbg_misc(wil, "dump_station: %pM CID %d MID %d\n", mac, cid,
 578                      vif->mid);
 579 
 580         rc = wil_cid_fill_sinfo(vif, cid, sinfo);
 581 
 582         return rc;
 583 }
 584 
 585 static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
 586                                          struct wireless_dev *wdev)
 587 {
 588         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 589 
 590         wil_dbg_misc(wil, "start_p2p_device: entered\n");
 591         wil->p2p_dev_started = 1;
 592         return 0;
 593 }
 594 
 595 static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
 596                                          struct wireless_dev *wdev)
 597 {
 598         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 599 
 600         if (!wil->p2p_dev_started)
 601                 return;
 602 
 603         wil_dbg_misc(wil, "stop_p2p_device: entered\n");
 604         mutex_lock(&wil->mutex);
 605         mutex_lock(&wil->vif_mutex);
 606         wil_p2p_stop_radio_operations(wil);
 607         wil->p2p_dev_started = 0;
 608         mutex_unlock(&wil->vif_mutex);
 609         mutex_unlock(&wil->mutex);
 610 }
 611 
 612 static int wil_cfg80211_validate_add_iface(struct wil6210_priv *wil,
 613                                            enum nl80211_iftype new_type)
 614 {
 615         int i;
 616         struct wireless_dev *wdev;
 617         struct iface_combination_params params = {
 618                 .num_different_channels = 1,
 619         };
 620 
 621         for (i = 0; i < GET_MAX_VIFS(wil); i++) {
 622                 if (wil->vifs[i]) {
 623                         wdev = vif_to_wdev(wil->vifs[i]);
 624                         params.iftype_num[wdev->iftype]++;
 625                 }
 626         }
 627         params.iftype_num[new_type]++;
 628         return cfg80211_check_combinations(wil->wiphy, &params);
 629 }
 630 
 631 static int wil_cfg80211_validate_change_iface(struct wil6210_priv *wil,
 632                                               struct wil6210_vif *vif,
 633                                               enum nl80211_iftype new_type)
 634 {
 635         int i, ret = 0;
 636         struct wireless_dev *wdev;
 637         struct iface_combination_params params = {
 638                 .num_different_channels = 1,
 639         };
 640         bool check_combos = false;
 641 
 642         for (i = 0; i < GET_MAX_VIFS(wil); i++) {
 643                 struct wil6210_vif *vif_pos = wil->vifs[i];
 644 
 645                 if (vif_pos && vif != vif_pos) {
 646                         wdev = vif_to_wdev(vif_pos);
 647                         params.iftype_num[wdev->iftype]++;
 648                         check_combos = true;
 649                 }
 650         }
 651 
 652         if (check_combos) {
 653                 params.iftype_num[new_type]++;
 654                 ret = cfg80211_check_combinations(wil->wiphy, &params);
 655         }
 656         return ret;
 657 }
 658 
 659 static struct wireless_dev *
 660 wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
 661                        unsigned char name_assign_type,
 662                        enum nl80211_iftype type,
 663                        struct vif_params *params)
 664 {
 665         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 666         struct net_device *ndev_main = wil->main_ndev, *ndev;
 667         struct wil6210_vif *vif;
 668         struct wireless_dev *p2p_wdev, *wdev;
 669         int rc;
 670 
 671         wil_dbg_misc(wil, "add_iface, type %d\n", type);
 672 
 673         /* P2P device is not a real virtual interface, it is a management-only
 674          * interface that shares the main interface.
 675          * Skip concurrency checks here.
 676          */
 677         if (type == NL80211_IFTYPE_P2P_DEVICE) {
 678                 if (wil->p2p_wdev) {
 679                         wil_err(wil, "P2P_DEVICE interface already created\n");
 680                         return ERR_PTR(-EINVAL);
 681                 }
 682 
 683                 p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL);
 684                 if (!p2p_wdev)
 685                         return ERR_PTR(-ENOMEM);
 686 
 687                 p2p_wdev->iftype = type;
 688                 p2p_wdev->wiphy = wiphy;
 689                 /* use our primary ethernet address */
 690                 ether_addr_copy(p2p_wdev->address, ndev_main->perm_addr);
 691 
 692                 wil->p2p_wdev = p2p_wdev;
 693 
 694                 return p2p_wdev;
 695         }
 696 
 697         if (!wil->wiphy->n_iface_combinations) {
 698                 wil_err(wil, "virtual interfaces not supported\n");
 699                 return ERR_PTR(-EINVAL);
 700         }
 701 
 702         rc = wil_cfg80211_validate_add_iface(wil, type);
 703         if (rc) {
 704                 wil_err(wil, "iface validation failed, err=%d\n", rc);
 705                 return ERR_PTR(rc);
 706         }
 707 
 708         vif = wil_vif_alloc(wil, name, name_assign_type, type);
 709         if (IS_ERR(vif))
 710                 return ERR_CAST(vif);
 711 
 712         ndev = vif_to_ndev(vif);
 713         ether_addr_copy(ndev->perm_addr, ndev_main->perm_addr);
 714         if (is_valid_ether_addr(params->macaddr)) {
 715                 ether_addr_copy(ndev->dev_addr, params->macaddr);
 716         } else {
 717                 ether_addr_copy(ndev->dev_addr, ndev_main->perm_addr);
 718                 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << vif->mid)) |
 719                         0x2; /* locally administered */
 720         }
 721         wdev = vif_to_wdev(vif);
 722         ether_addr_copy(wdev->address, ndev->dev_addr);
 723 
 724         rc = wil_vif_add(wil, vif);
 725         if (rc)
 726                 goto out;
 727 
 728         wil_info(wil, "added VIF, mid %d iftype %d MAC %pM\n",
 729                  vif->mid, type, wdev->address);
 730         return wdev;
 731 out:
 732         wil_vif_free(vif);
 733         return ERR_PTR(rc);
 734 }
 735 
 736 int wil_vif_prepare_stop(struct wil6210_vif *vif)
 737 {
 738         struct wil6210_priv *wil = vif_to_wil(vif);
 739         struct wireless_dev *wdev = vif_to_wdev(vif);
 740         struct net_device *ndev;
 741         int rc;
 742 
 743         if (wdev->iftype != NL80211_IFTYPE_AP)
 744                 return 0;
 745 
 746         ndev = vif_to_ndev(vif);
 747         if (netif_carrier_ok(ndev)) {
 748                 rc = wmi_pcp_stop(vif);
 749                 if (rc) {
 750                         wil_info(wil, "failed to stop AP, status %d\n",
 751                                  rc);
 752                         /* continue */
 753                 }
 754                 wil_bcast_fini(vif);
 755                 netif_carrier_off(ndev);
 756         }
 757 
 758         return 0;
 759 }
 760 
 761 static int wil_cfg80211_del_iface(struct wiphy *wiphy,
 762                                   struct wireless_dev *wdev)
 763 {
 764         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 765         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
 766         int rc;
 767 
 768         wil_dbg_misc(wil, "del_iface\n");
 769 
 770         if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
 771                 if (wdev != wil->p2p_wdev) {
 772                         wil_err(wil, "delete of incorrect interface 0x%p\n",
 773                                 wdev);
 774                         return -EINVAL;
 775                 }
 776 
 777                 wil_cfg80211_stop_p2p_device(wiphy, wdev);
 778                 wil_p2p_wdev_free(wil);
 779                 return 0;
 780         }
 781 
 782         if (vif->mid == 0) {
 783                 wil_err(wil, "cannot remove the main interface\n");
 784                 return -EINVAL;
 785         }
 786 
 787         rc = wil_vif_prepare_stop(vif);
 788         if (rc)
 789                 goto out;
 790 
 791         wil_info(wil, "deleted VIF, mid %d iftype %d MAC %pM\n",
 792                  vif->mid, wdev->iftype, wdev->address);
 793 
 794         wil_vif_remove(wil, vif->mid);
 795 out:
 796         return rc;
 797 }
 798 
 799 static bool wil_is_safe_switch(enum nl80211_iftype from,
 800                                enum nl80211_iftype to)
 801 {
 802         if (from == NL80211_IFTYPE_STATION &&
 803             to == NL80211_IFTYPE_P2P_CLIENT)
 804                 return true;
 805 
 806         return false;
 807 }
 808 
 809 static int wil_cfg80211_change_iface(struct wiphy *wiphy,
 810                                      struct net_device *ndev,
 811                                      enum nl80211_iftype type,
 812                                      struct vif_params *params)
 813 {
 814         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 815         struct wil6210_vif *vif = ndev_to_vif(ndev);
 816         struct wireless_dev *wdev = vif_to_wdev(vif);
 817         int rc;
 818         bool fw_reset = false;
 819 
 820         wil_dbg_misc(wil, "change_iface: type=%d\n", type);
 821 
 822         if (wiphy->n_iface_combinations) {
 823                 rc = wil_cfg80211_validate_change_iface(wil, vif, type);
 824                 if (rc) {
 825                         wil_err(wil, "iface validation failed, err=%d\n", rc);
 826                         return rc;
 827                 }
 828         }
 829 
 830         /* do not reset FW when there are active VIFs,
 831          * because it can cause significant disruption
 832          */
 833         if (!wil_has_other_active_ifaces(wil, ndev, true, false) &&
 834             netif_running(ndev) && !wil_is_recovery_blocked(wil) &&
 835             !wil_is_safe_switch(wdev->iftype, type)) {
 836                 wil_dbg_misc(wil, "interface is up. resetting...\n");
 837                 mutex_lock(&wil->mutex);
 838                 __wil_down(wil);
 839                 rc = __wil_up(wil);
 840                 mutex_unlock(&wil->mutex);
 841 
 842                 if (rc)
 843                         return rc;
 844                 fw_reset = true;
 845         }
 846 
 847         switch (type) {
 848         case NL80211_IFTYPE_STATION:
 849         case NL80211_IFTYPE_AP:
 850         case NL80211_IFTYPE_P2P_CLIENT:
 851         case NL80211_IFTYPE_P2P_GO:
 852                 break;
 853         case NL80211_IFTYPE_MONITOR:
 854                 if (params->flags)
 855                         wil->monitor_flags = params->flags;
 856                 break;
 857         default:
 858                 return -EOPNOTSUPP;
 859         }
 860 
 861         if (vif->mid != 0 && wil_has_active_ifaces(wil, true, false)) {
 862                 if (!fw_reset)
 863                         wil_vif_prepare_stop(vif);
 864                 rc = wmi_port_delete(wil, vif->mid);
 865                 if (rc)
 866                         return rc;
 867                 rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, type);
 868                 if (rc)
 869                         return rc;
 870         }
 871 
 872         wdev->iftype = type;
 873         return 0;
 874 }
 875 
 876 static int wil_cfg80211_scan(struct wiphy *wiphy,
 877                              struct cfg80211_scan_request *request)
 878 {
 879         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 880         struct wireless_dev *wdev = request->wdev;
 881         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
 882         struct {
 883                 struct wmi_start_scan_cmd cmd;
 884                 u16 chnl[4];
 885         } __packed cmd;
 886         uint i, n;
 887         int rc;
 888 
 889         wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
 890 
 891         /* scan is supported on client interfaces and on AP interface */
 892         switch (wdev->iftype) {
 893         case NL80211_IFTYPE_STATION:
 894         case NL80211_IFTYPE_P2P_CLIENT:
 895         case NL80211_IFTYPE_P2P_DEVICE:
 896         case NL80211_IFTYPE_AP:
 897                 break;
 898         default:
 899                 return -EOPNOTSUPP;
 900         }
 901 
 902         /* FW don't support scan after connection attempt */
 903         if (test_bit(wil_status_dontscan, wil->status)) {
 904                 wil_err(wil, "Can't scan now\n");
 905                 return -EBUSY;
 906         }
 907 
 908         mutex_lock(&wil->mutex);
 909 
 910         mutex_lock(&wil->vif_mutex);
 911         if (vif->scan_request || vif->p2p.discovery_started) {
 912                 wil_err(wil, "Already scanning\n");
 913                 mutex_unlock(&wil->vif_mutex);
 914                 rc = -EAGAIN;
 915                 goto out;
 916         }
 917         mutex_unlock(&wil->vif_mutex);
 918 
 919         if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
 920                 if (!wil->p2p_dev_started) {
 921                         wil_err(wil, "P2P search requested on stopped P2P device\n");
 922                         rc = -EIO;
 923                         goto out;
 924                 }
 925                 /* social scan on P2P_DEVICE is handled as p2p search */
 926                 if (wil_p2p_is_social_scan(request)) {
 927                         vif->scan_request = request;
 928                         if (vif->mid == 0)
 929                                 wil->radio_wdev = wdev;
 930                         rc = wil_p2p_search(vif, request);
 931                         if (rc) {
 932                                 if (vif->mid == 0)
 933                                         wil->radio_wdev =
 934                                                 wil->main_ndev->ieee80211_ptr;
 935                                 vif->scan_request = NULL;
 936                         }
 937                         goto out;
 938                 }
 939         }
 940 
 941         (void)wil_p2p_stop_discovery(vif);
 942 
 943         wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
 944         wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
 945 
 946         for (i = 0; i < request->n_ssids; i++) {
 947                 wil_dbg_misc(wil, "SSID[%d]", i);
 948                 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
 949                                   request->ssids[i].ssid,
 950                                   request->ssids[i].ssid_len, true);
 951         }
 952 
 953         if (request->n_ssids)
 954                 rc = wmi_set_ssid(vif, request->ssids[0].ssid_len,
 955                                   request->ssids[0].ssid);
 956         else
 957                 rc = wmi_set_ssid(vif, 0, NULL);
 958 
 959         if (rc) {
 960                 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
 961                 goto out;
 962         }
 963 
 964         vif->scan_request = request;
 965         mod_timer(&vif->scan_timer, jiffies + WIL6210_SCAN_TO);
 966 
 967         memset(&cmd, 0, sizeof(cmd));
 968         cmd.cmd.scan_type = WMI_ACTIVE_SCAN;
 969         cmd.cmd.num_channels = 0;
 970         n = min(request->n_channels, 4U);
 971         for (i = 0; i < n; i++) {
 972                 int ch = request->channels[i]->hw_value;
 973 
 974                 if (ch == 0) {
 975                         wil_err(wil,
 976                                 "Scan requested for unknown frequency %dMhz\n",
 977                                 request->channels[i]->center_freq);
 978                         continue;
 979                 }
 980                 /* 0-based channel indexes */
 981                 cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
 982                 wil_dbg_misc(wil, "Scan for ch %d  : %d MHz\n", ch,
 983                              request->channels[i]->center_freq);
 984         }
 985 
 986         if (request->ie_len)
 987                 wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
 988                                   request->ie, request->ie_len, true);
 989         else
 990                 wil_dbg_misc(wil, "Scan has no IE's\n");
 991 
 992         rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ,
 993                         request->ie_len, request->ie);
 994         if (rc)
 995                 goto out_restore;
 996 
 997         if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
 998                 cmd.cmd.discovery_mode = 1;
 999                 wil_dbg_misc(wil, "active scan with discovery_mode=1\n");
1000         }
1001 
1002         if (vif->mid == 0)
1003                 wil->radio_wdev = wdev;
1004         rc = wmi_send(wil, WMI_START_SCAN_CMDID, vif->mid,
1005                       &cmd, sizeof(cmd.cmd) +
1006                       cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
1007 
1008 out_restore:
1009         if (rc) {
1010                 del_timer_sync(&vif->scan_timer);
1011                 if (vif->mid == 0)
1012                         wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
1013                 vif->scan_request = NULL;
1014         }
1015 out:
1016         mutex_unlock(&wil->mutex);
1017         return rc;
1018 }
1019 
1020 static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
1021                                     struct wireless_dev *wdev)
1022 {
1023         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1024         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1025 
1026         wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
1027 
1028         mutex_lock(&wil->mutex);
1029         mutex_lock(&wil->vif_mutex);
1030 
1031         if (!vif->scan_request)
1032                 goto out;
1033 
1034         if (wdev != vif->scan_request->wdev) {
1035                 wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
1036                 goto out;
1037         }
1038 
1039         if (wdev == wil->p2p_wdev && wil->radio_wdev == wil->p2p_wdev)
1040                 wil_p2p_stop_radio_operations(wil);
1041         else
1042                 wil_abort_scan(vif, true);
1043 
1044 out:
1045         mutex_unlock(&wil->vif_mutex);
1046         mutex_unlock(&wil->mutex);
1047 }
1048 
1049 static void wil_print_crypto(struct wil6210_priv *wil,
1050                              struct cfg80211_crypto_settings *c)
1051 {
1052         int i, n;
1053 
1054         wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
1055                      c->wpa_versions, c->cipher_group);
1056         wil_dbg_misc(wil, "Pairwise ciphers [%d] {\n", c->n_ciphers_pairwise);
1057         n = min_t(int, c->n_ciphers_pairwise, ARRAY_SIZE(c->ciphers_pairwise));
1058         for (i = 0; i < n; i++)
1059                 wil_dbg_misc(wil, "  [%d] = 0x%08x\n", i,
1060                              c->ciphers_pairwise[i]);
1061         wil_dbg_misc(wil, "}\n");
1062         wil_dbg_misc(wil, "AKM suites [%d] {\n", c->n_akm_suites);
1063         n = min_t(int, c->n_akm_suites, ARRAY_SIZE(c->akm_suites));
1064         for (i = 0; i < n; i++)
1065                 wil_dbg_misc(wil, "  [%d] = 0x%08x\n", i,
1066                              c->akm_suites[i]);
1067         wil_dbg_misc(wil, "}\n");
1068         wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
1069                      c->control_port, be16_to_cpu(c->control_port_ethertype),
1070                      c->control_port_no_encrypt);
1071 }
1072 
1073 static const char *
1074 wil_get_auth_type_name(enum nl80211_auth_type auth_type)
1075 {
1076         switch (auth_type) {
1077         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1078                 return "OPEN_SYSTEM";
1079         case NL80211_AUTHTYPE_SHARED_KEY:
1080                 return "SHARED_KEY";
1081         case NL80211_AUTHTYPE_FT:
1082                 return "FT";
1083         case NL80211_AUTHTYPE_NETWORK_EAP:
1084                 return "NETWORK_EAP";
1085         case NL80211_AUTHTYPE_SAE:
1086                 return "SAE";
1087         case NL80211_AUTHTYPE_AUTOMATIC:
1088                 return "AUTOMATIC";
1089         default:
1090                 return "unknown";
1091         }
1092 }
1093 static void wil_print_connect_params(struct wil6210_priv *wil,
1094                                      struct cfg80211_connect_params *sme)
1095 {
1096         wil_info(wil, "Connecting to:\n");
1097         if (sme->channel) {
1098                 wil_info(wil, "  Channel: %d freq %d\n",
1099                          sme->channel->hw_value, sme->channel->center_freq);
1100         }
1101         if (sme->bssid)
1102                 wil_info(wil, "  BSSID: %pM\n", sme->bssid);
1103         if (sme->ssid)
1104                 print_hex_dump(KERN_INFO, "  SSID: ", DUMP_PREFIX_OFFSET,
1105                                16, 1, sme->ssid, sme->ssid_len, true);
1106         if (sme->prev_bssid)
1107                 wil_info(wil, "  Previous BSSID=%pM\n", sme->prev_bssid);
1108         wil_info(wil, "  Auth Type: %s\n",
1109                  wil_get_auth_type_name(sme->auth_type));
1110         wil_info(wil, "  Privacy: %s\n", sme->privacy ? "secure" : "open");
1111         wil_info(wil, "  PBSS: %d\n", sme->pbss);
1112         wil_print_crypto(wil, &sme->crypto);
1113 }
1114 
1115 static int wil_ft_connect(struct wiphy *wiphy,
1116                           struct net_device *ndev,
1117                           struct cfg80211_connect_params *sme)
1118 {
1119         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1120         struct wil6210_vif *vif = ndev_to_vif(ndev);
1121         struct wmi_ft_auth_cmd auth_cmd;
1122         int rc;
1123 
1124         if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) {
1125                 wil_err(wil, "FT: FW does not support FT roaming\n");
1126                 return -EOPNOTSUPP;
1127         }
1128 
1129         if (!sme->prev_bssid) {
1130                 wil_err(wil, "FT: prev_bssid was not set\n");
1131                 return -EINVAL;
1132         }
1133 
1134         if (ether_addr_equal(sme->prev_bssid, sme->bssid)) {
1135                 wil_err(wil, "FT: can not roam to same AP\n");
1136                 return -EINVAL;
1137         }
1138 
1139         if (!test_bit(wil_vif_fwconnected, vif->status)) {
1140                 wil_err(wil, "FT: roam while not connected\n");
1141                 return -EINVAL;
1142         }
1143 
1144         if (vif->privacy != sme->privacy) {
1145                 wil_err(wil, "FT: privacy mismatch, current (%d) roam (%d)\n",
1146                         vif->privacy, sme->privacy);
1147                 return -EINVAL;
1148         }
1149 
1150         if (sme->pbss) {
1151                 wil_err(wil, "FT: roam is not valid for PBSS\n");
1152                 return -EINVAL;
1153         }
1154 
1155         memset(&auth_cmd, 0, sizeof(auth_cmd));
1156         auth_cmd.channel = sme->channel->hw_value - 1;
1157         ether_addr_copy(auth_cmd.bssid, sme->bssid);
1158 
1159         wil_info(wil, "FT: roaming\n");
1160 
1161         set_bit(wil_vif_ft_roam, vif->status);
1162         rc = wmi_send(wil, WMI_FT_AUTH_CMDID, vif->mid,
1163                       &auth_cmd, sizeof(auth_cmd));
1164         if (rc == 0)
1165                 mod_timer(&vif->connect_timer,
1166                           jiffies + msecs_to_jiffies(5000));
1167         else
1168                 clear_bit(wil_vif_ft_roam, vif->status);
1169 
1170         return rc;
1171 }
1172 
1173 static int wil_get_wmi_edmg_channel(struct wil6210_priv *wil, u8 edmg_bw_config,
1174                                     u8 edmg_channels, u8 *wmi_ch)
1175 {
1176         if (!edmg_bw_config) {
1177                 *wmi_ch = 0;
1178                 return 0;
1179         } else if (edmg_bw_config == WIL_EDMG_BW_CONFIGURATION) {
1180                 /* convert from edmg channel bitmap into edmg channel number */
1181                 switch (edmg_channels) {
1182                 case WIL_EDMG_CHANNEL_9_SUBCHANNELS:
1183                         return wil_spec2wmi_ch(9, wmi_ch);
1184                 case WIL_EDMG_CHANNEL_10_SUBCHANNELS:
1185                         return wil_spec2wmi_ch(10, wmi_ch);
1186                 case WIL_EDMG_CHANNEL_11_SUBCHANNELS:
1187                         return wil_spec2wmi_ch(11, wmi_ch);
1188                 default:
1189                         wil_err(wil, "Unsupported edmg channel bitmap 0x%x\n",
1190                                 edmg_channels);
1191                         return -EINVAL;
1192                 }
1193         } else {
1194                 wil_err(wil, "Unsupported EDMG BW configuration %d\n",
1195                         edmg_bw_config);
1196                 return -EINVAL;
1197         }
1198 }
1199 
1200 static int wil_cfg80211_connect(struct wiphy *wiphy,
1201                                 struct net_device *ndev,
1202                                 struct cfg80211_connect_params *sme)
1203 {
1204         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1205         struct wil6210_vif *vif = ndev_to_vif(ndev);
1206         struct cfg80211_bss *bss;
1207         struct wmi_connect_cmd conn;
1208         const u8 *ssid_eid;
1209         const u8 *rsn_eid;
1210         int ch;
1211         int rc = 0;
1212         bool is_ft_roam = false;
1213         u8 network_type;
1214         enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
1215 
1216         wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid);
1217         wil_print_connect_params(wil, sme);
1218 
1219         if (sme->auth_type == NL80211_AUTHTYPE_FT)
1220                 is_ft_roam = true;
1221         if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC &&
1222             test_bit(wil_vif_fwconnected, vif->status))
1223                 is_ft_roam = true;
1224 
1225         if (!is_ft_roam)
1226                 if (test_bit(wil_vif_fwconnecting, vif->status) ||
1227                     test_bit(wil_vif_fwconnected, vif->status))
1228                         return -EALREADY;
1229 
1230         if (sme->ie_len > WMI_MAX_IE_LEN) {
1231                 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
1232                 return -ERANGE;
1233         }
1234 
1235         rsn_eid = sme->ie ?
1236                         cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
1237                         NULL;
1238         if (sme->privacy && !rsn_eid) {
1239                 wil_info(wil, "WSC connection\n");
1240                 if (is_ft_roam) {
1241                         wil_err(wil, "No WSC with FT roam\n");
1242                         return -EINVAL;
1243                 }
1244         }
1245 
1246         if (sme->pbss)
1247                 bss_type = IEEE80211_BSS_TYPE_PBSS;
1248 
1249         bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1250                                sme->ssid, sme->ssid_len,
1251                                bss_type, IEEE80211_PRIVACY_ANY);
1252         if (!bss) {
1253                 wil_err(wil, "Unable to find BSS\n");
1254                 return -ENOENT;
1255         }
1256 
1257         ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1258         if (!ssid_eid) {
1259                 wil_err(wil, "No SSID\n");
1260                 rc = -ENOENT;
1261                 goto out;
1262         }
1263         vif->privacy = sme->privacy;
1264         vif->pbss = sme->pbss;
1265 
1266         rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
1267         if (rc)
1268                 goto out;
1269 
1270         switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
1271         case WLAN_CAPABILITY_DMG_TYPE_AP:
1272                 network_type = WMI_NETTYPE_INFRA;
1273                 break;
1274         case WLAN_CAPABILITY_DMG_TYPE_PBSS:
1275                 network_type = WMI_NETTYPE_P2P;
1276                 break;
1277         default:
1278                 wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
1279                         bss->capability);
1280                 rc = -EINVAL;
1281                 goto out;
1282         }
1283 
1284         ch = bss->channel->hw_value;
1285         if (ch == 0) {
1286                 wil_err(wil, "BSS at unknown frequency %dMhz\n",
1287                         bss->channel->center_freq);
1288                 rc = -EOPNOTSUPP;
1289                 goto out;
1290         }
1291 
1292         if (is_ft_roam) {
1293                 if (network_type != WMI_NETTYPE_INFRA) {
1294                         wil_err(wil, "FT: Unsupported BSS type, capability= 0x%04x\n",
1295                                 bss->capability);
1296                         rc = -EINVAL;
1297                         goto out;
1298                 }
1299                 rc = wil_ft_connect(wiphy, ndev, sme);
1300                 if (rc == 0)
1301                         vif->bss = bss;
1302                 goto out;
1303         }
1304 
1305         if (vif->privacy) {
1306                 /* For secure assoc, remove old keys */
1307                 rc = wmi_del_cipher_key(vif, 0, bss->bssid,
1308                                         WMI_KEY_USE_PAIRWISE);
1309                 if (rc) {
1310                         wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n");
1311                         goto out;
1312                 }
1313                 rc = wmi_del_cipher_key(vif, 0, bss->bssid,
1314                                         WMI_KEY_USE_RX_GROUP);
1315                 if (rc) {
1316                         wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n");
1317                         goto out;
1318                 }
1319         }
1320 
1321         /* WMI_CONNECT_CMD */
1322         memset(&conn, 0, sizeof(conn));
1323         conn.network_type = network_type;
1324         if (vif->privacy) {
1325                 if (rsn_eid) { /* regular secure connection */
1326                         conn.dot11_auth_mode = WMI_AUTH11_SHARED;
1327                         conn.auth_mode = WMI_AUTH_WPA2_PSK;
1328                         conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
1329                         conn.pairwise_crypto_len = 16;
1330                         conn.group_crypto_type = WMI_CRYPT_AES_GCMP;
1331                         conn.group_crypto_len = 16;
1332                 } else { /* WSC */
1333                         conn.dot11_auth_mode = WMI_AUTH11_WSC;
1334                         conn.auth_mode = WMI_AUTH_NONE;
1335                 }
1336         } else { /* insecure connection */
1337                 conn.dot11_auth_mode = WMI_AUTH11_OPEN;
1338                 conn.auth_mode = WMI_AUTH_NONE;
1339         }
1340 
1341         conn.ssid_len = min_t(u8, ssid_eid[1], 32);
1342         memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
1343         conn.channel = ch - 1;
1344 
1345         rc = wil_get_wmi_edmg_channel(wil, sme->edmg.bw_config,
1346                                       sme->edmg.channels, &conn.edmg_channel);
1347         if (rc < 0)
1348                 return rc;
1349 
1350         ether_addr_copy(conn.bssid, bss->bssid);
1351         ether_addr_copy(conn.dst_mac, bss->bssid);
1352 
1353         set_bit(wil_vif_fwconnecting, vif->status);
1354 
1355         rc = wmi_send(wil, WMI_CONNECT_CMDID, vif->mid, &conn, sizeof(conn));
1356         if (rc == 0) {
1357                 netif_carrier_on(ndev);
1358                 if (!wil_has_other_active_ifaces(wil, ndev, false, true))
1359                         wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
1360                 vif->bss = bss;
1361                 /* Connect can take lots of time */
1362                 mod_timer(&vif->connect_timer,
1363                           jiffies + msecs_to_jiffies(5000));
1364         } else {
1365                 clear_bit(wil_vif_fwconnecting, vif->status);
1366         }
1367 
1368  out:
1369         cfg80211_put_bss(wiphy, bss);
1370 
1371         return rc;
1372 }
1373 
1374 static int wil_cfg80211_disconnect(struct wiphy *wiphy,
1375                                    struct net_device *ndev,
1376                                    u16 reason_code)
1377 {
1378         int rc;
1379         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1380         struct wil6210_vif *vif = ndev_to_vif(ndev);
1381 
1382         wil_dbg_misc(wil, "disconnect: reason=%d, mid=%d\n",
1383                      reason_code, vif->mid);
1384 
1385         if (!(test_bit(wil_vif_fwconnecting, vif->status) ||
1386               test_bit(wil_vif_fwconnected, vif->status))) {
1387                 wil_err(wil, "Disconnect was called while disconnected\n");
1388                 return 0;
1389         }
1390 
1391         vif->locally_generated_disc = true;
1392         rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0,
1393                       WMI_DISCONNECT_EVENTID, NULL, 0,
1394                       WIL6210_DISCONNECT_TO_MS);
1395         if (rc)
1396                 wil_err(wil, "disconnect error %d\n", rc);
1397 
1398         return rc;
1399 }
1400 
1401 static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1402 {
1403         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1404         int rc;
1405 
1406         /* these parameters are explicitly not supported */
1407         if (changed & (WIPHY_PARAM_RETRY_LONG |
1408                        WIPHY_PARAM_FRAG_THRESHOLD |
1409                        WIPHY_PARAM_RTS_THRESHOLD))
1410                 return -ENOTSUPP;
1411 
1412         if (changed & WIPHY_PARAM_RETRY_SHORT) {
1413                 rc = wmi_set_mgmt_retry(wil, wiphy->retry_short);
1414                 if (rc)
1415                         return rc;
1416         }
1417 
1418         return 0;
1419 }
1420 
1421 int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
1422                          struct cfg80211_mgmt_tx_params *params,
1423                          u64 *cookie)
1424 {
1425         const u8 *buf = params->buf;
1426         size_t len = params->len;
1427         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1428         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1429         int rc;
1430         bool tx_status;
1431 
1432         wil_dbg_misc(wil, "mgmt_tx: channel %d offchan %d, wait %d\n",
1433                      params->chan ? params->chan->hw_value : -1,
1434                      params->offchan,
1435                      params->wait);
1436 
1437         /* Note, currently we support the "wait" parameter only on AP mode.
1438          * In other modes, user-space must call remain_on_channel before
1439          * mgmt_tx or listen on a channel other than active one.
1440          */
1441 
1442         if (params->chan && params->chan->hw_value == 0) {
1443                 wil_err(wil, "invalid channel\n");
1444                 return -EINVAL;
1445         }
1446 
1447         if (wdev->iftype != NL80211_IFTYPE_AP) {
1448                 wil_dbg_misc(wil,
1449                              "send WMI_SW_TX_REQ_CMDID on non-AP interfaces\n");
1450                 rc = wmi_mgmt_tx(vif, buf, len);
1451                 goto out;
1452         }
1453 
1454         if (!params->chan || params->chan->hw_value == vif->channel) {
1455                 wil_dbg_misc(wil,
1456                              "send WMI_SW_TX_REQ_CMDID for on-channel\n");
1457                 rc = wmi_mgmt_tx(vif, buf, len);
1458                 goto out;
1459         }
1460 
1461         if (params->offchan == 0) {
1462                 wil_err(wil,
1463                         "invalid channel params: current %d requested %d, off-channel not allowed\n",
1464                         vif->channel, params->chan->hw_value);
1465                 return -EBUSY;
1466         }
1467 
1468         /* use the wmi_mgmt_tx_ext only on AP mode and off-channel */
1469         rc = wmi_mgmt_tx_ext(vif, buf, len, params->chan->hw_value,
1470                              params->wait);
1471 
1472 out:
1473         /* when the sent packet was not acked by receiver(ACK=0), rc will
1474          * be -EAGAIN. In this case this function needs to return success,
1475          * the ACK=0 will be reflected in tx_status.
1476          */
1477         tx_status = (rc == 0);
1478         rc = (rc == -EAGAIN) ? 0 : rc;
1479         cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
1480                                 tx_status, GFP_KERNEL);
1481 
1482         return rc;
1483 }
1484 
1485 static int wil_cfg80211_set_channel(struct wiphy *wiphy,
1486                                     struct cfg80211_chan_def *chandef)
1487 {
1488         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1489 
1490         wil->monitor_chandef = *chandef;
1491 
1492         return 0;
1493 }
1494 
1495 static enum wmi_key_usage wil_detect_key_usage(struct wireless_dev *wdev,
1496                                                bool pairwise)
1497 {
1498         struct wil6210_priv *wil = wdev_to_wil(wdev);
1499         enum wmi_key_usage rc;
1500 
1501         if (pairwise) {
1502                 rc = WMI_KEY_USE_PAIRWISE;
1503         } else {
1504                 switch (wdev->iftype) {
1505                 case NL80211_IFTYPE_STATION:
1506                 case NL80211_IFTYPE_P2P_CLIENT:
1507                         rc = WMI_KEY_USE_RX_GROUP;
1508                         break;
1509                 case NL80211_IFTYPE_AP:
1510                 case NL80211_IFTYPE_P2P_GO:
1511                         rc = WMI_KEY_USE_TX_GROUP;
1512                         break;
1513                 default:
1514                         /* TODO: Rx GTK or Tx GTK? */
1515                         wil_err(wil, "Can't determine GTK type\n");
1516                         rc = WMI_KEY_USE_RX_GROUP;
1517                         break;
1518                 }
1519         }
1520         wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
1521 
1522         return rc;
1523 }
1524 
1525 static struct wil_sta_info *
1526 wil_find_sta_by_key_usage(struct wil6210_priv *wil, u8 mid,
1527                           enum wmi_key_usage key_usage, const u8 *mac_addr)
1528 {
1529         int cid = -EINVAL;
1530 
1531         if (key_usage == WMI_KEY_USE_TX_GROUP)
1532                 return NULL; /* not needed */
1533 
1534         /* supplicant provides Rx group key in STA mode with NULL MAC address */
1535         if (mac_addr)
1536                 cid = wil_find_cid(wil, mid, mac_addr);
1537         else if (key_usage == WMI_KEY_USE_RX_GROUP)
1538                 cid = wil_find_cid_by_idx(wil, mid, 0);
1539         if (cid < 0) {
1540                 wil_err(wil, "No CID for %pM %s\n", mac_addr,
1541                         key_usage_str[key_usage]);
1542                 return ERR_PTR(cid);
1543         }
1544 
1545         return &wil->sta[cid];
1546 }
1547 
1548 void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
1549                        struct wil_sta_info *cs,
1550                        struct key_params *params)
1551 {
1552         struct wil_tid_crypto_rx_single *cc;
1553         int tid;
1554 
1555         if (!cs)
1556                 return;
1557 
1558         switch (key_usage) {
1559         case WMI_KEY_USE_STORE_PTK:
1560         case WMI_KEY_USE_PAIRWISE:
1561                 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1562                         cc = &cs->tid_crypto_rx[tid].key_id[key_index];
1563                         if (params->seq)
1564                                 memcpy(cc->pn, params->seq,
1565                                        IEEE80211_GCMP_PN_LEN);
1566                         else
1567                                 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
1568                         cc->key_set = true;
1569                 }
1570                 break;
1571         case WMI_KEY_USE_RX_GROUP:
1572                 cc = &cs->group_crypto_rx.key_id[key_index];
1573                 if (params->seq)
1574                         memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
1575                 else
1576                         memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
1577                 cc->key_set = true;
1578                 break;
1579         default:
1580                 break;
1581         }
1582 }
1583 
1584 static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
1585                            struct wil_sta_info *cs)
1586 {
1587         struct wil_tid_crypto_rx_single *cc;
1588         int tid;
1589 
1590         if (!cs)
1591                 return;
1592 
1593         switch (key_usage) {
1594         case WMI_KEY_USE_PAIRWISE:
1595                 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1596                         cc = &cs->tid_crypto_rx[tid].key_id[key_index];
1597                         cc->key_set = false;
1598                 }
1599                 break;
1600         case WMI_KEY_USE_RX_GROUP:
1601                 cc = &cs->group_crypto_rx.key_id[key_index];
1602                 cc->key_set = false;
1603                 break;
1604         default:
1605                 break;
1606         }
1607 }
1608 
1609 static int wil_cfg80211_add_key(struct wiphy *wiphy,
1610                                 struct net_device *ndev,
1611                                 u8 key_index, bool pairwise,
1612                                 const u8 *mac_addr,
1613                                 struct key_params *params)
1614 {
1615         int rc;
1616         struct wil6210_vif *vif = ndev_to_vif(ndev);
1617         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1618         struct wireless_dev *wdev = vif_to_wdev(vif);
1619         enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise);
1620         struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid,
1621                                                             key_usage,
1622                                                             mac_addr);
1623 
1624         if (!params) {
1625                 wil_err(wil, "NULL params\n");
1626                 return -EINVAL;
1627         }
1628 
1629         wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
1630                      mac_addr, key_usage_str[key_usage], key_index,
1631                      params->seq_len, params->seq);
1632 
1633         if (IS_ERR(cs)) {
1634                 /* in FT, sta info may not be available as add_key may be
1635                  * sent by host before FW sends WMI_CONNECT_EVENT
1636                  */
1637                 if (!test_bit(wil_vif_ft_roam, vif->status)) {
1638                         wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
1639                                 mac_addr, key_usage_str[key_usage], key_index,
1640                                 params->seq_len, params->seq);
1641                         return -EINVAL;
1642                 }
1643         }
1644 
1645         if (!IS_ERR(cs))
1646                 wil_del_rx_key(key_index, key_usage, cs);
1647 
1648         if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
1649                 wil_err(wil,
1650                         "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
1651                         params->seq_len, mac_addr,
1652                         key_usage_str[key_usage], key_index,
1653                         params->seq_len, params->seq);
1654                 return -EINVAL;
1655         }
1656 
1657         spin_lock_bh(&wil->eap_lock);
1658         if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION &&
1659             (vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED ||
1660              vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) {
1661                 key_usage = WMI_KEY_USE_STORE_PTK;
1662                 vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT;
1663                 wil_dbg_misc(wil, "Store EAPOL key\n");
1664         }
1665         spin_unlock_bh(&wil->eap_lock);
1666 
1667         rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len,
1668                                 params->key, key_usage);
1669         if (!rc && !IS_ERR(cs)) {
1670                 /* update local storage used for AP recovery */
1671                 if (key_usage == WMI_KEY_USE_TX_GROUP && params->key &&
1672                     params->key_len <= WMI_MAX_KEY_LEN) {
1673                         vif->gtk_index = key_index;
1674                         memcpy(vif->gtk, params->key, params->key_len);
1675                         vif->gtk_len = params->key_len;
1676                 }
1677                 /* in FT set crypto will take place upon receiving
1678                  * WMI_RING_EN_EVENTID event
1679                  */
1680                 wil_set_crypto_rx(key_index, key_usage, cs, params);
1681         }
1682 
1683         return rc;
1684 }
1685 
1686 static int wil_cfg80211_del_key(struct wiphy *wiphy,
1687                                 struct net_device *ndev,
1688                                 u8 key_index, bool pairwise,
1689                                 const u8 *mac_addr)
1690 {
1691         struct wil6210_vif *vif = ndev_to_vif(ndev);
1692         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1693         struct wireless_dev *wdev = vif_to_wdev(vif);
1694         enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise);
1695         struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid,
1696                                                             key_usage,
1697                                                             mac_addr);
1698 
1699         wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
1700                      key_usage_str[key_usage], key_index);
1701 
1702         if (IS_ERR(cs))
1703                 wil_info(wil, "Not connected, %pM %s[%d]\n",
1704                          mac_addr, key_usage_str[key_usage], key_index);
1705 
1706         if (!IS_ERR_OR_NULL(cs))
1707                 wil_del_rx_key(key_index, key_usage, cs);
1708 
1709         return wmi_del_cipher_key(vif, key_index, mac_addr, key_usage);
1710 }
1711 
1712 /* Need to be present or wiphy_new() will WARN */
1713 static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
1714                                         struct net_device *ndev,
1715                                         u8 key_index, bool unicast,
1716                                         bool multicast)
1717 {
1718         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1719 
1720         wil_dbg_misc(wil, "set_default_key: entered\n");
1721         return 0;
1722 }
1723 
1724 static int wil_remain_on_channel(struct wiphy *wiphy,
1725                                  struct wireless_dev *wdev,
1726                                  struct ieee80211_channel *chan,
1727                                  unsigned int duration,
1728                                  u64 *cookie)
1729 {
1730         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1731         int rc;
1732 
1733         wil_dbg_misc(wil,
1734                      "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
1735                      chan->center_freq, duration, wdev->iftype);
1736 
1737         rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
1738         return rc;
1739 }
1740 
1741 static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
1742                                         struct wireless_dev *wdev,
1743                                         u64 cookie)
1744 {
1745         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1746         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1747 
1748         wil_dbg_misc(wil, "cancel_remain_on_channel\n");
1749 
1750         return wil_p2p_cancel_listen(vif, cookie);
1751 }
1752 
1753 /**
1754  * find a specific IE in a list of IEs
1755  * return a pointer to the beginning of IE in the list
1756  * or NULL if not found
1757  */
1758 static const u8 *_wil_cfg80211_find_ie(const u8 *ies, u16 ies_len, const u8 *ie,
1759                                        u16 ie_len)
1760 {
1761         struct ieee80211_vendor_ie *vie;
1762         u32 oui;
1763 
1764         /* IE tag at offset 0, length at offset 1 */
1765         if (ie_len < 2 || 2 + ie[1] > ie_len)
1766                 return NULL;
1767 
1768         if (ie[0] != WLAN_EID_VENDOR_SPECIFIC)
1769                 return cfg80211_find_ie(ie[0], ies, ies_len);
1770 
1771         /* make sure there is room for 3 bytes OUI + 1 byte OUI type */
1772         if (ie[1] < 4)
1773                 return NULL;
1774         vie = (struct ieee80211_vendor_ie *)ie;
1775         oui = vie->oui[0] << 16 | vie->oui[1] << 8 | vie->oui[2];
1776         return cfg80211_find_vendor_ie(oui, vie->oui_type, ies,
1777                                        ies_len);
1778 }
1779 
1780 /**
1781  * merge the IEs in two lists into a single list.
1782  * do not include IEs from the second list which exist in the first list.
1783  * add only vendor specific IEs from second list to keep
1784  * the merged list sorted (since vendor-specific IE has the
1785  * highest tag number)
1786  * caller must free the allocated memory for merged IEs
1787  */
1788 static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
1789                                          const u8 *ies2, u16 ies2_len,
1790                                          u8 **merged_ies, u16 *merged_len)
1791 {
1792         u8 *buf, *dpos;
1793         const u8 *spos;
1794 
1795         if (!ies1)
1796                 ies1_len = 0;
1797 
1798         if (!ies2)
1799                 ies2_len = 0;
1800 
1801         if (ies1_len == 0 && ies2_len == 0) {
1802                 *merged_ies = NULL;
1803                 *merged_len = 0;
1804                 return 0;
1805         }
1806 
1807         buf = kmalloc(ies1_len + ies2_len, GFP_KERNEL);
1808         if (!buf)
1809                 return -ENOMEM;
1810         if (ies1)
1811                 memcpy(buf, ies1, ies1_len);
1812         dpos = buf + ies1_len;
1813         spos = ies2;
1814         while (spos && (spos + 1 < ies2 + ies2_len)) {
1815                 /* IE tag at offset 0, length at offset 1 */
1816                 u16 ielen = 2 + spos[1];
1817 
1818                 if (spos + ielen > ies2 + ies2_len)
1819                         break;
1820                 if (spos[0] == WLAN_EID_VENDOR_SPECIFIC &&
1821                     (!ies1 || !_wil_cfg80211_find_ie(ies1, ies1_len,
1822                                                      spos, ielen))) {
1823                         memcpy(dpos, spos, ielen);
1824                         dpos += ielen;
1825                 }
1826                 spos += ielen;
1827         }
1828 
1829         *merged_ies = buf;
1830         *merged_len = dpos - buf;
1831         return 0;
1832 }
1833 
1834 static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
1835 {
1836         wil_hex_dump_misc("head     ", DUMP_PREFIX_OFFSET, 16, 1,
1837                           b->head, b->head_len, true);
1838         wil_hex_dump_misc("tail     ", DUMP_PREFIX_OFFSET, 16, 1,
1839                           b->tail, b->tail_len, true);
1840         wil_hex_dump_misc("BCON IE  ", DUMP_PREFIX_OFFSET, 16, 1,
1841                           b->beacon_ies, b->beacon_ies_len, true);
1842         wil_hex_dump_misc("PROBE    ", DUMP_PREFIX_OFFSET, 16, 1,
1843                           b->probe_resp, b->probe_resp_len, true);
1844         wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
1845                           b->proberesp_ies, b->proberesp_ies_len, true);
1846         wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
1847                           b->assocresp_ies, b->assocresp_ies_len, true);
1848 }
1849 
1850 /* internal functions for device reset and starting AP */
1851 static u8 *
1852 _wil_cfg80211_get_proberesp_ies(const u8 *proberesp, u16 proberesp_len,
1853                                 u16 *ies_len)
1854 {
1855         u8 *ies = NULL;
1856 
1857         if (proberesp) {
1858                 struct ieee80211_mgmt *f =
1859                         (struct ieee80211_mgmt *)proberesp;
1860                 size_t hlen = offsetof(struct ieee80211_mgmt,
1861                                        u.probe_resp.variable);
1862 
1863                 ies = f->u.probe_resp.variable;
1864                 if (ies_len)
1865                         *ies_len = proberesp_len - hlen;
1866         }
1867 
1868         return ies;
1869 }
1870 
1871 static int _wil_cfg80211_set_ies(struct wil6210_vif *vif,
1872                                  struct cfg80211_beacon_data *bcon)
1873 {
1874         int rc;
1875         u16 len = 0, proberesp_len = 0;
1876         u8 *ies = NULL, *proberesp;
1877 
1878         /* update local storage used for AP recovery */
1879         wil_memdup_ie(&vif->proberesp, &vif->proberesp_len, bcon->probe_resp,
1880                       bcon->probe_resp_len);
1881         wil_memdup_ie(&vif->proberesp_ies, &vif->proberesp_ies_len,
1882                       bcon->proberesp_ies, bcon->proberesp_ies_len);
1883         wil_memdup_ie(&vif->assocresp_ies, &vif->assocresp_ies_len,
1884                       bcon->assocresp_ies, bcon->assocresp_ies_len);
1885 
1886         proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp,
1887                                                     bcon->probe_resp_len,
1888                                                     &proberesp_len);
1889         rc = _wil_cfg80211_merge_extra_ies(proberesp,
1890                                            proberesp_len,
1891                                            bcon->proberesp_ies,
1892                                            bcon->proberesp_ies_len,
1893                                            &ies, &len);
1894 
1895         if (rc)
1896                 goto out;
1897 
1898         rc = wmi_set_ie(vif, WMI_FRAME_PROBE_RESP, len, ies);
1899         if (rc)
1900                 goto out;
1901 
1902         if (bcon->assocresp_ies)
1903                 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP,
1904                                 bcon->assocresp_ies_len, bcon->assocresp_ies);
1905         else
1906                 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP, len, ies);
1907 #if 0 /* to use beacon IE's, remove this #if 0 */
1908         if (rc)
1909                 goto out;
1910 
1911         rc = wmi_set_ie(vif, WMI_FRAME_BEACON,
1912                         bcon->tail_len, bcon->tail);
1913 #endif
1914 out:
1915         kfree(ies);
1916         return rc;
1917 }
1918 
1919 static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1920                                   struct net_device *ndev,
1921                                   const u8 *ssid, size_t ssid_len, u32 privacy,
1922                                   int bi, u8 chan, u8 wmi_edmg_channel,
1923                                   struct cfg80211_beacon_data *bcon,
1924                                   u8 hidden_ssid, u32 pbss)
1925 {
1926         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1927         struct wil6210_vif *vif = ndev_to_vif(ndev);
1928         int rc;
1929         struct wireless_dev *wdev = ndev->ieee80211_ptr;
1930         u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
1931         u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO);
1932         u16 proberesp_len = 0;
1933         u8 *proberesp;
1934         bool ft = false;
1935 
1936         if (pbss)
1937                 wmi_nettype = WMI_NETTYPE_P2P;
1938 
1939         wil_dbg_misc(wil, "start_ap: mid=%d, is_go=%d\n", vif->mid, is_go);
1940         if (is_go && !pbss) {
1941                 wil_err(wil, "P2P GO must be in PBSS\n");
1942                 return -ENOTSUPP;
1943         }
1944 
1945         wil_set_recovery_state(wil, fw_recovery_idle);
1946 
1947         proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp,
1948                                                     bcon->probe_resp_len,
1949                                                     &proberesp_len);
1950         /* check that the probe response IEs has a MDE */
1951         if ((proberesp && proberesp_len > 0 &&
1952              cfg80211_find_ie(WLAN_EID_MOBILITY_DOMAIN,
1953                               proberesp,
1954                               proberesp_len)))
1955                 ft = true;
1956 
1957         if (ft) {
1958                 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING,
1959                               wil->fw_capabilities)) {
1960                         wil_err(wil, "FW does not support FT roaming\n");
1961                         return -ENOTSUPP;
1962                 }
1963                 set_bit(wil_vif_ft_roam, vif->status);
1964         }
1965 
1966         mutex_lock(&wil->mutex);
1967 
1968         if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
1969                 __wil_down(wil);
1970                 rc = __wil_up(wil);
1971                 if (rc)
1972                         goto out;
1973         }
1974 
1975         rc = wmi_set_ssid(vif, ssid_len, ssid);
1976         if (rc)
1977                 goto out;
1978 
1979         rc = _wil_cfg80211_set_ies(vif, bcon);
1980         if (rc)
1981                 goto out;
1982 
1983         vif->privacy = privacy;
1984         vif->channel = chan;
1985         vif->wmi_edmg_channel = wmi_edmg_channel;
1986         vif->hidden_ssid = hidden_ssid;
1987         vif->pbss = pbss;
1988         vif->bi = bi;
1989         memcpy(vif->ssid, ssid, ssid_len);
1990         vif->ssid_len = ssid_len;
1991 
1992         netif_carrier_on(ndev);
1993         if (!wil_has_other_active_ifaces(wil, ndev, false, true))
1994                 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
1995 
1996         rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, wmi_edmg_channel,
1997                            hidden_ssid, is_go);
1998         if (rc)
1999                 goto err_pcp_start;
2000 
2001         rc = wil_bcast_init(vif);
2002         if (rc)
2003                 goto err_bcast;
2004 
2005         goto out; /* success */
2006 
2007 err_bcast:
2008         wmi_pcp_stop(vif);
2009 err_pcp_start:
2010         netif_carrier_off(ndev);
2011         if (!wil_has_other_active_ifaces(wil, ndev, false, true))
2012                 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
2013 out:
2014         mutex_unlock(&wil->mutex);
2015         return rc;
2016 }
2017 
2018 void wil_cfg80211_ap_recovery(struct wil6210_priv *wil)
2019 {
2020         int rc, i;
2021         struct wiphy *wiphy = wil_to_wiphy(wil);
2022 
2023         for (i = 0; i < GET_MAX_VIFS(wil); i++) {
2024                 struct wil6210_vif *vif = wil->vifs[i];
2025                 struct net_device *ndev;
2026                 struct cfg80211_beacon_data bcon = {};
2027                 struct key_params key_params = {};
2028 
2029                 if (!vif || vif->ssid_len == 0)
2030                         continue;
2031 
2032                 ndev = vif_to_ndev(vif);
2033                 bcon.proberesp_ies = vif->proberesp_ies;
2034                 bcon.assocresp_ies = vif->assocresp_ies;
2035                 bcon.probe_resp = vif->proberesp;
2036                 bcon.proberesp_ies_len = vif->proberesp_ies_len;
2037                 bcon.assocresp_ies_len = vif->assocresp_ies_len;
2038                 bcon.probe_resp_len = vif->proberesp_len;
2039 
2040                 wil_info(wil,
2041                          "AP (vif %d) recovery: privacy %d, bi %d, channel %d, hidden %d, pbss %d\n",
2042                          i, vif->privacy, vif->bi, vif->channel,
2043                          vif->hidden_ssid, vif->pbss);
2044                 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
2045                                   vif->ssid, vif->ssid_len, true);
2046                 rc = _wil_cfg80211_start_ap(wiphy, ndev,
2047                                             vif->ssid, vif->ssid_len,
2048                                             vif->privacy, vif->bi,
2049                                             vif->channel,
2050                                             vif->wmi_edmg_channel, &bcon,
2051                                             vif->hidden_ssid, vif->pbss);
2052                 if (rc) {
2053                         wil_err(wil, "vif %d recovery failed (%d)\n", i, rc);
2054                         continue;
2055                 }
2056 
2057                 if (!vif->privacy || vif->gtk_len == 0)
2058                         continue;
2059 
2060                 key_params.key = vif->gtk;
2061                 key_params.key_len = vif->gtk_len;
2062                 key_params.seq_len = IEEE80211_GCMP_PN_LEN;
2063                 rc = wil_cfg80211_add_key(wiphy, ndev, vif->gtk_index, false,
2064                                           NULL, &key_params);
2065                 if (rc)
2066                         wil_err(wil, "vif %d recovery add key failed (%d)\n",
2067                                 i, rc);
2068         }
2069 }
2070 
2071 static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
2072                                       struct net_device *ndev,
2073                                       struct cfg80211_beacon_data *bcon)
2074 {
2075         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2076         struct wireless_dev *wdev = ndev->ieee80211_ptr;
2077         struct wil6210_vif *vif = ndev_to_vif(ndev);
2078         int rc;
2079         u32 privacy = 0;
2080 
2081         wil_dbg_misc(wil, "change_beacon, mid=%d\n", vif->mid);
2082         wil_print_bcon_data(bcon);
2083 
2084         if (bcon->tail &&
2085             cfg80211_find_ie(WLAN_EID_RSN, bcon->tail,
2086                              bcon->tail_len))
2087                 privacy = 1;
2088 
2089         memcpy(vif->ssid, wdev->ssid, wdev->ssid_len);
2090         vif->ssid_len = wdev->ssid_len;
2091 
2092         /* in case privacy has changed, need to restart the AP */
2093         if (vif->privacy != privacy) {
2094                 wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n",
2095                              vif->privacy, privacy);
2096 
2097                 rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid,
2098                                             vif->ssid_len, privacy,
2099                                             wdev->beacon_interval,
2100                                             vif->channel,
2101                                             vif->wmi_edmg_channel, bcon,
2102                                             vif->hidden_ssid,
2103                                             vif->pbss);
2104         } else {
2105                 rc = _wil_cfg80211_set_ies(vif, bcon);
2106         }
2107 
2108         return rc;
2109 }
2110 
2111 static int wil_cfg80211_start_ap(struct wiphy *wiphy,
2112                                  struct net_device *ndev,
2113                                  struct cfg80211_ap_settings *info)
2114 {
2115         int rc;
2116         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2117         struct ieee80211_channel *channel = info->chandef.chan;
2118         struct cfg80211_beacon_data *bcon = &info->beacon;
2119         struct cfg80211_crypto_settings *crypto = &info->crypto;
2120         u8 wmi_edmg_channel;
2121         u8 hidden_ssid;
2122 
2123         wil_dbg_misc(wil, "start_ap\n");
2124 
2125         rc = wil_get_wmi_edmg_channel(wil, info->chandef.edmg.bw_config,
2126                                       info->chandef.edmg.channels,
2127                                       &wmi_edmg_channel);
2128         if (rc < 0)
2129                 return rc;
2130 
2131         if (!channel) {
2132                 wil_err(wil, "AP: No channel???\n");
2133                 return -EINVAL;
2134         }
2135 
2136         switch (info->hidden_ssid) {
2137         case NL80211_HIDDEN_SSID_NOT_IN_USE:
2138                 hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
2139                 break;
2140 
2141         case NL80211_HIDDEN_SSID_ZERO_LEN:
2142                 hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY;
2143                 break;
2144 
2145         case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
2146                 hidden_ssid = WMI_HIDDEN_SSID_CLEAR;
2147                 break;
2148 
2149         default:
2150                 wil_err(wil, "AP: Invalid hidden SSID %d\n", info->hidden_ssid);
2151                 return -EOPNOTSUPP;
2152         }
2153         wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
2154                      channel->center_freq, info->privacy ? "secure" : "open");
2155         wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
2156                      info->privacy, info->auth_type);
2157         wil_dbg_misc(wil, "Hidden SSID mode: %d\n",
2158                      info->hidden_ssid);
2159         wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
2160                      info->dtim_period);
2161         wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
2162         wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
2163                           info->ssid, info->ssid_len, true);
2164         wil_print_bcon_data(bcon);
2165         wil_print_crypto(wil, crypto);
2166 
2167         rc = _wil_cfg80211_start_ap(wiphy, ndev,
2168                                     info->ssid, info->ssid_len, info->privacy,
2169                                     info->beacon_interval, channel->hw_value,
2170                                     wmi_edmg_channel, bcon, hidden_ssid,
2171                                     info->pbss);
2172 
2173         return rc;
2174 }
2175 
2176 static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
2177                                 struct net_device *ndev)
2178 {
2179         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2180         struct wil6210_vif *vif = ndev_to_vif(ndev);
2181         bool last;
2182 
2183         wil_dbg_misc(wil, "stop_ap, mid=%d\n", vif->mid);
2184 
2185         netif_carrier_off(ndev);
2186         last = !wil_has_other_active_ifaces(wil, ndev, false, true);
2187         if (last) {
2188                 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
2189                 wil_set_recovery_state(wil, fw_recovery_idle);
2190                 set_bit(wil_status_resetting, wil->status);
2191         }
2192 
2193         mutex_lock(&wil->mutex);
2194 
2195         wmi_pcp_stop(vif);
2196         clear_bit(wil_vif_ft_roam, vif->status);
2197         vif->ssid_len = 0;
2198         wil_memdup_ie(&vif->proberesp, &vif->proberesp_len, NULL, 0);
2199         wil_memdup_ie(&vif->proberesp_ies, &vif->proberesp_ies_len, NULL, 0);
2200         wil_memdup_ie(&vif->assocresp_ies, &vif->assocresp_ies_len, NULL, 0);
2201         memset(vif->gtk, 0, WMI_MAX_KEY_LEN);
2202         vif->gtk_len = 0;
2203 
2204         if (last)
2205                 __wil_down(wil);
2206         else
2207                 wil_bcast_fini(vif);
2208 
2209         mutex_unlock(&wil->mutex);
2210 
2211         return 0;
2212 }
2213 
2214 static int wil_cfg80211_add_station(struct wiphy *wiphy,
2215                                     struct net_device *dev,
2216                                     const u8 *mac,
2217                                     struct station_parameters *params)
2218 {
2219         struct wil6210_vif *vif = ndev_to_vif(dev);
2220         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2221 
2222         wil_dbg_misc(wil, "add station %pM aid %d mid %d mask 0x%x set 0x%x\n",
2223                      mac, params->aid, vif->mid,
2224                      params->sta_flags_mask, params->sta_flags_set);
2225 
2226         if (!disable_ap_sme) {
2227                 wil_err(wil, "not supported with AP SME enabled\n");
2228                 return -EOPNOTSUPP;
2229         }
2230 
2231         if (params->aid > WIL_MAX_DMG_AID) {
2232                 wil_err(wil, "invalid aid\n");
2233                 return -EINVAL;
2234         }
2235 
2236         return wmi_new_sta(vif, mac, params->aid);
2237 }
2238 
2239 static int wil_cfg80211_del_station(struct wiphy *wiphy,
2240                                     struct net_device *dev,
2241                                     struct station_del_parameters *params)
2242 {
2243         struct wil6210_vif *vif = ndev_to_vif(dev);
2244         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2245 
2246         wil_dbg_misc(wil, "del_station: %pM, reason=%d mid=%d\n",
2247                      params->mac, params->reason_code, vif->mid);
2248 
2249         mutex_lock(&wil->mutex);
2250         wil6210_disconnect(vif, params->mac, params->reason_code);
2251         mutex_unlock(&wil->mutex);
2252 
2253         return 0;
2254 }
2255 
2256 static int wil_cfg80211_change_station(struct wiphy *wiphy,
2257                                        struct net_device *dev,
2258                                        const u8 *mac,
2259                                        struct station_parameters *params)
2260 {
2261         struct wil6210_vif *vif = ndev_to_vif(dev);
2262         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2263         int authorize;
2264         int cid, i;
2265         struct wil_ring_tx_data *txdata = NULL;
2266 
2267         wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n",
2268                      mac, params->sta_flags_mask, params->sta_flags_set,
2269                      vif->mid);
2270 
2271         if (!disable_ap_sme) {
2272                 wil_dbg_misc(wil, "not supported with AP SME enabled\n");
2273                 return -EOPNOTSUPP;
2274         }
2275 
2276         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
2277                 return 0;
2278 
2279         cid = wil_find_cid(wil, vif->mid, mac);
2280         if (cid < 0) {
2281                 wil_err(wil, "station not found\n");
2282                 return -ENOLINK;
2283         }
2284 
2285         for (i = 0; i < ARRAY_SIZE(wil->ring2cid_tid); i++)
2286                 if (wil->ring2cid_tid[i][0] == cid) {
2287                         txdata = &wil->ring_tx_data[i];
2288                         break;
2289                 }
2290 
2291         if (!txdata) {
2292                 wil_err(wil, "ring data not found\n");
2293                 return -ENOLINK;
2294         }
2295 
2296         authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
2297         txdata->dot1x_open = authorize ? 1 : 0;
2298         wil_dbg_misc(wil, "cid %d ring %d authorize %d\n", cid, i,
2299                      txdata->dot1x_open);
2300 
2301         return 0;
2302 }
2303 
2304 /* probe_client handling */
2305 static void wil_probe_client_handle(struct wil6210_priv *wil,
2306                                     struct wil6210_vif *vif,
2307                                     struct wil_probe_client_req *req)
2308 {
2309         struct net_device *ndev = vif_to_ndev(vif);
2310         struct wil_sta_info *sta = &wil->sta[req->cid];
2311         /* assume STA is alive if it is still connected,
2312          * else FW will disconnect it
2313          */
2314         bool alive = (sta->status == wil_sta_connected);
2315 
2316         cfg80211_probe_status(ndev, sta->addr, req->cookie, alive,
2317                               0, false, GFP_KERNEL);
2318 }
2319 
2320 static struct list_head *next_probe_client(struct wil6210_vif *vif)
2321 {
2322         struct list_head *ret = NULL;
2323 
2324         mutex_lock(&vif->probe_client_mutex);
2325 
2326         if (!list_empty(&vif->probe_client_pending)) {
2327                 ret = vif->probe_client_pending.next;
2328                 list_del(ret);
2329         }
2330 
2331         mutex_unlock(&vif->probe_client_mutex);
2332 
2333         return ret;
2334 }
2335 
2336 void wil_probe_client_worker(struct work_struct *work)
2337 {
2338         struct wil6210_vif *vif = container_of(work, struct wil6210_vif,
2339                                                probe_client_worker);
2340         struct wil6210_priv *wil = vif_to_wil(vif);
2341         struct wil_probe_client_req *req;
2342         struct list_head *lh;
2343 
2344         while ((lh = next_probe_client(vif)) != NULL) {
2345                 req = list_entry(lh, struct wil_probe_client_req, list);
2346 
2347                 wil_probe_client_handle(wil, vif, req);
2348                 kfree(req);
2349         }
2350 }
2351 
2352 void wil_probe_client_flush(struct wil6210_vif *vif)
2353 {
2354         struct wil_probe_client_req *req, *t;
2355         struct wil6210_priv *wil = vif_to_wil(vif);
2356 
2357         wil_dbg_misc(wil, "probe_client_flush\n");
2358 
2359         mutex_lock(&vif->probe_client_mutex);
2360 
2361         list_for_each_entry_safe(req, t, &vif->probe_client_pending, list) {
2362                 list_del(&req->list);
2363                 kfree(req);
2364         }
2365 
2366         mutex_unlock(&vif->probe_client_mutex);
2367 }
2368 
2369 static int wil_cfg80211_probe_client(struct wiphy *wiphy,
2370                                      struct net_device *dev,
2371                                      const u8 *peer, u64 *cookie)
2372 {
2373         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2374         struct wil6210_vif *vif = ndev_to_vif(dev);
2375         struct wil_probe_client_req *req;
2376         int cid = wil_find_cid(wil, vif->mid, peer);
2377 
2378         wil_dbg_misc(wil, "probe_client: %pM => CID %d MID %d\n",
2379                      peer, cid, vif->mid);
2380 
2381         if (cid < 0)
2382                 return -ENOLINK;
2383 
2384         req = kzalloc(sizeof(*req), GFP_KERNEL);
2385         if (!req)
2386                 return -ENOMEM;
2387 
2388         req->cid = cid;
2389         req->cookie = cid;
2390 
2391         mutex_lock(&vif->probe_client_mutex);
2392         list_add_tail(&req->list, &vif->probe_client_pending);
2393         mutex_unlock(&vif->probe_client_mutex);
2394 
2395         *cookie = req->cookie;
2396         queue_work(wil->wq_service, &vif->probe_client_worker);
2397         return 0;
2398 }
2399 
2400 static int wil_cfg80211_change_bss(struct wiphy *wiphy,
2401                                    struct net_device *dev,
2402                                    struct bss_parameters *params)
2403 {
2404         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2405         struct wil6210_vif *vif = ndev_to_vif(dev);
2406 
2407         if (params->ap_isolate >= 0) {
2408                 wil_dbg_misc(wil, "change_bss: ap_isolate MID %d, %d => %d\n",
2409                              vif->mid, vif->ap_isolate, params->ap_isolate);
2410                 vif->ap_isolate = params->ap_isolate;
2411         }
2412 
2413         return 0;
2414 }
2415 
2416 static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
2417                                        struct net_device *dev,
2418                                        bool enabled, int timeout)
2419 {
2420         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2421         enum wmi_ps_profile_type ps_profile;
2422 
2423         wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
2424                      enabled, timeout);
2425 
2426         if (enabled)
2427                 ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
2428         else
2429                 ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
2430 
2431         return wil_ps_update(wil, ps_profile);
2432 }
2433 
2434 static int wil_cfg80211_suspend(struct wiphy *wiphy,
2435                                 struct cfg80211_wowlan *wow)
2436 {
2437         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2438         int rc;
2439 
2440         /* Setting the wakeup trigger based on wow is TBD */
2441 
2442         if (test_bit(wil_status_suspended, wil->status)) {
2443                 wil_dbg_pm(wil, "trying to suspend while suspended\n");
2444                 return 0;
2445         }
2446 
2447         rc = wil_can_suspend(wil, false);
2448         if (rc)
2449                 goto out;
2450 
2451         wil_dbg_pm(wil, "suspending\n");
2452 
2453         mutex_lock(&wil->mutex);
2454         mutex_lock(&wil->vif_mutex);
2455         wil_p2p_stop_radio_operations(wil);
2456         wil_abort_scan_all_vifs(wil, true);
2457         mutex_unlock(&wil->vif_mutex);
2458         mutex_unlock(&wil->mutex);
2459 
2460 out:
2461         return rc;
2462 }
2463 
2464 static int wil_cfg80211_resume(struct wiphy *wiphy)
2465 {
2466         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2467 
2468         wil_dbg_pm(wil, "resuming\n");
2469 
2470         return 0;
2471 }
2472 
2473 static int
2474 wil_cfg80211_sched_scan_start(struct wiphy *wiphy,
2475                               struct net_device *dev,
2476                               struct cfg80211_sched_scan_request *request)
2477 {
2478         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2479         struct wil6210_vif *vif = ndev_to_vif(dev);
2480         int i, rc;
2481 
2482         if (vif->mid != 0)
2483                 return -EOPNOTSUPP;
2484 
2485         wil_dbg_misc(wil,
2486                      "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n",
2487                      request->n_ssids, request->ie_len, request->flags);
2488         for (i = 0; i < request->n_ssids; i++) {
2489                 wil_dbg_misc(wil, "SSID[%d]:", i);
2490                 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
2491                                   request->ssids[i].ssid,
2492                                   request->ssids[i].ssid_len, true);
2493         }
2494         wil_dbg_misc(wil, "channels:");
2495         for (i = 0; i < request->n_channels; i++)
2496                 wil_dbg_misc(wil, " %d%s", request->channels[i]->hw_value,
2497                              i == request->n_channels - 1 ? "\n" : "");
2498         wil_dbg_misc(wil, "n_match_sets %d, min_rssi_thold %d, delay %d\n",
2499                      request->n_match_sets, request->min_rssi_thold,
2500                      request->delay);
2501         for (i = 0; i < request->n_match_sets; i++) {
2502                 struct cfg80211_match_set *ms = &request->match_sets[i];
2503 
2504                 wil_dbg_misc(wil, "MATCHSET[%d]: rssi_thold %d\n",
2505                              i, ms->rssi_thold);
2506                 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
2507                                   ms->ssid.ssid,
2508                                   ms->ssid.ssid_len, true);
2509         }
2510         wil_dbg_misc(wil, "n_scan_plans %d\n", request->n_scan_plans);
2511         for (i = 0; i < request->n_scan_plans; i++) {
2512                 struct cfg80211_sched_scan_plan *sp = &request->scan_plans[i];
2513 
2514                 wil_dbg_misc(wil, "SCAN PLAN[%d]: interval %d iterations %d\n",
2515                              i, sp->interval, sp->iterations);
2516         }
2517 
2518         rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ,
2519                         request->ie_len, request->ie);
2520         if (rc)
2521                 return rc;
2522         return wmi_start_sched_scan(wil, request);
2523 }
2524 
2525 static int
2526 wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
2527                              u64 reqid)
2528 {
2529         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2530         struct wil6210_vif *vif = ndev_to_vif(dev);
2531         int rc;
2532 
2533         if (vif->mid != 0)
2534                 return -EOPNOTSUPP;
2535 
2536         rc = wmi_stop_sched_scan(wil);
2537         /* device would return error if it thinks PNO is already stopped.
2538          * ignore the return code so user space and driver gets back in-sync
2539          */
2540         wil_dbg_misc(wil, "sched scan stopped (%d)\n", rc);
2541 
2542         return 0;
2543 }
2544 
2545 static int
2546 wil_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev,
2547                            struct cfg80211_update_ft_ies_params *ftie)
2548 {
2549         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2550         struct wil6210_vif *vif = ndev_to_vif(dev);
2551         struct cfg80211_bss *bss;
2552         struct wmi_ft_reassoc_cmd reassoc;
2553         int rc = 0;
2554 
2555         wil_dbg_misc(wil, "update ft ies, mid=%d\n", vif->mid);
2556         wil_hex_dump_misc("FT IE ", DUMP_PREFIX_OFFSET, 16, 1,
2557                           ftie->ie, ftie->ie_len, true);
2558 
2559         if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) {
2560                 wil_err(wil, "FW does not support FT roaming\n");
2561                 return -EOPNOTSUPP;
2562         }
2563 
2564         rc = wmi_update_ft_ies(vif, ftie->ie_len, ftie->ie);
2565         if (rc)
2566                 return rc;
2567 
2568         if (!test_bit(wil_vif_ft_roam, vif->status))
2569                 /* vif is not roaming */
2570                 return 0;
2571 
2572         /* wil_vif_ft_roam is set. wil_cfg80211_update_ft_ies is used as
2573          * a trigger for reassoc
2574          */
2575 
2576         bss = vif->bss;
2577         if (!bss) {
2578                 wil_err(wil, "FT: bss is NULL\n");
2579                 return -EINVAL;
2580         }
2581 
2582         memset(&reassoc, 0, sizeof(reassoc));
2583         ether_addr_copy(reassoc.bssid, bss->bssid);
2584 
2585         rc = wmi_send(wil, WMI_FT_REASSOC_CMDID, vif->mid,
2586                       &reassoc, sizeof(reassoc));
2587         if (rc)
2588                 wil_err(wil, "FT: reassoc failed (%d)\n", rc);
2589 
2590         return rc;
2591 }
2592 
2593 static const struct cfg80211_ops wil_cfg80211_ops = {
2594         .add_virtual_intf = wil_cfg80211_add_iface,
2595         .del_virtual_intf = wil_cfg80211_del_iface,
2596         .scan = wil_cfg80211_scan,
2597         .abort_scan = wil_cfg80211_abort_scan,
2598         .connect = wil_cfg80211_connect,
2599         .disconnect = wil_cfg80211_disconnect,
2600         .set_wiphy_params = wil_cfg80211_set_wiphy_params,
2601         .change_virtual_intf = wil_cfg80211_change_iface,
2602         .get_station = wil_cfg80211_get_station,
2603         .dump_station = wil_cfg80211_dump_station,
2604         .remain_on_channel = wil_remain_on_channel,
2605         .cancel_remain_on_channel = wil_cancel_remain_on_channel,
2606         .mgmt_tx = wil_cfg80211_mgmt_tx,
2607         .set_monitor_channel = wil_cfg80211_set_channel,
2608         .add_key = wil_cfg80211_add_key,
2609         .del_key = wil_cfg80211_del_key,
2610         .set_default_key = wil_cfg80211_set_default_key,
2611         /* AP mode */
2612         .change_beacon = wil_cfg80211_change_beacon,
2613         .start_ap = wil_cfg80211_start_ap,
2614         .stop_ap = wil_cfg80211_stop_ap,
2615         .add_station = wil_cfg80211_add_station,
2616         .del_station = wil_cfg80211_del_station,
2617         .change_station = wil_cfg80211_change_station,
2618         .probe_client = wil_cfg80211_probe_client,
2619         .change_bss = wil_cfg80211_change_bss,
2620         /* P2P device */
2621         .start_p2p_device = wil_cfg80211_start_p2p_device,
2622         .stop_p2p_device = wil_cfg80211_stop_p2p_device,
2623         .set_power_mgmt = wil_cfg80211_set_power_mgmt,
2624         .suspend = wil_cfg80211_suspend,
2625         .resume = wil_cfg80211_resume,
2626         .sched_scan_start = wil_cfg80211_sched_scan_start,
2627         .sched_scan_stop = wil_cfg80211_sched_scan_stop,
2628         .update_ft_ies = wil_cfg80211_update_ft_ies,
2629 };
2630 
2631 static void wil_wiphy_init(struct wiphy *wiphy)
2632 {
2633         wiphy->max_scan_ssids = 1;
2634         wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
2635         wiphy->max_remain_on_channel_duration = WIL_MAX_ROC_DURATION_MS;
2636         wiphy->max_num_pmkids = 0 /* TODO: */;
2637         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2638                                  BIT(NL80211_IFTYPE_AP) |
2639                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
2640                                  BIT(NL80211_IFTYPE_P2P_GO) |
2641                                  BIT(NL80211_IFTYPE_P2P_DEVICE) |
2642                                  BIT(NL80211_IFTYPE_MONITOR);
2643         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2644                         WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2645                         WIPHY_FLAG_PS_ON_BY_DEFAULT;
2646         if (!disable_ap_sme)
2647                 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
2648         dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
2649                 __func__, wiphy->flags);
2650         wiphy->probe_resp_offload =
2651                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
2652                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
2653                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
2654 
2655         wiphy->bands[NL80211_BAND_60GHZ] = &wil_band_60ghz;
2656 
2657         /* may change after reading FW capabilities */
2658         wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
2659 
2660         wiphy->cipher_suites = wil_cipher_suites;
2661         wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
2662         wiphy->mgmt_stypes = wil_mgmt_stypes;
2663         wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
2664 
2665         wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
2666         wiphy->vendor_commands = wil_nl80211_vendor_commands;
2667 
2668 #ifdef CONFIG_PM
2669         wiphy->wowlan = &wil_wowlan_support;
2670 #endif
2671 }
2672 
2673 int wil_cfg80211_iface_combinations_from_fw(
2674         struct wil6210_priv *wil, const struct wil_fw_record_concurrency *conc)
2675 {
2676         struct wiphy *wiphy = wil_to_wiphy(wil);
2677         u32 total_limits = 0;
2678         u16 n_combos;
2679         const struct wil_fw_concurrency_combo *combo;
2680         const struct wil_fw_concurrency_limit *limit;
2681         struct ieee80211_iface_combination *iface_combinations;
2682         struct ieee80211_iface_limit *iface_limit;
2683         int i, j;
2684 
2685         if (wiphy->iface_combinations) {
2686                 wil_dbg_misc(wil, "iface_combinations already set, skipping\n");
2687                 return 0;
2688         }
2689 
2690         combo = conc->combos;
2691         n_combos = le16_to_cpu(conc->n_combos);
2692         for (i = 0; i < n_combos; i++) {
2693                 total_limits += combo->n_limits;
2694                 limit = combo->limits + combo->n_limits;
2695                 combo = (struct wil_fw_concurrency_combo *)limit;
2696         }
2697 
2698         iface_combinations =
2699                 kzalloc(n_combos * sizeof(struct ieee80211_iface_combination) +
2700                         total_limits * sizeof(struct ieee80211_iface_limit),
2701                         GFP_KERNEL);
2702         if (!iface_combinations)
2703                 return -ENOMEM;
2704         iface_limit = (struct ieee80211_iface_limit *)(iface_combinations +
2705                                                        n_combos);
2706         combo = conc->combos;
2707         for (i = 0; i < n_combos; i++) {
2708                 iface_combinations[i].max_interfaces = combo->max_interfaces;
2709                 iface_combinations[i].num_different_channels =
2710                         combo->n_diff_channels;
2711                 iface_combinations[i].beacon_int_infra_match =
2712                         combo->same_bi;
2713                 iface_combinations[i].n_limits = combo->n_limits;
2714                 wil_dbg_misc(wil,
2715                              "iface_combination %d: max_if %d, num_ch %d, bi_match %d\n",
2716                              i, iface_combinations[i].max_interfaces,
2717                              iface_combinations[i].num_different_channels,
2718                              iface_combinations[i].beacon_int_infra_match);
2719                 limit = combo->limits;
2720                 for (j = 0; j < combo->n_limits; j++) {
2721                         iface_limit[j].max = le16_to_cpu(limit[j].max);
2722                         iface_limit[j].types = le16_to_cpu(limit[j].types);
2723                         wil_dbg_misc(wil,
2724                                      "limit %d: max %d types 0x%x\n", j,
2725                                      iface_limit[j].max, iface_limit[j].types);
2726                 }
2727                 iface_combinations[i].limits = iface_limit;
2728                 iface_limit += combo->n_limits;
2729                 limit += combo->n_limits;
2730                 combo = (struct wil_fw_concurrency_combo *)limit;
2731         }
2732 
2733         wil_dbg_misc(wil, "multiple VIFs supported, n_mids %d\n", conc->n_mids);
2734         wil->max_vifs = conc->n_mids + 1; /* including main interface */
2735         if (wil->max_vifs > WIL_MAX_VIFS) {
2736                 wil_info(wil, "limited number of VIFs supported(%d, FW %d)\n",
2737                          WIL_MAX_VIFS, wil->max_vifs);
2738                 wil->max_vifs = WIL_MAX_VIFS;
2739         }
2740         wiphy->n_iface_combinations = n_combos;
2741         wiphy->iface_combinations = iface_combinations;
2742         return 0;
2743 }
2744 
2745 struct wil6210_priv *wil_cfg80211_init(struct device *dev)
2746 {
2747         struct wiphy *wiphy;
2748         struct wil6210_priv *wil;
2749         struct ieee80211_channel *ch;
2750 
2751         dev_dbg(dev, "%s()\n", __func__);
2752 
2753         /* Note: the wireless_dev structure is no longer allocated here.
2754          * Instead, it is allocated as part of the net_device structure
2755          * for main interface and each VIF.
2756          */
2757         wiphy = wiphy_new(&wil_cfg80211_ops, sizeof(struct wil6210_priv));
2758         if (!wiphy)
2759                 return ERR_PTR(-ENOMEM);
2760 
2761         set_wiphy_dev(wiphy, dev);
2762         wil_wiphy_init(wiphy);
2763 
2764         wil = wiphy_to_wil(wiphy);
2765         wil->wiphy = wiphy;
2766 
2767         /* default monitor channel */
2768         ch = wiphy->bands[NL80211_BAND_60GHZ]->channels;
2769         cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT);
2770 
2771         return wil;
2772 }
2773 
2774 void wil_cfg80211_deinit(struct wil6210_priv *wil)
2775 {
2776         struct wiphy *wiphy = wil_to_wiphy(wil);
2777 
2778         dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
2779 
2780         if (!wiphy)
2781                 return;
2782 
2783         kfree(wiphy->iface_combinations);
2784         wiphy->iface_combinations = NULL;
2785 
2786         wiphy_free(wiphy);
2787         /* do not access wil6210_priv after returning from here */
2788 }
2789 
2790 void wil_p2p_wdev_free(struct wil6210_priv *wil)
2791 {
2792         struct wireless_dev *p2p_wdev;
2793 
2794         mutex_lock(&wil->vif_mutex);
2795         p2p_wdev = wil->p2p_wdev;
2796         wil->p2p_wdev = NULL;
2797         wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
2798         mutex_unlock(&wil->vif_mutex);
2799         if (p2p_wdev) {
2800                 cfg80211_unregister_wdev(p2p_wdev);
2801                 kfree(p2p_wdev);
2802         }
2803 }
2804 
2805 static int wil_rf_sector_status_to_rc(u8 status)
2806 {
2807         switch (status) {
2808         case WMI_RF_SECTOR_STATUS_SUCCESS:
2809                 return 0;
2810         case WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR:
2811                 return -EINVAL;
2812         case WMI_RF_SECTOR_STATUS_BUSY_ERROR:
2813                 return -EAGAIN;
2814         case WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR:
2815                 return -EOPNOTSUPP;
2816         default:
2817                 return -EINVAL;
2818         }
2819 }
2820 
2821 static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
2822                                  struct wireless_dev *wdev,
2823                                  const void *data, int data_len)
2824 {
2825         struct wil6210_priv *wil = wdev_to_wil(wdev);
2826         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
2827         int rc;
2828         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2829         u16 sector_index;
2830         u8 sector_type;
2831         u32 rf_modules_vec;
2832         struct wmi_get_rf_sector_params_cmd cmd;
2833         struct {
2834                 struct wmi_cmd_hdr wmi;
2835                 struct wmi_get_rf_sector_params_done_event evt;
2836         } __packed reply = {
2837                 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2838         };
2839         struct sk_buff *msg;
2840         struct nlattr *nl_cfgs, *nl_cfg;
2841         u32 i;
2842         struct wmi_rf_sector_info *si;
2843 
2844         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
2845                 return -EOPNOTSUPP;
2846 
2847         rc = nla_parse_deprecated(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data,
2848                                   data_len, wil_rf_sector_policy, NULL);
2849         if (rc) {
2850                 wil_err(wil, "Invalid rf sector ATTR\n");
2851                 return rc;
2852         }
2853 
2854         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
2855             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
2856             !tb[QCA_ATTR_DMG_RF_MODULE_MASK]) {
2857                 wil_err(wil, "Invalid rf sector spec\n");
2858                 return -EINVAL;
2859         }
2860 
2861         sector_index = nla_get_u16(
2862                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
2863         if (sector_index >= WIL_MAX_RF_SECTORS) {
2864                 wil_err(wil, "Invalid sector index %d\n", sector_index);
2865                 return -EINVAL;
2866         }
2867 
2868         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
2869         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
2870                 wil_err(wil, "Invalid sector type %d\n", sector_type);
2871                 return -EINVAL;
2872         }
2873 
2874         rf_modules_vec = nla_get_u32(
2875                 tb[QCA_ATTR_DMG_RF_MODULE_MASK]);
2876         if (rf_modules_vec >= BIT(WMI_MAX_RF_MODULES_NUM)) {
2877                 wil_err(wil, "Invalid rf module mask 0x%x\n", rf_modules_vec);
2878                 return -EINVAL;
2879         }
2880 
2881         cmd.sector_idx = cpu_to_le16(sector_index);
2882         cmd.sector_type = sector_type;
2883         cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2884         rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid,
2885                       &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
2886                       &reply, sizeof(reply),
2887                       500);
2888         if (rc)
2889                 return rc;
2890         if (reply.evt.status) {
2891                 wil_err(wil, "get rf sector cfg failed with status %d\n",
2892                         reply.evt.status);
2893                 return wil_rf_sector_status_to_rc(reply.evt.status);
2894         }
2895 
2896         msg = cfg80211_vendor_cmd_alloc_reply_skb(
2897                 wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
2898         if (!msg)
2899                 return -ENOMEM;
2900 
2901         if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
2902                               le64_to_cpu(reply.evt.tsf),
2903                               QCA_ATTR_PAD))
2904                 goto nla_put_failure;
2905 
2906         nl_cfgs = nla_nest_start_noflag(msg, QCA_ATTR_DMG_RF_SECTOR_CFG);
2907         if (!nl_cfgs)
2908                 goto nla_put_failure;
2909         for (i = 0; i < WMI_MAX_RF_MODULES_NUM; i++) {
2910                 if (!(rf_modules_vec & BIT(i)))
2911                         continue;
2912                 nl_cfg = nla_nest_start_noflag(msg, i);
2913                 if (!nl_cfg)
2914                         goto nla_put_failure;
2915                 si = &reply.evt.sectors_info[i];
2916                 if (nla_put_u8(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX,
2917                                i) ||
2918                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0,
2919                                 le32_to_cpu(si->etype0)) ||
2920                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1,
2921                                 le32_to_cpu(si->etype1)) ||
2922                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2,
2923                                 le32_to_cpu(si->etype2)) ||
2924                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI,
2925                                 le32_to_cpu(si->psh_hi)) ||
2926                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO,
2927                                 le32_to_cpu(si->psh_lo)) ||
2928                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16,
2929                                 le32_to_cpu(si->dtype_swch_off)))
2930                         goto nla_put_failure;
2931                 nla_nest_end(msg, nl_cfg);
2932         }
2933 
2934         nla_nest_end(msg, nl_cfgs);
2935         rc = cfg80211_vendor_cmd_reply(msg);
2936         return rc;
2937 nla_put_failure:
2938         kfree_skb(msg);
2939         return -ENOBUFS;
2940 }
2941 
2942 static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2943                                  struct wireless_dev *wdev,
2944                                  const void *data, int data_len)
2945 {
2946         struct wil6210_priv *wil = wdev_to_wil(wdev);
2947         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
2948         int rc, tmp;
2949         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2950         struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1];
2951         u16 sector_index, rf_module_index;
2952         u8 sector_type;
2953         u32 rf_modules_vec = 0;
2954         struct wmi_set_rf_sector_params_cmd cmd;
2955         struct {
2956                 struct wmi_cmd_hdr wmi;
2957                 struct wmi_set_rf_sector_params_done_event evt;
2958         } __packed reply = {
2959                 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2960         };
2961         struct nlattr *nl_cfg;
2962         struct wmi_rf_sector_info *si;
2963 
2964         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
2965                 return -EOPNOTSUPP;
2966 
2967         rc = nla_parse_deprecated(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data,
2968                                   data_len, wil_rf_sector_policy, NULL);
2969         if (rc) {
2970                 wil_err(wil, "Invalid rf sector ATTR\n");
2971                 return rc;
2972         }
2973 
2974         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
2975             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
2976             !tb[QCA_ATTR_DMG_RF_SECTOR_CFG]) {
2977                 wil_err(wil, "Invalid rf sector spec\n");
2978                 return -EINVAL;
2979         }
2980 
2981         sector_index = nla_get_u16(
2982                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
2983         if (sector_index >= WIL_MAX_RF_SECTORS) {
2984                 wil_err(wil, "Invalid sector index %d\n", sector_index);
2985                 return -EINVAL;
2986         }
2987 
2988         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
2989         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
2990                 wil_err(wil, "Invalid sector type %d\n", sector_type);
2991                 return -EINVAL;
2992         }
2993 
2994         memset(&cmd, 0, sizeof(cmd));
2995 
2996         cmd.sector_idx = cpu_to_le16(sector_index);
2997         cmd.sector_type = sector_type;
2998         nla_for_each_nested(nl_cfg, tb[QCA_ATTR_DMG_RF_SECTOR_CFG],
2999                             tmp) {
3000                 rc = nla_parse_nested_deprecated(tb2,
3001                                                  QCA_ATTR_DMG_RF_SECTOR_CFG_MAX,
3002                                                  nl_cfg,
3003                                                  wil_rf_sector_cfg_policy,
3004                                                  NULL);
3005                 if (rc) {
3006                         wil_err(wil, "invalid sector cfg\n");
3007                         return -EINVAL;
3008                 }
3009 
3010                 if (!tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX] ||
3011                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0] ||
3012                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1] ||
3013                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2] ||
3014                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI] ||
3015                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO] ||
3016                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]) {
3017                         wil_err(wil, "missing cfg params\n");
3018                         return -EINVAL;
3019                 }
3020 
3021                 rf_module_index = nla_get_u8(
3022                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX]);
3023                 if (rf_module_index >= WMI_MAX_RF_MODULES_NUM) {
3024                         wil_err(wil, "invalid RF module index %d\n",
3025                                 rf_module_index);
3026                         return -EINVAL;
3027                 }
3028                 rf_modules_vec |= BIT(rf_module_index);
3029                 si = &cmd.sectors_info[rf_module_index];
3030                 si->etype0 = cpu_to_le32(nla_get_u32(
3031                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0]));
3032                 si->etype1 = cpu_to_le32(nla_get_u32(
3033                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1]));
3034                 si->etype2 = cpu_to_le32(nla_get_u32(
3035                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2]));
3036                 si->psh_hi = cpu_to_le32(nla_get_u32(
3037                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI]));
3038                 si->psh_lo = cpu_to_le32(nla_get_u32(
3039                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO]));
3040                 si->dtype_swch_off = cpu_to_le32(nla_get_u32(
3041                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]));
3042         }
3043 
3044         cmd.rf_modules_vec = rf_modules_vec & 0xFF;
3045         rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid,
3046                       &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
3047                       &reply, sizeof(reply),
3048                       500);
3049         if (rc)
3050                 return rc;
3051         return wil_rf_sector_status_to_rc(reply.evt.status);
3052 }
3053 
3054 static int wil_rf_sector_get_selected(struct wiphy *wiphy,
3055                                       struct wireless_dev *wdev,
3056                                       const void *data, int data_len)
3057 {
3058         struct wil6210_priv *wil = wdev_to_wil(wdev);
3059         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
3060         int rc;
3061         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
3062         u8 sector_type, mac_addr[ETH_ALEN];
3063         int cid = 0;
3064         struct wmi_get_selected_rf_sector_index_cmd cmd;
3065         struct {
3066                 struct wmi_cmd_hdr wmi;
3067                 struct wmi_get_selected_rf_sector_index_done_event evt;
3068         } __packed reply = {
3069                 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
3070         };
3071         struct sk_buff *msg;
3072 
3073         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
3074                 return -EOPNOTSUPP;
3075 
3076         rc = nla_parse_deprecated(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data,
3077                                   data_len, wil_rf_sector_policy, NULL);
3078         if (rc) {
3079                 wil_err(wil, "Invalid rf sector ATTR\n");
3080                 return rc;
3081         }
3082 
3083         if (!tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
3084                 wil_err(wil, "Invalid rf sector spec\n");
3085                 return -EINVAL;
3086         }
3087         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
3088         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
3089                 wil_err(wil, "Invalid sector type %d\n", sector_type);
3090                 return -EINVAL;
3091         }
3092 
3093         if (tb[QCA_ATTR_MAC_ADDR]) {
3094                 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
3095                 cid = wil_find_cid(wil, vif->mid, mac_addr);
3096                 if (cid < 0) {
3097                         wil_err(wil, "invalid MAC address %pM\n", mac_addr);
3098                         return -ENOENT;
3099                 }
3100         } else {
3101                 if (test_bit(wil_vif_fwconnected, vif->status)) {
3102                         wil_err(wil, "must specify MAC address when connected\n");
3103                         return -EINVAL;
3104                 }
3105         }
3106 
3107         memset(&cmd, 0, sizeof(cmd));
3108         cmd.cid = (u8)cid;
3109         cmd.sector_type = sector_type;
3110         rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid,
3111                       &cmd, sizeof(cmd),
3112                       WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
3113                       &reply, sizeof(reply),
3114                       500);
3115         if (rc)
3116                 return rc;
3117         if (reply.evt.status) {
3118                 wil_err(wil, "get rf selected sector cfg failed with status %d\n",
3119                         reply.evt.status);
3120                 return wil_rf_sector_status_to_rc(reply.evt.status);
3121         }
3122 
3123         msg = cfg80211_vendor_cmd_alloc_reply_skb(
3124                 wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
3125         if (!msg)
3126                 return -ENOMEM;
3127 
3128         if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
3129                               le64_to_cpu(reply.evt.tsf),
3130                               QCA_ATTR_PAD) ||
3131             nla_put_u16(msg, QCA_ATTR_DMG_RF_SECTOR_INDEX,
3132                         le16_to_cpu(reply.evt.sector_idx)))
3133                 goto nla_put_failure;
3134 
3135         rc = cfg80211_vendor_cmd_reply(msg);
3136         return rc;
3137 nla_put_failure:
3138         kfree_skb(msg);
3139         return -ENOBUFS;
3140 }
3141 
3142 static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
3143                                           u8 mid, u16 sector_index,
3144                                           u8 sector_type, u8 cid)
3145 {
3146         struct wmi_set_selected_rf_sector_index_cmd cmd;
3147         struct {
3148                 struct wmi_cmd_hdr wmi;
3149                 struct wmi_set_selected_rf_sector_index_done_event evt;
3150         } __packed reply = {
3151                 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
3152         };
3153         int rc;
3154 
3155         memset(&cmd, 0, sizeof(cmd));
3156         cmd.sector_idx = cpu_to_le16(sector_index);
3157         cmd.sector_type = sector_type;
3158         cmd.cid = (u8)cid;
3159         rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid,
3160                       &cmd, sizeof(cmd),
3161                       WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
3162                       &reply, sizeof(reply),
3163                       500);
3164         if (rc)
3165                 return rc;
3166         return wil_rf_sector_status_to_rc(reply.evt.status);
3167 }
3168 
3169 static int wil_rf_sector_set_selected(struct wiphy *wiphy,
3170                                       struct wireless_dev *wdev,
3171                                       const void *data, int data_len)
3172 {
3173         struct wil6210_priv *wil = wdev_to_wil(wdev);
3174         struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
3175         int rc;
3176         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
3177         u16 sector_index;
3178         u8 sector_type, mac_addr[ETH_ALEN], i;
3179         int cid = 0;
3180 
3181         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
3182                 return -EOPNOTSUPP;
3183 
3184         rc = nla_parse_deprecated(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data,
3185                                   data_len, wil_rf_sector_policy, NULL);
3186         if (rc) {
3187                 wil_err(wil, "Invalid rf sector ATTR\n");
3188                 return rc;
3189         }
3190 
3191         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
3192             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
3193                 wil_err(wil, "Invalid rf sector spec\n");
3194                 return -EINVAL;
3195         }
3196 
3197         sector_index = nla_get_u16(
3198                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
3199         if (sector_index >= WIL_MAX_RF_SECTORS &&
3200             sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
3201                 wil_err(wil, "Invalid sector index %d\n", sector_index);
3202                 return -EINVAL;
3203         }
3204 
3205         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
3206         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
3207                 wil_err(wil, "Invalid sector type %d\n", sector_type);
3208                 return -EINVAL;
3209         }
3210 
3211         if (tb[QCA_ATTR_MAC_ADDR]) {
3212                 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
3213                 if (!is_broadcast_ether_addr(mac_addr)) {
3214                         cid = wil_find_cid(wil, vif->mid, mac_addr);
3215                         if (cid < 0) {
3216                                 wil_err(wil, "invalid MAC address %pM\n",
3217                                         mac_addr);
3218                                 return -ENOENT;
3219                         }
3220                 } else {
3221                         if (sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
3222                                 wil_err(wil, "broadcast MAC valid only with unlocking\n");
3223                                 return -EINVAL;
3224                         }
3225                         cid = -1;
3226                 }
3227         } else {
3228                 if (test_bit(wil_vif_fwconnected, vif->status)) {
3229                         wil_err(wil, "must specify MAC address when connected\n");
3230                         return -EINVAL;
3231                 }
3232                 /* otherwise, using cid=0 for unassociated station */
3233         }
3234 
3235         if (cid >= 0) {
3236                 rc = wil_rf_sector_wmi_set_selected(wil, vif->mid, sector_index,
3237                                                     sector_type, cid);
3238         } else {
3239                 /* unlock all cids */
3240                 rc = wil_rf_sector_wmi_set_selected(
3241                         wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX,
3242                         sector_type, WIL_CID_ALL);
3243                 if (rc == -EINVAL) {
3244                         for (i = 0; i < wil->max_assoc_sta; i++) {
3245                                 if (wil->sta[i].mid != vif->mid)
3246                                         continue;
3247                                 rc = wil_rf_sector_wmi_set_selected(
3248                                         wil, vif->mid,
3249                                         WMI_INVALID_RF_SECTOR_INDEX,
3250                                         sector_type, i);
3251                                 /* the FW will silently ignore and return
3252                                  * success for unused cid, so abort the loop
3253                                  * on any other error
3254                                  */
3255                                 if (rc) {
3256                                         wil_err(wil, "unlock cid %d failed with status %d\n",
3257                                                 i, rc);
3258                                         break;
3259                                 }
3260                         }
3261                 }
3262         }
3263 
3264         return rc;
3265 }

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