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