]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/net/wireless/iwlwifi/mvm/sta.c
virtio-scsi: Fix virtqueue affinity setup
[linux-imx.git] / drivers / net / wireless / iwlwifi / mvm / sta.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 COPYING.
26  *
27  * Contact Information:
28  *  Intel Linux Wireless <ilw@linux.intel.com>
29  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30  *
31  * BSD LICENSE
32  *
33  * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  *
40  *  * Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  *  * Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in
44  *    the documentation and/or other materials provided with the
45  *    distribution.
46  *  * Neither the name Intel Corporation nor the names of its
47  *    contributors may be used to endorse or promote products derived
48  *    from this software without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61  *
62  *****************************************************************************/
63 #include <net/mac80211.h>
64
65 #include "mvm.h"
66 #include "sta.h"
67 #include "rs.h"
68
69 static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
70 {
71         int sta_id;
72
73         WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
74
75         lockdep_assert_held(&mvm->mutex);
76
77         /* Don't take rcu_read_lock() since we are protected by mvm->mutex */
78         for (sta_id = 0; sta_id < IWL_MVM_STATION_COUNT; sta_id++)
79                 if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
80                                                lockdep_is_held(&mvm->mutex)))
81                         return sta_id;
82         return IWL_MVM_STATION_COUNT;
83 }
84
85 /* send station add/update command to firmware */
86 int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
87                            bool update)
88 {
89         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
90         struct iwl_mvm_add_sta_cmd add_sta_cmd;
91         int ret;
92         u32 status;
93         u32 agg_size = 0, mpdu_dens = 0;
94
95         memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
96
97         add_sta_cmd.sta_id = mvm_sta->sta_id;
98         add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
99         if (!update) {
100                 add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
101                 memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN);
102         }
103         add_sta_cmd.add_modify = update ? 1 : 0;
104
105         add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
106                                                      STA_FLG_MIMO_EN_MSK);
107
108         switch (sta->bandwidth) {
109         case IEEE80211_STA_RX_BW_160:
110                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ);
111                 /* fall through */
112         case IEEE80211_STA_RX_BW_80:
113                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ);
114                 /* fall through */
115         case IEEE80211_STA_RX_BW_40:
116                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ);
117                 /* fall through */
118         case IEEE80211_STA_RX_BW_20:
119                 if (sta->ht_cap.ht_supported)
120                         add_sta_cmd.station_flags |=
121                                 cpu_to_le32(STA_FLG_FAT_EN_20MHZ);
122                 break;
123         }
124
125         switch (sta->rx_nss) {
126         case 1:
127                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
128                 break;
129         case 2:
130                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2);
131                 break;
132         case 3 ... 8:
133                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3);
134                 break;
135         }
136
137         switch (sta->smps_mode) {
138         case IEEE80211_SMPS_AUTOMATIC:
139         case IEEE80211_SMPS_NUM_MODES:
140                 WARN_ON(1);
141                 break;
142         case IEEE80211_SMPS_STATIC:
143                 /* override NSS */
144                 add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK);
145                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
146                 break;
147         case IEEE80211_SMPS_DYNAMIC:
148                 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT);
149                 break;
150         case IEEE80211_SMPS_OFF:
151                 /* nothing */
152                 break;
153         }
154
155         if (sta->ht_cap.ht_supported) {
156                 add_sta_cmd.station_flags_msk |=
157                         cpu_to_le32(STA_FLG_MAX_AGG_SIZE_MSK |
158                                     STA_FLG_AGG_MPDU_DENS_MSK);
159
160                 mpdu_dens = sta->ht_cap.ampdu_density;
161         }
162
163         if (sta->vht_cap.vht_supported) {
164                 agg_size = sta->vht_cap.cap &
165                         IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
166                 agg_size >>=
167                         IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
168         } else if (sta->ht_cap.ht_supported) {
169                 agg_size = sta->ht_cap.ampdu_factor;
170         }
171
172         add_sta_cmd.station_flags |=
173                 cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
174         add_sta_cmd.station_flags |=
175                 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
176
177         status = ADD_STA_SUCCESS;
178         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd),
179                                           &add_sta_cmd, &status);
180         if (ret)
181                 return ret;
182
183         switch (status) {
184         case ADD_STA_SUCCESS:
185                 IWL_DEBUG_ASSOC(mvm, "ADD_STA PASSED\n");
186                 break;
187         default:
188                 ret = -EIO;
189                 IWL_ERR(mvm, "ADD_STA failed\n");
190                 break;
191         }
192
193         return ret;
194 }
195
196 int iwl_mvm_add_sta(struct iwl_mvm *mvm,
197                     struct ieee80211_vif *vif,
198                     struct ieee80211_sta *sta)
199 {
200         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
201         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
202         int i, ret, sta_id;
203
204         lockdep_assert_held(&mvm->mutex);
205
206         if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
207                 sta_id = iwl_mvm_find_free_sta_id(mvm);
208         else
209                 sta_id = mvm_sta->sta_id;
210
211         if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
212                 return -ENOSPC;
213
214         spin_lock_init(&mvm_sta->lock);
215
216         mvm_sta->sta_id = sta_id;
217         mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id,
218                                                       mvmvif->color);
219         mvm_sta->vif = vif;
220         mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
221         mvm_sta->tx_protection = 0;
222         mvm_sta->tt_tx_protection = false;
223
224         /* HW restart, don't assume the memory has been zeroed */
225         atomic_set(&mvm->pending_frames[sta_id], 0);
226         mvm_sta->tid_disable_agg = 0;
227         mvm_sta->tfd_queue_msk = 0;
228         for (i = 0; i < IEEE80211_NUM_ACS; i++)
229                 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
230                         mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
231
232         /* for HW restart - need to reset the seq_number etc... */
233         memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data));
234
235         ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
236         if (ret)
237                 return ret;
238
239         /* The first station added is the AP, the others are TDLS STAs */
240         if (vif->type == NL80211_IFTYPE_STATION &&
241             mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
242                 mvmvif->ap_sta_id = sta_id;
243
244         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
245
246         return 0;
247 }
248
249 int iwl_mvm_update_sta(struct iwl_mvm *mvm,
250                        struct ieee80211_vif *vif,
251                        struct ieee80211_sta *sta)
252 {
253         return iwl_mvm_sta_send_to_fw(mvm, sta, true);
254 }
255
256 int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
257                       bool drain)
258 {
259         struct iwl_mvm_add_sta_cmd cmd = {};
260         int ret;
261         u32 status;
262
263         lockdep_assert_held(&mvm->mutex);
264
265         cmd.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color);
266         cmd.sta_id = mvmsta->sta_id;
267         cmd.add_modify = STA_MODE_MODIFY;
268         cmd.station_flags = drain ? cpu_to_le32(STA_FLG_DRAIN_FLOW) : 0;
269         cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
270
271         status = ADD_STA_SUCCESS;
272         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
273                                           &cmd, &status);
274         if (ret)
275                 return ret;
276
277         switch (status) {
278         case ADD_STA_SUCCESS:
279                 IWL_DEBUG_INFO(mvm, "Frames for staid %d will drained in fw\n",
280                                mvmsta->sta_id);
281                 break;
282         default:
283                 ret = -EIO;
284                 IWL_ERR(mvm, "Couldn't drain frames for staid %d\n",
285                         mvmsta->sta_id);
286                 break;
287         }
288
289         return ret;
290 }
291
292 /*
293  * Remove a station from the FW table. Before sending the command to remove
294  * the station validate that the station is indeed known to the driver (sanity
295  * only).
296  */
297 static int iwl_mvm_rm_sta_common(struct iwl_mvm *mvm, u8 sta_id)
298 {
299         struct ieee80211_sta *sta;
300         struct iwl_mvm_rm_sta_cmd rm_sta_cmd = {
301                 .sta_id = sta_id,
302         };
303         int ret;
304
305         sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
306                                         lockdep_is_held(&mvm->mutex));
307
308         /* Note: internal stations are marked as error values */
309         if (!sta) {
310                 IWL_ERR(mvm, "Invalid station id\n");
311                 return -EINVAL;
312         }
313
314         ret = iwl_mvm_send_cmd_pdu(mvm, REMOVE_STA, CMD_SYNC,
315                                    sizeof(rm_sta_cmd), &rm_sta_cmd);
316         if (ret) {
317                 IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
318                 return ret;
319         }
320
321         return 0;
322 }
323
324 void iwl_mvm_sta_drained_wk(struct work_struct *wk)
325 {
326         struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, sta_drained_wk);
327         u8 sta_id;
328
329         /*
330          * The mutex is needed because of the SYNC cmd, but not only: if the
331          * work would run concurrently with iwl_mvm_rm_sta, it would run before
332          * iwl_mvm_rm_sta sets the station as busy, and exit. Then
333          * iwl_mvm_rm_sta would set the station as busy, and nobody will clean
334          * that later.
335          */
336         mutex_lock(&mvm->mutex);
337
338         for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT) {
339                 int ret;
340                 struct ieee80211_sta *sta =
341                         rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
342                                                   lockdep_is_held(&mvm->mutex));
343
344                 /* This station is in use */
345                 if (!IS_ERR(sta))
346                         continue;
347
348                 if (PTR_ERR(sta) == -EINVAL) {
349                         IWL_ERR(mvm, "Drained sta %d, but it is internal?\n",
350                                 sta_id);
351                         continue;
352                 }
353
354                 if (!sta) {
355                         IWL_ERR(mvm, "Drained sta %d, but it was NULL?\n",
356                                 sta_id);
357                         continue;
358                 }
359
360                 WARN_ON(PTR_ERR(sta) != -EBUSY);
361                 /* This station was removed and we waited until it got drained,
362                  * we can now proceed and remove it.
363                  */
364                 ret = iwl_mvm_rm_sta_common(mvm, sta_id);
365                 if (ret) {
366                         IWL_ERR(mvm,
367                                 "Couldn't remove sta %d after it was drained\n",
368                                 sta_id);
369                         continue;
370                 }
371                 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
372                 clear_bit(sta_id, mvm->sta_drained);
373         }
374
375         mutex_unlock(&mvm->mutex);
376 }
377
378 int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
379                    struct ieee80211_vif *vif,
380                    struct ieee80211_sta *sta)
381 {
382         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
383         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
384         int ret;
385
386         lockdep_assert_held(&mvm->mutex);
387
388         if (vif->type == NL80211_IFTYPE_STATION &&
389             mvmvif->ap_sta_id == mvm_sta->sta_id) {
390                 /* flush its queues here since we are freeing mvm_sta */
391                 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
392
393                 /*
394                  * Put a non-NULL since the fw station isn't removed.
395                  * It will be removed after the MAC will be set as
396                  * unassoc.
397                  */
398                 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
399                                    ERR_PTR(-EINVAL));
400
401                 /* if we are associated - we can't remove the AP STA now */
402                 if (vif->bss_conf.assoc)
403                         return ret;
404
405                 /* unassoc - go ahead - remove the AP STA now */
406                 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
407         }
408
409         /*
410          * Make sure that the tx response code sees the station as -EBUSY and
411          * calls the drain worker.
412          */
413         spin_lock_bh(&mvm_sta->lock);
414         /*
415          * There are frames pending on the AC queues for this station.
416          * We need to wait until all the frames are drained...
417          */
418         if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) {
419                 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
420                                    ERR_PTR(-EBUSY));
421                 spin_unlock_bh(&mvm_sta->lock);
422                 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
423         } else {
424                 spin_unlock_bh(&mvm_sta->lock);
425                 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
426                 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
427         }
428
429         return ret;
430 }
431
432 int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
433                       struct ieee80211_vif *vif,
434                       u8 sta_id)
435 {
436         int ret = iwl_mvm_rm_sta_common(mvm, sta_id);
437
438         lockdep_assert_held(&mvm->mutex);
439
440         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
441         return ret;
442 }
443
444 int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
445                              u32 qmask)
446 {
447         if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
448                 sta->sta_id = iwl_mvm_find_free_sta_id(mvm);
449                 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT))
450                         return -ENOSPC;
451         }
452
453         sta->tfd_queue_msk = qmask;
454
455         /* put a non-NULL value so iterating over the stations won't stop */
456         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], ERR_PTR(-EINVAL));
457         return 0;
458 }
459
460 void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
461 {
462         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
463         memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
464         sta->sta_id = IWL_MVM_STATION_COUNT;
465 }
466
467 static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
468                                       struct iwl_mvm_int_sta *sta,
469                                       const u8 *addr,
470                                       u16 mac_id, u16 color)
471 {
472         struct iwl_mvm_add_sta_cmd cmd;
473         int ret;
474         u32 status;
475
476         lockdep_assert_held(&mvm->mutex);
477
478         memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd));
479         cmd.sta_id = sta->sta_id;
480         cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
481                                                              color));
482
483         cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
484
485         if (addr)
486                 memcpy(cmd.addr, addr, ETH_ALEN);
487
488         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
489                                           &cmd, &status);
490         if (ret)
491                 return ret;
492
493         switch (status) {
494         case ADD_STA_SUCCESS:
495                 IWL_DEBUG_INFO(mvm, "Internal station added.\n");
496                 return 0;
497         default:
498                 ret = -EIO;
499                 IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
500                         status);
501                 break;
502         }
503         return ret;
504 }
505
506 int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
507 {
508         int ret;
509
510         lockdep_assert_held(&mvm->mutex);
511
512         /* Add the aux station, but without any queues */
513         ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0);
514         if (ret)
515                 return ret;
516
517         ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
518                                          MAC_INDEX_AUX, 0);
519
520         if (ret)
521                 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
522         return ret;
523 }
524
525 /*
526  * Send the add station command for the vif's broadcast station.
527  * Assumes that the station was already allocated.
528  *
529  * @mvm: the mvm component
530  * @vif: the interface to which the broadcast station is added
531  * @bsta: the broadcast station to add.
532  */
533 int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
534                            struct iwl_mvm_int_sta *bsta)
535 {
536         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
537         static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
538
539         lockdep_assert_held(&mvm->mutex);
540
541         if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
542                 return -ENOSPC;
543
544         return iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
545                                           mvmvif->id, mvmvif->color);
546 }
547
548 /* Send the FW a request to remove the station from it's internal data
549  * structures, but DO NOT remove the entry from the local data structures. */
550 int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
551                               struct iwl_mvm_int_sta *bsta)
552 {
553         int ret;
554
555         lockdep_assert_held(&mvm->mutex);
556
557         ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
558         if (ret)
559                 IWL_WARN(mvm, "Failed sending remove station\n");
560         return ret;
561 }
562
563 /* Allocate a new station entry for the broadcast station to the given vif,
564  * and send it to the FW.
565  * Note that each P2P mac should have its own broadcast station.
566  *
567  * @mvm: the mvm component
568  * @vif: the interface to which the broadcast station is added
569  * @bsta: the broadcast station to add. */
570 int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
571                           struct iwl_mvm_int_sta *bsta)
572 {
573         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
574         static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
575         u32 qmask;
576         int ret;
577
578         lockdep_assert_held(&mvm->mutex);
579
580         qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
581         ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask);
582         if (ret)
583                 return ret;
584
585         ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
586                                          mvmvif->id, mvmvif->color);
587
588         if (ret)
589                 iwl_mvm_dealloc_int_sta(mvm, bsta);
590         return ret;
591 }
592
593 /*
594  * Send the FW a request to remove the station from it's internal data
595  * structures, and in addition remove it from the local data structure.
596  */
597 int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
598 {
599         int ret;
600
601         lockdep_assert_held(&mvm->mutex);
602
603         ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
604         if (ret)
605                 return ret;
606
607         iwl_mvm_dealloc_int_sta(mvm, bsta);
608         return ret;
609 }
610
611 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
612                        int tid, u16 ssn, bool start)
613 {
614         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
615         struct iwl_mvm_add_sta_cmd cmd = {};
616         int ret;
617         u32 status;
618
619         lockdep_assert_held(&mvm->mutex);
620
621         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
622         cmd.sta_id = mvm_sta->sta_id;
623         cmd.add_modify = STA_MODE_MODIFY;
624         cmd.add_immediate_ba_tid = (u8) tid;
625         cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
626         cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
627                                   STA_MODIFY_REMOVE_BA_TID;
628
629         status = ADD_STA_SUCCESS;
630         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
631                                           &cmd, &status);
632         if (ret)
633                 return ret;
634
635         switch (status) {
636         case ADD_STA_SUCCESS:
637                 IWL_DEBUG_INFO(mvm, "RX BA Session %sed in fw\n",
638                                start ? "start" : "stopp");
639                 break;
640         case ADD_STA_IMMEDIATE_BA_FAILURE:
641                 IWL_WARN(mvm, "RX BA Session refused by fw\n");
642                 ret = -ENOSPC;
643                 break;
644         default:
645                 ret = -EIO;
646                 IWL_ERR(mvm, "RX BA Session failed %sing, status 0x%x\n",
647                         start ? "start" : "stopp", status);
648                 break;
649         }
650
651         return ret;
652 }
653
654 static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
655                               int tid, u8 queue, bool start)
656 {
657         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
658         struct iwl_mvm_add_sta_cmd cmd = {};
659         int ret;
660         u32 status;
661
662         lockdep_assert_held(&mvm->mutex);
663
664         if (start) {
665                 mvm_sta->tfd_queue_msk |= BIT(queue);
666                 mvm_sta->tid_disable_agg &= ~BIT(tid);
667         } else {
668                 mvm_sta->tfd_queue_msk &= ~BIT(queue);
669                 mvm_sta->tid_disable_agg |= BIT(tid);
670         }
671
672         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
673         cmd.sta_id = mvm_sta->sta_id;
674         cmd.add_modify = STA_MODE_MODIFY;
675         cmd.modify_mask = STA_MODIFY_QUEUES | STA_MODIFY_TID_DISABLE_TX;
676         cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
677         cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
678
679         status = ADD_STA_SUCCESS;
680         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
681                                           &cmd, &status);
682         if (ret)
683                 return ret;
684
685         switch (status) {
686         case ADD_STA_SUCCESS:
687                 break;
688         default:
689                 ret = -EIO;
690                 IWL_ERR(mvm, "TX BA Session failed %sing, status 0x%x\n",
691                         start ? "start" : "stopp", status);
692                 break;
693         }
694
695         return ret;
696 }
697
698 static const u8 tid_to_ac[] = {
699         IEEE80211_AC_BE,
700         IEEE80211_AC_BK,
701         IEEE80211_AC_BK,
702         IEEE80211_AC_BE,
703         IEEE80211_AC_VI,
704         IEEE80211_AC_VI,
705         IEEE80211_AC_VO,
706         IEEE80211_AC_VO,
707 };
708
709 int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
710                              struct ieee80211_sta *sta, u16 tid, u16 *ssn)
711 {
712         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
713         struct iwl_mvm_tid_data *tid_data;
714         int txq_id;
715
716         if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
717                 return -EINVAL;
718
719         if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
720                 IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n",
721                         mvmsta->tid_data[tid].state);
722                 return -ENXIO;
723         }
724
725         lockdep_assert_held(&mvm->mutex);
726
727         for (txq_id = IWL_MVM_FIRST_AGG_QUEUE;
728              txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++)
729                 if (mvm->queue_to_mac80211[txq_id] ==
730                     IWL_INVALID_MAC80211_QUEUE)
731                         break;
732
733         if (txq_id > IWL_MVM_LAST_AGG_QUEUE) {
734                 IWL_ERR(mvm, "Failed to allocate agg queue\n");
735                 return -EIO;
736         }
737
738         /* the new tx queue is still connected to the same mac80211 queue */
739         mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_ac[tid]];
740
741         spin_lock_bh(&mvmsta->lock);
742         tid_data = &mvmsta->tid_data[tid];
743         tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
744         tid_data->txq_id = txq_id;
745         *ssn = tid_data->ssn;
746
747         IWL_DEBUG_TX_QUEUES(mvm,
748                             "Start AGG: sta %d tid %d queue %d - ssn = %d, next_recl = %d\n",
749                             mvmsta->sta_id, tid, txq_id, tid_data->ssn,
750                             tid_data->next_reclaimed);
751
752         if (tid_data->ssn == tid_data->next_reclaimed) {
753                 tid_data->state = IWL_AGG_STARTING;
754                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
755         } else {
756                 tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
757         }
758
759         spin_unlock_bh(&mvmsta->lock);
760
761         return 0;
762 }
763
764 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
765                             struct ieee80211_sta *sta, u16 tid, u8 buf_size)
766 {
767         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
768         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
769         int queue, fifo, ret;
770         u16 ssn;
771
772         buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
773
774         spin_lock_bh(&mvmsta->lock);
775         ssn = tid_data->ssn;
776         queue = tid_data->txq_id;
777         tid_data->state = IWL_AGG_ON;
778         tid_data->ssn = 0xffff;
779         spin_unlock_bh(&mvmsta->lock);
780
781         fifo = iwl_mvm_ac_to_tx_fifo[tid_to_ac[tid]];
782
783         ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
784         if (ret)
785                 return -EIO;
786
787         iwl_trans_txq_enable(mvm->trans, queue, fifo, mvmsta->sta_id, tid,
788                              buf_size, ssn);
789
790         /*
791          * Even though in theory the peer could have different
792          * aggregation reorder buffer sizes for different sessions,
793          * our ucode doesn't allow for that and has a global limit
794          * for each station. Therefore, use the minimum of all the
795          * aggregation sessions and our default value.
796          */
797         mvmsta->max_agg_bufsize =
798                 min(mvmsta->max_agg_bufsize, buf_size);
799         mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
800
801         IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
802                      sta->addr, tid);
803
804         if (mvm->cfg->ht_params->use_rts_for_aggregation) {
805                 /*
806                  * switch to RTS/CTS if it is the prefer protection
807                  * method for HT traffic
808                  * this function also sends the LQ command
809                  */
810                 return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
811                                              mvmsta, true);
812                 /*
813                  * TODO: remove the TLC_RTS flag when we tear down the last
814                  * AGG session (agg_tids_count in DVM)
815                  */
816         }
817
818         return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
819 }
820
821 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
822                             struct ieee80211_sta *sta, u16 tid)
823 {
824         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
825         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
826         u16 txq_id;
827         int err;
828
829
830         /*
831          * If mac80211 is cleaning its state, then say that we finished since
832          * our state has been cleared anyway.
833          */
834         if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
835                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
836                 return 0;
837         }
838
839         spin_lock_bh(&mvmsta->lock);
840
841         txq_id = tid_data->txq_id;
842
843         IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
844                             mvmsta->sta_id, tid, txq_id, tid_data->state);
845
846         switch (tid_data->state) {
847         case IWL_AGG_ON:
848                 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
849
850                 IWL_DEBUG_TX_QUEUES(mvm,
851                                     "ssn = %d, next_recl = %d\n",
852                                     tid_data->ssn, tid_data->next_reclaimed);
853
854                 /* There are still packets for this RA / TID in the HW */
855                 if (tid_data->ssn != tid_data->next_reclaimed) {
856                         tid_data->state = IWL_EMPTYING_HW_QUEUE_DELBA;
857                         err = 0;
858                         break;
859                 }
860
861                 tid_data->ssn = 0xffff;
862                 iwl_trans_txq_disable(mvm->trans, txq_id);
863                 /* fall through */
864         case IWL_AGG_STARTING:
865         case IWL_EMPTYING_HW_QUEUE_ADDBA:
866                 /*
867                  * The agg session has been stopped before it was set up. This
868                  * can happen when the AddBA timer times out for example.
869                  */
870
871                 /* No barriers since we are under mutex */
872                 lockdep_assert_held(&mvm->mutex);
873                 mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE;
874
875                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
876                 tid_data->state = IWL_AGG_OFF;
877                 err = 0;
878                 break;
879         default:
880                 IWL_ERR(mvm,
881                         "Stopping AGG while state not ON or starting for %d on %d (%d)\n",
882                         mvmsta->sta_id, tid, tid_data->state);
883                 IWL_ERR(mvm,
884                         "\ttid_data->txq_id = %d\n", tid_data->txq_id);
885                 err = -EINVAL;
886         }
887
888         spin_unlock_bh(&mvmsta->lock);
889
890         return err;
891 }
892
893 int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
894                             struct ieee80211_sta *sta, u16 tid)
895 {
896         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
897         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
898         u16 txq_id;
899
900         /*
901          * First set the agg state to OFF to avoid calling
902          * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
903          */
904         spin_lock_bh(&mvmsta->lock);
905         txq_id = tid_data->txq_id;
906         IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
907                             mvmsta->sta_id, tid, txq_id, tid_data->state);
908         tid_data->state = IWL_AGG_OFF;
909         spin_unlock_bh(&mvmsta->lock);
910
911         if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
912                 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
913
914         iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
915         mvm->queue_to_mac80211[tid_data->txq_id] =
916                                 IWL_INVALID_MAC80211_QUEUE;
917
918         return 0;
919 }
920
921 static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
922 {
923         int i;
924
925         lockdep_assert_held(&mvm->mutex);
926
927         i = find_first_zero_bit(mvm->fw_key_table, STA_KEY_MAX_NUM);
928
929         if (i == STA_KEY_MAX_NUM)
930                 return STA_KEY_IDX_INVALID;
931
932         __set_bit(i, mvm->fw_key_table);
933
934         return i;
935 }
936
937 static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
938                                  struct ieee80211_sta *sta)
939 {
940         struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
941
942         if (sta) {
943                 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
944
945                 return mvm_sta->sta_id;
946         }
947
948         /*
949          * The device expects GTKs for station interfaces to be
950          * installed as GTKs for the AP station. If we have no
951          * station ID, then use AP's station ID.
952          */
953         if (vif->type == NL80211_IFTYPE_STATION &&
954             mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
955                 return mvmvif->ap_sta_id;
956
957         return IWL_MVM_STATION_COUNT;
958 }
959
960 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
961                                 struct iwl_mvm_sta *mvm_sta,
962                                 struct ieee80211_key_conf *keyconf,
963                                 u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
964                                 u32 cmd_flags)
965 {
966         __le16 key_flags;
967         struct iwl_mvm_add_sta_cmd cmd = {};
968         int ret, status;
969         u16 keyidx;
970         int i;
971
972         keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
973                  STA_KEY_FLG_KEYID_MSK;
974         key_flags = cpu_to_le16(keyidx);
975         key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_KEY_MAP);
976
977         switch (keyconf->cipher) {
978         case WLAN_CIPHER_SUITE_TKIP:
979                 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
980                 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
981                 for (i = 0; i < 5; i++)
982                         cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
983                 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
984                 break;
985         case WLAN_CIPHER_SUITE_CCMP:
986                 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
987                 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
988                 break;
989         default:
990                 WARN_ON(1);
991                 return -EINVAL;
992         }
993
994         if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
995                 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
996
997         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
998         cmd.key.key_offset = keyconf->hw_key_idx;
999         cmd.key.key_flags = key_flags;
1000         cmd.add_modify = STA_MODE_MODIFY;
1001         cmd.modify_mask = STA_MODIFY_KEY;
1002         cmd.sta_id = sta_id;
1003
1004         status = ADD_STA_SUCCESS;
1005         if (cmd_flags == CMD_SYNC)
1006                 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
1007                                                   &cmd, &status);
1008         else
1009                 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
1010                                            sizeof(cmd), &cmd);
1011
1012         switch (status) {
1013         case ADD_STA_SUCCESS:
1014                 IWL_DEBUG_WEP(mvm, "MODIFY_STA: set dynamic key passed\n");
1015                 break;
1016         default:
1017                 ret = -EIO;
1018                 IWL_ERR(mvm, "MODIFY_STA: set dynamic key failed\n");
1019                 break;
1020         }
1021
1022         return ret;
1023 }
1024
1025 static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
1026                                  struct ieee80211_key_conf *keyconf,
1027                                  u8 sta_id, bool remove_key)
1028 {
1029         struct iwl_mvm_mgmt_mcast_key_cmd igtk_cmd = {};
1030
1031         /* verify the key details match the required command's expectations */
1032         if (WARN_ON((keyconf->cipher != WLAN_CIPHER_SUITE_AES_CMAC) ||
1033                     (keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
1034                     (keyconf->keyidx != 4 && keyconf->keyidx != 5)))
1035                 return -EINVAL;
1036
1037         igtk_cmd.key_id = cpu_to_le32(keyconf->keyidx);
1038         igtk_cmd.sta_id = cpu_to_le32(sta_id);
1039
1040         if (remove_key) {
1041                 igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
1042         } else {
1043                 struct ieee80211_key_seq seq;
1044                 const u8 *pn;
1045
1046                 memcpy(igtk_cmd.IGTK, keyconf->key, keyconf->keylen);
1047                 ieee80211_aes_cmac_calculate_k1_k2(keyconf,
1048                                                    igtk_cmd.K1, igtk_cmd.K2);
1049                 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1050                 pn = seq.aes_cmac.pn;
1051                 igtk_cmd.receive_seq_cnt = cpu_to_le64(((u64) pn[5] << 0) |
1052                                                        ((u64) pn[4] << 8) |
1053                                                        ((u64) pn[3] << 16) |
1054                                                        ((u64) pn[2] << 24) |
1055                                                        ((u64) pn[1] << 32) |
1056                                                        ((u64) pn[0] << 40));
1057         }
1058
1059         IWL_DEBUG_INFO(mvm, "%s igtk for sta %u\n",
1060                        remove_key ? "removing" : "installing",
1061                        igtk_cmd.sta_id);
1062
1063         return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, CMD_SYNC,
1064                                     sizeof(igtk_cmd), &igtk_cmd);
1065 }
1066
1067
1068 static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
1069                                        struct ieee80211_vif *vif,
1070                                        struct ieee80211_sta *sta)
1071 {
1072         struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
1073
1074         if (sta)
1075                 return sta->addr;
1076
1077         if (vif->type == NL80211_IFTYPE_STATION &&
1078             mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
1079                 u8 sta_id = mvmvif->ap_sta_id;
1080                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1081                                                 lockdep_is_held(&mvm->mutex));
1082                 return sta->addr;
1083         }
1084
1085
1086         return NULL;
1087 }
1088
1089 int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1090                         struct ieee80211_vif *vif,
1091                         struct ieee80211_sta *sta,
1092                         struct ieee80211_key_conf *keyconf,
1093                         bool have_key_offset)
1094 {
1095         struct iwl_mvm_sta *mvm_sta;
1096         int ret;
1097         u8 *addr, sta_id;
1098         struct ieee80211_key_seq seq;
1099         u16 p1k[5];
1100
1101         lockdep_assert_held(&mvm->mutex);
1102
1103         /* Get the station id from the mvm local station table */
1104         sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1105         if (sta_id == IWL_MVM_STATION_COUNT) {
1106                 IWL_ERR(mvm, "Failed to find station id\n");
1107                 return -EINVAL;
1108         }
1109
1110         if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
1111                 ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
1112                 goto end;
1113         }
1114
1115         /*
1116          * It is possible that the 'sta' parameter is NULL, and thus
1117          * there is a need to retrieve  the sta from the local station table.
1118          */
1119         if (!sta) {
1120                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1121                                                 lockdep_is_held(&mvm->mutex));
1122                 if (IS_ERR_OR_NULL(sta)) {
1123                         IWL_ERR(mvm, "Invalid station id\n");
1124                         return -EINVAL;
1125                 }
1126         }
1127
1128         mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1129         if (WARN_ON_ONCE(mvm_sta->vif != vif))
1130                 return -EINVAL;
1131
1132         if (!have_key_offset) {
1133                 /*
1134                  * The D3 firmware hardcodes the PTK offset to 0, so we have to
1135                  * configure it there. As a result, this workaround exists to
1136                  * let the caller set the key offset (hw_key_idx), see d3.c.
1137                  */
1138                 keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm);
1139                 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1140                         return -ENOSPC;
1141         }
1142
1143         switch (keyconf->cipher) {
1144         case WLAN_CIPHER_SUITE_TKIP:
1145                 addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
1146                 /* get phase 1 key from mac80211 */
1147                 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1148                 ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
1149                 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1150                                            seq.tkip.iv32, p1k, CMD_SYNC);
1151                 break;
1152         case WLAN_CIPHER_SUITE_CCMP:
1153                 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1154                                            0, NULL, CMD_SYNC);
1155                 break;
1156         default:
1157                 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher);
1158                 ret = -EINVAL;
1159         }
1160
1161         if (ret)
1162                 __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1163
1164 end:
1165         IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
1166                       keyconf->cipher, keyconf->keylen, keyconf->keyidx,
1167                       sta->addr, ret);
1168         return ret;
1169 }
1170
1171 int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1172                            struct ieee80211_vif *vif,
1173                            struct ieee80211_sta *sta,
1174                            struct ieee80211_key_conf *keyconf)
1175 {
1176         struct iwl_mvm_sta *mvm_sta;
1177         struct iwl_mvm_add_sta_cmd cmd = {};
1178         __le16 key_flags;
1179         int ret, status;
1180         u8 sta_id;
1181
1182         lockdep_assert_held(&mvm->mutex);
1183
1184         /* Get the station id from the mvm local station table */
1185         sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1186
1187         IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
1188                       keyconf->keyidx, sta_id);
1189
1190         if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1191                 return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
1192
1193         ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1194         if (!ret) {
1195                 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
1196                         keyconf->hw_key_idx);
1197                 return -ENOENT;
1198         }
1199
1200         if (sta_id == IWL_MVM_STATION_COUNT) {
1201                 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1202                 return 0;
1203         }
1204
1205         /*
1206          * It is possible that the 'sta' parameter is NULL, and thus
1207          * there is a need to retrieve the sta from the local station table,
1208          * for example when a GTK is removed (where the sta_id will then be
1209          * the AP ID, and no station was passed by mac80211.)
1210          */
1211         if (!sta) {
1212                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1213                                                 lockdep_is_held(&mvm->mutex));
1214                 if (!sta) {
1215                         IWL_ERR(mvm, "Invalid station id\n");
1216                         return -EINVAL;
1217                 }
1218         }
1219
1220         mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1221         if (WARN_ON_ONCE(mvm_sta->vif != vif))
1222                 return -EINVAL;
1223
1224         key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
1225                                  STA_KEY_FLG_KEYID_MSK);
1226         key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
1227         key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
1228
1229         if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1230                 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1231
1232         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
1233         cmd.key.key_flags = key_flags;
1234         cmd.key.key_offset = keyconf->hw_key_idx;
1235         cmd.sta_id = sta_id;
1236
1237         cmd.modify_mask = STA_MODIFY_KEY;
1238         cmd.add_modify = STA_MODE_MODIFY;
1239
1240         status = ADD_STA_SUCCESS;
1241         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
1242                                           &cmd, &status);
1243
1244         switch (status) {
1245         case ADD_STA_SUCCESS:
1246                 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
1247                 break;
1248         default:
1249                 ret = -EIO;
1250                 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
1251                 break;
1252         }
1253
1254         return ret;
1255 }
1256
1257 void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1258                              struct ieee80211_vif *vif,
1259                              struct ieee80211_key_conf *keyconf,
1260                              struct ieee80211_sta *sta, u32 iv32,
1261                              u16 *phase1key)
1262 {
1263         struct iwl_mvm_sta *mvm_sta;
1264         u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1265
1266         if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
1267                 return;
1268
1269         rcu_read_lock();
1270
1271         if (!sta) {
1272                 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
1273                 if (WARN_ON(IS_ERR_OR_NULL(sta))) {
1274                         rcu_read_unlock();
1275                         return;
1276                 }
1277         }
1278
1279         mvm_sta = (void *)sta->drv_priv;
1280         iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1281                              iv32, phase1key, CMD_ASYNC);
1282         rcu_read_unlock();
1283 }
1284
1285 void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1286                                 struct ieee80211_sta *sta)
1287 {
1288         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1289         struct iwl_mvm_add_sta_cmd cmd = {
1290                 .add_modify = STA_MODE_MODIFY,
1291                 .sta_id = mvmsta->sta_id,
1292                 .station_flags_msk = cpu_to_le32(STA_FLG_PS),
1293                 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1294         };
1295         int ret;
1296
1297         ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1298         if (ret)
1299                 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1300 }
1301
1302 void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1303                                        struct ieee80211_sta *sta,
1304                                        enum ieee80211_frame_release_type reason,
1305                                        u16 cnt)
1306 {
1307         u16 sleep_state_flags =
1308                 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1309                         STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1310         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1311         struct iwl_mvm_add_sta_cmd cmd = {
1312                 .add_modify = STA_MODE_MODIFY,
1313                 .sta_id = mvmsta->sta_id,
1314                 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1315                 .sleep_tx_count = cpu_to_le16(cnt),
1316                 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1317                 /*
1318                  * Same modify mask for sleep_tx_count and sleep_state_flags so
1319                  * we must set the sleep_state_flags too.
1320                  */
1321                 .sleep_state_flags = cpu_to_le16(sleep_state_flags),
1322         };
1323         int ret;
1324
1325         /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1326         ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1327         if (ret)
1328                 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1329 }