linux/drivers/net/wireless/iwlwifi/mvm/mac80211.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * This file is provided under a dual BSD/GPLv2 license.  When using or
   4 * redistributing this file, you may do so under either license.
   5 *
   6 * GPL LICENSE SUMMARY
   7 *
   8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of version 2 of the GNU General Public License as
  12 * published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  22 * USA
  23 *
  24 * The full GNU General Public License is included in this distribution
  25 * in the file called COPYING.
  26 *
  27 * Contact Information:
  28 *  Intel Linux Wireless <ilw@linux.intel.com>
  29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  30 *
  31 * BSD LICENSE
  32 *
  33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
  34 * All rights reserved.
  35 *
  36 * Redistribution and use in source and binary forms, with or without
  37 * modification, are permitted provided that the following conditions
  38 * are met:
  39 *
  40 *  * Redistributions of source code must retain the above copyright
  41 *    notice, this list of conditions and the following disclaimer.
  42 *  * Redistributions in binary form must reproduce the above copyright
  43 *    notice, this list of conditions and the following disclaimer in
  44 *    the documentation and/or other materials provided with the
  45 *    distribution.
  46 *  * Neither the name Intel Corporation nor the names of its
  47 *    contributors may be used to endorse or promote products derived
  48 *    from this software without specific prior written permission.
  49 *
  50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61 *
  62 *****************************************************************************/
  63#include <linux/kernel.h>
  64#include <linux/slab.h>
  65#include <linux/skbuff.h>
  66#include <linux/netdevice.h>
  67#include <linux/etherdevice.h>
  68#include <linux/ip.h>
  69#include <net/mac80211.h>
  70#include <net/tcp.h>
  71
  72#include "iwl-op-mode.h"
  73#include "iwl-io.h"
  74#include "mvm.h"
  75#include "sta.h"
  76#include "time-event.h"
  77#include "iwl-eeprom-parse.h"
  78#include "fw-api-scan.h"
  79#include "iwl-phy-db.h"
  80
  81static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
  82        {
  83                .max = 1,
  84                .types = BIT(NL80211_IFTYPE_STATION),
  85        },
  86        {
  87                .max = 1,
  88                .types = BIT(NL80211_IFTYPE_AP) |
  89                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
  90                        BIT(NL80211_IFTYPE_P2P_GO),
  91        },
  92        {
  93                .max = 1,
  94                .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
  95        },
  96};
  97
  98static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
  99        {
 100                .num_different_channels = 1,
 101                .max_interfaces = 3,
 102                .limits = iwl_mvm_limits,
 103                .n_limits = ARRAY_SIZE(iwl_mvm_limits),
 104        },
 105};
 106
 107#ifdef CONFIG_PM_SLEEP
 108static const struct nl80211_wowlan_tcp_data_token_feature
 109iwl_mvm_wowlan_tcp_token_feature = {
 110        .min_len = 0,
 111        .max_len = 255,
 112        .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
 113};
 114
 115static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
 116        .tok = &iwl_mvm_wowlan_tcp_token_feature,
 117        .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
 118                            sizeof(struct ethhdr) -
 119                            sizeof(struct iphdr) -
 120                            sizeof(struct tcphdr),
 121        .data_interval_max = 65535, /* __le16 in API */
 122        .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
 123                            sizeof(struct ethhdr) -
 124                            sizeof(struct iphdr) -
 125                            sizeof(struct tcphdr),
 126        .seq = true,
 127};
 128#endif
 129
 130static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
 131{
 132        int i;
 133
 134        memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
 135        for (i = 0; i < NUM_PHY_CTX; i++) {
 136                mvm->phy_ctxts[i].id = i;
 137                mvm->phy_ctxts[i].ref = 0;
 138        }
 139}
 140
 141int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 142{
 143        struct ieee80211_hw *hw = mvm->hw;
 144        int num_mac, ret, i;
 145
 146        /* Tell mac80211 our characteristics */
 147        hw->flags = IEEE80211_HW_SIGNAL_DBM |
 148                    IEEE80211_HW_SPECTRUM_MGMT |
 149                    IEEE80211_HW_REPORTS_TX_ACK_STATUS |
 150                    IEEE80211_HW_QUEUE_CONTROL |
 151                    IEEE80211_HW_WANT_MONITOR_VIF |
 152                    IEEE80211_HW_SUPPORTS_PS |
 153                    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
 154                    IEEE80211_HW_AMPDU_AGGREGATION |
 155                    IEEE80211_HW_TIMING_BEACON_ONLY |
 156                    IEEE80211_HW_CONNECTION_MONITOR;
 157
 158        hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
 159        hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
 160        hw->rate_control_algorithm = "iwl-mvm-rs";
 161
 162        /*
 163         * Enable 11w if advertised by firmware and software crypto
 164         * is not enabled (as the firmware will interpret some mgmt
 165         * packets, so enabling it with software crypto isn't safe)
 166         */
 167        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
 168            !iwlwifi_mod_params.sw_crypto)
 169                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 170
 171        hw->sta_data_size = sizeof(struct iwl_mvm_sta);
 172        hw->vif_data_size = sizeof(struct iwl_mvm_vif);
 173        hw->chanctx_data_size = sizeof(u16);
 174
 175        hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 176                BIT(NL80211_IFTYPE_P2P_CLIENT) |
 177                BIT(NL80211_IFTYPE_AP) |
 178                BIT(NL80211_IFTYPE_P2P_GO) |
 179                BIT(NL80211_IFTYPE_P2P_DEVICE);
 180
 181        hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
 182                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
 183                            WIPHY_FLAG_IBSS_RSN;
 184
 185        hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
 186        hw->wiphy->n_iface_combinations =
 187                ARRAY_SIZE(iwl_mvm_iface_combinations);
 188
 189        hw->wiphy->max_remain_on_channel_duration = 10000;
 190        hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 191
 192        /* Extract MAC address */
 193        memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
 194        hw->wiphy->addresses = mvm->addresses;
 195        hw->wiphy->n_addresses = 1;
 196
 197        /* Extract additional MAC addresses if available */
 198        num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
 199                min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
 200
 201        for (i = 1; i < num_mac; i++) {
 202                memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
 203                       ETH_ALEN);
 204                mvm->addresses[i].addr[5]++;
 205                hw->wiphy->n_addresses++;
 206        }
 207
 208        iwl_mvm_reset_phy_ctxts(mvm);
 209
 210        /* we create the 802.11 header and a max-length SSID element */
 211        hw->wiphy->max_scan_ie_len =
 212                mvm->fw->ucode_capa.max_probe_length - 24 - 34;
 213        hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 214
 215        if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
 216                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 217                        &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
 218        if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
 219                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 220                        &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
 221
 222        hw->wiphy->hw_version = mvm->trans->hw_id;
 223
 224        if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
 225                hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
 226        else
 227                hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 228
 229        hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
 230                               NL80211_FEATURE_P2P_GO_OPPPS;
 231
 232        mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
 233
 234#ifdef CONFIG_PM_SLEEP
 235        if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
 236            mvm->trans->ops->d3_suspend &&
 237            mvm->trans->ops->d3_resume &&
 238            device_can_wakeup(mvm->trans->dev)) {
 239                mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
 240                                    WIPHY_WOWLAN_DISCONNECT |
 241                                    WIPHY_WOWLAN_EAP_IDENTITY_REQ |
 242                                    WIPHY_WOWLAN_RFKILL_RELEASE;
 243                if (!iwlwifi_mod_params.sw_crypto)
 244                        mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
 245                                             WIPHY_WOWLAN_GTK_REKEY_FAILURE |
 246                                             WIPHY_WOWLAN_4WAY_HANDSHAKE;
 247
 248                mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
 249                mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
 250                mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
 251                mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
 252                hw->wiphy->wowlan = &mvm->wowlan;
 253        }
 254#endif
 255
 256        ret = iwl_mvm_leds_init(mvm);
 257        if (ret)
 258                return ret;
 259
 260        ret = ieee80211_register_hw(mvm->hw);
 261        if (ret)
 262                iwl_mvm_leds_exit(mvm);
 263
 264        return ret;
 265}
 266
 267static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
 268                           struct ieee80211_tx_control *control,
 269                           struct sk_buff *skb)
 270{
 271        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 272
 273        if (iwl_mvm_is_radio_killed(mvm)) {
 274                IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
 275                goto drop;
 276        }
 277
 278        if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
 279            !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
 280                goto drop;
 281
 282        if (control->sta) {
 283                if (iwl_mvm_tx_skb(mvm, skb, control->sta))
 284                        goto drop;
 285                return;
 286        }
 287
 288        if (iwl_mvm_tx_skb_non_sta(mvm, skb))
 289                goto drop;
 290        return;
 291 drop:
 292        ieee80211_free_txskb(hw, skb);
 293}
 294
 295static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
 296                                    struct ieee80211_vif *vif,
 297                                    enum ieee80211_ampdu_mlme_action action,
 298                                    struct ieee80211_sta *sta, u16 tid,
 299                                    u16 *ssn, u8 buf_size)
 300{
 301        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 302        int ret;
 303
 304        IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
 305                     sta->addr, tid, action);
 306
 307        if (!(mvm->nvm_data->sku_cap_11n_enable))
 308                return -EACCES;
 309
 310        mutex_lock(&mvm->mutex);
 311
 312        switch (action) {
 313        case IEEE80211_AMPDU_RX_START:
 314                if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) {
 315                        ret = -EINVAL;
 316                        break;
 317                }
 318                ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
 319                break;
 320        case IEEE80211_AMPDU_RX_STOP:
 321                ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
 322                break;
 323        case IEEE80211_AMPDU_TX_START:
 324                if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {
 325                        ret = -EINVAL;
 326                        break;
 327                }
 328                ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
 329                break;
 330        case IEEE80211_AMPDU_TX_STOP_CONT:
 331                ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
 332                break;
 333        case IEEE80211_AMPDU_TX_STOP_FLUSH:
 334        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
 335                ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
 336                break;
 337        case IEEE80211_AMPDU_TX_OPERATIONAL:
 338                ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
 339                break;
 340        default:
 341                WARN_ON_ONCE(1);
 342                ret = -EINVAL;
 343                break;
 344        }
 345        mutex_unlock(&mvm->mutex);
 346
 347        return ret;
 348}
 349
 350static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
 351                                     struct ieee80211_vif *vif)
 352{
 353        struct iwl_mvm *mvm = data;
 354        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 355
 356        mvmvif->uploaded = false;
 357        mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
 358
 359        /* does this make sense at all? */
 360        mvmvif->color++;
 361
 362        spin_lock_bh(&mvm->time_event_lock);
 363        iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
 364        spin_unlock_bh(&mvm->time_event_lock);
 365
 366        mvmvif->phy_ctxt = NULL;
 367}
 368
 369static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
 370{
 371        iwl_trans_stop_device(mvm->trans);
 372        iwl_trans_stop_hw(mvm->trans, false);
 373
 374        mvm->scan_status = IWL_MVM_SCAN_NONE;
 375
 376        /* just in case one was running */
 377        ieee80211_remain_on_channel_expired(mvm->hw);
 378
 379        ieee80211_iterate_active_interfaces_atomic(
 380                mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 381                iwl_mvm_cleanup_iterator, mvm);
 382
 383        mvm->p2p_device_vif = NULL;
 384
 385        iwl_mvm_reset_phy_ctxts(mvm);
 386        memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 387        memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
 388
 389        ieee80211_wake_queues(mvm->hw);
 390
 391        mvm->vif_count = 0;
 392        mvm->rx_ba_sessions = 0;
 393}
 394
 395static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
 396{
 397        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 398        int ret;
 399
 400        mutex_lock(&mvm->mutex);
 401
 402        /* Clean up some internal and mac80211 state on restart */
 403        if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
 404                iwl_mvm_restart_cleanup(mvm);
 405
 406        ret = iwl_mvm_up(mvm);
 407        mutex_unlock(&mvm->mutex);
 408
 409        return ret;
 410}
 411
 412static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
 413{
 414        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 415        int ret;
 416
 417        mutex_lock(&mvm->mutex);
 418
 419        clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 420        ret = iwl_mvm_update_quotas(mvm, NULL);
 421        if (ret)
 422                IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
 423                        ret);
 424
 425        mutex_unlock(&mvm->mutex);
 426}
 427
 428static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
 429{
 430        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 431
 432        flush_work(&mvm->async_handlers_wk);
 433
 434        mutex_lock(&mvm->mutex);
 435        /* async_handlers_wk is now blocked */
 436
 437        /*
 438         * The work item could be running or queued if the
 439         * ROC time event stops just as we get here.
 440         */
 441        cancel_work_sync(&mvm->roc_done_wk);
 442
 443        iwl_trans_stop_device(mvm->trans);
 444        iwl_trans_stop_hw(mvm->trans, false);
 445
 446        iwl_mvm_async_handlers_purge(mvm);
 447        /* async_handlers_list is empty and will stay empty: HW is stopped */
 448
 449        /* the fw is stopped, the aux sta is dead: clean up driver state */
 450        iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
 451
 452        mutex_unlock(&mvm->mutex);
 453
 454        /*
 455         * The worker might have been waiting for the mutex, let it run and
 456         * discover that its list is now empty.
 457         */
 458        cancel_work_sync(&mvm->async_handlers_wk);
 459}
 460
 461static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
 462                                        struct ieee80211_vif *vif)
 463{
 464        struct iwl_mvm *mvm = data;
 465        int ret;
 466
 467        ret = iwl_mvm_power_disable(mvm, vif);
 468        if (ret)
 469                IWL_ERR(mvm, "failed to disable power management\n");
 470}
 471
 472static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
 473                                          struct ieee80211_vif *vif)
 474{
 475        struct iwl_mvm *mvm = data;
 476
 477        iwl_mvm_power_update_mode(mvm, vif);
 478}
 479
 480static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
 481{
 482        u16 i;
 483
 484        lockdep_assert_held(&mvm->mutex);
 485
 486        for (i = 0; i < NUM_PHY_CTX; i++)
 487                if (!mvm->phy_ctxts[i].ref)
 488                        return &mvm->phy_ctxts[i];
 489
 490        IWL_ERR(mvm, "No available PHY context\n");
 491        return NULL;
 492}
 493
 494static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 495                                     struct ieee80211_vif *vif)
 496{
 497        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 498        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 499        int ret;
 500
 501        /*
 502         * Not much to do here. The stack will not allow interface
 503         * types or combinations that we didn't advertise, so we
 504         * don't really have to check the types.
 505         */
 506
 507        mutex_lock(&mvm->mutex);
 508
 509        /* Allocate resources for the MAC context, and add it the the fw  */
 510        ret = iwl_mvm_mac_ctxt_init(mvm, vif);
 511        if (ret)
 512                goto out_unlock;
 513
 514        /*
 515         * TODO: remove this temporary code.
 516         * Currently MVM FW supports power management only on single MAC.
 517         * If new interface added, disable PM on existing interface.
 518         * P2P device is a special case, since it is handled by FW similary to
 519         * scan. If P2P deviced is added, PM remains enabled on existing
 520         * interface.
 521         * Note: the method below does not count the new interface being added
 522         * at this moment.
 523         */
 524        if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
 525                mvm->vif_count++;
 526        if (mvm->vif_count > 1) {
 527                IWL_DEBUG_MAC80211(mvm,
 528                                   "Disable power on existing interfaces\n");
 529                ieee80211_iterate_active_interfaces_atomic(
 530                                            mvm->hw,
 531                                            IEEE80211_IFACE_ITER_NORMAL,
 532                                            iwl_mvm_pm_disable_iterator, mvm);
 533        }
 534
 535        /*
 536         * The AP binding flow can be done only after the beacon
 537         * template is configured (which happens only in the mac80211
 538         * start_ap() flow), and adding the broadcast station can happen
 539         * only after the binding.
 540         * In addition, since modifying the MAC before adding a bcast
 541         * station is not allowed by the FW, delay the adding of MAC context to
 542         * the point where we can also add the bcast station.
 543         * In short: there's not much we can do at this point, other than
 544         * allocating resources :)
 545         */
 546        if (vif->type == NL80211_IFTYPE_AP) {
 547                u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
 548                ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
 549                                               qmask);
 550                if (ret) {
 551                        IWL_ERR(mvm, "Failed to allocate bcast sta\n");
 552                        goto out_release;
 553                }
 554
 555                goto out_unlock;
 556        }
 557
 558        ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 559        if (ret)
 560                goto out_release;
 561
 562        /*
 563         * Update power state on the new interface. Admittedly, based on
 564         * mac80211 logics this power update will disable power management
 565         */
 566        iwl_mvm_power_update_mode(mvm, vif);
 567
 568        /* beacon filtering */
 569        if (!mvm->bf_allowed_vif &&
 570            vif->type == NL80211_IFTYPE_STATION && !vif->p2p){
 571                mvm->bf_allowed_vif = mvmvif;
 572                vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
 573        }
 574
 575        ret = iwl_mvm_disable_beacon_filter(mvm, vif);
 576        if (ret)
 577                goto out_release;
 578
 579        /*
 580         * P2P_DEVICE interface does not have a channel context assigned to it,
 581         * so a dedicated PHY context is allocated to it and the corresponding
 582         * MAC context is bound to it at this stage.
 583         */
 584        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 585
 586                mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
 587                if (!mvmvif->phy_ctxt) {
 588                        ret = -ENOSPC;
 589                        goto out_remove_mac;
 590                }
 591
 592                iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
 593                ret = iwl_mvm_binding_add_vif(mvm, vif);
 594                if (ret)
 595                        goto out_unref_phy;
 596
 597                ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 598                if (ret)
 599                        goto out_unbind;
 600
 601                /* Save a pointer to p2p device vif, so it can later be used to
 602                 * update the p2p device MAC when a GO is started/stopped */
 603                mvm->p2p_device_vif = vif;
 604        }
 605
 606        iwl_mvm_vif_dbgfs_register(mvm, vif);
 607        goto out_unlock;
 608
 609 out_unbind:
 610        iwl_mvm_binding_remove_vif(mvm, vif);
 611 out_unref_phy:
 612        iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
 613 out_remove_mac:
 614        mvmvif->phy_ctxt = NULL;
 615        iwl_mvm_mac_ctxt_remove(mvm, vif);
 616 out_release:
 617        if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
 618                mvm->vif_count--;
 619        ieee80211_iterate_active_interfaces(
 620                mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 621                iwl_mvm_power_update_iterator, mvm);
 622        iwl_mvm_mac_ctxt_release(mvm, vif);
 623 out_unlock:
 624        mutex_unlock(&mvm->mutex);
 625
 626        return ret;
 627}
 628
 629static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
 630                                        struct ieee80211_vif *vif)
 631{
 632        u32 tfd_msk = 0, ac;
 633
 634        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 635                if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 636                        tfd_msk |= BIT(vif->hw_queue[ac]);
 637
 638        if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
 639                tfd_msk |= BIT(vif->cab_queue);
 640
 641        if (tfd_msk) {
 642                mutex_lock(&mvm->mutex);
 643                iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
 644                mutex_unlock(&mvm->mutex);
 645        }
 646
 647        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 648                /*
 649                 * Flush the ROC worker which will flush the OFFCHANNEL queue.
 650                 * We assume here that all the packets sent to the OFFCHANNEL
 651                 * queue are sent in ROC session.
 652                 */
 653                flush_work(&mvm->roc_done_wk);
 654        } else {
 655                /*
 656                 * By now, all the AC queues are empty. The AGG queues are
 657                 * empty too. We already got all the Tx responses for all the
 658                 * packets in the queues. The drain work can have been
 659                 * triggered. Flush it.
 660                 */
 661                flush_work(&mvm->sta_drained_wk);
 662        }
 663}
 664
 665static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
 666                                         struct ieee80211_vif *vif)
 667{
 668        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 669        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 670
 671        iwl_mvm_prepare_mac_removal(mvm, vif);
 672
 673        mutex_lock(&mvm->mutex);
 674
 675        if (mvm->bf_allowed_vif == mvmvif) {
 676                mvm->bf_allowed_vif = NULL;
 677                vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
 678        }
 679
 680        iwl_mvm_vif_dbgfs_clean(mvm, vif);
 681
 682        /*
 683         * For AP/GO interface, the tear down of the resources allocated to the
 684         * interface is be handled as part of the stop_ap flow.
 685         */
 686        if (vif->type == NL80211_IFTYPE_AP) {
 687                iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
 688                goto out_release;
 689        }
 690
 691        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 692                mvm->p2p_device_vif = NULL;
 693                iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 694                iwl_mvm_binding_remove_vif(mvm, vif);
 695                iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
 696                mvmvif->phy_ctxt = NULL;
 697        }
 698
 699        /*
 700         * TODO: remove this temporary code.
 701         * Currently MVM FW supports power management only on single MAC.
 702         * Check if only one additional interface remains after removing
 703         * current one. Update power mode on the remaining interface.
 704         */
 705        if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
 706                mvm->vif_count--;
 707        IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
 708                           mvm->vif_count);
 709        if (mvm->vif_count == 1) {
 710                ieee80211_iterate_active_interfaces(
 711                                        mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 712                                        iwl_mvm_power_update_iterator, mvm);
 713        }
 714
 715        iwl_mvm_mac_ctxt_remove(mvm, vif);
 716
 717out_release:
 718        iwl_mvm_mac_ctxt_release(mvm, vif);
 719        mutex_unlock(&mvm->mutex);
 720}
 721
 722static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
 723{
 724        return 0;
 725}
 726
 727static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
 728                                     unsigned int changed_flags,
 729                                     unsigned int *total_flags,
 730                                     u64 multicast)
 731{
 732        *total_flags = 0;
 733}
 734
 735static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
 736                                          struct ieee80211_vif *vif)
 737{
 738        struct iwl_mcast_filter_cmd mcast_filter_cmd = {
 739                .pass_all = 1,
 740        };
 741
 742        memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
 743
 744        return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
 745                                    sizeof(mcast_filter_cmd),
 746                                    &mcast_filter_cmd);
 747}
 748
 749static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
 750                                             struct ieee80211_vif *vif,
 751                                             struct ieee80211_bss_conf *bss_conf,
 752                                             u32 changes)
 753{
 754        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 755        int ret;
 756
 757        ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
 758        if (ret)
 759                IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
 760
 761        if (changes & BSS_CHANGED_ASSOC) {
 762                if (bss_conf->assoc) {
 763                        /* add quota for this interface */
 764                        ret = iwl_mvm_update_quotas(mvm, vif);
 765                        if (ret) {
 766                                IWL_ERR(mvm, "failed to update quotas\n");
 767                                return;
 768                        }
 769                        iwl_mvm_bt_coex_vif_assoc(mvm, vif);
 770                        iwl_mvm_configure_mcast_filter(mvm, vif);
 771                } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
 772                        /* remove AP station now that the MAC is unassoc */
 773                        ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
 774                        if (ret)
 775                                IWL_ERR(mvm, "failed to remove AP station\n");
 776                        mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
 777                        /* remove quota for this interface */
 778                        ret = iwl_mvm_update_quotas(mvm, NULL);
 779                        if (ret)
 780                                IWL_ERR(mvm, "failed to update quotas\n");
 781                }
 782                ret = iwl_mvm_power_update_mode(mvm, vif);
 783                if (ret)
 784                        IWL_ERR(mvm, "failed to update power mode\n");
 785        } else if (changes & BSS_CHANGED_BEACON_INFO) {
 786                /*
 787                 * We received a beacon _after_ association so
 788                 * remove the session protection.
 789                 */
 790                iwl_mvm_remove_time_event(mvm, mvmvif,
 791                                          &mvmvif->time_event_data);
 792        } else if (changes & BSS_CHANGED_PS) {
 793                ret = iwl_mvm_power_update_mode(mvm, vif);
 794                if (ret)
 795                        IWL_ERR(mvm, "failed to update power mode\n");
 796        }
 797}
 798
 799static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 800{
 801        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 802        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 803        int ret;
 804
 805        mutex_lock(&mvm->mutex);
 806
 807        /* Send the beacon template */
 808        ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
 809        if (ret)
 810                goto out_unlock;
 811
 812        /* Add the mac context */
 813        ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 814        if (ret)
 815                goto out_unlock;
 816
 817        /* Perform the binding */
 818        ret = iwl_mvm_binding_add_vif(mvm, vif);
 819        if (ret)
 820                goto out_remove;
 821
 822        mvmvif->ap_active = true;
 823
 824        /* Send the bcast station. At this stage the TBTT and DTIM time events
 825         * are added and applied to the scheduler */
 826        ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 827        if (ret)
 828                goto out_unbind;
 829
 830        ret = iwl_mvm_update_quotas(mvm, vif);
 831        if (ret)
 832                goto out_rm_bcast;
 833
 834        /* Need to update the P2P Device MAC */
 835        if (vif->p2p && mvm->p2p_device_vif)
 836                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
 837
 838        mutex_unlock(&mvm->mutex);
 839        return 0;
 840
 841out_rm_bcast:
 842        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 843out_unbind:
 844        iwl_mvm_binding_remove_vif(mvm, vif);
 845out_remove:
 846        iwl_mvm_mac_ctxt_remove(mvm, vif);
 847out_unlock:
 848        mutex_unlock(&mvm->mutex);
 849        return ret;
 850}
 851
 852static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 853{
 854        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 855        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 856
 857        iwl_mvm_prepare_mac_removal(mvm, vif);
 858
 859        mutex_lock(&mvm->mutex);
 860
 861        mvmvif->ap_active = false;
 862
 863        /* Need to update the P2P Device MAC */
 864        if (vif->p2p && mvm->p2p_device_vif)
 865                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
 866
 867        iwl_mvm_update_quotas(mvm, NULL);
 868        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 869        iwl_mvm_binding_remove_vif(mvm, vif);
 870        iwl_mvm_mac_ctxt_remove(mvm, vif);
 871
 872        mutex_unlock(&mvm->mutex);
 873}
 874
 875static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
 876                                        struct ieee80211_vif *vif,
 877                                        struct ieee80211_bss_conf *bss_conf,
 878                                        u32 changes)
 879{
 880        /* Need to send a new beacon template to the FW */
 881        if (changes & BSS_CHANGED_BEACON) {
 882                if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
 883                        IWL_WARN(mvm, "Failed updating beacon data\n");
 884        }
 885}
 886
 887static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
 888                                     struct ieee80211_vif *vif,
 889                                     struct ieee80211_bss_conf *bss_conf,
 890                                     u32 changes)
 891{
 892        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 893
 894        mutex_lock(&mvm->mutex);
 895
 896        switch (vif->type) {
 897        case NL80211_IFTYPE_STATION:
 898                iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
 899                break;
 900        case NL80211_IFTYPE_AP:
 901                iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
 902                break;
 903        default:
 904                /* shouldn't happen */
 905                WARN_ON_ONCE(1);
 906        }
 907
 908        mutex_unlock(&mvm->mutex);
 909}
 910
 911static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
 912                               struct ieee80211_vif *vif,
 913                               struct cfg80211_scan_request *req)
 914{
 915        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 916        int ret;
 917
 918        if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
 919                return -EINVAL;
 920
 921        mutex_lock(&mvm->mutex);
 922
 923        if (mvm->scan_status == IWL_MVM_SCAN_NONE)
 924                ret = iwl_mvm_scan_request(mvm, vif, req);
 925        else
 926                ret = -EBUSY;
 927
 928        mutex_unlock(&mvm->mutex);
 929
 930        return ret;
 931}
 932
 933static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
 934                                       struct ieee80211_vif *vif)
 935{
 936        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 937
 938        mutex_lock(&mvm->mutex);
 939
 940        iwl_mvm_cancel_scan(mvm);
 941
 942        mutex_unlock(&mvm->mutex);
 943}
 944
 945static void
 946iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
 947                                  struct ieee80211_sta *sta, u16 tid,
 948                                  int num_frames,
 949                                  enum ieee80211_frame_release_type reason,
 950                                  bool more_data)
 951{
 952        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 953
 954        /* TODO: how do we tell the fw to send frames for a specific TID */
 955
 956        /*
 957         * The fw will send EOSP notification when the last frame will be
 958         * transmitted.
 959         */
 960        iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames);
 961}
 962
 963static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
 964                                   struct ieee80211_vif *vif,
 965                                   enum sta_notify_cmd cmd,
 966                                   struct ieee80211_sta *sta)
 967{
 968        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 969        struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
 970
 971        switch (cmd) {
 972        case STA_NOTIFY_SLEEP:
 973                if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
 974                        ieee80211_sta_block_awake(hw, sta, true);
 975                /*
 976                 * The fw updates the STA to be asleep. Tx packets on the Tx
 977                 * queues to this station will not be transmitted. The fw will
 978                 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
 979                 */
 980                break;
 981        case STA_NOTIFY_AWAKE:
 982                if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
 983                        break;
 984                iwl_mvm_sta_modify_ps_wake(mvm, sta);
 985                break;
 986        default:
 987                break;
 988        }
 989}
 990
 991static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
 992                                 struct ieee80211_vif *vif,
 993                                 struct ieee80211_sta *sta,
 994                                 enum ieee80211_sta_state old_state,
 995                                 enum ieee80211_sta_state new_state)
 996{
 997        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 998        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 999        int ret;
1000
1001        IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
1002                           sta->addr, old_state, new_state);
1003
1004        /* this would be a mac80211 bug ... but don't crash */
1005        if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
1006                return -EINVAL;
1007
1008        /* if a STA is being removed, reuse its ID */
1009        flush_work(&mvm->sta_drained_wk);
1010
1011        mutex_lock(&mvm->mutex);
1012        if (old_state == IEEE80211_STA_NOTEXIST &&
1013            new_state == IEEE80211_STA_NONE) {
1014                /*
1015                 * Firmware bug - it'll crash if the beacon interval is less
1016                 * than 16. We can't avoid connecting at all, so refuse the
1017                 * station state change, this will cause mac80211 to abandon
1018                 * attempts to connect to this AP, and eventually wpa_s will
1019                 * blacklist the AP...
1020                 */
1021                if (vif->type == NL80211_IFTYPE_STATION &&
1022                    vif->bss_conf.beacon_int < 16) {
1023                        IWL_ERR(mvm,
1024                                "AP %pM beacon interval is %d, refusing due to firmware bug!\n",
1025                                sta->addr, vif->bss_conf.beacon_int);
1026                        ret = -EINVAL;
1027                        goto out_unlock;
1028                }
1029                ret = iwl_mvm_add_sta(mvm, vif, sta);
1030        } else if (old_state == IEEE80211_STA_NONE &&
1031                   new_state == IEEE80211_STA_AUTH) {
1032                ret = 0;
1033        } else if (old_state == IEEE80211_STA_AUTH &&
1034                   new_state == IEEE80211_STA_ASSOC) {
1035                ret = iwl_mvm_update_sta(mvm, vif, sta);
1036                if (ret == 0)
1037                        iwl_mvm_rs_rate_init(mvm, sta,
1038                                             mvmvif->phy_ctxt->channel->band);
1039        } else if (old_state == IEEE80211_STA_ASSOC &&
1040                   new_state == IEEE80211_STA_AUTHORIZED) {
1041                /* enable beacon filtering */
1042                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
1043                ret = 0;
1044        } else if (old_state == IEEE80211_STA_AUTHORIZED &&
1045                   new_state == IEEE80211_STA_ASSOC) {
1046                /* disable beacon filtering */
1047                WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
1048                ret = 0;
1049        } else if (old_state == IEEE80211_STA_ASSOC &&
1050                   new_state == IEEE80211_STA_AUTH) {
1051                ret = 0;
1052        } else if (old_state == IEEE80211_STA_AUTH &&
1053                   new_state == IEEE80211_STA_NONE) {
1054                ret = 0;
1055        } else if (old_state == IEEE80211_STA_NONE &&
1056                   new_state == IEEE80211_STA_NOTEXIST) {
1057                ret = iwl_mvm_rm_sta(mvm, vif, sta);
1058        } else {
1059                ret = -EIO;
1060        }
1061 out_unlock:
1062        mutex_unlock(&mvm->mutex);
1063
1064        return ret;
1065}
1066
1067static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1068{
1069        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1070
1071        mvm->rts_threshold = value;
1072
1073        return 0;
1074}
1075
1076static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
1077                               struct ieee80211_vif *vif, u16 ac,
1078                               const struct ieee80211_tx_queue_params *params)
1079{
1080        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1081        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1082
1083        mvmvif->queue_params[ac] = *params;
1084
1085        /*
1086         * No need to update right away, we'll get BSS_CHANGED_QOS
1087         * The exception is P2P_DEVICE interface which needs immediate update.
1088         */
1089        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1090                int ret;
1091
1092                mutex_lock(&mvm->mutex);
1093                ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1094                mutex_unlock(&mvm->mutex);
1095                return ret;
1096        }
1097        return 0;
1098}
1099
1100static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1101                                      struct ieee80211_vif *vif)
1102{
1103        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1104        u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
1105                           200 + vif->bss_conf.beacon_int);
1106        u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
1107                               100 + vif->bss_conf.beacon_int);
1108
1109        if (WARN_ON_ONCE(vif->bss_conf.assoc))
1110                return;
1111
1112        mutex_lock(&mvm->mutex);
1113        /* Try really hard to protect the session and hear a beacon */
1114        iwl_mvm_protect_session(mvm, vif, duration, min_duration);
1115        mutex_unlock(&mvm->mutex);
1116}
1117
1118static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1119                               enum set_key_cmd cmd,
1120                               struct ieee80211_vif *vif,
1121                               struct ieee80211_sta *sta,
1122                               struct ieee80211_key_conf *key)
1123{
1124        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1125        int ret;
1126
1127        if (iwlwifi_mod_params.sw_crypto) {
1128                IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1129                return -EOPNOTSUPP;
1130        }
1131
1132        switch (key->cipher) {
1133        case WLAN_CIPHER_SUITE_TKIP:
1134                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1135                /* fall-through */
1136        case WLAN_CIPHER_SUITE_CCMP:
1137                key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1138                break;
1139        case WLAN_CIPHER_SUITE_AES_CMAC:
1140                WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1141                break;
1142        case WLAN_CIPHER_SUITE_WEP40:
1143        case WLAN_CIPHER_SUITE_WEP104:
1144                /*
1145                 * Support for TX only, at least for now, so accept
1146                 * the key and do nothing else. Then mac80211 will
1147                 * pass it for TX but we don't have to use it for RX.
1148                 */
1149                return 0;
1150        default:
1151                return -EOPNOTSUPP;
1152        }
1153
1154        mutex_lock(&mvm->mutex);
1155
1156        switch (cmd) {
1157        case SET_KEY:
1158                if (vif->type == NL80211_IFTYPE_AP && !sta) {
1159                        /* GTK on AP interface is a TX-only key, return 0 */
1160                        ret = 0;
1161                        key->hw_key_idx = STA_KEY_IDX_INVALID;
1162                        break;
1163                }
1164
1165                IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1166                ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1167                if (ret) {
1168                        IWL_WARN(mvm, "set key failed\n");
1169                        /*
1170                         * can't add key for RX, but we don't need it
1171                         * in the device for TX so still return 0
1172                         */
1173                        key->hw_key_idx = STA_KEY_IDX_INVALID;
1174                        ret = 0;
1175                }
1176
1177                break;
1178        case DISABLE_KEY:
1179                if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1180                        ret = 0;
1181                        break;
1182                }
1183
1184                IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1185                ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1186                break;
1187        default:
1188                ret = -EINVAL;
1189        }
1190
1191        mutex_unlock(&mvm->mutex);
1192        return ret;
1193}
1194
1195static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1196                                        struct ieee80211_vif *vif,
1197                                        struct ieee80211_key_conf *keyconf,
1198                                        struct ieee80211_sta *sta,
1199                                        u32 iv32, u16 *phase1key)
1200{
1201        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1202
1203        iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1204}
1205
1206
1207static int iwl_mvm_roc(struct ieee80211_hw *hw,
1208                       struct ieee80211_vif *vif,
1209                       struct ieee80211_channel *channel,
1210                       int duration,
1211                       enum ieee80211_roc_type type)
1212{
1213        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1214        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1215        struct cfg80211_chan_def chandef;
1216        struct iwl_mvm_phy_ctxt *phy_ctxt;
1217        int ret, i;
1218
1219        IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1220                           duration, type);
1221
1222        if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1223                IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1224                return -EINVAL;
1225        }
1226
1227        mutex_lock(&mvm->mutex);
1228
1229        for (i = 0; i < NUM_PHY_CTX; i++) {
1230                phy_ctxt = &mvm->phy_ctxts[i];
1231                if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
1232                        continue;
1233
1234                if (phy_ctxt->ref && channel == phy_ctxt->channel) {
1235                        /*
1236                         * Unbind the P2P_DEVICE from the current PHY context,
1237                         * and if the PHY context is not used remove it.
1238                         */
1239                        ret = iwl_mvm_binding_remove_vif(mvm, vif);
1240                        if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1241                                goto out_unlock;
1242
1243                        iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1244
1245                        /* Bind the P2P_DEVICE to the current PHY Context */
1246                        mvmvif->phy_ctxt = phy_ctxt;
1247
1248                        ret = iwl_mvm_binding_add_vif(mvm, vif);
1249                        if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1250                                goto out_unlock;
1251
1252                        iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1253                        goto schedule_time_event;
1254                }
1255        }
1256
1257        /* Need to update the PHY context only if the ROC channel changed */
1258        if (channel == mvmvif->phy_ctxt->channel)
1259                goto schedule_time_event;
1260
1261        cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1262
1263        /*
1264         * Change the PHY context configuration as it is currently referenced
1265         * only by the P2P Device MAC
1266         */
1267        if (mvmvif->phy_ctxt->ref == 1) {
1268                ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
1269                                               &chandef, 1, 1);
1270                if (ret)
1271                        goto out_unlock;
1272        } else {
1273                /*
1274                 * The PHY context is shared with other MACs. Need to remove the
1275                 * P2P Device from the binding, allocate an new PHY context and
1276                 * create a new binding
1277                 */
1278                phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1279                if (!phy_ctxt) {
1280                        ret = -ENOSPC;
1281                        goto out_unlock;
1282                }
1283
1284                ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
1285                                               1, 1);
1286                if (ret) {
1287                        IWL_ERR(mvm, "Failed to change PHY context\n");
1288                        goto out_unlock;
1289                }
1290
1291                /* Unbind the P2P_DEVICE from the current PHY context */
1292                ret = iwl_mvm_binding_remove_vif(mvm, vif);
1293                if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1294                        goto out_unlock;
1295
1296                iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1297
1298                /* Bind the P2P_DEVICE to the new allocated PHY context */
1299                mvmvif->phy_ctxt = phy_ctxt;
1300
1301                ret = iwl_mvm_binding_add_vif(mvm, vif);
1302                if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1303                        goto out_unlock;
1304
1305                iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1306        }
1307
1308schedule_time_event:
1309        /* Schedule the time events */
1310        ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1311
1312out_unlock:
1313        mutex_unlock(&mvm->mutex);
1314        IWL_DEBUG_MAC80211(mvm, "leave\n");
1315        return ret;
1316}
1317
1318static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1319{
1320        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1321
1322        IWL_DEBUG_MAC80211(mvm, "enter\n");
1323
1324        mutex_lock(&mvm->mutex);
1325        iwl_mvm_stop_p2p_roc(mvm);
1326        mutex_unlock(&mvm->mutex);
1327
1328        IWL_DEBUG_MAC80211(mvm, "leave\n");
1329        return 0;
1330}
1331
1332static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1333                               struct ieee80211_chanctx_conf *ctx)
1334{
1335        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1336        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1337        struct iwl_mvm_phy_ctxt *phy_ctxt;
1338        int ret;
1339
1340        IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
1341
1342        mutex_lock(&mvm->mutex);
1343        phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1344        if (!phy_ctxt) {
1345                ret = -ENOSPC;
1346                goto out;
1347        }
1348
1349        ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1350                                       ctx->rx_chains_static,
1351                                       ctx->rx_chains_dynamic);
1352        if (ret) {
1353                IWL_ERR(mvm, "Failed to add PHY context\n");
1354                goto out;
1355        }
1356
1357        iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
1358        *phy_ctxt_id = phy_ctxt->id;
1359out:
1360        mutex_unlock(&mvm->mutex);
1361        return ret;
1362}
1363
1364static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1365                                   struct ieee80211_chanctx_conf *ctx)
1366{
1367        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1368        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1369        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1370
1371        mutex_lock(&mvm->mutex);
1372        iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
1373        mutex_unlock(&mvm->mutex);
1374}
1375
1376static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1377                                   struct ieee80211_chanctx_conf *ctx,
1378                                   u32 changed)
1379{
1380        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1381        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1382        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1383
1384        if (WARN_ONCE((phy_ctxt->ref > 1) &&
1385                      (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1386                                   IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1387                                   IEEE80211_CHANCTX_CHANGE_RADAR)),
1388                      "Cannot change PHY. Ref=%d, changed=0x%X\n",
1389                      phy_ctxt->ref, changed))
1390                return;
1391
1392        mutex_lock(&mvm->mutex);
1393        iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1394                                 ctx->rx_chains_static,
1395                                 ctx->rx_chains_dynamic);
1396        mutex_unlock(&mvm->mutex);
1397}
1398
1399static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1400                                      struct ieee80211_vif *vif,
1401                                      struct ieee80211_chanctx_conf *ctx)
1402{
1403        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1404        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1405        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1406        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1407        int ret;
1408
1409        mutex_lock(&mvm->mutex);
1410
1411        mvmvif->phy_ctxt = phy_ctxt;
1412
1413        switch (vif->type) {
1414        case NL80211_IFTYPE_AP:
1415                /*
1416                 * The AP binding flow is handled as part of the start_ap flow
1417                 * (in bss_info_changed).
1418                 */
1419                ret = 0;
1420                goto out_unlock;
1421        case NL80211_IFTYPE_STATION:
1422        case NL80211_IFTYPE_ADHOC:
1423        case NL80211_IFTYPE_MONITOR:
1424                break;
1425        default:
1426                ret = -EINVAL;
1427                goto out_unlock;
1428        }
1429
1430        ret = iwl_mvm_binding_add_vif(mvm, vif);
1431        if (ret)
1432                goto out_unlock;
1433
1434        /*
1435         * Setting the quota at this stage is only required for monitor
1436         * interfaces. For the other types, the bss_info changed flow
1437         * will handle quota settings.
1438         */
1439        if (vif->type == NL80211_IFTYPE_MONITOR) {
1440                mvmvif->monitor_active = true;
1441                ret = iwl_mvm_update_quotas(mvm, vif);
1442                if (ret)
1443                        goto out_remove_binding;
1444        }
1445
1446        goto out_unlock;
1447
1448 out_remove_binding:
1449        iwl_mvm_binding_remove_vif(mvm, vif);
1450 out_unlock:
1451        mutex_unlock(&mvm->mutex);
1452        if (ret)
1453                mvmvif->phy_ctxt = NULL;
1454        return ret;
1455}
1456
1457static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1458                                         struct ieee80211_vif *vif,
1459                                         struct ieee80211_chanctx_conf *ctx)
1460{
1461        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1462        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1463
1464        mutex_lock(&mvm->mutex);
1465
1466        iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1467
1468        if (vif->type == NL80211_IFTYPE_AP)
1469                goto out_unlock;
1470
1471        switch (vif->type) {
1472        case NL80211_IFTYPE_MONITOR:
1473                mvmvif->monitor_active = false;
1474                iwl_mvm_update_quotas(mvm, NULL);
1475                break;
1476        default:
1477                break;
1478        }
1479
1480        iwl_mvm_binding_remove_vif(mvm, vif);
1481out_unlock:
1482        mvmvif->phy_ctxt = NULL;
1483        mutex_unlock(&mvm->mutex);
1484}
1485
1486static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1487                           struct ieee80211_sta *sta,
1488                           bool set)
1489{
1490        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1491        struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1492
1493        if (!mvm_sta || !mvm_sta->vif) {
1494                IWL_ERR(mvm, "Station is not associated to a vif\n");
1495                return -EINVAL;
1496        }
1497
1498        return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1499}
1500
1501static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw,
1502                                      struct ieee80211_vif *vif,
1503                                      enum ieee80211_rssi_event rssi_event)
1504{
1505        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1506
1507        iwl_mvm_bt_rssi_event(mvm, vif, rssi_event);
1508}
1509
1510struct ieee80211_ops iwl_mvm_hw_ops = {
1511        .tx = iwl_mvm_mac_tx,
1512        .ampdu_action = iwl_mvm_mac_ampdu_action,
1513        .start = iwl_mvm_mac_start,
1514        .restart_complete = iwl_mvm_mac_restart_complete,
1515        .stop = iwl_mvm_mac_stop,
1516        .add_interface = iwl_mvm_mac_add_interface,
1517        .remove_interface = iwl_mvm_mac_remove_interface,
1518        .config = iwl_mvm_mac_config,
1519        .configure_filter = iwl_mvm_configure_filter,
1520        .bss_info_changed = iwl_mvm_bss_info_changed,
1521        .hw_scan = iwl_mvm_mac_hw_scan,
1522        .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1523        .sta_state = iwl_mvm_mac_sta_state,
1524        .sta_notify = iwl_mvm_mac_sta_notify,
1525        .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1526        .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1527        .conf_tx = iwl_mvm_mac_conf_tx,
1528        .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1529        .set_key = iwl_mvm_mac_set_key,
1530        .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1531        .remain_on_channel = iwl_mvm_roc,
1532        .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1533        .rssi_callback = iwl_mvm_mac_rssi_callback,
1534
1535        .add_chanctx = iwl_mvm_add_chanctx,
1536        .remove_chanctx = iwl_mvm_remove_chanctx,
1537        .change_chanctx = iwl_mvm_change_chanctx,
1538        .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1539        .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1540
1541        .start_ap = iwl_mvm_start_ap,
1542        .stop_ap = iwl_mvm_stop_ap,
1543
1544        .set_tim = iwl_mvm_set_tim,
1545
1546#ifdef CONFIG_PM_SLEEP
1547        /* look at d3.c */
1548        .suspend = iwl_mvm_suspend,
1549        .resume = iwl_mvm_resume,
1550        .set_wakeup = iwl_mvm_set_wakeup,
1551        .set_rekey_data = iwl_mvm_set_rekey_data,
1552#if IS_ENABLED(CONFIG_IPV6)
1553        .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1554#endif
1555        .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1556#endif
1557};
1558