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