]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/iwlwifi/mvm/mac80211.c
iwlwifi: mvm: don't delay the association until after beacon
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / mvm / mac80211.c
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 LICENSE.GPL.
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 <net/mac80211.h>
69
70 #include "iwl-op-mode.h"
71 #include "iwl-io.h"
72 #include "mvm.h"
73 #include "sta.h"
74 #include "time-event.h"
75 #include "iwl-eeprom-parse.h"
76 #include "fw-api-scan.h"
77 #include "iwl-phy-db.h"
78
79 static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
80         {
81                 .max = 1,
82                 .types = BIT(NL80211_IFTYPE_STATION) |
83                         BIT(NL80211_IFTYPE_AP),
84         },
85         {
86                 .max = 1,
87                 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
88                         BIT(NL80211_IFTYPE_P2P_GO),
89         },
90         {
91                 .max = 1,
92                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
93         },
94 };
95
96 static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
97         {
98                 .num_different_channels = 1,
99                 .max_interfaces = 3,
100                 .limits = iwl_mvm_limits,
101                 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
102         },
103 };
104
105 int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106 {
107         struct ieee80211_hw *hw = mvm->hw;
108         int num_mac, ret;
109
110         /* Tell mac80211 our characteristics */
111         hw->flags = IEEE80211_HW_SIGNAL_DBM |
112                     IEEE80211_HW_SPECTRUM_MGMT |
113                     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
114                     IEEE80211_HW_QUEUE_CONTROL |
115                     IEEE80211_HW_WANT_MONITOR_VIF |
116                     IEEE80211_HW_SCAN_WHILE_IDLE |
117                     IEEE80211_HW_SUPPORTS_PS |
118                     IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
119                     IEEE80211_HW_AMPDU_AGGREGATION;
120
121         hw->queues = IWL_FIRST_AMPDU_QUEUE;
122         hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
123         hw->rate_control_algorithm = "iwl-mvm-rs";
124
125         /*
126          * Enable 11w if advertised by firmware and software crypto
127          * is not enabled (as the firmware will interpret some mgmt
128          * packets, so enabling it with software crypto isn't safe)
129          */
130         if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
131             !iwlwifi_mod_params.sw_crypto)
132                 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
133
134         hw->sta_data_size = sizeof(struct iwl_mvm_sta);
135         hw->vif_data_size = sizeof(struct iwl_mvm_vif);
136         hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
137
138         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
139                 BIT(NL80211_IFTYPE_P2P_CLIENT) |
140                 BIT(NL80211_IFTYPE_AP) |
141                 BIT(NL80211_IFTYPE_P2P_GO) |
142                 BIT(NL80211_IFTYPE_P2P_DEVICE);
143
144         hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
145                             WIPHY_FLAG_DISABLE_BEACON_HINTS |
146                             WIPHY_FLAG_IBSS_RSN;
147
148         hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
149         hw->wiphy->n_iface_combinations =
150                 ARRAY_SIZE(iwl_mvm_iface_combinations);
151
152         hw->wiphy->max_remain_on_channel_duration = 500;
153         hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
154
155         /* Extract MAC address */
156         memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
157         hw->wiphy->addresses = mvm->addresses;
158         hw->wiphy->n_addresses = 1;
159         num_mac = mvm->nvm_data->n_hw_addrs;
160         if (num_mac > 1) {
161                 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr,
162                        ETH_ALEN);
163                 mvm->addresses[1].addr[5]++;
164                 hw->wiphy->n_addresses++;
165         }
166
167         /* we create the 802.11 header and a max-length SSID element */
168         hw->wiphy->max_scan_ie_len =
169                 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
170         hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
171
172         if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
173                 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
174                         &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
175         if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
176                 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
177                         &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
178
179         hw->wiphy->hw_version = mvm->trans->hw_id;
180
181         if (iwlwifi_mod_params.power_save)
182                 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
183         else
184                 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
185
186         hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
187                                NL80211_FEATURE_P2P_GO_OPPPS;
188
189         mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
190
191 #ifdef CONFIG_PM_SLEEP
192         if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
193             mvm->trans->ops->d3_suspend &&
194             mvm->trans->ops->d3_resume &&
195             device_can_wakeup(mvm->trans->dev)) {
196                 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
197                                           WIPHY_WOWLAN_DISCONNECT |
198                                           WIPHY_WOWLAN_EAP_IDENTITY_REQ |
199                                           WIPHY_WOWLAN_RFKILL_RELEASE;
200                 if (!iwlwifi_mod_params.sw_crypto)
201                         hw->wiphy->wowlan.flags |=
202                                 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
203                                 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
204                                 WIPHY_WOWLAN_4WAY_HANDSHAKE;
205
206                 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
207                 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
208                 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
209         }
210 #endif
211
212         ret = iwl_mvm_leds_init(mvm);
213         if (ret)
214                 return ret;
215
216         return ieee80211_register_hw(mvm->hw);
217 }
218
219 static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
220                            struct ieee80211_tx_control *control,
221                            struct sk_buff *skb)
222 {
223         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
224
225         if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) {
226                 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n");
227                 goto drop;
228         }
229
230         if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE &&
231             !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
232                 goto drop;
233
234         if (control->sta) {
235                 if (iwl_mvm_tx_skb(mvm, skb, control->sta))
236                         goto drop;
237                 return;
238         }
239
240         if (iwl_mvm_tx_skb_non_sta(mvm, skb))
241                 goto drop;
242         return;
243  drop:
244         ieee80211_free_txskb(hw, skb);
245 }
246
247 static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
248                                     struct ieee80211_vif *vif,
249                                     enum ieee80211_ampdu_mlme_action action,
250                                     struct ieee80211_sta *sta, u16 tid,
251                                     u16 *ssn, u8 buf_size)
252 {
253         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
254         int ret;
255
256         IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
257                      sta->addr, tid, action);
258
259         if (!(mvm->nvm_data->sku_cap_11n_enable))
260                 return -EACCES;
261
262         mutex_lock(&mvm->mutex);
263
264         switch (action) {
265         case IEEE80211_AMPDU_RX_START:
266                 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) {
267                         ret = -EINVAL;
268                         break;
269                 }
270                 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
271                 break;
272         case IEEE80211_AMPDU_RX_STOP:
273                 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
274                 break;
275         case IEEE80211_AMPDU_TX_START:
276                 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
277                 break;
278         case IEEE80211_AMPDU_TX_STOP_CONT:
279         case IEEE80211_AMPDU_TX_STOP_FLUSH:
280         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
281                 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
282                 break;
283         case IEEE80211_AMPDU_TX_OPERATIONAL:
284                 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
285                 break;
286         default:
287                 WARN_ON_ONCE(1);
288                 ret = -EINVAL;
289                 break;
290         }
291         mutex_unlock(&mvm->mutex);
292
293         return ret;
294 }
295
296 static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
297                                      struct ieee80211_vif *vif)
298 {
299         struct iwl_mvm *mvm = data;
300         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
301
302         mvmvif->uploaded = false;
303         mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
304
305         /* does this make sense at all? */
306         mvmvif->color++;
307
308         spin_lock_bh(&mvm->time_event_lock);
309         iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
310         spin_unlock_bh(&mvm->time_event_lock);
311
312         if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
313                 mvmvif->phy_ctxt = NULL;
314 }
315
316 static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
317 {
318         iwl_trans_stop_device(mvm->trans);
319         iwl_trans_stop_hw(mvm->trans, false);
320
321         mvm->scan_status = IWL_MVM_SCAN_NONE;
322
323         /* just in case one was running */
324         ieee80211_remain_on_channel_expired(mvm->hw);
325
326         ieee80211_iterate_active_interfaces_atomic(
327                 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
328                 iwl_mvm_cleanup_iterator, mvm);
329
330         memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
331         memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
332
333         ieee80211_wake_queues(mvm->hw);
334
335         mvm->vif_count = 0;
336 }
337
338 static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
339 {
340         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
341         int ret;
342
343         mutex_lock(&mvm->mutex);
344
345         /* Clean up some internal and mac80211 state on restart */
346         if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
347                 iwl_mvm_restart_cleanup(mvm);
348
349         ret = iwl_mvm_up(mvm);
350         mutex_unlock(&mvm->mutex);
351
352         return ret;
353 }
354
355 static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
356 {
357         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
358         int ret;
359
360         mutex_lock(&mvm->mutex);
361
362         clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
363         ret = iwl_mvm_update_quotas(mvm, NULL);
364         if (ret)
365                 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
366                         ret);
367
368         mutex_unlock(&mvm->mutex);
369 }
370
371 static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
372 {
373         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
374
375         flush_work(&mvm->async_handlers_wk);
376
377         mutex_lock(&mvm->mutex);
378         /* async_handlers_wk is now blocked */
379
380         /*
381          * The work item could be running or queued if the
382          * ROC time event stops just as we get here.
383          */
384         cancel_work_sync(&mvm->roc_done_wk);
385
386         iwl_trans_stop_device(mvm->trans);
387         iwl_trans_stop_hw(mvm->trans, false);
388
389         iwl_mvm_async_handlers_purge(mvm);
390         /* async_handlers_list is empty and will stay empty: HW is stopped */
391
392         /* the fw is stopped, the aux sta is dead: clean up driver state */
393         iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
394
395         mutex_unlock(&mvm->mutex);
396
397         /*
398          * The worker might have been waiting for the mutex, let it run and
399          * discover that its list is now empty.
400          */
401         cancel_work_sync(&mvm->async_handlers_wk);
402 }
403
404 static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
405                                         struct ieee80211_vif *vif)
406 {
407         struct iwl_mvm *mvm = data;
408         int ret;
409
410         ret = iwl_mvm_power_disable(mvm, vif);
411         if (ret)
412                 IWL_ERR(mvm, "failed to disable power management\n");
413 }
414
415 static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
416                                           struct ieee80211_vif *vif)
417 {
418         struct iwl_mvm *mvm = data;
419
420         iwl_mvm_power_update_mode(mvm, vif);
421 }
422
423 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
424                                      struct ieee80211_vif *vif)
425 {
426         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
427         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
428         int ret;
429
430         /*
431          * Not much to do here. The stack will not allow interface
432          * types or combinations that we didn't advertise, so we
433          * don't really have to check the types.
434          */
435
436         mutex_lock(&mvm->mutex);
437
438         /* Allocate resources for the MAC context, and add it the the fw  */
439         ret = iwl_mvm_mac_ctxt_init(mvm, vif);
440         if (ret)
441                 goto out_unlock;
442
443         /*
444          * The AP binding flow can be done only after the beacon
445          * template is configured (which happens only in the mac80211
446          * start_ap() flow), and adding the broadcast station can happen
447          * only after the binding.
448          * In addition, since modifying the MAC before adding a bcast
449          * station is not allowed by the FW, delay the adding of MAC context to
450          * the point where we can also add the bcast station.
451          * In short: there's not much we can do at this point, other than
452          * allocating resources :)
453          */
454         if (vif->type == NL80211_IFTYPE_AP) {
455                 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
456                 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
457                                                qmask);
458                 if (ret) {
459                         IWL_ERR(mvm, "Failed to allocate bcast sta\n");
460                         goto out_release;
461                 }
462
463                 goto out_unlock;
464         }
465
466         /*
467          * TODO: remove this temporary code.
468          * Currently MVM FW supports power management only on single MAC.
469          * Iterate and disable PM on all active interfaces.
470          * Note: the method below does not count the new interface being added
471          * at this moment.
472          */
473         mvm->vif_count++;
474         if (mvm->vif_count > 1) {
475                 IWL_DEBUG_MAC80211(mvm,
476                                    "Disable power on existing interfaces\n");
477                 ieee80211_iterate_active_interfaces_atomic(
478                                             mvm->hw,
479                                             IEEE80211_IFACE_ITER_NORMAL,
480                                             iwl_mvm_pm_disable_iterator, mvm);
481         }
482
483         ret = iwl_mvm_mac_ctxt_add(mvm, vif);
484         if (ret)
485                 goto out_release;
486
487         /*
488          * Update power state on the new interface. Admittedly, based on
489          * mac80211 logics this power update will disable power management
490          */
491         iwl_mvm_power_update_mode(mvm, vif);
492
493         /*
494          * P2P_DEVICE interface does not have a channel context assigned to it,
495          * so a dedicated PHY context is allocated to it and the corresponding
496          * MAC context is bound to it at this stage.
497          */
498         if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
499                 struct ieee80211_channel *chan;
500                 struct cfg80211_chan_def chandef;
501
502                 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
503
504                 /*
505                  * The channel used here isn't relevant as it's
506                  * going to be overwritten as part of the ROC flow.
507                  * For now use the first channel we have.
508                  */
509                 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
510                 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
511                 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
512                                            &chandef, 1, 1);
513                 if (ret)
514                         goto out_remove_mac;
515
516                 ret = iwl_mvm_binding_add_vif(mvm, vif);
517                 if (ret)
518                         goto out_remove_phy;
519
520                 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
521                 if (ret)
522                         goto out_unbind;
523
524                 /* Save a pointer to p2p device vif, so it can later be used to
525                  * update the p2p device MAC when a GO is started/stopped */
526                 mvm->p2p_device_vif = vif;
527         }
528
529         goto out_unlock;
530
531  out_unbind:
532         iwl_mvm_binding_remove_vif(mvm, vif);
533  out_remove_phy:
534         iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
535  out_remove_mac:
536         mvmvif->phy_ctxt = NULL;
537         iwl_mvm_mac_ctxt_remove(mvm, vif);
538  out_release:
539         /*
540          * TODO: remove this temporary code.
541          * Currently MVM FW supports power management only on single MAC.
542          * Check if only one additional interface remains after rereasing
543          * current one. Update power mode on the remaining interface.
544          */
545         mvm->vif_count--;
546         IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
547                            mvm->vif_count);
548         if (mvm->vif_count == 1) {
549                 ieee80211_iterate_active_interfaces(
550                                         mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
551                                         iwl_mvm_power_update_iterator, mvm);
552         }
553         iwl_mvm_mac_ctxt_release(mvm, vif);
554  out_unlock:
555         mutex_unlock(&mvm->mutex);
556
557         return ret;
558 }
559
560 static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
561                                          struct ieee80211_vif *vif)
562 {
563         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
564         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
565         u32 tfd_msk = 0, ac;
566
567         for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
568                 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
569                         tfd_msk |= BIT(vif->hw_queue[ac]);
570
571         if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
572                 tfd_msk |= BIT(vif->cab_queue);
573
574         if (tfd_msk) {
575                 mutex_lock(&mvm->mutex);
576                 iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
577                 mutex_unlock(&mvm->mutex);
578         }
579
580         if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
581                 /*
582                  * Flush the ROC worker which will flush the OFFCHANNEL queue.
583                  * We assume here that all the packets sent to the OFFCHANNEL
584                  * queue are sent in ROC session.
585                  */
586                 flush_work(&mvm->roc_done_wk);
587         } else {
588                 /*
589                  * By now, all the AC queues are empty. The AGG queues are
590                  * empty too. We already got all the Tx responses for all the
591                  * packets in the queues. The drain work can have been
592                  * triggered. Flush it. This work item takes the mutex, so kill
593                  * it before we take it.
594                  */
595                 flush_work(&mvm->sta_drained_wk);
596         }
597
598         mutex_lock(&mvm->mutex);
599
600         /*
601          * For AP/GO interface, the tear down of the resources allocated to the
602          * interface should be handled as part of the bss_info_changed flow.
603          */
604         if (vif->type == NL80211_IFTYPE_AP) {
605                 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
606                 goto out_release;
607         }
608
609         if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
610                 mvm->p2p_device_vif = NULL;
611                 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
612                 iwl_mvm_binding_remove_vif(mvm, vif);
613                 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
614                 mvmvif->phy_ctxt = NULL;
615         }
616
617         /*
618          * TODO: remove this temporary code.
619          * Currently MVM FW supports power management only on single MAC.
620          * Check if only one additional interface remains after removing
621          * current one. Update power mode on the remaining interface.
622          */
623         if (mvm->vif_count)
624                 mvm->vif_count--;
625         IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
626                            mvm->vif_count);
627         if (mvm->vif_count == 1) {
628                 ieee80211_iterate_active_interfaces(
629                                         mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
630                                         iwl_mvm_power_update_iterator, mvm);
631         }
632
633         iwl_mvm_mac_ctxt_remove(mvm, vif);
634
635 out_release:
636         iwl_mvm_mac_ctxt_release(mvm, vif);
637         mutex_unlock(&mvm->mutex);
638 }
639
640 static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
641 {
642         return 0;
643 }
644
645 static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
646                                      unsigned int changed_flags,
647                                      unsigned int *total_flags,
648                                      u64 multicast)
649 {
650         *total_flags = 0;
651 }
652
653 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
654                                              struct ieee80211_vif *vif,
655                                              struct ieee80211_bss_conf *bss_conf,
656                                              u32 changes)
657 {
658         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
659         int ret;
660
661         ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
662         if (ret)
663                 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
664
665         if (changes & BSS_CHANGED_ASSOC) {
666                 if (bss_conf->assoc) {
667                         /* add quota for this interface */
668                         ret = iwl_mvm_update_quotas(mvm, vif);
669                         if (ret) {
670                                 IWL_ERR(mvm, "failed to update quotas\n");
671                                 return;
672                         }
673                 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
674                         /* remove AP station now that the MAC is unassoc */
675                         ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
676                         if (ret)
677                                 IWL_ERR(mvm, "failed to remove AP station\n");
678                         mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
679                         /* remove quota for this interface */
680                         ret = iwl_mvm_update_quotas(mvm, NULL);
681                         if (ret)
682                                 IWL_ERR(mvm, "failed to update quotas\n");
683                 }
684         } else if (changes & BSS_CHANGED_DTIM_PERIOD) {
685                 /*
686                  * We received a beacon _after_ association so
687                  * remove the session protection.
688                  */
689                 iwl_mvm_remove_time_event(mvm, mvmvif,
690                                           &mvmvif->time_event_data);
691         } else if (changes & BSS_CHANGED_PS) {
692                 /*
693                  * TODO: remove this temporary code.
694                  * Currently MVM FW supports power management only on single
695                  * MAC. Avoid power mode update if more than one interface
696                  * is active.
697                  */
698                 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
699                                    mvm->vif_count);
700                 if (mvm->vif_count == 1) {
701                         ret = iwl_mvm_power_update_mode(mvm, vif);
702                         if (ret)
703                                 IWL_ERR(mvm, "failed to update power mode\n");
704                 }
705         }
706 }
707
708 static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
709 {
710         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
711         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
712         int ret;
713
714         mutex_lock(&mvm->mutex);
715
716         /* Send the beacon template */
717         ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
718         if (ret)
719                 goto out_unlock;
720
721         /* Add the mac context */
722         ret = iwl_mvm_mac_ctxt_add(mvm, vif);
723         if (ret)
724                 goto out_unlock;
725
726         /* Perform the binding */
727         ret = iwl_mvm_binding_add_vif(mvm, vif);
728         if (ret)
729                 goto out_remove;
730
731         mvmvif->ap_active = true;
732
733         /* Send the bcast station. At this stage the TBTT and DTIM time events
734          * are added and applied to the scheduler */
735         ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
736         if (ret)
737                 goto out_unbind;
738
739         ret = iwl_mvm_update_quotas(mvm, vif);
740         if (ret)
741                 goto out_rm_bcast;
742
743         /* Need to update the P2P Device MAC */
744         if (vif->p2p && mvm->p2p_device_vif)
745                 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
746
747         mutex_unlock(&mvm->mutex);
748         return 0;
749
750 out_rm_bcast:
751         iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
752 out_unbind:
753         iwl_mvm_binding_remove_vif(mvm, vif);
754 out_remove:
755         iwl_mvm_mac_ctxt_remove(mvm, vif);
756 out_unlock:
757         mutex_unlock(&mvm->mutex);
758         return ret;
759 }
760
761 static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
762 {
763         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
764         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
765
766         mutex_lock(&mvm->mutex);
767
768         mvmvif->ap_active = false;
769
770         /* Need to update the P2P Device MAC */
771         if (vif->p2p && mvm->p2p_device_vif)
772                 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
773
774         iwl_mvm_update_quotas(mvm, NULL);
775         iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
776         iwl_mvm_binding_remove_vif(mvm, vif);
777         iwl_mvm_mac_ctxt_remove(mvm, vif);
778
779         mutex_unlock(&mvm->mutex);
780 }
781
782 static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
783                                         struct ieee80211_vif *vif,
784                                         struct ieee80211_bss_conf *bss_conf,
785                                         u32 changes)
786 {
787         /* Need to send a new beacon template to the FW */
788         if (changes & BSS_CHANGED_BEACON) {
789                 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
790                         IWL_WARN(mvm, "Failed updating beacon data\n");
791         }
792 }
793
794 static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
795                                      struct ieee80211_vif *vif,
796                                      struct ieee80211_bss_conf *bss_conf,
797                                      u32 changes)
798 {
799         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
800
801         mutex_lock(&mvm->mutex);
802
803         switch (vif->type) {
804         case NL80211_IFTYPE_STATION:
805                 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
806                 break;
807         case NL80211_IFTYPE_AP:
808                 iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
809                 break;
810         default:
811                 /* shouldn't happen */
812                 WARN_ON_ONCE(1);
813         }
814
815         mutex_unlock(&mvm->mutex);
816 }
817
818 static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
819                                struct ieee80211_vif *vif,
820                                struct cfg80211_scan_request *req)
821 {
822         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
823         int ret;
824
825         if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
826                 return -EINVAL;
827
828         mutex_lock(&mvm->mutex);
829
830         if (mvm->scan_status == IWL_MVM_SCAN_NONE)
831                 ret = iwl_mvm_scan_request(mvm, vif, req);
832         else
833                 ret = -EBUSY;
834
835         mutex_unlock(&mvm->mutex);
836
837         return ret;
838 }
839
840 static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
841                                        struct ieee80211_vif *vif)
842 {
843         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
844
845         mutex_lock(&mvm->mutex);
846
847         iwl_mvm_cancel_scan(mvm);
848
849         mutex_unlock(&mvm->mutex);
850 }
851
852 static void
853 iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
854                                   struct ieee80211_sta *sta, u16 tid,
855                                   int num_frames,
856                                   enum ieee80211_frame_release_type reason,
857                                   bool more_data)
858 {
859         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
860         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
861
862         /* TODO: how do we tell the fw to send frames for a specific TID */
863
864         /*
865          * The fw will send EOSP notification when the last frame will be
866          * transmitted.
867          */
868         iwl_mvm_sta_modify_sleep_tx_count(mvm, mvmsta->sta_id, reason,
869                                           num_frames);
870 }
871
872 static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
873                                    struct ieee80211_vif *vif,
874                                    enum sta_notify_cmd cmd,
875                                    struct ieee80211_sta *sta)
876 {
877         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
878         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
879
880         switch (cmd) {
881         case STA_NOTIFY_SLEEP:
882                 if (atomic_read(&mvmsta->pending_frames) > 0)
883                         ieee80211_sta_block_awake(hw, sta, true);
884                 /*
885                  * The fw updates the STA to be asleep. Tx packets on the Tx
886                  * queues to this station will not be transmitted. The fw will
887                  * send a Tx response with TX_STATUS_FAIL_DEST_PS.
888                  */
889                 break;
890         case STA_NOTIFY_AWAKE:
891                 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION))
892                         break;
893                 iwl_mvm_sta_modify_ps_wake(mvm, mvmsta->sta_id);
894                 break;
895         default:
896                 break;
897         }
898 }
899
900 static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
901                                  struct ieee80211_vif *vif,
902                                  struct ieee80211_sta *sta,
903                                  enum ieee80211_sta_state old_state,
904                                  enum ieee80211_sta_state new_state)
905 {
906         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
907         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
908         int ret;
909
910         IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
911                            sta->addr, old_state, new_state);
912
913         /* this would be a mac80211 bug ... but don't crash */
914         if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
915                 return -EINVAL;
916
917         /* if a STA is being removed, reuse its ID */
918         flush_work(&mvm->sta_drained_wk);
919
920         mutex_lock(&mvm->mutex);
921         if (old_state == IEEE80211_STA_NOTEXIST &&
922             new_state == IEEE80211_STA_NONE) {
923                 ret = iwl_mvm_add_sta(mvm, vif, sta);
924         } else if (old_state == IEEE80211_STA_NONE &&
925                    new_state == IEEE80211_STA_AUTH) {
926                 ret = 0;
927         } else if (old_state == IEEE80211_STA_AUTH &&
928                    new_state == IEEE80211_STA_ASSOC) {
929                 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
930                 ret = 0;
931         } else if (old_state == IEEE80211_STA_ASSOC &&
932                    new_state == IEEE80211_STA_AUTHORIZED) {
933                 ret = 0;
934         } else if (old_state == IEEE80211_STA_AUTHORIZED &&
935                    new_state == IEEE80211_STA_ASSOC) {
936                 ret = 0;
937         } else if (old_state == IEEE80211_STA_ASSOC &&
938                    new_state == IEEE80211_STA_AUTH) {
939                 ret = 0;
940         } else if (old_state == IEEE80211_STA_AUTH &&
941                    new_state == IEEE80211_STA_NONE) {
942                 ret = 0;
943         } else if (old_state == IEEE80211_STA_NONE &&
944                    new_state == IEEE80211_STA_NOTEXIST) {
945                 ret = iwl_mvm_rm_sta(mvm, vif, sta);
946         } else {
947                 ret = -EIO;
948         }
949         mutex_unlock(&mvm->mutex);
950
951         return ret;
952 }
953
954 static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
955 {
956         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
957
958         mvm->rts_threshold = value;
959
960         return 0;
961 }
962
963 static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
964                                struct ieee80211_vif *vif, u16 ac,
965                                const struct ieee80211_tx_queue_params *params)
966 {
967         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
968         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
969
970         mvmvif->queue_params[ac] = *params;
971
972         /*
973          * No need to update right away, we'll get BSS_CHANGED_QOS
974          * The exception is P2P_DEVICE interface which needs immediate update.
975          */
976         if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
977                 int ret;
978
979                 mutex_lock(&mvm->mutex);
980                 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
981                 mutex_unlock(&mvm->mutex);
982                 return ret;
983         }
984         return 0;
985 }
986
987 static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
988                                       struct ieee80211_vif *vif)
989 {
990         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
991         u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
992                            200 + vif->bss_conf.beacon_int);
993         u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
994                                100 + vif->bss_conf.beacon_int);
995
996         if (WARN_ON_ONCE(vif->bss_conf.assoc))
997                 return;
998
999         mutex_lock(&mvm->mutex);
1000         /* Try really hard to protect the session and hear a beacon */
1001         iwl_mvm_protect_session(mvm, vif, duration, min_duration);
1002         mutex_unlock(&mvm->mutex);
1003 }
1004
1005 static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1006                                enum set_key_cmd cmd,
1007                                struct ieee80211_vif *vif,
1008                                struct ieee80211_sta *sta,
1009                                struct ieee80211_key_conf *key)
1010 {
1011         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1012         int ret;
1013
1014         if (iwlwifi_mod_params.sw_crypto) {
1015                 IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1016                 return -EOPNOTSUPP;
1017         }
1018
1019         switch (key->cipher) {
1020         case WLAN_CIPHER_SUITE_TKIP:
1021                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1022                 /* fall-through */
1023         case WLAN_CIPHER_SUITE_CCMP:
1024                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1025                 break;
1026         case WLAN_CIPHER_SUITE_AES_CMAC:
1027                 WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1028                 break;
1029         case WLAN_CIPHER_SUITE_WEP40:
1030         case WLAN_CIPHER_SUITE_WEP104:
1031                 /*
1032                  * Support for TX only, at least for now, so accept
1033                  * the key and do nothing else. Then mac80211 will
1034                  * pass it for TX but we don't have to use it for RX.
1035                  */
1036                 return 0;
1037         default:
1038                 return -EOPNOTSUPP;
1039         }
1040
1041         mutex_lock(&mvm->mutex);
1042
1043         switch (cmd) {
1044         case SET_KEY:
1045                 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1046                 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1047                 if (ret) {
1048                         IWL_WARN(mvm, "set key failed\n");
1049                         /*
1050                          * can't add key for RX, but we don't need it
1051                          * in the device for TX so still return 0
1052                          */
1053                         ret = 0;
1054                 }
1055
1056                 break;
1057         case DISABLE_KEY:
1058                 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1059                 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1060                 break;
1061         default:
1062                 ret = -EINVAL;
1063         }
1064
1065         mutex_unlock(&mvm->mutex);
1066         return ret;
1067 }
1068
1069 static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1070                                         struct ieee80211_vif *vif,
1071                                         struct ieee80211_key_conf *keyconf,
1072                                         struct ieee80211_sta *sta,
1073                                         u32 iv32, u16 *phase1key)
1074 {
1075         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1076
1077         iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1078 }
1079
1080
1081 static int iwl_mvm_roc(struct ieee80211_hw *hw,
1082                        struct ieee80211_vif *vif,
1083                        struct ieee80211_channel *channel,
1084                        int duration)
1085 {
1086         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1087         struct cfg80211_chan_def chandef;
1088         int ret;
1089
1090         if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1091                 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1092                 return -EINVAL;
1093         }
1094
1095         IWL_DEBUG_MAC80211(mvm, "enter (%d, %d)\n", channel->hw_value,
1096                            duration);
1097
1098         mutex_lock(&mvm->mutex);
1099
1100         cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1101         ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1102                                        &chandef, 1, 1);
1103
1104         /* Schedule the time events */
1105         ret = iwl_mvm_start_p2p_roc(mvm, vif, duration);
1106
1107         mutex_unlock(&mvm->mutex);
1108         IWL_DEBUG_MAC80211(mvm, "leave\n");
1109
1110         return ret;
1111 }
1112
1113 static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1114 {
1115         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1116
1117         IWL_DEBUG_MAC80211(mvm, "enter\n");
1118
1119         mutex_lock(&mvm->mutex);
1120         iwl_mvm_stop_p2p_roc(mvm);
1121         mutex_unlock(&mvm->mutex);
1122
1123         IWL_DEBUG_MAC80211(mvm, "leave\n");
1124         return 0;
1125 }
1126
1127 static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1128                                struct ieee80211_chanctx_conf *ctx)
1129 {
1130         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1131         struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1132         int ret;
1133
1134         mutex_lock(&mvm->mutex);
1135
1136         IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
1137         ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
1138                                    ctx->rx_chains_static,
1139                                    ctx->rx_chains_dynamic);
1140         mutex_unlock(&mvm->mutex);
1141         return ret;
1142 }
1143
1144 static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1145                                    struct ieee80211_chanctx_conf *ctx)
1146 {
1147         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1148         struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1149
1150         mutex_lock(&mvm->mutex);
1151         iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt);
1152         mutex_unlock(&mvm->mutex);
1153 }
1154
1155 static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1156                                    struct ieee80211_chanctx_conf *ctx,
1157                                    u32 changed)
1158 {
1159         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1160         struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1161
1162         mutex_lock(&mvm->mutex);
1163         iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1164                                  ctx->rx_chains_static,
1165                                  ctx->rx_chains_dynamic);
1166         mutex_unlock(&mvm->mutex);
1167 }
1168
1169 static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1170                                       struct ieee80211_vif *vif,
1171                                       struct ieee80211_chanctx_conf *ctx)
1172 {
1173         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1174         struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv;
1175         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1176         int ret;
1177
1178         mutex_lock(&mvm->mutex);
1179
1180         mvmvif->phy_ctxt = phyctx;
1181
1182         switch (vif->type) {
1183         case NL80211_IFTYPE_AP:
1184                 /*
1185                  * The AP binding flow is handled as part of the start_ap flow
1186                  * (in bss_info_changed).
1187                  */
1188                 ret = 0;
1189                 goto out_unlock;
1190         case NL80211_IFTYPE_STATION:
1191         case NL80211_IFTYPE_ADHOC:
1192         case NL80211_IFTYPE_MONITOR:
1193                 break;
1194         default:
1195                 ret = -EINVAL;
1196                 goto out_unlock;
1197         }
1198
1199         ret = iwl_mvm_binding_add_vif(mvm, vif);
1200         if (ret)
1201                 goto out_unlock;
1202
1203         /*
1204          * Setting the quota at this stage is only required for monitor
1205          * interfaces. For the other types, the bss_info changed flow
1206          * will handle quota settings.
1207          */
1208         if (vif->type == NL80211_IFTYPE_MONITOR) {
1209                 ret = iwl_mvm_update_quotas(mvm, vif);
1210                 if (ret)
1211                         goto out_remove_binding;
1212         }
1213
1214         goto out_unlock;
1215
1216  out_remove_binding:
1217         iwl_mvm_binding_remove_vif(mvm, vif);
1218  out_unlock:
1219         mutex_unlock(&mvm->mutex);
1220         if (ret)
1221                 mvmvif->phy_ctxt = NULL;
1222         return ret;
1223 }
1224
1225 static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1226                                          struct ieee80211_vif *vif,
1227                                          struct ieee80211_chanctx_conf *ctx)
1228 {
1229         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1230         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1231
1232         mutex_lock(&mvm->mutex);
1233
1234         iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1235
1236         if (vif->type == NL80211_IFTYPE_AP)
1237                 goto out_unlock;
1238
1239         iwl_mvm_binding_remove_vif(mvm, vif);
1240         switch (vif->type) {
1241         case NL80211_IFTYPE_MONITOR:
1242                 iwl_mvm_update_quotas(mvm, vif);
1243                 break;
1244         default:
1245                 break;
1246         }
1247
1248 out_unlock:
1249         mvmvif->phy_ctxt = NULL;
1250         mutex_unlock(&mvm->mutex);
1251 }
1252
1253 static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1254                            struct ieee80211_sta *sta,
1255                            bool set)
1256 {
1257         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1258         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1259
1260         if (!mvm_sta || !mvm_sta->vif) {
1261                 IWL_ERR(mvm, "Station is not associated to a vif\n");
1262                 return -EINVAL;
1263         }
1264
1265         return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1266 }
1267
1268 struct ieee80211_ops iwl_mvm_hw_ops = {
1269         .tx = iwl_mvm_mac_tx,
1270         .ampdu_action = iwl_mvm_mac_ampdu_action,
1271         .start = iwl_mvm_mac_start,
1272         .restart_complete = iwl_mvm_mac_restart_complete,
1273         .stop = iwl_mvm_mac_stop,
1274         .add_interface = iwl_mvm_mac_add_interface,
1275         .remove_interface = iwl_mvm_mac_remove_interface,
1276         .config = iwl_mvm_mac_config,
1277         .configure_filter = iwl_mvm_configure_filter,
1278         .bss_info_changed = iwl_mvm_bss_info_changed,
1279         .hw_scan = iwl_mvm_mac_hw_scan,
1280         .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1281         .sta_state = iwl_mvm_mac_sta_state,
1282         .sta_notify = iwl_mvm_mac_sta_notify,
1283         .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1284         .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1285         .conf_tx = iwl_mvm_mac_conf_tx,
1286         .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1287         .set_key = iwl_mvm_mac_set_key,
1288         .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1289         .remain_on_channel = iwl_mvm_roc,
1290         .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1291
1292         .add_chanctx = iwl_mvm_add_chanctx,
1293         .remove_chanctx = iwl_mvm_remove_chanctx,
1294         .change_chanctx = iwl_mvm_change_chanctx,
1295         .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1296         .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1297
1298         .start_ap = iwl_mvm_start_ap,
1299         .stop_ap = iwl_mvm_stop_ap,
1300
1301         .set_tim = iwl_mvm_set_tim,
1302
1303 #ifdef CONFIG_PM_SLEEP
1304         /* look at d3.c */
1305         .suspend = iwl_mvm_suspend,
1306         .resume = iwl_mvm_resume,
1307         .set_wakeup = iwl_mvm_set_wakeup,
1308         .set_rekey_data = iwl_mvm_set_rekey_data,
1309 #if IS_ENABLED(CONFIG_IPV6)
1310         .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1311 #endif
1312         .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1313 #endif
1314 };