47c9da3834ea0157ef8a9d040b411f1e9d0fa862
[linux-flexiantxendom0-3.2.10.git] / drivers / net / wireless / iwlegacy / iwl-sta.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4  *
5  * Portions of this file are derived from the ipw3945 project, as well
6  * as portions of the ieee80211 subsystem header files.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of version 2 of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20  *
21  * The full GNU General Public License is included in this distribution in the
22  * file called LICENSE.
23  *
24  * Contact Information:
25  *  Intel Linux Wireless <ilw@linux.intel.com>
26  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27  *
28  *****************************************************************************/
29
30 #include <net/mac80211.h>
31 #include <linux/etherdevice.h>
32 #include <linux/sched.h>
33 #include <linux/lockdep.h>
34
35 #include "iwl-dev.h"
36 #include "iwl-core.h"
37 #include "iwl-sta.h"
38
39 /* priv->sta_lock must be held */
40 static void iwl_legacy_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
41 {
42
43         if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
44                 IWL_ERR(priv,
45                         "ACTIVATE a non DRIVER active station id %u addr %pM\n",
46                         sta_id, priv->stations[sta_id].sta.sta.addr);
47
48         if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
49                 IWL_DEBUG_ASSOC(priv,
50                         "STA id %u addr %pM already present"
51                         " in uCode (according to driver)\n",
52                         sta_id, priv->stations[sta_id].sta.sta.addr);
53         } else {
54                 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
55                 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
56                                 sta_id, priv->stations[sta_id].sta.sta.addr);
57         }
58 }
59
60 static int iwl_legacy_process_add_sta_resp(struct iwl_priv *priv,
61                                     struct iwl_legacy_addsta_cmd *addsta,
62                                     struct iwl_rx_packet *pkt,
63                                     bool sync)
64 {
65         u8 sta_id = addsta->sta.sta_id;
66         unsigned long flags;
67         int ret = -EIO;
68
69         if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
70                 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
71                         pkt->hdr.flags);
72                 return ret;
73         }
74
75         IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
76                        sta_id);
77
78         spin_lock_irqsave(&priv->sta_lock, flags);
79
80         switch (pkt->u.add_sta.status) {
81         case ADD_STA_SUCCESS_MSK:
82                 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
83                 iwl_legacy_sta_ucode_activate(priv, sta_id);
84                 ret = 0;
85                 break;
86         case ADD_STA_NO_ROOM_IN_TABLE:
87                 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
88                         sta_id);
89                 break;
90         case ADD_STA_NO_BLOCK_ACK_RESOURCE:
91                 IWL_ERR(priv,
92                         "Adding station %d failed, no block ack resource.\n",
93                         sta_id);
94                 break;
95         case ADD_STA_MODIFY_NON_EXIST_STA:
96                 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
97                         sta_id);
98                 break;
99         default:
100                 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
101                                 pkt->u.add_sta.status);
102                 break;
103         }
104
105         IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
106                        priv->stations[sta_id].sta.mode ==
107                        STA_CONTROL_MODIFY_MSK ?  "Modified" : "Added",
108                        sta_id, priv->stations[sta_id].sta.sta.addr);
109
110         /*
111          * XXX: The MAC address in the command buffer is often changed from
112          * the original sent to the device. That is, the MAC address
113          * written to the command buffer often is not the same MAC adress
114          * read from the command buffer when the command returns. This
115          * issue has not yet been resolved and this debugging is left to
116          * observe the problem.
117          */
118         IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
119                        priv->stations[sta_id].sta.mode ==
120                        STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
121                        addsta->sta.addr);
122         spin_unlock_irqrestore(&priv->sta_lock, flags);
123
124         return ret;
125 }
126
127 static void iwl_legacy_add_sta_callback(struct iwl_priv *priv,
128                                  struct iwl_device_cmd *cmd,
129                                  struct iwl_rx_packet *pkt)
130 {
131         struct iwl_legacy_addsta_cmd *addsta =
132                 (struct iwl_legacy_addsta_cmd *)cmd->cmd.payload;
133
134         iwl_legacy_process_add_sta_resp(priv, addsta, pkt, false);
135
136 }
137
138 int iwl_legacy_send_add_sta(struct iwl_priv *priv,
139                      struct iwl_legacy_addsta_cmd *sta, u8 flags)
140 {
141         struct iwl_rx_packet *pkt = NULL;
142         int ret = 0;
143         u8 data[sizeof(*sta)];
144         struct iwl_host_cmd cmd = {
145                 .id = REPLY_ADD_STA,
146                 .flags = flags,
147                 .data = data,
148         };
149         u8 sta_id __maybe_unused = sta->sta.sta_id;
150
151         IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
152                        sta_id, sta->sta.addr, flags & CMD_ASYNC ?  "a" : "");
153
154         if (flags & CMD_ASYNC)
155                 cmd.callback = iwl_legacy_add_sta_callback;
156         else {
157                 cmd.flags |= CMD_WANT_SKB;
158                 might_sleep();
159         }
160
161         cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
162         ret = iwl_legacy_send_cmd(priv, &cmd);
163
164         if (ret || (flags & CMD_ASYNC))
165                 return ret;
166
167         if (ret == 0) {
168                 pkt = (struct iwl_rx_packet *)cmd.reply_page;
169                 ret = iwl_legacy_process_add_sta_resp(priv, sta, pkt, true);
170         }
171         iwl_legacy_free_pages(priv, cmd.reply_page);
172
173         return ret;
174 }
175 EXPORT_SYMBOL(iwl_legacy_send_add_sta);
176
177 static void iwl_legacy_set_ht_add_station(struct iwl_priv *priv, u8 index,
178                                    struct ieee80211_sta *sta,
179                                    struct iwl_rxon_context *ctx)
180 {
181         struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
182         __le32 sta_flags;
183         u8 mimo_ps_mode;
184
185         if (!sta || !sta_ht_inf->ht_supported)
186                 goto done;
187
188         mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
189         IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
190                         (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
191                         "static" :
192                         (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
193                         "dynamic" : "disabled");
194
195         sta_flags = priv->stations[index].sta.station_flags;
196
197         sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
198
199         switch (mimo_ps_mode) {
200         case WLAN_HT_CAP_SM_PS_STATIC:
201                 sta_flags |= STA_FLG_MIMO_DIS_MSK;
202                 break;
203         case WLAN_HT_CAP_SM_PS_DYNAMIC:
204                 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
205                 break;
206         case WLAN_HT_CAP_SM_PS_DISABLED:
207                 break;
208         default:
209                 IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
210                 break;
211         }
212
213         sta_flags |= cpu_to_le32(
214               (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
215
216         sta_flags |= cpu_to_le32(
217               (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
218
219         if (iwl_legacy_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
220                 sta_flags |= STA_FLG_HT40_EN_MSK;
221         else
222                 sta_flags &= ~STA_FLG_HT40_EN_MSK;
223
224         priv->stations[index].sta.station_flags = sta_flags;
225  done:
226         return;
227 }
228
229 /**
230  * iwl_legacy_prep_station - Prepare station information for addition
231  *
232  * should be called with sta_lock held
233  */
234 u8 iwl_legacy_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
235                     const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
236 {
237         struct iwl_station_entry *station;
238         int i;
239         u8 sta_id = IWL_INVALID_STATION;
240         u16 rate;
241
242         if (is_ap)
243                 sta_id = ctx->ap_sta_id;
244         else if (is_broadcast_ether_addr(addr))
245                 sta_id = ctx->bcast_sta_id;
246         else
247                 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
248                         if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
249                                                 addr)) {
250                                 sta_id = i;
251                                 break;
252                         }
253
254                         if (!priv->stations[i].used &&
255                             sta_id == IWL_INVALID_STATION)
256                                 sta_id = i;
257                 }
258
259         /*
260          * These two conditions have the same outcome, but keep them
261          * separate
262          */
263         if (unlikely(sta_id == IWL_INVALID_STATION))
264                 return sta_id;
265
266         /*
267          * uCode is not able to deal with multiple requests to add a
268          * station. Keep track if one is in progress so that we do not send
269          * another.
270          */
271         if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
272                 IWL_DEBUG_INFO(priv,
273                                 "STA %d already in process of being added.\n",
274                                 sta_id);
275                 return sta_id;
276         }
277
278         if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
279             (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
280             !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
281                 IWL_DEBUG_ASSOC(priv,
282                                 "STA %d (%pM) already added, not adding again.\n",
283                                 sta_id, addr);
284                 return sta_id;
285         }
286
287         station = &priv->stations[sta_id];
288         station->used = IWL_STA_DRIVER_ACTIVE;
289         IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
290                         sta_id, addr);
291         priv->num_stations++;
292
293         /* Set up the REPLY_ADD_STA command to send to device */
294         memset(&station->sta, 0, sizeof(struct iwl_legacy_addsta_cmd));
295         memcpy(station->sta.sta.addr, addr, ETH_ALEN);
296         station->sta.mode = 0;
297         station->sta.sta.sta_id = sta_id;
298         station->sta.station_flags = ctx->station_flags;
299         station->ctxid = ctx->ctxid;
300
301         if (sta) {
302                 struct iwl_station_priv_common *sta_priv;
303
304                 sta_priv = (void *)sta->drv_priv;
305                 sta_priv->ctx = ctx;
306         }
307
308         /*
309          * OK to call unconditionally, since local stations (IBSS BSSID
310          * STA and broadcast STA) pass in a NULL sta, and mac80211
311          * doesn't allow HT IBSS.
312          */
313         iwl_legacy_set_ht_add_station(priv, sta_id, sta, ctx);
314
315         /* 3945 only */
316         rate = (priv->band == IEEE80211_BAND_5GHZ) ?
317                 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
318         /* Turn on both antennas for the station... */
319         station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
320
321         return sta_id;
322
323 }
324 EXPORT_SYMBOL_GPL(iwl_legacy_prep_station);
325
326 #define STA_WAIT_TIMEOUT (HZ/2)
327
328 /**
329  * iwl_legacy_add_station_common -
330  */
331 int
332 iwl_legacy_add_station_common(struct iwl_priv *priv,
333                         struct iwl_rxon_context *ctx,
334                            const u8 *addr, bool is_ap,
335                            struct ieee80211_sta *sta, u8 *sta_id_r)
336 {
337         unsigned long flags_spin;
338         int ret = 0;
339         u8 sta_id;
340         struct iwl_legacy_addsta_cmd sta_cmd;
341
342         *sta_id_r = 0;
343         spin_lock_irqsave(&priv->sta_lock, flags_spin);
344         sta_id = iwl_legacy_prep_station(priv, ctx, addr, is_ap, sta);
345         if (sta_id == IWL_INVALID_STATION) {
346                 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
347                         addr);
348                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
349                 return -EINVAL;
350         }
351
352         /*
353          * uCode is not able to deal with multiple requests to add a
354          * station. Keep track if one is in progress so that we do not send
355          * another.
356          */
357         if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
358                 IWL_DEBUG_INFO(priv,
359                         "STA %d already in process of being added.\n",
360                        sta_id);
361                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
362                 return -EEXIST;
363         }
364
365         if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
366             (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
367                 IWL_DEBUG_ASSOC(priv,
368                         "STA %d (%pM) already added, not adding again.\n",
369                         sta_id, addr);
370                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
371                 return -EEXIST;
372         }
373
374         priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
375         memcpy(&sta_cmd, &priv->stations[sta_id].sta,
376                                 sizeof(struct iwl_legacy_addsta_cmd));
377         spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
378
379         /* Add station to device's station table */
380         ret = iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC);
381         if (ret) {
382                 spin_lock_irqsave(&priv->sta_lock, flags_spin);
383                 IWL_ERR(priv, "Adding station %pM failed.\n",
384                         priv->stations[sta_id].sta.sta.addr);
385                 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
386                 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
387                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
388         }
389         *sta_id_r = sta_id;
390         return ret;
391 }
392 EXPORT_SYMBOL(iwl_legacy_add_station_common);
393
394 /**
395  * iwl_legacy_sta_ucode_deactivate - deactivate ucode status for a station
396  *
397  * priv->sta_lock must be held
398  */
399 static void iwl_legacy_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
400 {
401         /* Ucode must be active and driver must be non active */
402         if ((priv->stations[sta_id].used &
403              (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) !=
404                                                 IWL_STA_UCODE_ACTIVE)
405                 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
406
407         priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
408
409         memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
410         IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
411 }
412
413 static int iwl_legacy_send_remove_station(struct iwl_priv *priv,
414                                    const u8 *addr, int sta_id,
415                                    bool temporary)
416 {
417         struct iwl_rx_packet *pkt;
418         int ret;
419
420         unsigned long flags_spin;
421         struct iwl_rem_sta_cmd rm_sta_cmd;
422
423         struct iwl_host_cmd cmd = {
424                 .id = REPLY_REMOVE_STA,
425                 .len = sizeof(struct iwl_rem_sta_cmd),
426                 .flags = CMD_SYNC,
427                 .data = &rm_sta_cmd,
428         };
429
430         memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
431         rm_sta_cmd.num_sta = 1;
432         memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
433
434         cmd.flags |= CMD_WANT_SKB;
435
436         ret = iwl_legacy_send_cmd(priv, &cmd);
437
438         if (ret)
439                 return ret;
440
441         pkt = (struct iwl_rx_packet *)cmd.reply_page;
442         if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
443                 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
444                           pkt->hdr.flags);
445                 ret = -EIO;
446         }
447
448         if (!ret) {
449                 switch (pkt->u.rem_sta.status) {
450                 case REM_STA_SUCCESS_MSK:
451                         if (!temporary) {
452                                 spin_lock_irqsave(&priv->sta_lock, flags_spin);
453                                 iwl_legacy_sta_ucode_deactivate(priv, sta_id);
454                                 spin_unlock_irqrestore(&priv->sta_lock,
455                                                                 flags_spin);
456                         }
457                         IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
458                         break;
459                 default:
460                         ret = -EIO;
461                         IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
462                         break;
463                 }
464         }
465         iwl_legacy_free_pages(priv, cmd.reply_page);
466
467         return ret;
468 }
469
470 /**
471  * iwl_legacy_remove_station - Remove driver's knowledge of station.
472  */
473 int iwl_legacy_remove_station(struct iwl_priv *priv, const u8 sta_id,
474                        const u8 *addr)
475 {
476         unsigned long flags;
477
478         if (!iwl_legacy_is_ready(priv)) {
479                 IWL_DEBUG_INFO(priv,
480                         "Unable to remove station %pM, device not ready.\n",
481                         addr);
482                 /*
483                  * It is typical for stations to be removed when we are
484                  * going down. Return success since device will be down
485                  * soon anyway
486                  */
487                 return 0;
488         }
489
490         IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d  %pM\n",
491                         sta_id, addr);
492
493         if (WARN_ON(sta_id == IWL_INVALID_STATION))
494                 return -EINVAL;
495
496         spin_lock_irqsave(&priv->sta_lock, flags);
497
498         if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
499                 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
500                                 addr);
501                 goto out_err;
502         }
503
504         if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
505                 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
506                                 addr);
507                 goto out_err;
508         }
509
510         if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
511                 kfree(priv->stations[sta_id].lq);
512                 priv->stations[sta_id].lq = NULL;
513         }
514
515         priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
516
517         priv->num_stations--;
518
519         BUG_ON(priv->num_stations < 0);
520
521         spin_unlock_irqrestore(&priv->sta_lock, flags);
522
523         return iwl_legacy_send_remove_station(priv, addr, sta_id, false);
524 out_err:
525         spin_unlock_irqrestore(&priv->sta_lock, flags);
526         return -EINVAL;
527 }
528 EXPORT_SYMBOL_GPL(iwl_legacy_remove_station);
529
530 /**
531  * iwl_legacy_clear_ucode_stations - clear ucode station table bits
532  *
533  * This function clears all the bits in the driver indicating
534  * which stations are active in the ucode. Call when something
535  * other than explicit station management would cause this in
536  * the ucode, e.g. unassociated RXON.
537  */
538 void iwl_legacy_clear_ucode_stations(struct iwl_priv *priv,
539                               struct iwl_rxon_context *ctx)
540 {
541         int i;
542         unsigned long flags_spin;
543         bool cleared = false;
544
545         IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
546
547         spin_lock_irqsave(&priv->sta_lock, flags_spin);
548         for (i = 0; i < priv->hw_params.max_stations; i++) {
549                 if (ctx && ctx->ctxid != priv->stations[i].ctxid)
550                         continue;
551
552                 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
553                         IWL_DEBUG_INFO(priv,
554                                 "Clearing ucode active for station %d\n", i);
555                         priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
556                         cleared = true;
557                 }
558         }
559         spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
560
561         if (!cleared)
562                 IWL_DEBUG_INFO(priv,
563                         "No active stations found to be cleared\n");
564 }
565 EXPORT_SYMBOL(iwl_legacy_clear_ucode_stations);
566
567 /**
568  * iwl_legacy_restore_stations() - Restore driver known stations to device
569  *
570  * All stations considered active by driver, but not present in ucode, is
571  * restored.
572  *
573  * Function sleeps.
574  */
575 void
576 iwl_legacy_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
577 {
578         struct iwl_legacy_addsta_cmd sta_cmd;
579         struct iwl_link_quality_cmd lq;
580         unsigned long flags_spin;
581         int i;
582         bool found = false;
583         int ret;
584         bool send_lq;
585
586         if (!iwl_legacy_is_ready(priv)) {
587                 IWL_DEBUG_INFO(priv,
588                         "Not ready yet, not restoring any stations.\n");
589                 return;
590         }
591
592         IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
593         spin_lock_irqsave(&priv->sta_lock, flags_spin);
594         for (i = 0; i < priv->hw_params.max_stations; i++) {
595                 if (ctx->ctxid != priv->stations[i].ctxid)
596                         continue;
597                 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
598                             !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
599                         IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
600                                         priv->stations[i].sta.sta.addr);
601                         priv->stations[i].sta.mode = 0;
602                         priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
603                         found = true;
604                 }
605         }
606
607         for (i = 0; i < priv->hw_params.max_stations; i++) {
608                 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
609                         memcpy(&sta_cmd, &priv->stations[i].sta,
610                                sizeof(struct iwl_legacy_addsta_cmd));
611                         send_lq = false;
612                         if (priv->stations[i].lq) {
613                                 memcpy(&lq, priv->stations[i].lq,
614                                        sizeof(struct iwl_link_quality_cmd));
615                                 send_lq = true;
616                         }
617                         spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
618                         ret = iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC);
619                         if (ret) {
620                                 spin_lock_irqsave(&priv->sta_lock, flags_spin);
621                                 IWL_ERR(priv, "Adding station %pM failed.\n",
622                                         priv->stations[i].sta.sta.addr);
623                                 priv->stations[i].used &=
624                                                 ~IWL_STA_DRIVER_ACTIVE;
625                                 priv->stations[i].used &=
626                                                 ~IWL_STA_UCODE_INPROGRESS;
627                                 spin_unlock_irqrestore(&priv->sta_lock,
628                                                                 flags_spin);
629                         }
630                         /*
631                          * Rate scaling has already been initialized, send
632                          * current LQ command
633                          */
634                         if (send_lq)
635                                 iwl_legacy_send_lq_cmd(priv, ctx, &lq,
636                                                                 CMD_SYNC, true);
637                         spin_lock_irqsave(&priv->sta_lock, flags_spin);
638                         priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
639                 }
640         }
641
642         spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
643         if (!found)
644                 IWL_DEBUG_INFO(priv, "Restoring all known stations"
645                                 " .... no stations to be restored.\n");
646         else
647                 IWL_DEBUG_INFO(priv, "Restoring all known stations"
648                                 " .... complete.\n");
649 }
650 EXPORT_SYMBOL(iwl_legacy_restore_stations);
651
652 int iwl_legacy_get_free_ucode_key_index(struct iwl_priv *priv)
653 {
654         int i;
655
656         for (i = 0; i < priv->sta_key_max_num; i++)
657                 if (!test_and_set_bit(i, &priv->ucode_key_table))
658                         return i;
659
660         return WEP_INVALID_OFFSET;
661 }
662 EXPORT_SYMBOL(iwl_legacy_get_free_ucode_key_index);
663
664 void iwl_legacy_dealloc_bcast_stations(struct iwl_priv *priv)
665 {
666         unsigned long flags;
667         int i;
668
669         spin_lock_irqsave(&priv->sta_lock, flags);
670         for (i = 0; i < priv->hw_params.max_stations; i++) {
671                 if (!(priv->stations[i].used & IWL_STA_BCAST))
672                         continue;
673
674                 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
675                 priv->num_stations--;
676                 BUG_ON(priv->num_stations < 0);
677                 kfree(priv->stations[i].lq);
678                 priv->stations[i].lq = NULL;
679         }
680         spin_unlock_irqrestore(&priv->sta_lock, flags);
681 }
682 EXPORT_SYMBOL_GPL(iwl_legacy_dealloc_bcast_stations);
683
684 #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
685 static void iwl_legacy_dump_lq_cmd(struct iwl_priv *priv,
686                            struct iwl_link_quality_cmd *lq)
687 {
688         int i;
689         IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
690         IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
691                        lq->general_params.single_stream_ant_msk,
692                        lq->general_params.dual_stream_ant_msk);
693
694         for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
695                 IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
696                                i, lq->rs_table[i].rate_n_flags);
697 }
698 #else
699 static inline void iwl_legacy_dump_lq_cmd(struct iwl_priv *priv,
700                                    struct iwl_link_quality_cmd *lq)
701 {
702 }
703 #endif
704
705 /**
706  * iwl_legacy_is_lq_table_valid() - Test one aspect of LQ cmd for validity
707  *
708  * It sometimes happens when a HT rate has been in use and we
709  * loose connectivity with AP then mac80211 will first tell us that the
710  * current channel is not HT anymore before removing the station. In such a
711  * scenario the RXON flags will be updated to indicate we are not
712  * communicating HT anymore, but the LQ command may still contain HT rates.
713  * Test for this to prevent driver from sending LQ command between the time
714  * RXON flags are updated and when LQ command is updated.
715  */
716 static bool iwl_legacy_is_lq_table_valid(struct iwl_priv *priv,
717                               struct iwl_rxon_context *ctx,
718                               struct iwl_link_quality_cmd *lq)
719 {
720         int i;
721
722         if (ctx->ht.enabled)
723                 return true;
724
725         IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
726                        ctx->active.channel);
727         for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
728                 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) &
729                                                 RATE_MCS_HT_MSK) {
730                         IWL_DEBUG_INFO(priv,
731                                        "index %d of LQ expects HT channel\n",
732                                        i);
733                         return false;
734                 }
735         }
736         return true;
737 }
738
739 /**
740  * iwl_legacy_send_lq_cmd() - Send link quality command
741  * @init: This command is sent as part of station initialization right
742  *        after station has been added.
743  *
744  * The link quality command is sent as the last step of station creation.
745  * This is the special case in which init is set and we call a callback in
746  * this case to clear the state indicating that station creation is in
747  * progress.
748  */
749 int iwl_legacy_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
750                     struct iwl_link_quality_cmd *lq, u8 flags, bool init)
751 {
752         int ret = 0;
753         unsigned long flags_spin;
754
755         struct iwl_host_cmd cmd = {
756                 .id = REPLY_TX_LINK_QUALITY_CMD,
757                 .len = sizeof(struct iwl_link_quality_cmd),
758                 .flags = flags,
759                 .data = lq,
760         };
761
762         if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
763                 return -EINVAL;
764
765
766         spin_lock_irqsave(&priv->sta_lock, flags_spin);
767         if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
768                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
769                 return -EINVAL;
770         }
771         spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
772
773         iwl_legacy_dump_lq_cmd(priv, lq);
774         BUG_ON(init && (cmd.flags & CMD_ASYNC));
775
776         if (iwl_legacy_is_lq_table_valid(priv, ctx, lq))
777                 ret = iwl_legacy_send_cmd(priv, &cmd);
778         else
779                 ret = -EINVAL;
780
781         if (cmd.flags & CMD_ASYNC)
782                 return ret;
783
784         if (init) {
785                 IWL_DEBUG_INFO(priv, "init LQ command complete,"
786                                 " clearing sta addition status for sta %d\n",
787                                lq->sta_id);
788                 spin_lock_irqsave(&priv->sta_lock, flags_spin);
789                 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
790                 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
791         }
792         return ret;
793 }
794 EXPORT_SYMBOL(iwl_legacy_send_lq_cmd);
795
796 int iwl_legacy_mac_sta_remove(struct ieee80211_hw *hw,
797                        struct ieee80211_vif *vif,
798                        struct ieee80211_sta *sta)
799 {
800         struct iwl_priv *priv = hw->priv;
801         struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
802         int ret;
803
804         IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
805                         sta->addr);
806         mutex_lock(&priv->mutex);
807         IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
808                         sta->addr);
809         ret = iwl_legacy_remove_station(priv, sta_common->sta_id, sta->addr);
810         if (ret)
811                 IWL_ERR(priv, "Error removing station %pM\n",
812                         sta->addr);
813         mutex_unlock(&priv->mutex);
814         return ret;
815 }
816 EXPORT_SYMBOL(iwl_legacy_mac_sta_remove);