linux/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012-2012 Quantenna Communications, Inc.
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License
   7 * as published by the Free Software Foundation; either version 2
   8 * of the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/etherdevice.h>
  19#include <linux/vmalloc.h>
  20#include <linux/ieee80211.h>
  21#include <net/cfg80211.h>
  22#include <net/netlink.h>
  23
  24#include "cfg80211.h"
  25#include "commands.h"
  26#include "core.h"
  27#include "util.h"
  28#include "bus.h"
  29
  30/* Supported rates to be advertised to the cfg80211 */
  31static struct ieee80211_rate qtnf_rates_2g[] = {
  32        {.bitrate = 10, .hw_value = 2, },
  33        {.bitrate = 20, .hw_value = 4, },
  34        {.bitrate = 55, .hw_value = 11, },
  35        {.bitrate = 110, .hw_value = 22, },
  36        {.bitrate = 60, .hw_value = 12, },
  37        {.bitrate = 90, .hw_value = 18, },
  38        {.bitrate = 120, .hw_value = 24, },
  39        {.bitrate = 180, .hw_value = 36, },
  40        {.bitrate = 240, .hw_value = 48, },
  41        {.bitrate = 360, .hw_value = 72, },
  42        {.bitrate = 480, .hw_value = 96, },
  43        {.bitrate = 540, .hw_value = 108, },
  44};
  45
  46/* Supported rates to be advertised to the cfg80211 */
  47static struct ieee80211_rate qtnf_rates_5g[] = {
  48        {.bitrate = 60, .hw_value = 12, },
  49        {.bitrate = 90, .hw_value = 18, },
  50        {.bitrate = 120, .hw_value = 24, },
  51        {.bitrate = 180, .hw_value = 36, },
  52        {.bitrate = 240, .hw_value = 48, },
  53        {.bitrate = 360, .hw_value = 72, },
  54        {.bitrate = 480, .hw_value = 96, },
  55        {.bitrate = 540, .hw_value = 108, },
  56};
  57
  58/* Supported crypto cipher suits to be advertised to cfg80211 */
  59static const u32 qtnf_cipher_suites[] = {
  60        WLAN_CIPHER_SUITE_TKIP,
  61        WLAN_CIPHER_SUITE_CCMP,
  62        WLAN_CIPHER_SUITE_AES_CMAC,
  63};
  64
  65/* Supported mgmt frame types to be advertised to cfg80211 */
  66static const struct ieee80211_txrx_stypes
  67qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = {
  68        [NL80211_IFTYPE_STATION] = {
  69                .tx = BIT(IEEE80211_STYPE_ACTION >> 4),
  70                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  71                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  72        },
  73        [NL80211_IFTYPE_AP] = {
  74                .tx = BIT(IEEE80211_STYPE_ACTION >> 4),
  75                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  76                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  77        },
  78};
  79
  80static int
  81qtnf_change_virtual_intf(struct wiphy *wiphy,
  82                         struct net_device *dev,
  83                         enum nl80211_iftype type,
  84                         struct vif_params *params)
  85{
  86        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
  87        u8 *mac_addr;
  88        int ret;
  89
  90        if (params)
  91                mac_addr = params->macaddr;
  92        else
  93                mac_addr = NULL;
  94
  95        qtnf_scan_done(vif->mac, true);
  96
  97        ret = qtnf_cmd_send_change_intf_type(vif, type, mac_addr);
  98        if (ret) {
  99                pr_err("VIF%u.%u: failed to change VIF type: %d\n",
 100                       vif->mac->macid, vif->vifid, ret);
 101                return ret;
 102        }
 103
 104        vif->wdev.iftype = type;
 105        return 0;
 106}
 107
 108int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 109{
 110        struct net_device *netdev =  wdev->netdev;
 111        struct qtnf_vif *vif;
 112
 113        if (WARN_ON(!netdev))
 114                return -EFAULT;
 115
 116        vif = qtnf_netdev_get_priv(wdev->netdev);
 117
 118        if (qtnf_cmd_send_del_intf(vif))
 119                pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid,
 120                       vif->vifid);
 121
 122        /* Stop data */
 123        netif_tx_stop_all_queues(netdev);
 124        if (netif_carrier_ok(netdev))
 125                netif_carrier_off(netdev);
 126
 127        if (netdev->reg_state == NETREG_REGISTERED)
 128                unregister_netdevice(netdev);
 129
 130        vif->netdev->ieee80211_ptr = NULL;
 131        vif->netdev = NULL;
 132        vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
 133        eth_zero_addr(vif->mac_addr);
 134
 135        return 0;
 136}
 137
 138static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
 139                                                  const char *name,
 140                                                  unsigned char name_assign_t,
 141                                                  enum nl80211_iftype type,
 142                                                  struct vif_params *params)
 143{
 144        struct qtnf_wmac *mac;
 145        struct qtnf_vif *vif;
 146        u8 *mac_addr = NULL;
 147
 148        mac = wiphy_priv(wiphy);
 149
 150        if (!mac)
 151                return ERR_PTR(-EFAULT);
 152
 153        switch (type) {
 154        case NL80211_IFTYPE_STATION:
 155        case NL80211_IFTYPE_AP:
 156                vif = qtnf_mac_get_free_vif(mac);
 157                if (!vif) {
 158                        pr_err("MAC%u: no free VIF available\n", mac->macid);
 159                        return ERR_PTR(-EFAULT);
 160                }
 161
 162                eth_zero_addr(vif->mac_addr);
 163                vif->bss_priority = QTNF_DEF_BSS_PRIORITY;
 164                vif->wdev.wiphy = wiphy;
 165                vif->wdev.iftype = type;
 166                vif->sta_state = QTNF_STA_DISCONNECTED;
 167                break;
 168        default:
 169                pr_err("MAC%u: unsupported IF type %d\n", mac->macid, type);
 170                return ERR_PTR(-ENOTSUPP);
 171        }
 172
 173        if (params)
 174                mac_addr = params->macaddr;
 175
 176        if (qtnf_cmd_send_add_intf(vif, type, mac_addr)) {
 177                pr_err("VIF%u.%u: failed to add VIF\n", mac->macid, vif->vifid);
 178                goto err_cmd;
 179        }
 180
 181        if (!is_valid_ether_addr(vif->mac_addr)) {
 182                pr_err("VIF%u.%u: FW reported bad MAC: %pM\n",
 183                       mac->macid, vif->vifid, vif->mac_addr);
 184                goto err_mac;
 185        }
 186
 187        if (qtnf_core_net_attach(mac, vif, name, name_assign_t, type)) {
 188                pr_err("VIF%u.%u: failed to attach netdev\n", mac->macid,
 189                       vif->vifid);
 190                goto err_net;
 191        }
 192
 193        vif->wdev.netdev = vif->netdev;
 194        return &vif->wdev;
 195
 196err_net:
 197        vif->netdev = NULL;
 198err_mac:
 199        qtnf_cmd_send_del_intf(vif);
 200err_cmd:
 201        vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
 202
 203        return ERR_PTR(-EFAULT);
 204}
 205
 206static int qtnf_mgmt_set_appie(struct qtnf_vif *vif,
 207                               const struct cfg80211_beacon_data *info)
 208{
 209        int ret = 0;
 210
 211        if (!info->beacon_ies || !info->beacon_ies_len) {
 212                ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON,
 213                                                   NULL, 0);
 214        } else {
 215                ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON,
 216                                                   info->beacon_ies,
 217                                                   info->beacon_ies_len);
 218        }
 219
 220        if (ret)
 221                goto out;
 222
 223        if (!info->proberesp_ies || !info->proberesp_ies_len) {
 224                ret = qtnf_cmd_send_mgmt_set_appie(vif,
 225                                                   QLINK_MGMT_FRAME_PROBE_RESP,
 226                                                   NULL, 0);
 227        } else {
 228                ret = qtnf_cmd_send_mgmt_set_appie(vif,
 229                                                   QLINK_MGMT_FRAME_PROBE_RESP,
 230                                                   info->proberesp_ies,
 231                                                   info->proberesp_ies_len);
 232        }
 233
 234        if (ret)
 235                goto out;
 236
 237        if (!info->assocresp_ies || !info->assocresp_ies_len) {
 238                ret = qtnf_cmd_send_mgmt_set_appie(vif,
 239                                                   QLINK_MGMT_FRAME_ASSOC_RESP,
 240                                                   NULL, 0);
 241        } else {
 242                ret = qtnf_cmd_send_mgmt_set_appie(vif,
 243                                                   QLINK_MGMT_FRAME_ASSOC_RESP,
 244                                                   info->assocresp_ies,
 245                                                   info->assocresp_ies_len);
 246        }
 247
 248out:
 249        return ret;
 250}
 251
 252static int qtnf_change_beacon(struct wiphy *wiphy, struct net_device *dev,
 253                              struct cfg80211_beacon_data *info)
 254{
 255        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 256
 257        if (!(vif->bss_status & QTNF_STATE_AP_START)) {
 258                pr_err("VIF%u.%u: not started\n", vif->mac->macid, vif->vifid);
 259                return -EFAULT;
 260        }
 261
 262        return qtnf_mgmt_set_appie(vif, info);
 263}
 264
 265static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
 266                         struct cfg80211_ap_settings *settings)
 267{
 268        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 269        struct qtnf_bss_config *bss_cfg;
 270        int ret;
 271
 272        bss_cfg = &vif->bss_cfg;
 273
 274        memset(bss_cfg, 0, sizeof(*bss_cfg));
 275
 276        bss_cfg->bcn_period = settings->beacon_interval;
 277        bss_cfg->dtim = settings->dtim_period;
 278        bss_cfg->auth_type = settings->auth_type;
 279        bss_cfg->privacy = settings->privacy;
 280
 281        bss_cfg->ssid_len = settings->ssid_len;
 282        memcpy(&bss_cfg->ssid, settings->ssid, bss_cfg->ssid_len);
 283
 284        memcpy(&bss_cfg->chandef, &settings->chandef,
 285               sizeof(struct cfg80211_chan_def));
 286        memcpy(&bss_cfg->crypto, &settings->crypto,
 287               sizeof(struct cfg80211_crypto_settings));
 288
 289        ret = qtnf_cmd_send_config_ap(vif);
 290        if (ret) {
 291                pr_err("VIF%u.%u: failed to push config to FW\n",
 292                       vif->mac->macid, vif->vifid);
 293                goto out;
 294        }
 295
 296        if (!(vif->bss_status & QTNF_STATE_AP_CONFIG)) {
 297                pr_err("VIF%u.%u: AP config failed in FW\n", vif->mac->macid,
 298                       vif->vifid);
 299                ret = -EFAULT;
 300                goto out;
 301        }
 302
 303        ret = qtnf_mgmt_set_appie(vif, &settings->beacon);
 304        if (ret) {
 305                pr_err("VIF%u.%u: failed to add IEs to beacon\n",
 306                       vif->mac->macid, vif->vifid);
 307                goto out;
 308        }
 309
 310        ret = qtnf_cmd_send_start_ap(vif);
 311        if (ret) {
 312                pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid,
 313                       vif->vifid);
 314                goto out;
 315        }
 316
 317        if (!(vif->bss_status & QTNF_STATE_AP_START)) {
 318                pr_err("VIF%u.%u: FW failed to start AP operation\n",
 319                       vif->mac->macid, vif->vifid);
 320                ret = -EFAULT;
 321        }
 322
 323out:
 324        return ret;
 325}
 326
 327static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 328{
 329        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 330        int ret;
 331
 332        ret = qtnf_cmd_send_stop_ap(vif);
 333        if (ret) {
 334                pr_err("VIF%u.%u: failed to stop AP operation in FW\n",
 335                       vif->mac->macid, vif->vifid);
 336                vif->bss_status &= ~QTNF_STATE_AP_START;
 337                vif->bss_status &= ~QTNF_STATE_AP_CONFIG;
 338
 339                netif_carrier_off(vif->netdev);
 340        }
 341
 342        return ret;
 343}
 344
 345static int qtnf_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 346{
 347        struct qtnf_wmac *mac = wiphy_priv(wiphy);
 348        struct qtnf_vif *vif;
 349        int ret;
 350
 351        vif = qtnf_mac_get_base_vif(mac);
 352        if (!vif) {
 353                pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
 354                return -EFAULT;
 355        }
 356
 357        if (changed & (WIPHY_PARAM_RETRY_LONG | WIPHY_PARAM_RETRY_SHORT)) {
 358                pr_err("MAC%u: can't modify retry params\n", mac->macid);
 359                return -EOPNOTSUPP;
 360        }
 361
 362        ret = qtnf_cmd_send_update_phy_params(mac, changed);
 363        if (ret)
 364                pr_err("MAC%u: failed to update PHY params\n", mac->macid);
 365
 366        return ret;
 367}
 368
 369static void
 370qtnf_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
 371                         u16 frame_type, bool reg)
 372{
 373        struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
 374        u16 mgmt_type;
 375        u16 new_mask;
 376        u16 qlink_frame_type = 0;
 377
 378        mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
 379
 380        if (reg)
 381                new_mask = vif->mgmt_frames_bitmask | BIT(mgmt_type);
 382        else
 383                new_mask = vif->mgmt_frames_bitmask & ~BIT(mgmt_type);
 384
 385        if (new_mask == vif->mgmt_frames_bitmask)
 386                return;
 387
 388        switch (frame_type & IEEE80211_FCTL_STYPE) {
 389        case IEEE80211_STYPE_PROBE_REQ:
 390                qlink_frame_type = QLINK_MGMT_FRAME_PROBE_REQ;
 391                break;
 392        case IEEE80211_STYPE_ACTION:
 393                qlink_frame_type = QLINK_MGMT_FRAME_ACTION;
 394                break;
 395        default:
 396                pr_warn("VIF%u.%u: unsupported frame type: %X\n",
 397                        vif->mac->macid, vif->vifid,
 398                        (frame_type & IEEE80211_FCTL_STYPE) >> 4);
 399                return;
 400        }
 401
 402        if (qtnf_cmd_send_register_mgmt(vif, qlink_frame_type, reg)) {
 403                pr_warn("VIF%u.%u: failed to %sregister mgmt frame type 0x%x\n",
 404                        vif->mac->macid, vif->vifid, reg ? "" : "un",
 405                        frame_type);
 406                return;
 407        }
 408
 409        vif->mgmt_frames_bitmask = new_mask;
 410        pr_debug("VIF%u.%u: %sregistered mgmt frame type 0x%x\n",
 411                 vif->mac->macid, vif->vifid, reg ? "" : "un", frame_type);
 412}
 413
 414static int
 415qtnf_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 416             struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 417{
 418        struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
 419        const struct ieee80211_mgmt *mgmt_frame = (void *)params->buf;
 420        u32 short_cookie = prandom_u32();
 421        u16 flags = 0;
 422
 423        *cookie = short_cookie;
 424
 425        if (params->offchan)
 426                flags |= QLINK_MGMT_FRAME_TX_FLAG_OFFCHAN;
 427
 428        if (params->no_cck)
 429                flags |= QLINK_MGMT_FRAME_TX_FLAG_NO_CCK;
 430
 431        if (params->dont_wait_for_ack)
 432                flags |= QLINK_MGMT_FRAME_TX_FLAG_ACK_NOWAIT;
 433
 434        pr_debug("%s freq:%u; FC:%.4X; DA:%pM; len:%zu; C:%.8X; FL:%.4X\n",
 435                 wdev->netdev->name, params->chan->center_freq,
 436                 le16_to_cpu(mgmt_frame->frame_control), mgmt_frame->da,
 437                 params->len, short_cookie, flags);
 438
 439        return qtnf_cmd_send_mgmt_frame(vif, short_cookie, flags,
 440                                        params->chan->center_freq,
 441                                        params->buf, params->len);
 442}
 443
 444static int
 445qtnf_get_station(struct wiphy *wiphy, struct net_device *dev,
 446                 const u8 *mac, struct station_info *sinfo)
 447{
 448        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 449
 450        return qtnf_cmd_get_sta_info(vif, mac, sinfo);
 451}
 452
 453static int
 454qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,
 455                  int idx, u8 *mac, struct station_info *sinfo)
 456{
 457        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 458        const struct qtnf_sta_node *sta_node;
 459        int ret;
 460
 461        sta_node = qtnf_sta_list_lookup_index(&vif->sta_list, idx);
 462
 463        if (unlikely(!sta_node))
 464                return -ENOENT;
 465
 466        ether_addr_copy(mac, sta_node->mac_addr);
 467
 468        ret = qtnf_cmd_get_sta_info(vif, sta_node->mac_addr, sinfo);
 469
 470        if (unlikely(ret == -ENOENT)) {
 471                qtnf_sta_list_del(&vif->sta_list, mac);
 472                cfg80211_del_sta(vif->netdev, mac, GFP_KERNEL);
 473                sinfo->filled = 0;
 474        }
 475
 476        return ret;
 477}
 478
 479static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev,
 480                        u8 key_index, bool pairwise, const u8 *mac_addr,
 481                        struct key_params *params)
 482{
 483        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 484        int ret;
 485
 486        ret = qtnf_cmd_send_add_key(vif, key_index, pairwise, mac_addr, params);
 487        if (ret)
 488                pr_err("VIF%u.%u: failed to add key: cipher=%x idx=%u pw=%u\n",
 489                       vif->mac->macid, vif->vifid, params->cipher, key_index,
 490                       pairwise);
 491
 492        return ret;
 493}
 494
 495static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev,
 496                        u8 key_index, bool pairwise, const u8 *mac_addr)
 497{
 498        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 499        int ret;
 500
 501        ret = qtnf_cmd_send_del_key(vif, key_index, pairwise, mac_addr);
 502        if (ret)
 503                pr_err("VIF%u.%u: failed to delete key: idx=%u pw=%u\n",
 504                       vif->mac->macid, vif->vifid, key_index, pairwise);
 505
 506        return ret;
 507}
 508
 509static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev,
 510                                u8 key_index, bool unicast, bool multicast)
 511{
 512        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 513        int ret;
 514
 515        ret = qtnf_cmd_send_set_default_key(vif, key_index, unicast, multicast);
 516        if (ret)
 517                pr_err("VIF%u.%u: failed to set dflt key: idx=%u uc=%u mc=%u\n",
 518                       vif->mac->macid, vif->vifid, key_index, unicast,
 519                       multicast);
 520
 521        return ret;
 522}
 523
 524static int
 525qtnf_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev,
 526                          u8 key_index)
 527{
 528        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 529        int ret;
 530
 531        ret = qtnf_cmd_send_set_default_mgmt_key(vif, key_index);
 532        if (ret)
 533                pr_err("VIF%u.%u: failed to set default MGMT key: idx=%u\n",
 534                       vif->mac->macid, vif->vifid, key_index);
 535
 536        return ret;
 537}
 538
 539static int
 540qtnf_change_station(struct wiphy *wiphy, struct net_device *dev,
 541                    const u8 *mac, struct station_parameters *params)
 542{
 543        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 544        int ret;
 545
 546        ret = qtnf_cmd_send_change_sta(vif, mac, params);
 547        if (ret)
 548                pr_err("VIF%u.%u: failed to change STA %pM\n",
 549                       vif->mac->macid, vif->vifid, mac);
 550
 551        return ret;
 552}
 553
 554static int
 555qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,
 556                 struct station_del_parameters *params)
 557{
 558        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 559        int ret;
 560
 561        if (params->mac &&
 562            (vif->wdev.iftype == NL80211_IFTYPE_AP) &&
 563            !is_broadcast_ether_addr(params->mac) &&
 564            !qtnf_sta_list_lookup(&vif->sta_list, params->mac))
 565                return 0;
 566
 567        qtnf_scan_done(vif->mac, true);
 568
 569        ret = qtnf_cmd_send_del_sta(vif, params);
 570        if (ret)
 571                pr_err("VIF%u.%u: failed to delete STA %pM\n",
 572                       vif->mac->macid, vif->vifid, params->mac);
 573        return ret;
 574}
 575
 576static int
 577qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 578{
 579        struct qtnf_wmac *mac = wiphy_priv(wiphy);
 580        int ret;
 581
 582        mac->scan_req = request;
 583
 584        ret = qtnf_cmd_send_scan(mac);
 585        if (ret)
 586                pr_err("MAC%u: failed to start scan\n", mac->macid);
 587
 588        return ret;
 589}
 590
 591static int
 592qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
 593             struct cfg80211_connect_params *sme)
 594{
 595        struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
 596        struct qtnf_bss_config *bss_cfg;
 597        int ret;
 598
 599        if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
 600                return -EOPNOTSUPP;
 601
 602        if (vif->sta_state != QTNF_STA_DISCONNECTED)
 603                return -EBUSY;
 604
 605        bss_cfg = &vif->bss_cfg;
 606        memset(bss_cfg, 0, sizeof(*bss_cfg));
 607
 608        bss_cfg->ssid_len = sme->ssid_len;
 609        memcpy(&bss_cfg->ssid, sme->ssid, bss_cfg->ssid_len);
 610        bss_cfg->chandef.chan = sme->channel;
 611        bss_cfg->auth_type = sme->auth_type;
 612        bss_cfg->privacy = sme->privacy;
 613        bss_cfg->mfp = sme->mfp;
 614
 615        if ((sme->bg_scan_period > 0) &&
 616            (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
 617                bss_cfg->bg_scan_period = sme->bg_scan_period;
 618        else if (sme->bg_scan_period == -1)
 619                bss_cfg->bg_scan_period = QTNF_DEFAULT_BG_SCAN_PERIOD;
 620        else
 621                bss_cfg->bg_scan_period = 0; /* disabled */
 622
 623        bss_cfg->connect_flags = 0;
 624
 625        if (sme->flags & ASSOC_REQ_DISABLE_HT)
 626                bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
 627        if (sme->flags & ASSOC_REQ_DISABLE_VHT)
 628                bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT;
 629        if (sme->flags & ASSOC_REQ_USE_RRM)
 630                bss_cfg->connect_flags |= QLINK_STA_CONNECT_USE_RRM;
 631
 632        memcpy(&bss_cfg->crypto, &sme->crypto, sizeof(bss_cfg->crypto));
 633        if (sme->bssid)
 634                ether_addr_copy(bss_cfg->bssid, sme->bssid);
 635        else
 636                eth_zero_addr(bss_cfg->bssid);
 637
 638        ret = qtnf_cmd_send_connect(vif, sme);
 639        if (ret) {
 640                pr_err("VIF%u.%u: failed to connect\n", vif->mac->macid,
 641                       vif->vifid);
 642                return ret;
 643        }
 644
 645        vif->sta_state = QTNF_STA_CONNECTING;
 646        return 0;
 647}
 648
 649static int
 650qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,
 651                u16 reason_code)
 652{
 653        struct qtnf_wmac *mac = wiphy_priv(wiphy);
 654        struct qtnf_vif *vif;
 655        int ret;
 656
 657        vif = qtnf_mac_get_base_vif(mac);
 658        if (!vif) {
 659                pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
 660                return -EFAULT;
 661        }
 662
 663        if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
 664                return -EOPNOTSUPP;
 665
 666        if (vif->sta_state == QTNF_STA_DISCONNECTED)
 667                return 0;
 668
 669        ret = qtnf_cmd_send_disconnect(vif, reason_code);
 670        if (ret) {
 671                pr_err("VIF%u.%u: failed to disconnect\n", mac->macid,
 672                       vif->vifid);
 673                return ret;
 674        }
 675
 676        vif->sta_state = QTNF_STA_DISCONNECTED;
 677        return 0;
 678}
 679
 680static struct cfg80211_ops qtn_cfg80211_ops = {
 681        .add_virtual_intf       = qtnf_add_virtual_intf,
 682        .change_virtual_intf    = qtnf_change_virtual_intf,
 683        .del_virtual_intf       = qtnf_del_virtual_intf,
 684        .start_ap               = qtnf_start_ap,
 685        .change_beacon          = qtnf_change_beacon,
 686        .stop_ap                = qtnf_stop_ap,
 687        .set_wiphy_params       = qtnf_set_wiphy_params,
 688        .mgmt_frame_register    = qtnf_mgmt_frame_register,
 689        .mgmt_tx                = qtnf_mgmt_tx,
 690        .change_station         = qtnf_change_station,
 691        .del_station            = qtnf_del_station,
 692        .get_station            = qtnf_get_station,
 693        .dump_station           = qtnf_dump_station,
 694        .add_key                = qtnf_add_key,
 695        .del_key                = qtnf_del_key,
 696        .set_default_key        = qtnf_set_default_key,
 697        .set_default_mgmt_key   = qtnf_set_default_mgmt_key,
 698        .scan                   = qtnf_scan,
 699        .connect                = qtnf_connect,
 700        .disconnect             = qtnf_disconnect
 701};
 702
 703static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy,
 704                                       struct regulatory_request *req)
 705{
 706        struct qtnf_wmac *mac = wiphy_priv(wiphy);
 707        struct qtnf_bus *bus;
 708        struct qtnf_vif *vif;
 709        struct qtnf_wmac *chan_mac;
 710        int i;
 711        enum nl80211_band band;
 712
 713        bus = mac->bus;
 714
 715        pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac->macid, req->initiator,
 716                 req->alpha2[0], req->alpha2[1]);
 717
 718        vif = qtnf_mac_get_base_vif(mac);
 719        if (!vif) {
 720                pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
 721                return;
 722        }
 723
 724        /* ignore non-ISO3166 country codes */
 725        for (i = 0; i < sizeof(req->alpha2); i++) {
 726                if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
 727                        pr_err("MAC%u: not an ISO3166 code\n", mac->macid);
 728                        return;
 729                }
 730        }
 731        if (!strncasecmp(req->alpha2, bus->hw_info.alpha2_code,
 732                         sizeof(req->alpha2))) {
 733                pr_warn("MAC%u: unchanged country code\n", mac->macid);
 734                return;
 735        }
 736
 737        if (qtnf_cmd_send_regulatory_config(mac, req->alpha2)) {
 738                pr_err("MAC%u: failed to configure regulatory\n", mac->macid);
 739                return;
 740        }
 741
 742        for (i = 0; i < bus->hw_info.num_mac; i++) {
 743                chan_mac = bus->mac[i];
 744
 745                if (!chan_mac)
 746                        continue;
 747
 748                if (!(bus->hw_info.mac_bitmap & BIT(i)))
 749                        continue;
 750
 751                for (band = 0; band < NUM_NL80211_BANDS; ++band) {
 752                        if (!wiphy->bands[band])
 753                                continue;
 754
 755                        if (qtnf_cmd_get_mac_chan_info(chan_mac,
 756                                                       wiphy->bands[band])) {
 757                                pr_err("MAC%u: can't get channel info\n",
 758                                       chan_mac->macid);
 759                                qtnf_core_detach(bus);
 760
 761                                return;
 762                        }
 763                }
 764        }
 765}
 766
 767void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo,
 768                                struct ieee80211_supported_band *band)
 769{
 770        struct ieee80211_sta_ht_cap *ht_cap;
 771        struct ieee80211_sta_vht_cap *vht_cap;
 772
 773        ht_cap = &band->ht_cap;
 774        ht_cap->ht_supported = true;
 775        memcpy(&ht_cap->cap, &macinfo->ht_cap.cap_info,
 776               sizeof(u16));
 777        ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
 778        ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
 779        memcpy(&ht_cap->mcs, &macinfo->ht_cap.mcs,
 780               sizeof(ht_cap->mcs));
 781
 782        if (macinfo->phymode_cap & QLINK_PHYMODE_AC) {
 783                vht_cap = &band->vht_cap;
 784                vht_cap->vht_supported = true;
 785                memcpy(&vht_cap->cap,
 786                       &macinfo->vht_cap.vht_cap_info, sizeof(u32));
 787                /* Update MCS support for VHT */
 788                memcpy(&vht_cap->vht_mcs,
 789                       &macinfo->vht_cap.supp_mcs,
 790                       sizeof(struct ieee80211_vht_mcs_info));
 791        }
 792}
 793
 794struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus)
 795{
 796        struct wiphy *wiphy;
 797
 798        wiphy = wiphy_new(&qtn_cfg80211_ops, sizeof(struct qtnf_wmac));
 799        if (!wiphy)
 800                return NULL;
 801
 802        set_wiphy_dev(wiphy, bus->dev);
 803
 804        return wiphy;
 805}
 806
 807static int qtnf_wiphy_setup_if_comb(struct wiphy *wiphy,
 808                                    struct ieee80211_iface_combination *if_comb,
 809                                    const struct qtnf_mac_info *mac_info)
 810{
 811        size_t max_interfaces = 0;
 812        u16 interface_modes = 0;
 813        size_t i;
 814
 815        if (unlikely(!mac_info->limits || !mac_info->n_limits))
 816                return -ENOENT;
 817
 818        if_comb->limits = mac_info->limits;
 819        if_comb->n_limits = mac_info->n_limits;
 820
 821        for (i = 0; i < mac_info->n_limits; i++) {
 822                max_interfaces += mac_info->limits[i].max;
 823                interface_modes |= mac_info->limits[i].types;
 824        }
 825
 826        if_comb->num_different_channels = 1;
 827        if_comb->beacon_int_infra_match = true;
 828        if_comb->max_interfaces = max_interfaces;
 829        if_comb->radar_detect_widths = mac_info->radar_detect_widths;
 830        wiphy->interface_modes = interface_modes;
 831
 832        return 0;
 833}
 834
 835int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
 836{
 837        struct wiphy *wiphy = priv_to_wiphy(mac);
 838        struct ieee80211_iface_combination *iface_comb = NULL;
 839        int ret;
 840
 841        if (!wiphy) {
 842                pr_err("invalid wiphy pointer\n");
 843                return -EFAULT;
 844        }
 845
 846        iface_comb = kzalloc(sizeof(*iface_comb), GFP_KERNEL);
 847        if (!iface_comb) {
 848                ret = -ENOMEM;
 849                goto out;
 850        }
 851
 852        ret = qtnf_wiphy_setup_if_comb(wiphy, iface_comb, &mac->macinfo);
 853        if (ret)
 854                goto out;
 855
 856        pr_info("MAC%u: phymode=%#x radar=%#x\n", mac->macid,
 857                mac->macinfo.phymode_cap, mac->macinfo.radar_detect_widths);
 858
 859        wiphy->frag_threshold = mac->macinfo.frag_thr;
 860        wiphy->rts_threshold = mac->macinfo.rts_thr;
 861        wiphy->retry_short = mac->macinfo.sretry_limit;
 862        wiphy->retry_long = mac->macinfo.lretry_limit;
 863        wiphy->coverage_class = mac->macinfo.coverage_class;
 864
 865        wiphy->max_scan_ssids = QTNF_MAX_SSID_LIST_LENGTH;
 866        wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN;
 867        wiphy->mgmt_stypes = qtnf_mgmt_stypes;
 868        wiphy->max_remain_on_channel_duration = 5000;
 869
 870        wiphy->iface_combinations = iface_comb;
 871        wiphy->n_iface_combinations = 1;
 872
 873        /* Initialize cipher suits */
 874        wiphy->cipher_suites = qtnf_cipher_suites;
 875        wiphy->n_cipher_suites = ARRAY_SIZE(qtnf_cipher_suites);
 876        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 877        wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
 878                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
 879                        WIPHY_FLAG_AP_UAPSD;
 880
 881        wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
 882                                    NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;
 883
 884        wiphy->available_antennas_tx = mac->macinfo.num_tx_chain;
 885        wiphy->available_antennas_rx = mac->macinfo.num_rx_chain;
 886
 887        wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta;
 888
 889        ether_addr_copy(wiphy->perm_addr, mac->macaddr);
 890
 891        if (hw_info->hw_capab & QLINK_HW_SUPPORTS_REG_UPDATE) {
 892                pr_debug("device supports REG_UPDATE\n");
 893                wiphy->reg_notifier = qtnf_cfg80211_reg_notifier;
 894                pr_debug("hint regulatory about EP region: %c%c\n",
 895                         hw_info->alpha2_code[0],
 896                         hw_info->alpha2_code[1]);
 897                regulatory_hint(wiphy, hw_info->alpha2_code);
 898        } else {
 899                pr_debug("device doesn't support REG_UPDATE\n");
 900                wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
 901        }
 902
 903        ret = wiphy_register(wiphy);
 904
 905out:
 906        if (ret < 0) {
 907                kfree(iface_comb);
 908                return ret;
 909        }
 910
 911        return 0;
 912}
 913
 914void qtnf_netdev_updown(struct net_device *ndev, bool up)
 915{
 916        struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
 917
 918        if (qtnf_cmd_send_updown_intf(vif, up))
 919                pr_err("failed to send up/down command to FW\n");
 920}
 921
 922void qtnf_virtual_intf_cleanup(struct net_device *ndev)
 923{
 924        struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
 925        struct qtnf_wmac *mac = wiphy_priv(vif->wdev.wiphy);
 926
 927        if (vif->wdev.iftype == NL80211_IFTYPE_STATION) {
 928                switch (vif->sta_state) {
 929                case QTNF_STA_DISCONNECTED:
 930                        break;
 931                case QTNF_STA_CONNECTING:
 932                        cfg80211_connect_result(vif->netdev,
 933                                                vif->bss_cfg.bssid, NULL, 0,
 934                                                NULL, 0,
 935                                                WLAN_STATUS_UNSPECIFIED_FAILURE,
 936                                                GFP_KERNEL);
 937                        qtnf_disconnect(vif->wdev.wiphy, ndev,
 938                                        WLAN_REASON_DEAUTH_LEAVING);
 939                        break;
 940                case QTNF_STA_CONNECTED:
 941                        cfg80211_disconnected(vif->netdev,
 942                                              WLAN_REASON_DEAUTH_LEAVING,
 943                                              NULL, 0, 1, GFP_KERNEL);
 944                        qtnf_disconnect(vif->wdev.wiphy, ndev,
 945                                        WLAN_REASON_DEAUTH_LEAVING);
 946                        break;
 947                }
 948
 949                vif->sta_state = QTNF_STA_DISCONNECTED;
 950                qtnf_scan_done(mac, true);
 951        }
 952}
 953
 954void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif)
 955{
 956        if (vif->wdev.iftype == NL80211_IFTYPE_STATION) {
 957                switch (vif->sta_state) {
 958                case QTNF_STA_CONNECTING:
 959                        cfg80211_connect_result(vif->netdev,
 960                                                vif->bss_cfg.bssid, NULL, 0,
 961                                                NULL, 0,
 962                                                WLAN_STATUS_UNSPECIFIED_FAILURE,
 963                                                GFP_KERNEL);
 964                        break;
 965                case QTNF_STA_CONNECTED:
 966                        cfg80211_disconnected(vif->netdev,
 967                                              WLAN_REASON_DEAUTH_LEAVING,
 968                                              NULL, 0, 1, GFP_KERNEL);
 969                        break;
 970                case QTNF_STA_DISCONNECTED:
 971                        break;
 972                }
 973        }
 974
 975        cfg80211_shutdown_all_interfaces(vif->wdev.wiphy);
 976        vif->sta_state = QTNF_STA_DISCONNECTED;
 977}
 978
 979void qtnf_band_init_rates(struct ieee80211_supported_band *band)
 980{
 981        switch (band->band) {
 982        case NL80211_BAND_2GHZ:
 983                band->bitrates = qtnf_rates_2g;
 984                band->n_bitrates = ARRAY_SIZE(qtnf_rates_2g);
 985                break;
 986        case NL80211_BAND_5GHZ:
 987                band->bitrates = qtnf_rates_5g;
 988                band->n_bitrates = ARRAY_SIZE(qtnf_rates_5g);
 989                break;
 990        default:
 991                band->bitrates = NULL;
 992                band->n_bitrates = 0;
 993                break;
 994        }
 995}
 996