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