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