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 - 2014 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 - 2014 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#include "testmode.h"
  81
  82static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
  83        {
  84                .max = 1,
  85                .types = BIT(NL80211_IFTYPE_STATION),
  86        },
  87        {
  88                .max = 1,
  89                .types = BIT(NL80211_IFTYPE_AP) |
  90                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
  91                        BIT(NL80211_IFTYPE_P2P_GO),
  92        },
  93        {
  94                .max = 1,
  95                .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
  96        },
  97};
  98
  99static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
 100        {
 101                .num_different_channels = 1,
 102                .max_interfaces = 3,
 103                .limits = iwl_mvm_limits,
 104                .n_limits = ARRAY_SIZE(iwl_mvm_limits),
 105        },
 106};
 107
 108#ifdef CONFIG_PM_SLEEP
 109static const struct nl80211_wowlan_tcp_data_token_feature
 110iwl_mvm_wowlan_tcp_token_feature = {
 111        .min_len = 0,
 112        .max_len = 255,
 113        .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
 114};
 115
 116static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
 117        .tok = &iwl_mvm_wowlan_tcp_token_feature,
 118        .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
 119                            sizeof(struct ethhdr) -
 120                            sizeof(struct iphdr) -
 121                            sizeof(struct tcphdr),
 122        .data_interval_max = 65535, /* __le16 in API */
 123        .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
 124                            sizeof(struct ethhdr) -
 125                            sizeof(struct iphdr) -
 126                            sizeof(struct tcphdr),
 127        .seq = true,
 128};
 129#endif
 130
 131static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
 132{
 133        int i;
 134
 135        memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
 136        for (i = 0; i < NUM_PHY_CTX; i++) {
 137                mvm->phy_ctxts[i].id = i;
 138                mvm->phy_ctxts[i].ref = 0;
 139        }
 140}
 141
 142static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
 143{
 144        /* we create the 802.11 header and SSID element */
 145        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID)
 146                return mvm->fw->ucode_capa.max_probe_length - 24 - 2;
 147        return mvm->fw->ucode_capa.max_probe_length - 24 - 34;
 148}
 149
 150int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 151{
 152        struct ieee80211_hw *hw = mvm->hw;
 153        int num_mac, ret, i;
 154
 155        /* Tell mac80211 our characteristics */
 156        hw->flags = IEEE80211_HW_SIGNAL_DBM |
 157                    IEEE80211_HW_SPECTRUM_MGMT |
 158                    IEEE80211_HW_REPORTS_TX_ACK_STATUS |
 159                    IEEE80211_HW_QUEUE_CONTROL |
 160                    IEEE80211_HW_WANT_MONITOR_VIF |
 161                    IEEE80211_HW_SUPPORTS_PS |
 162                    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
 163                    IEEE80211_HW_AMPDU_AGGREGATION |
 164                    IEEE80211_HW_TIMING_BEACON_ONLY |
 165                    IEEE80211_HW_CONNECTION_MONITOR |
 166                    IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
 167                    IEEE80211_HW_SUPPORTS_STATIC_SMPS;
 168
 169        hw->queues = mvm->first_agg_queue;
 170        hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
 171        hw->rate_control_algorithm = "iwl-mvm-rs";
 172
 173        /*
 174         * Enable 11w if advertised by firmware and software crypto
 175         * is not enabled (as the firmware will interpret some mgmt
 176         * packets, so enabling it with software crypto isn't safe)
 177         */
 178        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
 179            !iwlwifi_mod_params.sw_crypto)
 180                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 181
 182        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) {
 183                hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
 184                hw->uapsd_queues = IWL_UAPSD_AC_INFO;
 185                hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
 186        }
 187
 188        hw->sta_data_size = sizeof(struct iwl_mvm_sta);
 189        hw->vif_data_size = sizeof(struct iwl_mvm_vif);
 190        hw->chanctx_data_size = sizeof(u16);
 191
 192        hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 193                BIT(NL80211_IFTYPE_P2P_CLIENT) |
 194                BIT(NL80211_IFTYPE_AP) |
 195                BIT(NL80211_IFTYPE_P2P_GO) |
 196                BIT(NL80211_IFTYPE_P2P_DEVICE);
 197
 198        /* IBSS has bugs in older versions */
 199        if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
 200                hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
 201
 202        hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 203        hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
 204                                       REGULATORY_DISABLE_BEACON_HINTS;
 205
 206        hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
 207        hw->wiphy->n_iface_combinations =
 208                ARRAY_SIZE(iwl_mvm_iface_combinations);
 209
 210        hw->wiphy->max_remain_on_channel_duration = 10000;
 211        hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 212
 213        /* Extract MAC address */
 214        memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
 215        hw->wiphy->addresses = mvm->addresses;
 216        hw->wiphy->n_addresses = 1;
 217
 218        /* Extract additional MAC addresses if available */
 219        num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
 220                min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
 221
 222        for (i = 1; i < num_mac; i++) {
 223                memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
 224                       ETH_ALEN);
 225                mvm->addresses[i].addr[5]++;
 226                hw->wiphy->n_addresses++;
 227        }
 228
 229        iwl_mvm_reset_phy_ctxts(mvm);
 230
 231        hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
 232
 233        hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 234
 235        if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
 236                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 237                        &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
 238        if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
 239                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 240                        &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
 241
 242        hw->wiphy->hw_version = mvm->trans->hw_id;
 243
 244        if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
 245                hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
 246        else
 247                hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 248
 249        if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
 250                hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
 251                hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
 252                hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
 253                /* we create the 802.11 header and zero length SSID IE. */
 254                hw->wiphy->max_sched_scan_ie_len =
 255                                        SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
 256        }
 257
 258        hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
 259                               NL80211_FEATURE_P2P_GO_OPPPS |
 260                               NL80211_FEATURE_LOW_PRIORITY_SCAN;
 261
 262        mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
 263
 264        /* currently FW API supports only one optional cipher scheme */
 265        if (mvm->fw->cs[0].cipher) {
 266                mvm->hw->n_cipher_schemes = 1;
 267                mvm->hw->cipher_schemes = &mvm->fw->cs[0];
 268        }
 269
 270#ifdef CONFIG_PM_SLEEP
 271        if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
 272            mvm->trans->ops->d3_suspend &&
 273            mvm->trans->ops->d3_resume &&
 274            device_can_wakeup(mvm->trans->dev)) {
 275                mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
 276                                    WIPHY_WOWLAN_DISCONNECT |
 277                                    WIPHY_WOWLAN_EAP_IDENTITY_REQ |
 278                                    WIPHY_WOWLAN_RFKILL_RELEASE;
 279                if (!iwlwifi_mod_params.sw_crypto)
 280                        mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
 281                                             WIPHY_WOWLAN_GTK_REKEY_FAILURE |
 282                                             WIPHY_WOWLAN_4WAY_HANDSHAKE;
 283
 284                mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
 285                mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
 286                mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
 287                mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
 288                hw->wiphy->wowlan = &mvm->wowlan;
 289        }
 290#endif
 291
 292        ret = iwl_mvm_leds_init(mvm);
 293        if (ret)
 294                return ret;
 295
 296        ret = ieee80211_register_hw(mvm->hw);
 297        if (ret)
 298                iwl_mvm_leds_exit(mvm);
 299
 300        return ret;
 301}
 302
 303static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
 304                           struct ieee80211_tx_control *control,
 305                           struct sk_buff *skb)
 306{
 307        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 308
 309        if (iwl_mvm_is_radio_killed(mvm)) {
 310                IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
 311                goto drop;
 312        }
 313
 314        if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
 315            !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
 316                goto drop;
 317
 318        if (control->sta) {
 319                if (iwl_mvm_tx_skb(mvm, skb, control->sta))
 320                        goto drop;
 321                return;
 322        }
 323
 324        if (iwl_mvm_tx_skb_non_sta(mvm, skb))
 325                goto drop;
 326        return;
 327 drop:
 328        ieee80211_free_txskb(hw, skb);
 329}
 330
 331static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg)
 332{
 333        if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
 334                return false;
 335        return true;
 336}
 337
 338static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg)
 339{
 340        if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
 341                return false;
 342        if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG)
 343                return true;
 344
 345        /* enabled by default */
 346        return true;
 347}
 348
 349static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
 350                                    struct ieee80211_vif *vif,
 351                                    enum ieee80211_ampdu_mlme_action action,
 352                                    struct ieee80211_sta *sta, u16 tid,
 353                                    u16 *ssn, u8 buf_size)
 354{
 355        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 356        int ret;
 357
 358        IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
 359                     sta->addr, tid, action);
 360
 361        if (!(mvm->nvm_data->sku_cap_11n_enable))
 362                return -EACCES;
 363
 364        mutex_lock(&mvm->mutex);
 365
 366        switch (action) {
 367        case IEEE80211_AMPDU_RX_START:
 368                if (!iwl_enable_rx_ampdu(mvm->cfg)) {
 369                        ret = -EINVAL;
 370                        break;
 371                }
 372                ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
 373                break;
 374        case IEEE80211_AMPDU_RX_STOP:
 375                ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
 376                break;
 377        case IEEE80211_AMPDU_TX_START:
 378                if (!iwl_enable_tx_ampdu(mvm->cfg)) {
 379                        ret = -EINVAL;
 380                        break;
 381                }
 382                ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
 383                break;
 384        case IEEE80211_AMPDU_TX_STOP_CONT:
 385                ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
 386                break;
 387        case IEEE80211_AMPDU_TX_STOP_FLUSH:
 388        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
 389                ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
 390                break;
 391        case IEEE80211_AMPDU_TX_OPERATIONAL:
 392                ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
 393                break;
 394        default:
 395                WARN_ON_ONCE(1);
 396                ret = -EINVAL;
 397                break;
 398        }
 399        mutex_unlock(&mvm->mutex);
 400
 401        return ret;
 402}
 403
 404static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
 405                                     struct ieee80211_vif *vif)
 406{
 407        struct iwl_mvm *mvm = data;
 408        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 409
 410        mvmvif->uploaded = false;
 411        mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
 412
 413        /* does this make sense at all? */
 414        mvmvif->color++;
 415
 416        spin_lock_bh(&mvm->time_event_lock);
 417        iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
 418        spin_unlock_bh(&mvm->time_event_lock);
 419
 420        mvmvif->phy_ctxt = NULL;
 421}
 422
 423static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
 424{
 425        iwl_trans_stop_device(mvm->trans);
 426
 427        mvm->scan_status = IWL_MVM_SCAN_NONE;
 428
 429        /* just in case one was running */
 430        ieee80211_remain_on_channel_expired(mvm->hw);
 431
 432        ieee80211_iterate_active_interfaces_atomic(
 433                mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 434                iwl_mvm_cleanup_iterator, mvm);
 435
 436        mvm->p2p_device_vif = NULL;
 437
 438        iwl_mvm_reset_phy_ctxts(mvm);
 439        memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 440        memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
 441
 442        ieee80211_wake_queues(mvm->hw);
 443
 444        mvm->vif_count = 0;
 445        mvm->rx_ba_sessions = 0;
 446}
 447
 448static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
 449{
 450        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 451        int ret;
 452
 453        mutex_lock(&mvm->mutex);
 454
 455        /* Clean up some internal and mac80211 state on restart */
 456        if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
 457                iwl_mvm_restart_cleanup(mvm);
 458
 459        ret = iwl_mvm_up(mvm);
 460        mutex_unlock(&mvm->mutex);
 461
 462        return ret;
 463}
 464
 465static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
 466{
 467        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 468        int ret;
 469
 470        mutex_lock(&mvm->mutex);
 471
 472        clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 473        ret = iwl_mvm_update_quotas(mvm, NULL);
 474        if (ret)
 475                IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
 476                        ret);
 477
 478        mutex_unlock(&mvm->mutex);
 479}
 480
 481static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
 482{
 483        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 484
 485        flush_work(&mvm->async_handlers_wk);
 486
 487        mutex_lock(&mvm->mutex);
 488        /* async_handlers_wk is now blocked */
 489
 490        /*
 491         * The work item could be running or queued if the
 492         * ROC time event stops just as we get here.
 493         */
 494        cancel_work_sync(&mvm->roc_done_wk);
 495
 496        iwl_trans_stop_device(mvm->trans);
 497
 498        iwl_mvm_async_handlers_purge(mvm);
 499        /* async_handlers_list is empty and will stay empty: HW is stopped */
 500
 501        /* the fw is stopped, the aux sta is dead: clean up driver state */
 502        iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
 503
 504        mutex_unlock(&mvm->mutex);
 505
 506        /*
 507         * The worker might have been waiting for the mutex, let it run and
 508         * discover that its list is now empty.
 509         */
 510        cancel_work_sync(&mvm->async_handlers_wk);
 511}
 512
 513static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
 514                                          struct ieee80211_vif *vif)
 515{
 516        struct iwl_mvm *mvm = data;
 517
 518        iwl_mvm_power_update_mode(mvm, vif);
 519}
 520
 521static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
 522{
 523        u16 i;
 524
 525        lockdep_assert_held(&mvm->mutex);
 526
 527        for (i = 0; i < NUM_PHY_CTX; i++)
 528                if (!mvm->phy_ctxts[i].ref)
 529                        return &mvm->phy_ctxts[i];
 530
 531        IWL_ERR(mvm, "No available PHY context\n");
 532        return NULL;
 533}
 534
 535static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 536                                s8 tx_power)
 537{
 538        /* FW is in charge of regulatory enforcement */
 539        struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
 540                .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id,
 541                .pwr_restriction = cpu_to_le16(tx_power),
 542        };
 543
 544        return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC,
 545                                    sizeof(reduce_txpwr_cmd),
 546                                    &reduce_txpwr_cmd);
 547}
 548
 549static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 550                                     struct ieee80211_vif *vif)
 551{
 552        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 553        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 554        int ret;
 555
 556        /*
 557         * Not much to do here. The stack will not allow interface
 558         * types or combinations that we didn't advertise, so we
 559         * don't really have to check the types.
 560         */
 561
 562        mutex_lock(&mvm->mutex);
 563
 564        /* Allocate resources for the MAC context, and add it to the fw  */
 565        ret = iwl_mvm_mac_ctxt_init(mvm, vif);
 566        if (ret)
 567                goto out_unlock;
 568
 569        /* Counting number of interfaces is needed for legacy PM */
 570        if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
 571                mvm->vif_count++;
 572
 573        /*
 574         * The AP binding flow can be done only after the beacon
 575         * template is configured (which happens only in the mac80211
 576         * start_ap() flow), and adding the broadcast station can happen
 577         * only after the binding.
 578         * In addition, since modifying the MAC before adding a bcast
 579         * station is not allowed by the FW, delay the adding of MAC context to
 580         * the point where we can also add the bcast station.
 581         * In short: there's not much we can do at this point, other than
 582         * allocating resources :)
 583         */
 584        if (vif->type == NL80211_IFTYPE_AP ||
 585            vif->type == NL80211_IFTYPE_ADHOC) {
 586                u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
 587                ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
 588                                               qmask);
 589                if (ret) {
 590                        IWL_ERR(mvm, "Failed to allocate bcast sta\n");
 591                        goto out_release;
 592                }
 593
 594                iwl_mvm_vif_dbgfs_register(mvm, vif);
 595                goto out_unlock;
 596        }
 597
 598        ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 599        if (ret)
 600                goto out_release;
 601
 602        iwl_mvm_power_disable(mvm, vif);
 603
 604        /* beacon filtering */
 605        ret = iwl_mvm_disable_beacon_filter(mvm, vif);
 606        if (ret)
 607                goto out_remove_mac;
 608
 609        if (!mvm->bf_allowed_vif &&
 610            vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
 611            mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){
 612                mvm->bf_allowed_vif = mvmvif;
 613                vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
 614                                     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
 615        }
 616
 617        /*
 618         * P2P_DEVICE interface does not have a channel context assigned to it,
 619         * so a dedicated PHY context is allocated to it and the corresponding
 620         * MAC context is bound to it at this stage.
 621         */
 622        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 623
 624                mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
 625                if (!mvmvif->phy_ctxt) {
 626                        ret = -ENOSPC;
 627                        goto out_free_bf;
 628                }
 629
 630                iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
 631                ret = iwl_mvm_binding_add_vif(mvm, vif);
 632                if (ret)
 633                        goto out_unref_phy;
 634
 635                ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 636                if (ret)
 637                        goto out_unbind;
 638
 639                /* Save a pointer to p2p device vif, so it can later be used to
 640                 * update the p2p device MAC when a GO is started/stopped */
 641                mvm->p2p_device_vif = vif;
 642        }
 643
 644        iwl_mvm_vif_dbgfs_register(mvm, vif);
 645        goto out_unlock;
 646
 647 out_unbind:
 648        iwl_mvm_binding_remove_vif(mvm, vif);
 649 out_unref_phy:
 650        iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
 651 out_free_bf:
 652        if (mvm->bf_allowed_vif == mvmvif) {
 653                mvm->bf_allowed_vif = NULL;
 654                vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
 655                                       IEEE80211_VIF_SUPPORTS_CQM_RSSI);
 656        }
 657 out_remove_mac:
 658        mvmvif->phy_ctxt = NULL;
 659        iwl_mvm_mac_ctxt_remove(mvm, vif);
 660 out_release:
 661        if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
 662                mvm->vif_count--;
 663
 664        /* TODO: remove this when legacy PM will be discarded */
 665        ieee80211_iterate_active_interfaces(
 666                mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 667                iwl_mvm_power_update_iterator, mvm);
 668
 669        iwl_mvm_mac_ctxt_release(mvm, vif);
 670 out_unlock:
 671        mutex_unlock(&mvm->mutex);
 672
 673        return ret;
 674}
 675
 676static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
 677                                        struct ieee80211_vif *vif)
 678{
 679        u32 tfd_msk = 0, ac;
 680
 681        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 682                if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 683                        tfd_msk |= BIT(vif->hw_queue[ac]);
 684
 685        if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
 686                tfd_msk |= BIT(vif->cab_queue);
 687
 688        if (tfd_msk) {
 689                mutex_lock(&mvm->mutex);
 690                iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
 691                mutex_unlock(&mvm->mutex);
 692        }
 693
 694        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 695                /*
 696                 * Flush the ROC worker which will flush the OFFCHANNEL queue.
 697                 * We assume here that all the packets sent to the OFFCHANNEL
 698                 * queue are sent in ROC session.
 699                 */
 700                flush_work(&mvm->roc_done_wk);
 701        } else {
 702                /*
 703                 * By now, all the AC queues are empty. The AGG queues are
 704                 * empty too. We already got all the Tx responses for all the
 705                 * packets in the queues. The drain work can have been
 706                 * triggered. Flush it.
 707                 */
 708                flush_work(&mvm->sta_drained_wk);
 709        }
 710}
 711
 712static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
 713                                         struct ieee80211_vif *vif)
 714{
 715        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 716        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 717
 718        iwl_mvm_prepare_mac_removal(mvm, vif);
 719
 720        mutex_lock(&mvm->mutex);
 721
 722        if (mvm->bf_allowed_vif == mvmvif) {
 723                mvm->bf_allowed_vif = NULL;
 724                vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
 725                                       IEEE80211_VIF_SUPPORTS_CQM_RSSI);
 726        }
 727
 728        iwl_mvm_vif_dbgfs_clean(mvm, vif);
 729
 730        /*
 731         * For AP/GO interface, the tear down of the resources allocated to the
 732         * interface is be handled as part of the stop_ap flow.
 733         */
 734        if (vif->type == NL80211_IFTYPE_AP ||
 735            vif->type == NL80211_IFTYPE_ADHOC) {
 736#ifdef CONFIG_NL80211_TESTMODE
 737                if (vif == mvm->noa_vif) {
 738                        mvm->noa_vif = NULL;
 739                        mvm->noa_duration = 0;
 740                }
 741#endif
 742                iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
 743                goto out_release;
 744        }
 745
 746        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
 747                mvm->p2p_device_vif = NULL;
 748                iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 749                iwl_mvm_binding_remove_vif(mvm, vif);
 750                iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
 751                mvmvif->phy_ctxt = NULL;
 752        }
 753
 754        if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
 755                mvm->vif_count--;
 756
 757        /* TODO: remove this when legacy PM will be discarded */
 758        ieee80211_iterate_active_interfaces(
 759                mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 760                iwl_mvm_power_update_iterator, mvm);
 761
 762        iwl_mvm_mac_ctxt_remove(mvm, vif);
 763
 764out_release:
 765        iwl_mvm_mac_ctxt_release(mvm, vif);
 766        mutex_unlock(&mvm->mutex);
 767}
 768
 769static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
 770{
 771        return 0;
 772}
 773
 774struct iwl_mvm_mc_iter_data {
 775        struct iwl_mvm *mvm;
 776        int port_id;
 777};
 778
 779static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
 780                                      struct ieee80211_vif *vif)
 781{
 782        struct iwl_mvm_mc_iter_data *data = _data;
 783        struct iwl_mvm *mvm = data->mvm;
 784        struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
 785        int ret, len;
 786
 787        /* if we don't have free ports, mcast frames will be dropped */
 788        if (WARN_ON_ONCE(data->port_id >= MAX_PORT_ID_NUM))
 789                return;
 790
 791        if (vif->type != NL80211_IFTYPE_STATION ||
 792            !vif->bss_conf.assoc)
 793                return;
 794
 795        cmd->port_id = data->port_id++;
 796        memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
 797        len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
 798
 799        ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd);
 800        if (ret)
 801                IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
 802}
 803
 804static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
 805{
 806        struct iwl_mvm_mc_iter_data iter_data = {
 807                .mvm = mvm,
 808        };
 809
 810        lockdep_assert_held(&mvm->mutex);
 811
 812        if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
 813                return;
 814
 815        ieee80211_iterate_active_interfaces(
 816                mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 817                iwl_mvm_mc_iface_iterator, &iter_data);
 818}
 819
 820static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
 821                                     struct netdev_hw_addr_list *mc_list)
 822{
 823        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 824        struct iwl_mcast_filter_cmd *cmd;
 825        struct netdev_hw_addr *addr;
 826        int addr_count = netdev_hw_addr_list_count(mc_list);
 827        bool pass_all = false;
 828        int len;
 829
 830        if (addr_count > MAX_MCAST_FILTERING_ADDRESSES) {
 831                pass_all = true;
 832                addr_count = 0;
 833        }
 834
 835        len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
 836        cmd = kzalloc(len, GFP_ATOMIC);
 837        if (!cmd)
 838                return 0;
 839
 840        if (pass_all) {
 841                cmd->pass_all = 1;
 842                return (u64)(unsigned long)cmd;
 843        }
 844
 845        netdev_hw_addr_list_for_each(addr, mc_list) {
 846                IWL_DEBUG_MAC80211(mvm, "mcast addr (%d): %pM\n",
 847                                   cmd->count, addr->addr);
 848                memcpy(&cmd->addr_list[cmd->count * ETH_ALEN],
 849                       addr->addr, ETH_ALEN);
 850                cmd->count++;
 851        }
 852
 853        return (u64)(unsigned long)cmd;
 854}
 855
 856static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
 857                                     unsigned int changed_flags,
 858                                     unsigned int *total_flags,
 859                                     u64 multicast)
 860{
 861        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 862        struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast;
 863
 864        mutex_lock(&mvm->mutex);
 865
 866        /* replace previous configuration */
 867        kfree(mvm->mcast_filter_cmd);
 868        mvm->mcast_filter_cmd = cmd;
 869
 870        if (!cmd)
 871                goto out;
 872
 873        iwl_mvm_recalc_multicast(mvm);
 874out:
 875        mutex_unlock(&mvm->mutex);
 876        *total_flags = 0;
 877}
 878
 879static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
 880                                             struct ieee80211_vif *vif,
 881                                             struct ieee80211_bss_conf *bss_conf,
 882                                             u32 changes)
 883{
 884        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 885        int ret;
 886
 887        /*
 888         * Re-calculate the tsf id, as the master-slave relations depend on the
 889         * beacon interval, which was not known when the station interface was
 890         * added.
 891         */
 892        if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
 893                iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
 894
 895        ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
 896        if (ret)
 897                IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
 898
 899        if (changes & BSS_CHANGED_ASSOC) {
 900                if (bss_conf->assoc) {
 901                        /* add quota for this interface */
 902                        ret = iwl_mvm_update_quotas(mvm, vif);
 903                        if (ret) {
 904                                IWL_ERR(mvm, "failed to update quotas\n");
 905                                return;
 906                        }
 907
 908                        if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
 909                                     &mvm->status)) {
 910                                /*
 911                                 * If we're restarting then the firmware will
 912                                 * obviously have lost synchronisation with
 913                                 * the AP. It will attempt to synchronise by
 914                                 * itself, but we can make it more reliable by
 915                                 * scheduling a session protection time event.
 916                                 *
 917                                 * The firmware needs to receive a beacon to
 918                                 * catch up with synchronisation, use 110% of
 919                                 * the beacon interval.
 920                                 *
 921                                 * Set a large maximum delay to allow for more
 922                                 * than a single interface.
 923                                 */
 924                                u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
 925                                iwl_mvm_protect_session(mvm, vif, dur, dur,
 926                                                        5 * dur);
 927                        }
 928
 929                        iwl_mvm_sf_update(mvm, vif, false);
 930                        iwl_mvm_power_vif_assoc(mvm, vif);
 931                } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
 932                        /*
 933                         * If update fails - SF might be running in associated
 934                         * mode while disassociated - which is forbidden.
 935                         */
 936                        WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
 937                                  "Failed to update SF upon disassociation\n");
 938
 939                        /* remove AP station now that the MAC is unassoc */
 940                        ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
 941                        if (ret)
 942                                IWL_ERR(mvm, "failed to remove AP station\n");
 943                        mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
 944                        /* remove quota for this interface */
 945                        ret = iwl_mvm_update_quotas(mvm, NULL);
 946                        if (ret)
 947                                IWL_ERR(mvm, "failed to update quotas\n");
 948                }
 949
 950                iwl_mvm_recalc_multicast(mvm);
 951
 952                /* reset rssi values */
 953                mvmvif->bf_data.ave_beacon_signal = 0;
 954
 955                if (!(mvm->fw->ucode_capa.flags &
 956                                        IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
 957                        /* Workaround for FW bug, otherwise FW disables device
 958                         * power save upon disassociation
 959                         */
 960                        ret = iwl_mvm_power_update_mode(mvm, vif);
 961                        if (ret)
 962                                IWL_ERR(mvm, "failed to update power mode\n");
 963                }
 964                iwl_mvm_bt_coex_vif_change(mvm);
 965                iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
 966                                    IEEE80211_SMPS_AUTOMATIC);
 967        } else if (changes & BSS_CHANGED_BEACON_INFO) {
 968                /*
 969                 * We received a beacon _after_ association so
 970                 * remove the session protection.
 971                 */
 972                iwl_mvm_remove_time_event(mvm, mvmvif,
 973                                          &mvmvif->time_event_data);
 974        } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
 975                              BSS_CHANGED_QOS)) {
 976                ret = iwl_mvm_power_update_mode(mvm, vif);
 977                if (ret)
 978                        IWL_ERR(mvm, "failed to update power mode\n");
 979        }
 980        if (changes & BSS_CHANGED_TXPOWER) {
 981                IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
 982                                bss_conf->txpower);
 983                iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
 984        }
 985
 986        if (changes & BSS_CHANGED_CQM) {
 987                IWL_DEBUG_MAC80211(mvm, "cqm info_changed");
 988                /* reset cqm events tracking */
 989                mvmvif->bf_data.last_cqm_event = 0;
 990                ret = iwl_mvm_update_beacon_filter(mvm, vif);
 991                if (ret)
 992                        IWL_ERR(mvm, "failed to update CQM thresholds\n");
 993        }
 994}
 995
 996static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
 997                                 struct ieee80211_vif *vif)
 998{
 999        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1000        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1001        int ret;
1002
1003        mutex_lock(&mvm->mutex);
1004
1005        /* Send the beacon template */
1006        ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
1007        if (ret)
1008                goto out_unlock;
1009
1010        /*
1011         * Re-calculate the tsf id, as the master-slave relations depend on the
1012         * beacon interval, which was not known when the AP interface was added.
1013         */
1014        if (vif->type == NL80211_IFTYPE_AP)
1015                iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
1016
1017        /* Add the mac context */
1018        ret = iwl_mvm_mac_ctxt_add(mvm, vif);
1019        if (ret)
1020                goto out_unlock;
1021
1022        /* Perform the binding */
1023        ret = iwl_mvm_binding_add_vif(mvm, vif);
1024        if (ret)
1025                goto out_remove;
1026
1027        mvmvif->ap_ibss_active = true;
1028
1029        /* Send the bcast station. At this stage the TBTT and DTIM time events
1030         * are added and applied to the scheduler */
1031        ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
1032        if (ret)
1033                goto out_unbind;
1034
1035        /* must be set before quota calculations */
1036        mvmvif->ap_ibss_active = true;
1037
1038        /* power updated needs to be done before quotas */
1039        mvm->bound_vif_cnt++;
1040        iwl_mvm_power_update_binding(mvm, vif, true);
1041
1042        ret = iwl_mvm_update_quotas(mvm, vif);
1043        if (ret)
1044                goto out_quota_failed;
1045
1046        /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
1047        if (vif->p2p && mvm->p2p_device_vif)
1048                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
1049
1050        iwl_mvm_bt_coex_vif_change(mvm);
1051
1052        mutex_unlock(&mvm->mutex);
1053        return 0;
1054
1055out_quota_failed:
1056        mvm->bound_vif_cnt--;
1057        iwl_mvm_power_update_binding(mvm, vif, false);
1058        mvmvif->ap_ibss_active = false;
1059        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
1060out_unbind:
1061        iwl_mvm_binding_remove_vif(mvm, vif);
1062out_remove:
1063        iwl_mvm_mac_ctxt_remove(mvm, vif);
1064out_unlock:
1065        mutex_unlock(&mvm->mutex);
1066        return ret;
1067}
1068
1069static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
1070                                 struct ieee80211_vif *vif)
1071{
1072        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1073        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1074
1075        iwl_mvm_prepare_mac_removal(mvm, vif);
1076
1077        mutex_lock(&mvm->mutex);
1078
1079        mvmvif->ap_ibss_active = false;
1080
1081        iwl_mvm_bt_coex_vif_change(mvm);
1082
1083        /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
1084        if (vif->p2p && mvm->p2p_device_vif)
1085                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
1086
1087        iwl_mvm_update_quotas(mvm, NULL);
1088        iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
1089        iwl_mvm_binding_remove_vif(mvm, vif);
1090
1091        mvm->bound_vif_cnt--;
1092        iwl_mvm_power_update_binding(mvm, vif, false);
1093
1094        iwl_mvm_mac_ctxt_remove(mvm, vif);
1095
1096        mutex_unlock(&mvm->mutex);
1097}
1098
1099static void
1100iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
1101                                 struct ieee80211_vif *vif,
1102                                 struct ieee80211_bss_conf *bss_conf,
1103                                 u32 changes)
1104{
1105        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1106        enum ieee80211_bss_change ht_change = BSS_CHANGED_ERP_CTS_PROT |
1107                                              BSS_CHANGED_HT |
1108                                              BSS_CHANGED_BANDWIDTH;
1109        int ret;
1110
1111        /* Changes will be applied when the AP/IBSS is started */
1112        if (!mvmvif->ap_ibss_active)
1113                return;
1114
1115        if (changes & ht_change) {
1116                ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1117                if (ret)
1118                        IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1119        }
1120
1121        /* Need to send a new beacon template to the FW */
1122        if (changes & BSS_CHANGED_BEACON) {
1123                if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
1124                        IWL_WARN(mvm, "Failed updating beacon data\n");
1125        }
1126}
1127
1128static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
1129                                     struct ieee80211_vif *vif,
1130                                     struct ieee80211_bss_conf *bss_conf,
1131                                     u32 changes)
1132{
1133        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1134
1135        mutex_lock(&mvm->mutex);
1136
1137        switch (vif->type) {
1138        case NL80211_IFTYPE_STATION:
1139                iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
1140                break;
1141        case NL80211_IFTYPE_AP:
1142        case NL80211_IFTYPE_ADHOC:
1143                iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes);
1144                break;
1145        default:
1146                /* shouldn't happen */
1147                WARN_ON_ONCE(1);
1148        }
1149
1150        mutex_unlock(&mvm->mutex);
1151}
1152
1153static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1154                               struct ieee80211_vif *vif,
1155                               struct cfg80211_scan_request *req)
1156{
1157        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1158        int ret;
1159
1160        if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
1161                return -EINVAL;
1162
1163        mutex_lock(&mvm->mutex);
1164
1165        if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1166                ret = iwl_mvm_scan_request(mvm, vif, req);
1167        else
1168                ret = -EBUSY;
1169
1170        mutex_unlock(&mvm->mutex);
1171
1172        return ret;
1173}
1174
1175static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
1176                                       struct ieee80211_vif *vif)
1177{
1178        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1179
1180        mutex_lock(&mvm->mutex);
1181
1182        iwl_mvm_cancel_scan(mvm);
1183
1184        mutex_unlock(&mvm->mutex);
1185}
1186
1187static void
1188iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
1189                                  struct ieee80211_sta *sta, u16 tid,
1190                                  int num_frames,
1191                                  enum ieee80211_frame_release_type reason,
1192                                  bool more_data)
1193{
1194        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1195
1196        /* TODO: how do we tell the fw to send frames for a specific TID */
1197
1198        /*
1199         * The fw will send EOSP notification when the last frame will be
1200         * transmitted.
1201         */
1202        iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames);
1203}
1204
1205static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1206                                   struct ieee80211_vif *vif,
1207                                   enum sta_notify_cmd cmd,
1208                                   struct ieee80211_sta *sta)
1209{
1210        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1211        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1212
1213        switch (cmd) {
1214        case STA_NOTIFY_SLEEP:
1215                if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
1216                        ieee80211_sta_block_awake(hw, sta, true);
1217                /*
1218                 * The fw updates the STA to be asleep. Tx packets on the Tx
1219                 * queues to this station will not be transmitted. The fw will
1220                 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
1221                 */
1222                break;
1223        case STA_NOTIFY_AWAKE:
1224                if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
1225                        break;
1226                iwl_mvm_sta_modify_ps_wake(mvm, sta);
1227                break;
1228        default:
1229                break;
1230        }
1231}
1232
1233static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
1234                                       struct ieee80211_vif *vif,
1235                                       struct ieee80211_sta *sta)
1236{
1237        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1238        struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1239
1240        /*
1241         * This is called before mac80211 does RCU synchronisation,
1242         * so here we already invalidate our internal RCU-protected
1243         * station pointer. The rest of the code will thus no longer
1244         * be able to find the station this way, and we don't rely
1245         * on further RCU synchronisation after the sta_state()
1246         * callback deleted the station.
1247         */
1248        mutex_lock(&mvm->mutex);
1249        if (sta == rcu_access_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id]))
1250                rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
1251                                   ERR_PTR(-ENOENT));
1252        mutex_unlock(&mvm->mutex);
1253}
1254
1255static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1256                                 struct ieee80211_vif *vif,
1257                                 struct ieee80211_sta *sta,
1258                                 enum ieee80211_sta_state old_state,
1259                                 enum ieee80211_sta_state new_state)
1260{
1261        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1262        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1263        int ret;
1264
1265        IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
1266                           sta->addr, old_state, new_state);
1267
1268        /* this would be a mac80211 bug ... but don't crash */
1269        if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
1270                return -EINVAL;
1271
1272        /* if a STA is being removed, reuse its ID */
1273        flush_work(&mvm->sta_drained_wk);
1274
1275        mutex_lock(&mvm->mutex);
1276        if (old_state == IEEE80211_STA_NOTEXIST &&
1277            new_state == IEEE80211_STA_NONE) {
1278                /*
1279                 * Firmware bug - it'll crash if the beacon interval is less
1280                 * than 16. We can't avoid connecting at all, so refuse the
1281                 * station state change, this will cause mac80211 to abandon
1282                 * attempts to connect to this AP, and eventually wpa_s will
1283                 * blacklist the AP...
1284                 */
1285                if (vif->type == NL80211_IFTYPE_STATION &&
1286                    vif->bss_conf.beacon_int < 16) {
1287                        IWL_ERR(mvm,
1288                                "AP %pM beacon interval is %d, refusing due to firmware bug!\n",
1289                                sta->addr, vif->bss_conf.beacon_int);
1290                        ret = -EINVAL;
1291                        goto out_unlock;
1292                }
1293                ret = iwl_mvm_add_sta(mvm, vif, sta);
1294        } else if (old_state == IEEE80211_STA_NONE &&
1295                   new_state == IEEE80211_STA_AUTH) {
1296                ret = 0;
1297        } else if (old_state == IEEE80211_STA_AUTH &&
1298                   new_state == IEEE80211_STA_ASSOC) {
1299                ret = iwl_mvm_update_sta(mvm, vif, sta);
1300                if (ret == 0)
1301                        iwl_mvm_rs_rate_init(mvm, sta,
1302                                             mvmvif->phy_ctxt->channel->band,
1303                                             true);
1304        } else if (old_state == IEEE80211_STA_ASSOC &&
1305                   new_state == IEEE80211_STA_AUTHORIZED) {
1306                /* enable beacon filtering */
1307                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
1308                ret = 0;
1309        } else if (old_state == IEEE80211_STA_AUTHORIZED &&
1310                   new_state == IEEE80211_STA_ASSOC) {
1311                /* disable beacon filtering */
1312                WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
1313                ret = 0;
1314        } else if (old_state == IEEE80211_STA_ASSOC &&
1315                   new_state == IEEE80211_STA_AUTH) {
1316                ret = 0;
1317        } else if (old_state == IEEE80211_STA_AUTH &&
1318                   new_state == IEEE80211_STA_NONE) {
1319                ret = 0;
1320        } else if (old_state == IEEE80211_STA_NONE &&
1321                   new_state == IEEE80211_STA_NOTEXIST) {
1322                ret = iwl_mvm_rm_sta(mvm, vif, sta);
1323        } else {
1324                ret = -EIO;
1325        }
1326 out_unlock:
1327        mutex_unlock(&mvm->mutex);
1328
1329        return ret;
1330}
1331
1332static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1333{
1334        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1335
1336        mvm->rts_threshold = value;
1337
1338        return 0;
1339}
1340
1341static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
1342                                  struct ieee80211_vif *vif,
1343                                  struct ieee80211_sta *sta, u32 changed)
1344{
1345        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1346
1347        if (vif->type == NL80211_IFTYPE_STATION &&
1348            changed & IEEE80211_RC_NSS_CHANGED)
1349                iwl_mvm_sf_update(mvm, vif, false);
1350}
1351
1352static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
1353                               struct ieee80211_vif *vif, u16 ac,
1354                               const struct ieee80211_tx_queue_params *params)
1355{
1356        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1357        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1358
1359        mvmvif->queue_params[ac] = *params;
1360
1361        /*
1362         * No need to update right away, we'll get BSS_CHANGED_QOS
1363         * The exception is P2P_DEVICE interface which needs immediate update.
1364         */
1365        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1366                int ret;
1367
1368                mutex_lock(&mvm->mutex);
1369                ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1370                mutex_unlock(&mvm->mutex);
1371                return ret;
1372        }
1373        return 0;
1374}
1375
1376static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1377                                      struct ieee80211_vif *vif)
1378{
1379        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1380        u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
1381                           200 + vif->bss_conf.beacon_int);
1382        u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
1383                               100 + vif->bss_conf.beacon_int);
1384
1385        if (WARN_ON_ONCE(vif->bss_conf.assoc))
1386                return;
1387
1388        mutex_lock(&mvm->mutex);
1389        /* Try really hard to protect the session and hear a beacon */
1390        iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
1391        mutex_unlock(&mvm->mutex);
1392}
1393
1394static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1395                                        struct ieee80211_vif *vif,
1396                                        struct cfg80211_sched_scan_request *req,
1397                                        struct ieee80211_sched_scan_ies *ies)
1398{
1399        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1400        int ret;
1401
1402        mutex_lock(&mvm->mutex);
1403
1404        if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
1405                IWL_DEBUG_SCAN(mvm,
1406                               "SCHED SCAN request during internal scan - abort\n");
1407                ret = -EBUSY;
1408                goto out;
1409        }
1410
1411        mvm->scan_status = IWL_MVM_SCAN_SCHED;
1412
1413        ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1414        if (ret)
1415                goto err;
1416
1417        ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1418        if (ret)
1419                goto err;
1420
1421        ret = iwl_mvm_sched_scan_start(mvm, req);
1422        if (!ret)
1423                goto out;
1424err:
1425        mvm->scan_status = IWL_MVM_SCAN_NONE;
1426out:
1427        mutex_unlock(&mvm->mutex);
1428        return ret;
1429}
1430
1431static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1432                                        struct ieee80211_vif *vif)
1433{
1434        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1435
1436        mutex_lock(&mvm->mutex);
1437        iwl_mvm_sched_scan_stop(mvm);
1438        mutex_unlock(&mvm->mutex);
1439}
1440
1441static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1442                               enum set_key_cmd cmd,
1443                               struct ieee80211_vif *vif,
1444                               struct ieee80211_sta *sta,
1445                               struct ieee80211_key_conf *key)
1446{
1447        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1448        int ret;
1449
1450        if (iwlwifi_mod_params.sw_crypto) {
1451                IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1452                return -EOPNOTSUPP;
1453        }
1454
1455        switch (key->cipher) {
1456        case WLAN_CIPHER_SUITE_TKIP:
1457                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1458                /* fall-through */
1459        case WLAN_CIPHER_SUITE_CCMP:
1460                key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1461                break;
1462        case WLAN_CIPHER_SUITE_AES_CMAC:
1463                WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1464                break;
1465        case WLAN_CIPHER_SUITE_WEP40:
1466        case WLAN_CIPHER_SUITE_WEP104:
1467                /*
1468                 * Support for TX only, at least for now, so accept
1469                 * the key and do nothing else. Then mac80211 will
1470                 * pass it for TX but we don't have to use it for RX.
1471                 */
1472                return 0;
1473        default:
1474                /* currently FW supports only one optional cipher scheme */
1475                if (hw->n_cipher_schemes &&
1476                    hw->cipher_schemes->cipher == key->cipher)
1477                        key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
1478                else
1479                        return -EOPNOTSUPP;
1480        }
1481
1482        mutex_lock(&mvm->mutex);
1483
1484        switch (cmd) {
1485        case SET_KEY:
1486                if ((vif->type == NL80211_IFTYPE_ADHOC ||
1487                     vif->type == NL80211_IFTYPE_AP) && !sta) {
1488                        /*
1489                         * GTK on AP interface is a TX-only key, return 0;
1490                         * on IBSS they're per-station and because we're lazy
1491                         * we don't support them for RX, so do the same.
1492                         */
1493                        ret = 0;
1494                        key->hw_key_idx = STA_KEY_IDX_INVALID;
1495                        break;
1496                }
1497
1498                IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1499                ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1500                if (ret) {
1501                        IWL_WARN(mvm, "set key failed\n");
1502                        /*
1503                         * can't add key for RX, but we don't need it
1504                         * in the device for TX so still return 0
1505                         */
1506                        key->hw_key_idx = STA_KEY_IDX_INVALID;
1507                        ret = 0;
1508                }
1509
1510                break;
1511        case DISABLE_KEY:
1512                if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1513                        ret = 0;
1514                        break;
1515                }
1516
1517                IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1518                ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1519                break;
1520        default:
1521                ret = -EINVAL;
1522        }
1523
1524        mutex_unlock(&mvm->mutex);
1525        return ret;
1526}
1527
1528static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1529                                        struct ieee80211_vif *vif,
1530                                        struct ieee80211_key_conf *keyconf,
1531                                        struct ieee80211_sta *sta,
1532                                        u32 iv32, u16 *phase1key)
1533{
1534        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1535
1536        if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1537                return;
1538
1539        iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1540}
1541
1542
1543static int iwl_mvm_roc(struct ieee80211_hw *hw,
1544                       struct ieee80211_vif *vif,
1545                       struct ieee80211_channel *channel,
1546                       int duration,
1547                       enum ieee80211_roc_type type)
1548{
1549        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1550        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1551        struct cfg80211_chan_def chandef;
1552        struct iwl_mvm_phy_ctxt *phy_ctxt;
1553        int ret, i;
1554
1555        IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1556                           duration, type);
1557
1558        if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1559                IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1560                return -EINVAL;
1561        }
1562
1563        mutex_lock(&mvm->mutex);
1564
1565        for (i = 0; i < NUM_PHY_CTX; i++) {
1566                phy_ctxt = &mvm->phy_ctxts[i];
1567                if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
1568                        continue;
1569
1570                if (phy_ctxt->ref && channel == phy_ctxt->channel) {
1571                        /*
1572                         * Unbind the P2P_DEVICE from the current PHY context,
1573                         * and if the PHY context is not used remove it.
1574                         */
1575                        ret = iwl_mvm_binding_remove_vif(mvm, vif);
1576                        if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1577                                goto out_unlock;
1578
1579                        iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1580
1581                        /* Bind the P2P_DEVICE to the current PHY Context */
1582                        mvmvif->phy_ctxt = phy_ctxt;
1583
1584                        ret = iwl_mvm_binding_add_vif(mvm, vif);
1585                        if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1586                                goto out_unlock;
1587
1588                        iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1589                        goto schedule_time_event;
1590                }
1591        }
1592
1593        /* Need to update the PHY context only if the ROC channel changed */
1594        if (channel == mvmvif->phy_ctxt->channel)
1595                goto schedule_time_event;
1596
1597        cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1598
1599        /*
1600         * Change the PHY context configuration as it is currently referenced
1601         * only by the P2P Device MAC
1602         */
1603        if (mvmvif->phy_ctxt->ref == 1) {
1604                ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
1605                                               &chandef, 1, 1);
1606                if (ret)
1607                        goto out_unlock;
1608        } else {
1609                /*
1610                 * The PHY context is shared with other MACs. Need to remove the
1611                 * P2P Device from the binding, allocate an new PHY context and
1612                 * create a new binding
1613                 */
1614                phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1615                if (!phy_ctxt) {
1616                        ret = -ENOSPC;
1617                        goto out_unlock;
1618                }
1619
1620                ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
1621                                               1, 1);
1622                if (ret) {
1623                        IWL_ERR(mvm, "Failed to change PHY context\n");
1624                        goto out_unlock;
1625                }
1626
1627                /* Unbind the P2P_DEVICE from the current PHY context */
1628                ret = iwl_mvm_binding_remove_vif(mvm, vif);
1629                if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1630                        goto out_unlock;
1631
1632                iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1633
1634                /* Bind the P2P_DEVICE to the new allocated PHY context */
1635                mvmvif->phy_ctxt = phy_ctxt;
1636
1637                ret = iwl_mvm_binding_add_vif(mvm, vif);
1638                if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1639                        goto out_unlock;
1640
1641                iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1642        }
1643
1644schedule_time_event:
1645        /* Schedule the time events */
1646        ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1647
1648out_unlock:
1649        mutex_unlock(&mvm->mutex);
1650        IWL_DEBUG_MAC80211(mvm, "leave\n");
1651        return ret;
1652}
1653
1654static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1655{
1656        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1657
1658        IWL_DEBUG_MAC80211(mvm, "enter\n");
1659
1660        mutex_lock(&mvm->mutex);
1661        iwl_mvm_stop_p2p_roc(mvm);
1662        mutex_unlock(&mvm->mutex);
1663
1664        IWL_DEBUG_MAC80211(mvm, "leave\n");
1665        return 0;
1666}
1667
1668static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1669                               struct ieee80211_chanctx_conf *ctx)
1670{
1671        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1672        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1673        struct iwl_mvm_phy_ctxt *phy_ctxt;
1674        int ret;
1675
1676        IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
1677
1678        mutex_lock(&mvm->mutex);
1679        phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1680        if (!phy_ctxt) {
1681                ret = -ENOSPC;
1682                goto out;
1683        }
1684
1685        ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1686                                       ctx->rx_chains_static,
1687                                       ctx->rx_chains_dynamic);
1688        if (ret) {
1689                IWL_ERR(mvm, "Failed to add PHY context\n");
1690                goto out;
1691        }
1692
1693        iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
1694        *phy_ctxt_id = phy_ctxt->id;
1695out:
1696        mutex_unlock(&mvm->mutex);
1697        return ret;
1698}
1699
1700static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1701                                   struct ieee80211_chanctx_conf *ctx)
1702{
1703        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1704        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1705        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1706
1707        mutex_lock(&mvm->mutex);
1708        iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
1709        mutex_unlock(&mvm->mutex);
1710}
1711
1712static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1713                                   struct ieee80211_chanctx_conf *ctx,
1714                                   u32 changed)
1715{
1716        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1717        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1718        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1719
1720        if (WARN_ONCE((phy_ctxt->ref > 1) &&
1721                      (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1722                                   IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1723                                   IEEE80211_CHANCTX_CHANGE_RADAR |
1724                                   IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
1725                      "Cannot change PHY. Ref=%d, changed=0x%X\n",
1726                      phy_ctxt->ref, changed))
1727                return;
1728
1729        mutex_lock(&mvm->mutex);
1730        iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1731                                 ctx->rx_chains_static,
1732                                 ctx->rx_chains_dynamic);
1733        iwl_mvm_bt_coex_vif_change(mvm);
1734        mutex_unlock(&mvm->mutex);
1735}
1736
1737static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1738                                      struct ieee80211_vif *vif,
1739                                      struct ieee80211_chanctx_conf *ctx)
1740{
1741        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1742        u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1743        struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1744        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1745        int ret;
1746
1747        mutex_lock(&mvm->mutex);
1748
1749        mvmvif->phy_ctxt = phy_ctxt;
1750
1751        switch (vif->type) {
1752        case NL80211_IFTYPE_AP:
1753        case NL80211_IFTYPE_ADHOC:
1754                /*
1755                 * The AP binding flow is handled as part of the start_ap flow
1756                 * (in bss_info_changed), similarly for IBSS.
1757                 */
1758                ret = 0;
1759                goto out_unlock;
1760        case NL80211_IFTYPE_STATION:
1761        case NL80211_IFTYPE_MONITOR:
1762                break;
1763        default:
1764                ret = -EINVAL;
1765                goto out_unlock;
1766        }
1767
1768        ret = iwl_mvm_binding_add_vif(mvm, vif);
1769        if (ret)
1770                goto out_unlock;
1771
1772        /*
1773         * Power state must be updated before quotas,
1774         * otherwise fw will complain.
1775         */
1776        mvm->bound_vif_cnt++;
1777        iwl_mvm_power_update_binding(mvm, vif, true);
1778
1779        /* Setting the quota at this stage is only required for monitor
1780         * interfaces. For the other types, the bss_info changed flow
1781         * will handle quota settings.
1782         */
1783        if (vif->type == NL80211_IFTYPE_MONITOR) {
1784                mvmvif->monitor_active = true;
1785                ret = iwl_mvm_update_quotas(mvm, vif);
1786                if (ret)
1787                        goto out_remove_binding;
1788        }
1789
1790        goto out_unlock;
1791
1792 out_remove_binding:
1793        iwl_mvm_binding_remove_vif(mvm, vif);
1794        mvm->bound_vif_cnt--;
1795        iwl_mvm_power_update_binding(mvm, vif, false);
1796 out_unlock:
1797        mutex_unlock(&mvm->mutex);
1798        if (ret)
1799                mvmvif->phy_ctxt = NULL;
1800        return ret;
1801}
1802
1803static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1804                                         struct ieee80211_vif *vif,
1805                                         struct ieee80211_chanctx_conf *ctx)
1806{
1807        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1808        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1809
1810        mutex_lock(&mvm->mutex);
1811
1812        iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1813
1814        switch (vif->type) {
1815        case NL80211_IFTYPE_AP:
1816        case NL80211_IFTYPE_ADHOC:
1817                goto out_unlock;
1818        case NL80211_IFTYPE_MONITOR:
1819                mvmvif->monitor_active = false;
1820                iwl_mvm_update_quotas(mvm, NULL);
1821                break;
1822        default:
1823                break;
1824        }
1825
1826        iwl_mvm_binding_remove_vif(mvm, vif);
1827        mvm->bound_vif_cnt--;
1828        iwl_mvm_power_update_binding(mvm, vif, false);
1829
1830out_unlock:
1831        mvmvif->phy_ctxt = NULL;
1832        mutex_unlock(&mvm->mutex);
1833}
1834
1835static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1836                           struct ieee80211_sta *sta,
1837                           bool set)
1838{
1839        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1840        struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1841
1842        if (!mvm_sta || !mvm_sta->vif) {
1843                IWL_ERR(mvm, "Station is not associated to a vif\n");
1844                return -EINVAL;
1845        }
1846
1847        return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1848}
1849
1850#ifdef CONFIG_NL80211_TESTMODE
1851static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = {
1852        [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 },
1853        [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 },
1854        [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 },
1855};
1856
1857static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
1858                                      struct ieee80211_vif *vif,
1859                                      void *data, int len)
1860{
1861        struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1];
1862        int err;
1863        u32 noa_duration;
1864
1865        err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy);
1866        if (err)
1867                return err;
1868
1869        if (!tb[IWL_MVM_TM_ATTR_CMD])
1870                return -EINVAL;
1871
1872        switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) {
1873        case IWL_MVM_TM_CMD_SET_NOA:
1874                if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p ||
1875                    !vif->bss_conf.enable_beacon ||
1876                    !tb[IWL_MVM_TM_ATTR_NOA_DURATION])
1877                        return -EINVAL;
1878
1879                noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]);
1880                if (noa_duration >= vif->bss_conf.beacon_int)
1881                        return -EINVAL;
1882
1883                mvm->noa_duration = noa_duration;
1884                mvm->noa_vif = vif;
1885
1886                return iwl_mvm_update_quotas(mvm, NULL);
1887        case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
1888                /* must be associated client vif - ignore authorized */
1889                if (!vif || vif->type != NL80211_IFTYPE_STATION ||
1890                    !vif->bss_conf.assoc || !vif->bss_conf.dtim_period ||
1891                    !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])
1892                        return -EINVAL;
1893
1894                if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]))
1895                        return iwl_mvm_enable_beacon_filter(mvm, vif);
1896                return iwl_mvm_disable_beacon_filter(mvm, vif);
1897        }
1898
1899        return -EOPNOTSUPP;
1900}
1901
1902static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
1903                                    struct ieee80211_vif *vif,
1904                                    void *data, int len)
1905{
1906        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1907        int err;
1908
1909        mutex_lock(&mvm->mutex);
1910        err = __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len);
1911        mutex_unlock(&mvm->mutex);
1912
1913        return err;
1914}
1915#endif
1916
1917struct ieee80211_ops iwl_mvm_hw_ops = {
1918        .tx = iwl_mvm_mac_tx,
1919        .ampdu_action = iwl_mvm_mac_ampdu_action,
1920        .start = iwl_mvm_mac_start,
1921        .restart_complete = iwl_mvm_mac_restart_complete,
1922        .stop = iwl_mvm_mac_stop,
1923        .add_interface = iwl_mvm_mac_add_interface,
1924        .remove_interface = iwl_mvm_mac_remove_interface,
1925        .config = iwl_mvm_mac_config,
1926        .prepare_multicast = iwl_mvm_prepare_multicast,
1927        .configure_filter = iwl_mvm_configure_filter,
1928        .bss_info_changed = iwl_mvm_bss_info_changed,
1929        .hw_scan = iwl_mvm_mac_hw_scan,
1930        .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1931        .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove,
1932        .sta_state = iwl_mvm_mac_sta_state,
1933        .sta_notify = iwl_mvm_mac_sta_notify,
1934        .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1935        .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1936        .sta_rc_update = iwl_mvm_sta_rc_update,
1937        .conf_tx = iwl_mvm_mac_conf_tx,
1938        .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1939        .sched_scan_start = iwl_mvm_mac_sched_scan_start,
1940        .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
1941        .set_key = iwl_mvm_mac_set_key,
1942        .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1943        .remain_on_channel = iwl_mvm_roc,
1944        .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1945        .add_chanctx = iwl_mvm_add_chanctx,
1946        .remove_chanctx = iwl_mvm_remove_chanctx,
1947        .change_chanctx = iwl_mvm_change_chanctx,
1948        .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1949        .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1950
1951        .start_ap = iwl_mvm_start_ap_ibss,
1952        .stop_ap = iwl_mvm_stop_ap_ibss,
1953        .join_ibss = iwl_mvm_start_ap_ibss,
1954        .leave_ibss = iwl_mvm_stop_ap_ibss,
1955
1956        .set_tim = iwl_mvm_set_tim,
1957
1958        CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd)
1959
1960#ifdef CONFIG_PM_SLEEP
1961        /* look at d3.c */
1962        .suspend = iwl_mvm_suspend,
1963        .resume = iwl_mvm_resume,
1964        .set_wakeup = iwl_mvm_set_wakeup,
1965        .set_rekey_data = iwl_mvm_set_rekey_data,
1966#if IS_ENABLED(CONFIG_IPV6)
1967        .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1968#endif
1969        .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1970#endif
1971};
1972