aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2010-02-22 19:24:47 -0500
committerReinette Chatre <reinette.chatre@intel.com>2010-03-19 16:40:58 -0400
commitfe6b23dd361199bfbc50b0cbce6bed37c5797c75 (patch)
tree96acb9c114342d7dc731310159dc4195248d115e /drivers/net/wireless/iwlwifi/iwl-sta.c
parent7e2461910e9115c9964975f77584baf8c2f76bfe (diff)
iwlwifi: implement new mac80211 station add/remove calls
mac80211 recently implemented two new callbacks that are used to request station add/remove from the driver. The benefot from these new callbacks are that they enable the driver to sleep while performing this work. This is a big patch since a few things need to be coordinated in this move. First we need to decouple station management from rate scaling, which caused a lot of code to be moved and/or deleted. Next we needed to tie in with mac80211's station management callback and let it direct our station management as well as trigger the rate scaling initialization. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c528
1 files changed, 293 insertions, 235 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 312099099ed3..d401b6f226f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -29,6 +29,7 @@
29 29
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h>
32 33
33#include "iwl-dev.h" 34#include "iwl-dev.h"
34#include "iwl-core.h" 35#include "iwl-core.h"
@@ -61,6 +62,19 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
61 addr, priv->num_stations); 62 addr, priv->num_stations);
62 63
63 out: 64 out:
65 /*
66 * It may be possible that more commands interacting with stations
67 * arrive before we completed processing the adding of
68 * station
69 */
70 if (ret != IWL_INVALID_STATION &&
71 (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
72 ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
73 (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
74 IWL_ERR(priv, "Requested station info for sta %d before ready. \n",
75 ret);
76 ret = IWL_INVALID_STATION;
77 }
64 spin_unlock_irqrestore(&priv->sta_lock, flags); 78 spin_unlock_irqrestore(&priv->sta_lock, flags);
65 return ret; 79 return ret;
66} 80}
@@ -155,13 +169,6 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
155 priv->stations[sta_id].sta.mode == 169 priv->stations[sta_id].sta.mode ==
156 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 170 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
157 addsta->sta.addr); 171 addsta->sta.addr);
158
159 /*
160 * Determine if we wanted to modify or add a station,
161 * if adding a station succeeded we have some more initialization
162 * to do when using station notification. TODO
163 */
164
165 spin_unlock_irqrestore(&priv->sta_lock, flags); 172 spin_unlock_irqrestore(&priv->sta_lock, flags);
166} 173}
167 174
@@ -187,6 +194,10 @@ int iwl_send_add_sta(struct iwl_priv *priv,
187 .flags = flags, 194 .flags = flags,
188 .data = data, 195 .data = data,
189 }; 196 };
197 u8 sta_id = sta->sta.sta_id;
198
199 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
200 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
190 201
191 if (flags & CMD_ASYNC) 202 if (flags & CMD_ASYNC)
192 cmd.callback = iwl_add_sta_callback; 203 cmd.callback = iwl_add_sta_callback;
@@ -260,18 +271,19 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
260} 271}
261 272
262/** 273/**
263 * iwl_add_station - Add station to tables in driver and device 274 * iwl_prep_station - Prepare station information for addition
275 *
276 * should be called with sta_lock held
264 */ 277 */
265u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 278static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
266 struct ieee80211_sta_ht_cap *ht_info) 279 bool is_ap,
280 struct ieee80211_sta_ht_cap *ht_info)
267{ 281{
268 struct iwl_station_entry *station; 282 struct iwl_station_entry *station;
269 unsigned long flags_spin;
270 int i; 283 int i;
271 int sta_id = IWL_INVALID_STATION; 284 u8 sta_id = IWL_INVALID_STATION;
272 u16 rate; 285 u16 rate;
273 286
274 spin_lock_irqsave(&priv->sta_lock, flags_spin);
275 if (is_ap) 287 if (is_ap)
276 sta_id = IWL_AP_ID; 288 sta_id = IWL_AP_ID;
277 else if (is_broadcast_ether_addr(addr)) 289 else if (is_broadcast_ether_addr(addr))
@@ -289,20 +301,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
289 sta_id = i; 301 sta_id = i;
290 } 302 }
291 303
292 /* These two conditions have the same outcome, but keep them separate 304 /*
293 since they have different meanings */ 305 * These two conditions have the same outcome, but keep them
294 if (unlikely(sta_id == IWL_INVALID_STATION)) { 306 * separate
295 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 307 */
308 if (unlikely(sta_id == IWL_INVALID_STATION))
309 return sta_id;
310
311 /*
312 * uCode is not able to deal with multiple requests to add a
313 * station. Keep track if one is in progress so that we do not send
314 * another.
315 */
316 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
317 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
318 sta_id);
296 return sta_id; 319 return sta_id;
297 } 320 }
298 321
299 if (priv->stations[sta_id].used && 322 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
323 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
300 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { 324 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
301 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 325 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
326 sta_id, addr);
302 return sta_id; 327 return sta_id;
303 } 328 }
304 329
305
306 station = &priv->stations[sta_id]; 330 station = &priv->stations[sta_id];
307 station->used = IWL_STA_DRIVER_ACTIVE; 331 station->used = IWL_STA_DRIVER_ACTIVE;
308 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", 332 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
@@ -327,86 +351,185 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
327 /* Turn on both antennas for the station... */ 351 /* Turn on both antennas for the station... */
328 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); 352 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
329 353
354 return sta_id;
355
356}
357
358#define STA_WAIT_TIMEOUT (HZ/2)
359
360/**
361 * iwl_add_station_common -
362 */
363int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
364 bool is_ap,
365 struct ieee80211_sta_ht_cap *ht_info,
366 u8 *sta_id_r)
367{
368 struct iwl_station_entry *station;
369 unsigned long flags_spin;
370 int ret = 0;
371 u8 sta_id;
372
373 *sta_id_r = 0;
374 spin_lock_irqsave(&priv->sta_lock, flags_spin);
375 sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
376 if (sta_id == IWL_INVALID_STATION) {
377 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
378 addr);
379 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
380 return -EINVAL;
381 }
382
383 /*
384 * uCode is not able to deal with multiple requests to add a
385 * station. Keep track if one is in progress so that we do not send
386 * another.
387 */
388 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
389 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
390 sta_id);
391 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
392 return -EEXIST;
393 }
394
395 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
396 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
397 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
398 sta_id, addr);
399 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
400 return -EEXIST;
401 }
402
403 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
404 station = &priv->stations[sta_id];
330 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 405 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
331 406
332 /* Add station to device's station table */ 407 /* Add station to device's station table */
333 iwl_send_add_sta(priv, &station->sta, flags); 408 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC);
334 return sta_id; 409 if (ret) {
335 410 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
411 spin_lock_irqsave(&priv->sta_lock, flags_spin);
412 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
413 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
414 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
415 }
416 *sta_id_r = sta_id;
417 return ret;
336} 418}
337EXPORT_SYMBOL(iwl_add_station); 419EXPORT_SYMBOL(iwl_add_station_common);
338 420
339static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr) 421static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
340{ 422{
341 unsigned long flags; 423 int i, r;
342 u8 sta_id = iwl_find_station(priv, addr); 424 struct iwl_link_quality_cmd link_cmd = {
425 .reserved1 = 0,
426 };
427 u32 rate_flags;
428
429 /* Set up the rate scaling to start at selected rate, fall back
430 * all the way down to 1M in IEEE order, and then spin on 1M */
431 if (is_ap)
432 r = IWL_RATE_54M_INDEX;
433 else if (priv->band == IEEE80211_BAND_5GHZ)
434 r = IWL_RATE_6M_INDEX;
435 else
436 r = IWL_RATE_1M_INDEX;
343 437
344 BUG_ON(sta_id == IWL_INVALID_STATION); 438 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
439 rate_flags = 0;
440 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
441 rate_flags |= RATE_MCS_CCK_MSK;
345 442
346 IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr); 443 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
444 RATE_MCS_ANT_POS;
347 445
348 spin_lock_irqsave(&priv->sta_lock, flags); 446 link_cmd.rs_table[i].rate_n_flags =
447 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
448 r = iwl_get_prev_ieee_rate(r);
449 }
349 450
350 /* Ucode must be active and driver must be non active */ 451 link_cmd.general_params.single_stream_ant_msk =
351 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) 452 first_antenna(priv->hw_params.valid_tx_ant);
352 IWL_ERR(priv, "removed non active STA %d\n", sta_id); 453 link_cmd.general_params.dual_stream_ant_msk = 3;
454 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
455 link_cmd.agg_params.agg_time_limit =
456 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
353 457
354 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; 458 /* Update the rate scaling for control frame Tx to AP */
459 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
355 460
356 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); 461 iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD,
357 spin_unlock_irqrestore(&priv->sta_lock, flags); 462 sizeof(link_cmd), &link_cmd);
358} 463}
359 464
360static void iwl_remove_sta_callback(struct iwl_priv *priv, 465/*
361 struct iwl_device_cmd *cmd, 466 * iwl_add_local_stations - Add stations not requested by mac80211
362 struct iwl_rx_packet *pkt) 467 *
468 * This will be either the broadcast station or the bssid station needed by
469 * ad-hoc.
470 *
471 * Function sleeps.
472 */
473int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
363{ 474{
364 struct iwl_rem_sta_cmd *rm_sta = 475 int ret;
365 (struct iwl_rem_sta_cmd *)cmd->cmd.payload; 476 u8 sta_id;
366 const u8 *addr = rm_sta->addr;
367 477
368 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 478 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
369 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 479 if (ret) {
370 pkt->hdr.flags); 480 IWL_ERR(priv, "Unable to add station %pM\n", addr);
371 return; 481 return ret;
372 } 482 }
373 483
374 switch (pkt->u.rem_sta.status) { 484 if (init_rs)
375 case REM_STA_SUCCESS_MSK: 485 /* Set up default rate scaling table in device's station table */
376 iwl_sta_ucode_deactivate(priv, addr); 486 iwl_sta_init_lq(priv, addr, false);
377 break; 487 return 0;
378 default: 488}
379 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); 489EXPORT_SYMBOL(iwl_add_local_station);
380 break; 490
381 } 491/**
492 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
493 *
494 * priv->sta_lock must be held
495 */
496static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
497{
498 /* Ucode must be active and driver must be non active */
499 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
500 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
501
502 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
503
504 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
505 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
382} 506}
383 507
384static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, 508static int iwl_send_remove_station(struct iwl_priv *priv,
385 u8 flags) 509 struct iwl_station_entry *station)
386{ 510{
387 struct iwl_rx_packet *pkt; 511 struct iwl_rx_packet *pkt;
388 int ret; 512 int ret;
389 513
514 unsigned long flags_spin;
390 struct iwl_rem_sta_cmd rm_sta_cmd; 515 struct iwl_rem_sta_cmd rm_sta_cmd;
391 516
392 struct iwl_host_cmd cmd = { 517 struct iwl_host_cmd cmd = {
393 .id = REPLY_REMOVE_STA, 518 .id = REPLY_REMOVE_STA,
394 .len = sizeof(struct iwl_rem_sta_cmd), 519 .len = sizeof(struct iwl_rem_sta_cmd),
395 .flags = flags, 520 .flags = CMD_SYNC,
396 .data = &rm_sta_cmd, 521 .data = &rm_sta_cmd,
397 }; 522 };
398 523
399 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 524 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
400 rm_sta_cmd.num_sta = 1; 525 rm_sta_cmd.num_sta = 1;
401 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 526 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN);
527
528 cmd.flags |= CMD_WANT_SKB;
402 529
403 if (flags & CMD_ASYNC)
404 cmd.callback = iwl_remove_sta_callback;
405 else
406 cmd.flags |= CMD_WANT_SKB;
407 ret = iwl_send_cmd(priv, &cmd); 530 ret = iwl_send_cmd(priv, &cmd);
408 531
409 if (ret || (flags & CMD_ASYNC)) 532 if (ret)
410 return ret; 533 return ret;
411 534
412 pkt = (struct iwl_rx_packet *)cmd.reply_page; 535 pkt = (struct iwl_rx_packet *)cmd.reply_page;
@@ -419,7 +542,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
419 if (!ret) { 542 if (!ret) {
420 switch (pkt->u.rem_sta.status) { 543 switch (pkt->u.rem_sta.status) {
421 case REM_STA_SUCCESS_MSK: 544 case REM_STA_SUCCESS_MSK:
422 iwl_sta_ucode_deactivate(priv, addr); 545 spin_lock_irqsave(&priv->sta_lock, flags_spin);
546 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id);
547 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
423 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 548 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
424 break; 549 break;
425 default: 550 default:
@@ -436,23 +561,35 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
436/** 561/**
437 * iwl_remove_station - Remove driver's knowledge of station. 562 * iwl_remove_station - Remove driver's knowledge of station.
438 */ 563 */
439int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) 564static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
440{ 565{
441 int sta_id = IWL_INVALID_STATION; 566 int sta_id = IWL_INVALID_STATION;
442 int i, ret = -EINVAL; 567 int i, ret = -EINVAL;
443 unsigned long flags; 568 unsigned long flags;
569 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
570 struct iwl_station_entry *station;
571
572 if (!iwl_is_ready(priv)) {
573 IWL_DEBUG_INFO(priv,
574 "Unable to remove station %pM, device not ready. \n",
575 sta->addr);
576 /*
577 * It is typical for stations to be removed when we are
578 * going down. Return success since device will be down
579 * soon anyway
580 */
581 return 0;
582 }
444 583
445 spin_lock_irqsave(&priv->sta_lock, flags); 584 spin_lock_irqsave(&priv->sta_lock, flags);
446 585
447 if (is_ap) 586 if (is_ap)
448 sta_id = IWL_AP_ID; 587 sta_id = IWL_AP_ID;
449 else if (is_broadcast_ether_addr(addr))
450 sta_id = priv->hw_params.bcast_sta_id;
451 else 588 else
452 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) 589 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
453 if (priv->stations[i].used && 590 if (priv->stations[i].used &&
454 !compare_ether_addr(priv->stations[i].sta.sta.addr, 591 !compare_ether_addr(priv->stations[i].sta.sta.addr,
455 addr)) { 592 sta->addr)) {
456 sta_id = i; 593 sta_id = i;
457 break; 594 break;
458 } 595 }
@@ -461,17 +598,17 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
461 goto out; 598 goto out;
462 599
463 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 600 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
464 sta_id, addr); 601 sta_id, sta->addr);
465 602
466 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 603 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
467 IWL_ERR(priv, "Removing %pM but non DRIVER active\n", 604 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
468 addr); 605 sta->addr);
469 goto out; 606 goto out;
470 } 607 }
471 608
472 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 609 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
473 IWL_ERR(priv, "Removing %pM but non UCODE active\n", 610 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
474 addr); 611 sta->addr);
475 goto out; 612 goto out;
476 } 613 }
477 614
@@ -482,9 +619,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
482 619
483 BUG_ON(priv->num_stations < 0); 620 BUG_ON(priv->num_stations < 0);
484 621
622 station = &priv->stations[sta_id];
485 spin_unlock_irqrestore(&priv->sta_lock, flags); 623 spin_unlock_irqrestore(&priv->sta_lock, flags);
486 624
487 ret = iwl_send_remove_station(priv, addr, CMD_ASYNC); 625 ret = iwl_send_remove_station(priv, station);
488 return ret; 626 return ret;
489out: 627out:
490 spin_unlock_irqrestore(&priv->sta_lock, flags); 628 spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -548,12 +686,16 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
548 * 686 *
549 * All stations considered active by driver, but not present in ucode, is 687 * All stations considered active by driver, but not present in ucode, is
550 * restored. 688 * restored.
689 *
690 * Function sleeps.
551 */ 691 */
552void iwl_restore_stations(struct iwl_priv *priv) 692void iwl_restore_stations(struct iwl_priv *priv)
553{ 693{
694 struct iwl_station_entry *station;
554 unsigned long flags_spin; 695 unsigned long flags_spin;
555 int i; 696 int i;
556 bool found = false; 697 bool found = false;
698 int ret;
557 699
558 if (!iwl_is_ready(priv)) { 700 if (!iwl_is_ready(priv)) {
559 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); 701 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
@@ -575,8 +717,24 @@ void iwl_restore_stations(struct iwl_priv *priv)
575 717
576 for (i = 0; i < priv->hw_params.max_stations; i++) { 718 for (i = 0; i < priv->hw_params.max_stations; i++) {
577 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { 719 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
578 iwl_send_add_sta(priv, &priv->stations[i].sta, 720 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
579 CMD_ASYNC); 721 station = &priv->stations[i];
722 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
723 if (ret) {
724 IWL_ERR(priv, "Adding station %pM failed.\n",
725 station->sta.sta.addr);
726 spin_lock_irqsave(&priv->sta_lock, flags_spin);
727 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
728 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
729 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
730 }
731 /*
732 * Rate scaling has already been initialized, send
733 * current LQ command
734 */
735 if (station->lq)
736 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true);
737 spin_lock_irqsave(&priv->sta_lock, flags_spin);
580 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 738 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
581 } 739 }
582 } 740 }
@@ -585,7 +743,7 @@ void iwl_restore_stations(struct iwl_priv *priv)
585 if (!found) 743 if (!found)
586 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n"); 744 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
587 else 745 else
588 IWL_DEBUG_INFO(priv, "Restoring all known stations .... in progress.\n"); 746 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
589} 747}
590EXPORT_SYMBOL(iwl_restore_stations); 748EXPORT_SYMBOL(iwl_restore_stations);
591 749
@@ -1010,9 +1168,22 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
1010} 1168}
1011#endif 1169#endif
1012 1170
1171/**
1172 * iwl_send_lq_cmd() - Send link quality command
1173 * @init: This command is sent as part of station initialization right
1174 * after station has been added.
1175 *
1176 * The link quality command is sent as the last step of station creation.
1177 * This is the special case in which init is set and we call a callback in
1178 * this case to clear the state indicating that station creation is in
1179 * progress.
1180 */
1013int iwl_send_lq_cmd(struct iwl_priv *priv, 1181int iwl_send_lq_cmd(struct iwl_priv *priv,
1014 struct iwl_link_quality_cmd *lq, u8 flags) 1182 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
1015{ 1183{
1184 int ret = 0;
1185 unsigned long flags_spin;
1186
1016 struct iwl_host_cmd cmd = { 1187 struct iwl_host_cmd cmd = {
1017 .id = REPLY_TX_LINK_QUALITY_CMD, 1188 .id = REPLY_TX_LINK_QUALITY_CMD,
1018 .len = sizeof(struct iwl_link_quality_cmd), 1189 .len = sizeof(struct iwl_link_quality_cmd),
@@ -1028,167 +1199,31 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
1028 lq->sta_id = IWL_AP_ID; 1199 lq->sta_id = IWL_AP_ID;
1029 1200
1030 iwl_dump_lq_cmd(priv, lq); 1201 iwl_dump_lq_cmd(priv, lq);
1202 BUG_ON(init && (cmd.flags & CMD_ASYNC));
1031 1203
1032 if (iwl_is_associated(priv) && priv->assoc_station_added) 1204 iwl_dump_lq_cmd(priv, lq);
1033 return iwl_send_cmd(priv, &cmd); 1205 ret = iwl_send_cmd(priv, &cmd);
1206 if (ret || (cmd.flags & CMD_ASYNC))
1207 return ret;
1034 1208
1209 if (init) {
1210 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d \n",
1211 lq->sta_id);
1212 spin_lock_irqsave(&priv->sta_lock, flags_spin);
1213 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1214 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
1215 }
1035 return 0; 1216 return 0;
1036} 1217}
1037EXPORT_SYMBOL(iwl_send_lq_cmd); 1218EXPORT_SYMBOL(iwl_send_lq_cmd);
1038 1219
1039/** 1220/**
1040 * iwl_sta_init_lq - Initialize a station's hardware rate table
1041 *
1042 * The uCode's station table contains a table of fallback rates
1043 * for automatic fallback during transmission.
1044 *
1045 * NOTE: This sets up a default set of values. These will be replaced later
1046 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
1047 * rc80211_simple.
1048 *
1049 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
1050 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
1051 * which requires station table entry to exist).
1052 */
1053static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1054{
1055 int i, r;
1056 struct iwl_link_quality_cmd link_cmd = {
1057 .reserved1 = 0,
1058 };
1059 u32 rate_flags;
1060
1061 /* Set up the rate scaling to start at selected rate, fall back
1062 * all the way down to 1M in IEEE order, and then spin on 1M */
1063 if (is_ap)
1064 r = IWL_RATE_54M_INDEX;
1065 else if (priv->band == IEEE80211_BAND_5GHZ)
1066 r = IWL_RATE_6M_INDEX;
1067 else
1068 r = IWL_RATE_1M_INDEX;
1069
1070 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1071 rate_flags = 0;
1072 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1073 rate_flags |= RATE_MCS_CCK_MSK;
1074
1075 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1076 RATE_MCS_ANT_POS;
1077
1078 link_cmd.rs_table[i].rate_n_flags =
1079 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1080 r = iwl_get_prev_ieee_rate(r);
1081 }
1082
1083 link_cmd.general_params.single_stream_ant_msk =
1084 first_antenna(priv->hw_params.valid_tx_ant);
1085 link_cmd.general_params.dual_stream_ant_msk = 3;
1086 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1087 link_cmd.agg_params.agg_time_limit =
1088 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1089
1090 /* Update the rate scaling for control frame Tx to AP */
1091 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
1092
1093 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1094 sizeof(link_cmd), &link_cmd, NULL);
1095}
1096
1097/**
1098 * iwl_rxon_add_station - add station into station table.
1099 *
1100 * there is only one AP station with id= IWL_AP_ID
1101 * NOTE: mutex must be held before calling this function
1102 */
1103int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1104{
1105 struct ieee80211_sta *sta;
1106 struct ieee80211_sta_ht_cap ht_config;
1107 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1108 u8 sta_id;
1109
1110 /*
1111 * Set HT capabilities. It is ok to set this struct even if not using
1112 * HT config: the priv->current_ht_config.is_ht flag will just be false
1113 */
1114 rcu_read_lock();
1115 sta = ieee80211_find_sta(priv->vif, addr);
1116 if (sta) {
1117 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1118 cur_ht_config = &ht_config;
1119 }
1120 rcu_read_unlock();
1121
1122 /* Add station to device's station table */
1123 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1124
1125 /* Set up default rate scaling table in device's station table */
1126 iwl_sta_init_lq(priv, addr, is_ap);
1127
1128 return sta_id;
1129}
1130EXPORT_SYMBOL(iwl_rxon_add_station);
1131
1132/**
1133 * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table
1134 *
1135 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
1136 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
1137 * which requires station table entry to exist).
1138 */
1139static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1140{
1141 int i, r;
1142 struct iwl_link_quality_cmd link_cmd = {
1143 .reserved1 = 0,
1144 };
1145 u32 rate_flags;
1146
1147 /* Set up the rate scaling to start at selected rate, fall back
1148 * all the way down to 1M in IEEE order, and then spin on 1M */
1149 if (priv->band == IEEE80211_BAND_5GHZ)
1150 r = IWL_RATE_6M_INDEX;
1151 else
1152 r = IWL_RATE_1M_INDEX;
1153
1154 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1155 rate_flags = 0;
1156 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1157 rate_flags |= RATE_MCS_CCK_MSK;
1158
1159 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1160 RATE_MCS_ANT_POS;
1161
1162 link_cmd.rs_table[i].rate_n_flags =
1163 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1164 r = iwl_get_prev_ieee_rate(r);
1165 }
1166
1167 link_cmd.general_params.single_stream_ant_msk =
1168 first_antenna(priv->hw_params.valid_tx_ant);
1169 link_cmd.general_params.dual_stream_ant_msk = 3;
1170 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1171 link_cmd.agg_params.agg_time_limit =
1172 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1173
1174 /* Update the rate scaling for control frame Tx to AP */
1175 link_cmd.sta_id = priv->hw_params.bcast_sta_id;
1176
1177 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1178 sizeof(link_cmd), &link_cmd, NULL);
1179}
1180
1181
1182/**
1183 * iwl_add_bcast_station - add broadcast station into station table. 1221 * iwl_add_bcast_station - add broadcast station into station table.
1184 */ 1222 */
1185void iwl_add_bcast_station(struct iwl_priv *priv) 1223void iwl_add_bcast_station(struct iwl_priv *priv)
1186{ 1224{
1187 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1225 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1188 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1226 iwl_add_local_station(priv, iwl_bcast_addr, true);
1189
1190 /* Set up default rate scaling table in device's station table */
1191 iwl_sta_init_bcast_lq(priv);
1192} 1227}
1193EXPORT_SYMBOL(iwl_add_bcast_station); 1228EXPORT_SYMBOL(iwl_add_bcast_station);
1194 1229
@@ -1198,7 +1233,14 @@ EXPORT_SYMBOL(iwl_add_bcast_station);
1198void iwl3945_add_bcast_station(struct iwl_priv *priv) 1233void iwl3945_add_bcast_station(struct iwl_priv *priv)
1199{ 1234{
1200 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1235 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1201 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1236 iwl_add_local_station(priv, iwl_bcast_addr, false);
1237 /*
1238 * It is assumed that when station is added more initialization
1239 * needs to be done, but for 3945 it is not the case and we can
1240 * just release station table access right here.
1241 */
1242 priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1243
1202} 1244}
1203EXPORT_SYMBOL(iwl3945_add_bcast_station); 1245EXPORT_SYMBOL(iwl3945_add_bcast_station);
1204 1246
@@ -1221,6 +1263,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1221 /* If we are a client station in a BSS network, use the special 1263 /* If we are a client station in a BSS network, use the special
1222 * AP station entry (that's the only station we communicate with) */ 1264 * AP station entry (that's the only station we communicate with) */
1223 case NL80211_IFTYPE_STATION: 1265 case NL80211_IFTYPE_STATION:
1266 /*
1267 * If addition of station not complete yet, which means
1268 * that rate scaling has not been initialized, then return
1269 * the broadcast station.
1270 */
1271 if (!(priv->stations[IWL_AP_ID].used & IWL_STA_UCODE_ACTIVE))
1272 return priv->hw_params.bcast_sta_id;
1224 return IWL_AP_ID; 1273 return IWL_AP_ID;
1225 1274
1226 /* If we are an AP, then find the station, or use BCAST */ 1275 /* If we are an AP, then find the station, or use BCAST */
@@ -1237,13 +1286,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1237 if (sta_id != IWL_INVALID_STATION) 1286 if (sta_id != IWL_INVALID_STATION)
1238 return sta_id; 1287 return sta_id;
1239 1288
1240 /* Create new station table entry */
1241 sta_id = iwl_add_station(priv, hdr->addr1, false,
1242 CMD_ASYNC, NULL);
1243
1244 if (sta_id != IWL_INVALID_STATION)
1245 return sta_id;
1246
1247 IWL_DEBUG_DROP(priv, "Station %pM not in station map. " 1289 IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
1248 "Defaulting to broadcast...\n", 1290 "Defaulting to broadcast...\n",
1249 hdr->addr1); 1291 hdr->addr1);
@@ -1353,3 +1395,19 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1353 1395
1354 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1396 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1355} 1397}
1398
1399int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1400 struct ieee80211_vif *vif,
1401 struct ieee80211_sta *sta)
1402{
1403 int ret;
1404 struct iwl_priv *priv = hw->priv;
1405 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
1406 sta->addr);
1407 ret = iwl_remove_station(priv, sta);
1408 if (ret)
1409 IWL_ERR(priv, "Error removing station %pM\n",
1410 sta->addr);
1411 return ret;
1412}
1413EXPORT_SYMBOL(iwl_mac_sta_remove);