Merge tag 'stable/for-linus-3.10-rc0-tag-two' of git://git.kernel.org/pub/scm/linux...
[linux-block.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_sta->pending_frames, 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         if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
230                 mvm_sta->tfd_queue_msk |= BIT(vif->cab_queue);
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          * There are frames pending on the AC queues for this station.
411          * We need to wait until all the frames are drained...
412          */
413         if (atomic_read(&mvm_sta->pending_frames)) {
414                 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
415                 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
416                                    ERR_PTR(-EBUSY));
417         } else {
418                 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
419                 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
420         }
421
422         return ret;
423 }
424
425 int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
426                       struct ieee80211_vif *vif,
427                       u8 sta_id)
428 {
429         int ret = iwl_mvm_rm_sta_common(mvm, sta_id);
430
431         lockdep_assert_held(&mvm->mutex);
432
433         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
434         return ret;
435 }
436
437 int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
438                              u32 qmask)
439 {
440         if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
441                 sta->sta_id = iwl_mvm_find_free_sta_id(mvm);
442                 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT))
443                         return -ENOSPC;
444         }
445
446         sta->tfd_queue_msk = qmask;
447
448         /* put a non-NULL value so iterating over the stations won't stop */
449         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], ERR_PTR(-EINVAL));
450         return 0;
451 }
452
453 void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
454 {
455         rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
456         memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
457         sta->sta_id = IWL_MVM_STATION_COUNT;
458 }
459
460 static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
461                                       struct iwl_mvm_int_sta *sta,
462                                       const u8 *addr,
463                                       u16 mac_id, u16 color)
464 {
465         struct iwl_mvm_add_sta_cmd cmd;
466         int ret;
467         u32 status;
468
469         lockdep_assert_held(&mvm->mutex);
470
471         memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd));
472         cmd.sta_id = sta->sta_id;
473         cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
474                                                              color));
475
476         cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
477
478         if (addr)
479                 memcpy(cmd.addr, addr, ETH_ALEN);
480
481         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
482                                           &cmd, &status);
483         if (ret)
484                 return ret;
485
486         switch (status) {
487         case ADD_STA_SUCCESS:
488                 IWL_DEBUG_INFO(mvm, "Internal station added.\n");
489                 return 0;
490         default:
491                 ret = -EIO;
492                 IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
493                         status);
494                 break;
495         }
496         return ret;
497 }
498
499 int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
500 {
501         int ret;
502
503         lockdep_assert_held(&mvm->mutex);
504
505         /* Add the aux station, but without any queues */
506         ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0);
507         if (ret)
508                 return ret;
509
510         ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
511                                          MAC_INDEX_AUX, 0);
512
513         if (ret)
514                 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
515         return ret;
516 }
517
518 /*
519  * Send the add station command for the vif's broadcast station.
520  * Assumes that the station was already allocated.
521  *
522  * @mvm: the mvm component
523  * @vif: the interface to which the broadcast station is added
524  * @bsta: the broadcast station to add.
525  */
526 int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
527                            struct iwl_mvm_int_sta *bsta)
528 {
529         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
530         static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
531
532         lockdep_assert_held(&mvm->mutex);
533
534         if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
535                 return -ENOSPC;
536
537         return iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
538                                           mvmvif->id, mvmvif->color);
539 }
540
541 /* Send the FW a request to remove the station from it's internal data
542  * structures, but DO NOT remove the entry from the local data structures. */
543 int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
544                               struct iwl_mvm_int_sta *bsta)
545 {
546         int ret;
547
548         lockdep_assert_held(&mvm->mutex);
549
550         ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
551         if (ret)
552                 IWL_WARN(mvm, "Failed sending remove station\n");
553         return ret;
554 }
555
556 /* Allocate a new station entry for the broadcast station to the given vif,
557  * and send it to the FW.
558  * Note that each P2P mac should have its own broadcast station.
559  *
560  * @mvm: the mvm component
561  * @vif: the interface to which the broadcast station is added
562  * @bsta: the broadcast station to add. */
563 int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
564                           struct iwl_mvm_int_sta *bsta)
565 {
566         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
567         static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
568         u32 qmask;
569         int ret;
570
571         lockdep_assert_held(&mvm->mutex);
572
573         qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
574         ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask);
575         if (ret)
576                 return ret;
577
578         ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
579                                          mvmvif->id, mvmvif->color);
580
581         if (ret)
582                 iwl_mvm_dealloc_int_sta(mvm, bsta);
583         return ret;
584 }
585
586 /*
587  * Send the FW a request to remove the station from it's internal data
588  * structures, and in addition remove it from the local data structure.
589  */
590 int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
591 {
592         int ret;
593
594         lockdep_assert_held(&mvm->mutex);
595
596         ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
597         if (ret)
598                 return ret;
599
600         iwl_mvm_dealloc_int_sta(mvm, bsta);
601         return ret;
602 }
603
604 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
605                        int tid, u16 ssn, bool start)
606 {
607         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
608         struct iwl_mvm_add_sta_cmd cmd = {};
609         int ret;
610         u32 status;
611
612         lockdep_assert_held(&mvm->mutex);
613
614         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
615         cmd.sta_id = mvm_sta->sta_id;
616         cmd.add_modify = STA_MODE_MODIFY;
617         cmd.add_immediate_ba_tid = (u8) tid;
618         cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
619         cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
620                                   STA_MODIFY_REMOVE_BA_TID;
621
622         status = ADD_STA_SUCCESS;
623         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
624                                           &cmd, &status);
625         if (ret)
626                 return ret;
627
628         switch (status) {
629         case ADD_STA_SUCCESS:
630                 IWL_DEBUG_INFO(mvm, "RX BA Session %sed in fw\n",
631                                start ? "start" : "stopp");
632                 break;
633         case ADD_STA_IMMEDIATE_BA_FAILURE:
634                 IWL_WARN(mvm, "RX BA Session refused by fw\n");
635                 ret = -ENOSPC;
636                 break;
637         default:
638                 ret = -EIO;
639                 IWL_ERR(mvm, "RX BA Session failed %sing, status 0x%x\n",
640                         start ? "start" : "stopp", status);
641                 break;
642         }
643
644         return ret;
645 }
646
647 static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
648                               int tid, u8 queue, bool start)
649 {
650         struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
651         struct iwl_mvm_add_sta_cmd cmd = {};
652         int ret;
653         u32 status;
654
655         lockdep_assert_held(&mvm->mutex);
656
657         if (start) {
658                 mvm_sta->tfd_queue_msk |= BIT(queue);
659                 mvm_sta->tid_disable_agg &= ~BIT(tid);
660         } else {
661                 mvm_sta->tfd_queue_msk &= ~BIT(queue);
662                 mvm_sta->tid_disable_agg |= BIT(tid);
663         }
664
665         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
666         cmd.sta_id = mvm_sta->sta_id;
667         cmd.add_modify = STA_MODE_MODIFY;
668         cmd.modify_mask = STA_MODIFY_QUEUES | STA_MODIFY_TID_DISABLE_TX;
669         cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
670         cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
671
672         status = ADD_STA_SUCCESS;
673         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
674                                           &cmd, &status);
675         if (ret)
676                 return ret;
677
678         switch (status) {
679         case ADD_STA_SUCCESS:
680                 break;
681         default:
682                 ret = -EIO;
683                 IWL_ERR(mvm, "TX BA Session failed %sing, status 0x%x\n",
684                         start ? "start" : "stopp", status);
685                 break;
686         }
687
688         return ret;
689 }
690
691 static const u8 tid_to_ac[] = {
692         IEEE80211_AC_BE,
693         IEEE80211_AC_BK,
694         IEEE80211_AC_BK,
695         IEEE80211_AC_BE,
696         IEEE80211_AC_VI,
697         IEEE80211_AC_VI,
698         IEEE80211_AC_VO,
699         IEEE80211_AC_VO,
700 };
701
702 int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
703                              struct ieee80211_sta *sta, u16 tid, u16 *ssn)
704 {
705         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
706         struct iwl_mvm_tid_data *tid_data;
707         int txq_id;
708
709         if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
710                 return -EINVAL;
711
712         if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
713                 IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n",
714                         mvmsta->tid_data[tid].state);
715                 return -ENXIO;
716         }
717
718         lockdep_assert_held(&mvm->mutex);
719
720         for (txq_id = IWL_MVM_FIRST_AGG_QUEUE;
721              txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++)
722                 if (mvm->queue_to_mac80211[txq_id] ==
723                     IWL_INVALID_MAC80211_QUEUE)
724                         break;
725
726         if (txq_id > IWL_MVM_LAST_AGG_QUEUE) {
727                 IWL_ERR(mvm, "Failed to allocate agg queue\n");
728                 return -EIO;
729         }
730
731         /* the new tx queue is still connected to the same mac80211 queue */
732         mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_ac[tid]];
733
734         spin_lock_bh(&mvmsta->lock);
735         tid_data = &mvmsta->tid_data[tid];
736         tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
737         tid_data->txq_id = txq_id;
738         *ssn = tid_data->ssn;
739
740         IWL_DEBUG_TX_QUEUES(mvm,
741                             "Start AGG: sta %d tid %d queue %d - ssn = %d, next_recl = %d\n",
742                             mvmsta->sta_id, tid, txq_id, tid_data->ssn,
743                             tid_data->next_reclaimed);
744
745         if (tid_data->ssn == tid_data->next_reclaimed) {
746                 tid_data->state = IWL_AGG_STARTING;
747                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
748         } else {
749                 tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
750         }
751
752         spin_unlock_bh(&mvmsta->lock);
753
754         return 0;
755 }
756
757 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
758                             struct ieee80211_sta *sta, u16 tid, u8 buf_size)
759 {
760         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
761         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
762         int queue, fifo, ret;
763         u16 ssn;
764
765         buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
766
767         spin_lock_bh(&mvmsta->lock);
768         ssn = tid_data->ssn;
769         queue = tid_data->txq_id;
770         tid_data->state = IWL_AGG_ON;
771         tid_data->ssn = 0xffff;
772         spin_unlock_bh(&mvmsta->lock);
773
774         fifo = iwl_mvm_ac_to_tx_fifo[tid_to_ac[tid]];
775
776         ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
777         if (ret)
778                 return -EIO;
779
780         iwl_trans_txq_enable(mvm->trans, queue, fifo, mvmsta->sta_id, tid,
781                              buf_size, ssn);
782
783         /*
784          * Even though in theory the peer could have different
785          * aggregation reorder buffer sizes for different sessions,
786          * our ucode doesn't allow for that and has a global limit
787          * for each station. Therefore, use the minimum of all the
788          * aggregation sessions and our default value.
789          */
790         mvmsta->max_agg_bufsize =
791                 min(mvmsta->max_agg_bufsize, buf_size);
792         mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
793
794         if (mvm->cfg->ht_params->use_rts_for_aggregation) {
795                 /*
796                  * switch to RTS/CTS if it is the prefer protection
797                  * method for HT traffic
798                  */
799                 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
800                 /*
801                  * TODO: remove the TLC_RTS flag when we tear down the last
802                  * AGG session (agg_tids_count in DVM)
803                  */
804         }
805
806         IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
807                      sta->addr, tid);
808
809         return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
810 }
811
812 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
813                             struct ieee80211_sta *sta, u16 tid)
814 {
815         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
816         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
817         u16 txq_id;
818         int err;
819
820
821         /*
822          * If mac80211 is cleaning its state, then say that we finished since
823          * our state has been cleared anyway.
824          */
825         if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
826                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
827                 return 0;
828         }
829
830         spin_lock_bh(&mvmsta->lock);
831
832         txq_id = tid_data->txq_id;
833
834         IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
835                             mvmsta->sta_id, tid, txq_id, tid_data->state);
836
837         switch (tid_data->state) {
838         case IWL_AGG_ON:
839                 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
840
841                 IWL_DEBUG_TX_QUEUES(mvm,
842                                     "ssn = %d, next_recl = %d\n",
843                                     tid_data->ssn, tid_data->next_reclaimed);
844
845                 /* There are still packets for this RA / TID in the HW */
846                 if (tid_data->ssn != tid_data->next_reclaimed) {
847                         tid_data->state = IWL_EMPTYING_HW_QUEUE_DELBA;
848                         err = 0;
849                         break;
850                 }
851
852                 tid_data->ssn = 0xffff;
853                 iwl_trans_txq_disable(mvm->trans, txq_id);
854                 /* fall through */
855         case IWL_AGG_STARTING:
856         case IWL_EMPTYING_HW_QUEUE_ADDBA:
857                 /*
858                  * The agg session has been stopped before it was set up. This
859                  * can happen when the AddBA timer times out for example.
860                  */
861
862                 /* No barriers since we are under mutex */
863                 lockdep_assert_held(&mvm->mutex);
864                 mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE;
865
866                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
867                 tid_data->state = IWL_AGG_OFF;
868                 err = 0;
869                 break;
870         default:
871                 IWL_ERR(mvm,
872                         "Stopping AGG while state not ON or starting for %d on %d (%d)\n",
873                         mvmsta->sta_id, tid, tid_data->state);
874                 IWL_ERR(mvm,
875                         "\ttid_data->txq_id = %d\n", tid_data->txq_id);
876                 err = -EINVAL;
877         }
878
879         spin_unlock_bh(&mvmsta->lock);
880
881         return err;
882 }
883
884 int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
885                             struct ieee80211_sta *sta, u16 tid)
886 {
887         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
888         struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
889         u16 txq_id;
890
891         /*
892          * First set the agg state to OFF to avoid calling
893          * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
894          */
895         spin_lock_bh(&mvmsta->lock);
896         txq_id = tid_data->txq_id;
897         IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
898                             mvmsta->sta_id, tid, txq_id, tid_data->state);
899         tid_data->state = IWL_AGG_OFF;
900         spin_unlock_bh(&mvmsta->lock);
901
902         if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
903                 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
904
905         iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
906         mvm->queue_to_mac80211[tid_data->txq_id] =
907                                 IWL_INVALID_MAC80211_QUEUE;
908
909         return 0;
910 }
911
912 static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
913 {
914         int i;
915
916         lockdep_assert_held(&mvm->mutex);
917
918         i = find_first_zero_bit(mvm->fw_key_table, STA_KEY_MAX_NUM);
919
920         if (i == STA_KEY_MAX_NUM)
921                 return STA_KEY_IDX_INVALID;
922
923         __set_bit(i, mvm->fw_key_table);
924
925         return i;
926 }
927
928 static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
929                                  struct ieee80211_sta *sta)
930 {
931         struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
932
933         if (sta) {
934                 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
935
936                 return mvm_sta->sta_id;
937         }
938
939         /*
940          * The device expects GTKs for station interfaces to be
941          * installed as GTKs for the AP station. If we have no
942          * station ID, then use AP's station ID.
943          */
944         if (vif->type == NL80211_IFTYPE_STATION &&
945             mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
946                 return mvmvif->ap_sta_id;
947
948         return IWL_MVM_STATION_COUNT;
949 }
950
951 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
952                                 struct iwl_mvm_sta *mvm_sta,
953                                 struct ieee80211_key_conf *keyconf,
954                                 u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
955                                 u32 cmd_flags)
956 {
957         __le16 key_flags;
958         struct iwl_mvm_add_sta_cmd cmd = {};
959         int ret, status;
960         u16 keyidx;
961         int i;
962
963         keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
964                  STA_KEY_FLG_KEYID_MSK;
965         key_flags = cpu_to_le16(keyidx);
966         key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_KEY_MAP);
967
968         switch (keyconf->cipher) {
969         case WLAN_CIPHER_SUITE_TKIP:
970                 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
971                 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
972                 for (i = 0; i < 5; i++)
973                         cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
974                 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
975                 break;
976         case WLAN_CIPHER_SUITE_CCMP:
977                 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
978                 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
979                 break;
980         default:
981                 WARN_ON(1);
982                 return -EINVAL;
983         }
984
985         if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
986                 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
987
988         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
989         cmd.key.key_offset = keyconf->hw_key_idx;
990         cmd.key.key_flags = key_flags;
991         cmd.add_modify = STA_MODE_MODIFY;
992         cmd.modify_mask = STA_MODIFY_KEY;
993         cmd.sta_id = sta_id;
994
995         status = ADD_STA_SUCCESS;
996         if (cmd_flags == CMD_SYNC)
997                 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
998                                                   &cmd, &status);
999         else
1000                 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
1001                                            sizeof(cmd), &cmd);
1002
1003         switch (status) {
1004         case ADD_STA_SUCCESS:
1005                 IWL_DEBUG_WEP(mvm, "MODIFY_STA: set dynamic key passed\n");
1006                 break;
1007         default:
1008                 ret = -EIO;
1009                 IWL_ERR(mvm, "MODIFY_STA: set dynamic key failed\n");
1010                 break;
1011         }
1012
1013         return ret;
1014 }
1015
1016 static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
1017                                  struct ieee80211_key_conf *keyconf,
1018                                  u8 sta_id, bool remove_key)
1019 {
1020         struct iwl_mvm_mgmt_mcast_key_cmd igtk_cmd = {};
1021
1022         /* verify the key details match the required command's expectations */
1023         if (WARN_ON((keyconf->cipher != WLAN_CIPHER_SUITE_AES_CMAC) ||
1024                     (keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
1025                     (keyconf->keyidx != 4 && keyconf->keyidx != 5)))
1026                 return -EINVAL;
1027
1028         igtk_cmd.key_id = cpu_to_le32(keyconf->keyidx);
1029         igtk_cmd.sta_id = cpu_to_le32(sta_id);
1030
1031         if (remove_key) {
1032                 igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
1033         } else {
1034                 struct ieee80211_key_seq seq;
1035                 const u8 *pn;
1036
1037                 memcpy(igtk_cmd.IGTK, keyconf->key, keyconf->keylen);
1038                 ieee80211_aes_cmac_calculate_k1_k2(keyconf,
1039                                                    igtk_cmd.K1, igtk_cmd.K2);
1040                 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1041                 pn = seq.aes_cmac.pn;
1042                 igtk_cmd.receive_seq_cnt = cpu_to_le64(((u64) pn[5] << 0) |
1043                                                        ((u64) pn[4] << 8) |
1044                                                        ((u64) pn[3] << 16) |
1045                                                        ((u64) pn[2] << 24) |
1046                                                        ((u64) pn[1] << 32) |
1047                                                        ((u64) pn[0] << 40));
1048         }
1049
1050         IWL_DEBUG_INFO(mvm, "%s igtk for sta %u\n",
1051                        remove_key ? "removing" : "installing",
1052                        igtk_cmd.sta_id);
1053
1054         return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, CMD_SYNC,
1055                                     sizeof(igtk_cmd), &igtk_cmd);
1056 }
1057
1058
1059 static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
1060                                        struct ieee80211_vif *vif,
1061                                        struct ieee80211_sta *sta)
1062 {
1063         struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
1064
1065         if (sta)
1066                 return sta->addr;
1067
1068         if (vif->type == NL80211_IFTYPE_STATION &&
1069             mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
1070                 u8 sta_id = mvmvif->ap_sta_id;
1071                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1072                                                 lockdep_is_held(&mvm->mutex));
1073                 return sta->addr;
1074         }
1075
1076
1077         return NULL;
1078 }
1079
1080 int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1081                         struct ieee80211_vif *vif,
1082                         struct ieee80211_sta *sta,
1083                         struct ieee80211_key_conf *keyconf,
1084                         bool have_key_offset)
1085 {
1086         struct iwl_mvm_sta *mvm_sta;
1087         int ret;
1088         u8 *addr, sta_id;
1089         struct ieee80211_key_seq seq;
1090         u16 p1k[5];
1091
1092         lockdep_assert_held(&mvm->mutex);
1093
1094         /* Get the station id from the mvm local station table */
1095         sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1096         if (sta_id == IWL_MVM_STATION_COUNT) {
1097                 IWL_ERR(mvm, "Failed to find station id\n");
1098                 return -EINVAL;
1099         }
1100
1101         if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
1102                 ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
1103                 goto end;
1104         }
1105
1106         /*
1107          * It is possible that the 'sta' parameter is NULL, and thus
1108          * there is a need to retrieve  the sta from the local station table.
1109          */
1110         if (!sta) {
1111                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1112                                                 lockdep_is_held(&mvm->mutex));
1113                 if (IS_ERR_OR_NULL(sta)) {
1114                         IWL_ERR(mvm, "Invalid station id\n");
1115                         return -EINVAL;
1116                 }
1117         }
1118
1119         mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1120         if (WARN_ON_ONCE(mvm_sta->vif != vif))
1121                 return -EINVAL;
1122
1123         if (!have_key_offset) {
1124                 /*
1125                  * The D3 firmware hardcodes the PTK offset to 0, so we have to
1126                  * configure it there. As a result, this workaround exists to
1127                  * let the caller set the key offset (hw_key_idx), see d3.c.
1128                  */
1129                 keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm);
1130                 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1131                         return -ENOSPC;
1132         }
1133
1134         switch (keyconf->cipher) {
1135         case WLAN_CIPHER_SUITE_TKIP:
1136                 addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
1137                 /* get phase 1 key from mac80211 */
1138                 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1139                 ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
1140                 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1141                                            seq.tkip.iv32, p1k, CMD_SYNC);
1142                 break;
1143         case WLAN_CIPHER_SUITE_CCMP:
1144                 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1145                                            0, NULL, CMD_SYNC);
1146                 break;
1147         default:
1148                 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher);
1149                 ret = -EINVAL;
1150         }
1151
1152         if (ret)
1153                 __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1154
1155 end:
1156         IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
1157                       keyconf->cipher, keyconf->keylen, keyconf->keyidx,
1158                       sta->addr, ret);
1159         return ret;
1160 }
1161
1162 int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1163                            struct ieee80211_vif *vif,
1164                            struct ieee80211_sta *sta,
1165                            struct ieee80211_key_conf *keyconf)
1166 {
1167         struct iwl_mvm_sta *mvm_sta;
1168         struct iwl_mvm_add_sta_cmd cmd = {};
1169         __le16 key_flags;
1170         int ret, status;
1171         u8 sta_id;
1172
1173         lockdep_assert_held(&mvm->mutex);
1174
1175         /* Get the station id from the mvm local station table */
1176         sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1177
1178         IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
1179                       keyconf->keyidx, sta_id);
1180
1181         if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1182                 return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
1183
1184         ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1185         if (!ret) {
1186                 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
1187                         keyconf->hw_key_idx);
1188                 return -ENOENT;
1189         }
1190
1191         if (sta_id == IWL_MVM_STATION_COUNT) {
1192                 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1193                 return 0;
1194         }
1195
1196         /*
1197          * It is possible that the 'sta' parameter is NULL, and thus
1198          * there is a need to retrieve the sta from the local station table,
1199          * for example when a GTK is removed (where the sta_id will then be
1200          * the AP ID, and no station was passed by mac80211.)
1201          */
1202         if (!sta) {
1203                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1204                                                 lockdep_is_held(&mvm->mutex));
1205                 if (!sta) {
1206                         IWL_ERR(mvm, "Invalid station id\n");
1207                         return -EINVAL;
1208                 }
1209         }
1210
1211         mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1212         if (WARN_ON_ONCE(mvm_sta->vif != vif))
1213                 return -EINVAL;
1214
1215         key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
1216                                  STA_KEY_FLG_KEYID_MSK);
1217         key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
1218         key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
1219
1220         if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1221                 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1222
1223         cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
1224         cmd.key.key_flags = key_flags;
1225         cmd.key.key_offset = keyconf->hw_key_idx;
1226         cmd.sta_id = sta_id;
1227
1228         cmd.modify_mask = STA_MODIFY_KEY;
1229         cmd.add_modify = STA_MODE_MODIFY;
1230
1231         status = ADD_STA_SUCCESS;
1232         ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
1233                                           &cmd, &status);
1234
1235         switch (status) {
1236         case ADD_STA_SUCCESS:
1237                 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
1238                 break;
1239         default:
1240                 ret = -EIO;
1241                 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
1242                 break;
1243         }
1244
1245         return ret;
1246 }
1247
1248 void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1249                              struct ieee80211_vif *vif,
1250                              struct ieee80211_key_conf *keyconf,
1251                              struct ieee80211_sta *sta, u32 iv32,
1252                              u16 *phase1key)
1253 {
1254         struct iwl_mvm_sta *mvm_sta;
1255         u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1256
1257         if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
1258                 return;
1259
1260         rcu_read_lock();
1261
1262         if (!sta) {
1263                 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
1264                 if (WARN_ON(IS_ERR_OR_NULL(sta))) {
1265                         rcu_read_unlock();
1266                         return;
1267                 }
1268         }
1269
1270         mvm_sta = (void *)sta->drv_priv;
1271         iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1272                              iv32, phase1key, CMD_ASYNC);
1273         rcu_read_unlock();
1274 }
1275
1276 void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1277                                 struct ieee80211_sta *sta)
1278 {
1279         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1280         struct iwl_mvm_add_sta_cmd cmd = {
1281                 .add_modify = STA_MODE_MODIFY,
1282                 .sta_id = mvmsta->sta_id,
1283                 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1284                 .sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
1285                 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1286         };
1287         int ret;
1288
1289         /*
1290          * Same modify mask for sleep_tx_count and sleep_state_flags but this
1291          * should be fine since if we set the STA as "awake", then
1292          * sleep_tx_count is not relevant.
1293          */
1294         ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1295         if (ret)
1296                 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1297 }
1298
1299 void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1300                                        struct ieee80211_sta *sta,
1301                                        enum ieee80211_frame_release_type reason,
1302                                        u16 cnt)
1303 {
1304         u16 sleep_state_flags =
1305                 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1306                         STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1307         struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1308         struct iwl_mvm_add_sta_cmd cmd = {
1309                 .add_modify = STA_MODE_MODIFY,
1310                 .sta_id = mvmsta->sta_id,
1311                 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1312                 .sleep_tx_count = cpu_to_le16(cnt),
1313                 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1314                 /*
1315                  * Same modify mask for sleep_tx_count and sleep_state_flags so
1316                  * we must set the sleep_state_flags too.
1317                  */
1318                 .sleep_state_flags = cpu_to_le16(sleep_state_flags),
1319         };
1320         int ret;
1321
1322         /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1323         ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1324         if (ret)
1325                 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1326 }