iwlagn: add debug for mac80211 callback
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / wireless / iwlwifi / iwl-sta.c
blob07b72f2a21aaab384edcfa10e93bfc888f98f82e
1 /******************************************************************************
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
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.
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.
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
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
28 *****************************************************************************/
30 #include <net/mac80211.h>
31 #include <linux/etherdevice.h>
32 #include <linux/sched.h>
33 #include <linux/lockdep.h>
35 #include "iwl-dev.h"
36 #include "iwl-core.h"
37 #include "iwl-sta.h"
38 #include "iwl-trans.h"
39 #include "iwl-agn.h"
41 /* priv->shrd->sta_lock must be held */
42 static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
45 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
46 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
47 sta_id, priv->stations[sta_id].sta.sta.addr);
49 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
50 IWL_DEBUG_ASSOC(priv,
51 "STA id %u addr %pM already present 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);
60 static int iwl_process_add_sta_resp(struct iwl_priv *priv,
61 struct iwl_addsta_cmd *addsta,
62 struct iwl_rx_packet *pkt)
64 u8 sta_id = addsta->sta.sta_id;
65 unsigned long flags;
66 int ret = -EIO;
68 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
69 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
70 pkt->hdr.flags);
71 return ret;
74 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
75 sta_id);
77 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
79 switch (pkt->u.add_sta.status) {
80 case ADD_STA_SUCCESS_MSK:
81 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
82 iwl_sta_ucode_activate(priv, sta_id);
83 ret = 0;
84 break;
85 case ADD_STA_NO_ROOM_IN_TABLE:
86 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
87 sta_id);
88 break;
89 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
90 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
91 sta_id);
92 break;
93 case ADD_STA_MODIFY_NON_EXIST_STA:
94 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
95 sta_id);
96 break;
97 default:
98 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
99 pkt->u.add_sta.status);
100 break;
103 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
104 priv->stations[sta_id].sta.mode ==
105 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
106 sta_id, priv->stations[sta_id].sta.sta.addr);
109 * XXX: The MAC address in the command buffer is often changed from
110 * the original sent to the device. That is, the MAC address
111 * written to the command buffer often is not the same MAC address
112 * read from the command buffer when the command returns. This
113 * issue has not yet been resolved and this debugging is left to
114 * observe the problem.
116 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
117 priv->stations[sta_id].sta.mode ==
118 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
119 addsta->sta.addr);
120 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
122 return ret;
125 int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
126 struct iwl_device_cmd *cmd)
128 struct iwl_rx_packet *pkt = rxb_addr(rxb);
129 struct iwl_addsta_cmd *addsta =
130 (struct iwl_addsta_cmd *) cmd->payload;
132 return iwl_process_add_sta_resp(priv, addsta, pkt);
135 static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
137 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
138 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
139 memcpy(addsta, cmd, size);
140 /* resrved in 5000 */
141 addsta->rate_n_flags = cpu_to_le16(0);
142 return size;
145 int iwl_send_add_sta(struct iwl_priv *priv,
146 struct iwl_addsta_cmd *sta, u8 flags)
148 int ret = 0;
149 u8 data[sizeof(*sta)];
150 struct iwl_host_cmd cmd = {
151 .id = REPLY_ADD_STA,
152 .flags = flags,
153 .data = { data, },
155 u8 sta_id __maybe_unused = sta->sta.sta_id;
157 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
158 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
160 if (!(flags & CMD_ASYNC)) {
161 cmd.flags |= CMD_WANT_SKB;
162 might_sleep();
165 cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data);
166 ret = iwl_trans_send_cmd(trans(priv), &cmd);
168 if (ret || (flags & CMD_ASYNC))
169 return ret;
170 /*else the command was successfully sent in SYNC mode, need to free
171 * the reply page */
173 iwl_free_pages(priv->shrd, cmd.reply_page);
175 if (cmd.handler_status)
176 IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
177 cmd.handler_status);
179 return cmd.handler_status;
182 static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
183 struct ieee80211_sta *sta,
184 struct iwl_rxon_context *ctx)
186 struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
187 __le32 sta_flags;
188 u8 mimo_ps_mode;
190 if (!sta || !sta_ht_inf->ht_supported)
191 goto done;
193 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
194 IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
195 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
196 "static" :
197 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
198 "dynamic" : "disabled");
200 sta_flags = priv->stations[index].sta.station_flags;
202 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
204 switch (mimo_ps_mode) {
205 case WLAN_HT_CAP_SM_PS_STATIC:
206 sta_flags |= STA_FLG_MIMO_DIS_MSK;
207 break;
208 case WLAN_HT_CAP_SM_PS_DYNAMIC:
209 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
210 break;
211 case WLAN_HT_CAP_SM_PS_DISABLED:
212 break;
213 default:
214 IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
215 break;
218 sta_flags |= cpu_to_le32(
219 (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
221 sta_flags |= cpu_to_le32(
222 (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
224 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
225 sta_flags |= STA_FLG_HT40_EN_MSK;
226 else
227 sta_flags &= ~STA_FLG_HT40_EN_MSK;
229 priv->stations[index].sta.station_flags = sta_flags;
230 done:
231 return;
235 * iwl_prep_station - Prepare station information for addition
237 * should be called with sta_lock held
239 u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
240 const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
242 struct iwl_station_entry *station;
243 int i;
244 u8 sta_id = IWL_INVALID_STATION;
246 if (is_ap)
247 sta_id = ctx->ap_sta_id;
248 else if (is_broadcast_ether_addr(addr))
249 sta_id = ctx->bcast_sta_id;
250 else
251 for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) {
252 if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
253 addr)) {
254 sta_id = i;
255 break;
258 if (!priv->stations[i].used &&
259 sta_id == IWL_INVALID_STATION)
260 sta_id = i;
264 * These two conditions have the same outcome, but keep them
265 * separate
267 if (unlikely(sta_id == IWL_INVALID_STATION))
268 return sta_id;
271 * uCode is not able to deal with multiple requests to add a
272 * station. Keep track if one is in progress so that we do not send
273 * another.
275 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
276 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
277 sta_id);
278 return sta_id;
281 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
282 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
283 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
284 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
285 sta_id, addr);
286 return sta_id;
289 station = &priv->stations[sta_id];
290 station->used = IWL_STA_DRIVER_ACTIVE;
291 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
292 sta_id, addr);
293 priv->num_stations++;
295 /* Set up the REPLY_ADD_STA command to send to device */
296 memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
297 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
298 station->sta.mode = 0;
299 station->sta.sta.sta_id = sta_id;
300 station->sta.station_flags = ctx->station_flags;
301 station->ctxid = ctx->ctxid;
303 if (sta) {
304 struct iwl_station_priv *sta_priv;
306 sta_priv = (void *)sta->drv_priv;
307 sta_priv->ctx = ctx;
311 * OK to call unconditionally, since local stations (IBSS BSSID
312 * STA and broadcast STA) pass in a NULL sta, and mac80211
313 * doesn't allow HT IBSS.
315 iwl_set_ht_add_station(priv, sta_id, sta, ctx);
317 return sta_id;
321 #define STA_WAIT_TIMEOUT (HZ/2)
324 * iwl_add_station_common -
326 int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
327 const u8 *addr, bool is_ap,
328 struct ieee80211_sta *sta, u8 *sta_id_r)
330 unsigned long flags_spin;
331 int ret = 0;
332 u8 sta_id;
333 struct iwl_addsta_cmd sta_cmd;
335 *sta_id_r = 0;
336 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
337 sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
338 if (sta_id == IWL_INVALID_STATION) {
339 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
340 addr);
341 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
342 return -EINVAL;
346 * uCode is not able to deal with multiple requests to add a
347 * station. Keep track if one is in progress so that we do not send
348 * another.
350 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
351 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
352 sta_id);
353 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
354 return -EEXIST;
357 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
358 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
359 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
360 sta_id, addr);
361 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
362 return -EEXIST;
365 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
366 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
367 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
369 /* Add station to device's station table */
370 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
371 if (ret) {
372 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
373 IWL_ERR(priv, "Adding station %pM failed.\n",
374 priv->stations[sta_id].sta.sta.addr);
375 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
376 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
377 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
379 *sta_id_r = sta_id;
380 return ret;
384 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
386 * priv->shrd->sta_lock must be held
388 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
390 /* Ucode must be active and driver must be non active */
391 if ((priv->stations[sta_id].used &
392 (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != IWL_STA_UCODE_ACTIVE)
393 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
395 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
397 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
398 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
401 static int iwl_send_remove_station(struct iwl_priv *priv,
402 const u8 *addr, int sta_id,
403 bool temporary)
405 struct iwl_rx_packet *pkt;
406 int ret;
408 unsigned long flags_spin;
409 struct iwl_rem_sta_cmd rm_sta_cmd;
411 struct iwl_host_cmd cmd = {
412 .id = REPLY_REMOVE_STA,
413 .len = { sizeof(struct iwl_rem_sta_cmd), },
414 .flags = CMD_SYNC,
415 .data = { &rm_sta_cmd, },
418 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
419 rm_sta_cmd.num_sta = 1;
420 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
422 cmd.flags |= CMD_WANT_SKB;
424 ret = iwl_trans_send_cmd(trans(priv), &cmd);
426 if (ret)
427 return ret;
429 pkt = (struct iwl_rx_packet *)cmd.reply_page;
430 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
431 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
432 pkt->hdr.flags);
433 ret = -EIO;
436 if (!ret) {
437 switch (pkt->u.rem_sta.status) {
438 case REM_STA_SUCCESS_MSK:
439 if (!temporary) {
440 spin_lock_irqsave(&priv->shrd->sta_lock,
441 flags_spin);
442 iwl_sta_ucode_deactivate(priv, sta_id);
443 spin_unlock_irqrestore(&priv->shrd->sta_lock,
444 flags_spin);
446 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
447 break;
448 default:
449 ret = -EIO;
450 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
451 break;
454 iwl_free_pages(priv->shrd, cmd.reply_page);
456 return ret;
460 * iwl_remove_station - Remove driver's knowledge of station.
462 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
463 const u8 *addr)
465 unsigned long flags;
467 if (!iwl_is_ready(priv->shrd)) {
468 IWL_DEBUG_INFO(priv,
469 "Unable to remove station %pM, device not ready.\n",
470 addr);
472 * It is typical for stations to be removed when we are
473 * going down. Return success since device will be down
474 * soon anyway
476 return 0;
479 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
480 sta_id, addr);
482 if (WARN_ON(sta_id == IWL_INVALID_STATION))
483 return -EINVAL;
485 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
487 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
488 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
489 addr);
490 goto out_err;
493 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
494 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
495 addr);
496 goto out_err;
499 if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
500 kfree(priv->stations[sta_id].lq);
501 priv->stations[sta_id].lq = NULL;
504 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
506 priv->num_stations--;
508 if (WARN_ON(priv->num_stations < 0))
509 priv->num_stations = 0;
511 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
513 return iwl_send_remove_station(priv, addr, sta_id, false);
514 out_err:
515 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
516 return -EINVAL;
520 * iwl_clear_ucode_stations - clear ucode station table bits
522 * This function clears all the bits in the driver indicating
523 * which stations are active in the ucode. Call when something
524 * other than explicit station management would cause this in
525 * the ucode, e.g. unassociated RXON.
527 void iwl_clear_ucode_stations(struct iwl_priv *priv,
528 struct iwl_rxon_context *ctx)
530 int i;
531 unsigned long flags_spin;
532 bool cleared = false;
534 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
536 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
537 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
538 if (ctx && ctx->ctxid != priv->stations[i].ctxid)
539 continue;
541 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
542 IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
543 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
544 cleared = true;
547 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
549 if (!cleared)
550 IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
554 * iwl_restore_stations() - Restore driver known stations to device
556 * All stations considered active by driver, but not present in ucode, is
557 * restored.
559 * Function sleeps.
561 void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
563 struct iwl_addsta_cmd sta_cmd;
564 struct iwl_link_quality_cmd lq;
565 unsigned long flags_spin;
566 int i;
567 bool found = false;
568 int ret;
569 bool send_lq;
571 if (!iwl_is_ready(priv->shrd)) {
572 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
573 return;
576 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
577 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
578 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
579 if (ctx->ctxid != priv->stations[i].ctxid)
580 continue;
581 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
582 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
583 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
584 priv->stations[i].sta.sta.addr);
585 priv->stations[i].sta.mode = 0;
586 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
587 found = true;
591 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
592 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
593 memcpy(&sta_cmd, &priv->stations[i].sta,
594 sizeof(struct iwl_addsta_cmd));
595 send_lq = false;
596 if (priv->stations[i].lq) {
597 if (priv->shrd->wowlan)
598 iwl_sta_fill_lq(priv, ctx, i, &lq);
599 else
600 memcpy(&lq, priv->stations[i].lq,
601 sizeof(struct iwl_link_quality_cmd));
602 send_lq = true;
604 spin_unlock_irqrestore(&priv->shrd->sta_lock,
605 flags_spin);
606 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
607 if (ret) {
608 spin_lock_irqsave(&priv->shrd->sta_lock,
609 flags_spin);
610 IWL_ERR(priv, "Adding station %pM failed.\n",
611 priv->stations[i].sta.sta.addr);
612 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
613 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
614 spin_unlock_irqrestore(&priv->shrd->sta_lock,
615 flags_spin);
618 * Rate scaling has already been initialized, send
619 * current LQ command
621 if (send_lq)
622 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
623 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
624 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
628 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
629 if (!found)
630 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
631 else
632 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
635 void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
637 unsigned long flags;
638 int sta_id = ctx->ap_sta_id;
639 int ret;
640 struct iwl_addsta_cmd sta_cmd;
641 struct iwl_link_quality_cmd lq;
642 bool active;
644 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
645 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
646 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
647 return;
650 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
651 sta_cmd.mode = 0;
652 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
654 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
655 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
656 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
658 if (active) {
659 ret = iwl_send_remove_station(
660 priv, priv->stations[sta_id].sta.sta.addr,
661 sta_id, true);
662 if (ret)
663 IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
664 priv->stations[sta_id].sta.sta.addr, ret);
666 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
667 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
668 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
670 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
671 if (ret)
672 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
673 priv->stations[sta_id].sta.sta.addr, ret);
674 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
677 int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
679 int i;
681 for (i = 0; i < priv->sta_key_max_num; i++)
682 if (!test_and_set_bit(i, &priv->ucode_key_table))
683 return i;
685 return WEP_INVALID_OFFSET;
688 void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
690 unsigned long flags;
691 int i;
693 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
694 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
695 if (!(priv->stations[i].used & IWL_STA_BCAST))
696 continue;
698 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
699 priv->num_stations--;
700 if (WARN_ON(priv->num_stations < 0))
701 priv->num_stations = 0;
702 kfree(priv->stations[i].lq);
703 priv->stations[i].lq = NULL;
705 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
708 #ifdef CONFIG_IWLWIFI_DEBUG
709 static void iwl_dump_lq_cmd(struct iwl_priv *priv,
710 struct iwl_link_quality_cmd *lq)
712 int i;
713 IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
714 IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
715 lq->general_params.single_stream_ant_msk,
716 lq->general_params.dual_stream_ant_msk);
718 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
719 IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
720 i, lq->rs_table[i].rate_n_flags);
722 #else
723 static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
724 struct iwl_link_quality_cmd *lq)
727 #endif
730 * is_lq_table_valid() - Test one aspect of LQ cmd for validity
732 * It sometimes happens when a HT rate has been in use and we
733 * loose connectivity with AP then mac80211 will first tell us that the
734 * current channel is not HT anymore before removing the station. In such a
735 * scenario the RXON flags will be updated to indicate we are not
736 * communicating HT anymore, but the LQ command may still contain HT rates.
737 * Test for this to prevent driver from sending LQ command between the time
738 * RXON flags are updated and when LQ command is updated.
740 static bool is_lq_table_valid(struct iwl_priv *priv,
741 struct iwl_rxon_context *ctx,
742 struct iwl_link_quality_cmd *lq)
744 int i;
746 if (ctx->ht.enabled)
747 return true;
749 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
750 ctx->active.channel);
751 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
752 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
753 IWL_DEBUG_INFO(priv,
754 "index %d of LQ expects HT channel\n",
756 return false;
759 return true;
763 * iwl_send_lq_cmd() - Send link quality command
764 * @init: This command is sent as part of station initialization right
765 * after station has been added.
767 * The link quality command is sent as the last step of station creation.
768 * This is the special case in which init is set and we call a callback in
769 * this case to clear the state indicating that station creation is in
770 * progress.
772 int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
773 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
775 int ret = 0;
776 unsigned long flags_spin;
778 struct iwl_host_cmd cmd = {
779 .id = REPLY_TX_LINK_QUALITY_CMD,
780 .len = { sizeof(struct iwl_link_quality_cmd), },
781 .flags = flags,
782 .data = { lq, },
785 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
786 return -EINVAL;
789 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
790 if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
791 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
792 return -EINVAL;
794 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
796 iwl_dump_lq_cmd(priv, lq);
797 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
798 return -EINVAL;
800 if (is_lq_table_valid(priv, ctx, lq))
801 ret = iwl_trans_send_cmd(trans(priv), &cmd);
802 else
803 ret = -EINVAL;
805 if (cmd.flags & CMD_ASYNC)
806 return ret;
808 if (init) {
809 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d\n",
810 lq->sta_id);
811 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
812 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
813 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
815 return ret;
818 int iwl_mac_sta_remove(struct ieee80211_hw *hw,
819 struct ieee80211_vif *vif,
820 struct ieee80211_sta *sta)
822 struct iwl_priv *priv = hw->priv;
823 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
824 int ret;
826 IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
827 "station %pM\n", sta->addr);
828 mutex_lock(&priv->shrd->mutex);
829 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
830 sta->addr);
831 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
832 if (ret)
833 IWL_ERR(priv, "Error removing station %pM\n",
834 sta->addr);
835 mutex_unlock(&priv->shrd->mutex);
836 IWL_DEBUG_MAC80211(priv, "leave\n");
838 return ret;