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