diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 93 |
1 files changed, 56 insertions, 37 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 902c4d4293e9..8e84a08ff951 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -330,16 +330,25 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
330 | 330 | ||
331 | } | 331 | } |
332 | 332 | ||
333 | static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | 333 | /* |
334 | struct ieee80211_sta *sta, void *priv_sta) | 334 | * Called after adding a new station to initialize rate scaling |
335 | */ | ||
336 | void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id) | ||
335 | { | 337 | { |
336 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 338 | struct ieee80211_hw *hw = priv->hw; |
337 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 339 | struct ieee80211_conf *conf = &priv->hw->conf; |
340 | struct iwl3945_sta_priv *psta; | ||
341 | struct iwl3945_rs_sta *rs_sta; | ||
342 | struct ieee80211_supported_band *sband; | ||
338 | int i; | 343 | int i; |
339 | 344 | ||
340 | IWL_DEBUG_RATE(priv, "enter\n"); | 345 | IWL_DEBUG_INFO(priv, "enter\n"); |
346 | if (sta_id == priv->hw_params.bcast_sta_id) | ||
347 | goto out; | ||
341 | 348 | ||
342 | spin_lock_init(&rs_sta->lock); | 349 | psta = (struct iwl3945_sta_priv *) sta->drv_priv; |
350 | rs_sta = &psta->rs_sta; | ||
351 | sband = hw->wiphy->bands[conf->channel->band]; | ||
343 | 352 | ||
344 | rs_sta->priv = priv; | 353 | rs_sta->priv = priv; |
345 | 354 | ||
@@ -352,9 +361,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
352 | rs_sta->last_flush = jiffies; | 361 | rs_sta->last_flush = jiffies; |
353 | rs_sta->flush_time = IWL_RATE_FLUSH; | 362 | rs_sta->flush_time = IWL_RATE_FLUSH; |
354 | rs_sta->last_tx_packets = 0; | 363 | rs_sta->last_tx_packets = 0; |
355 | rs_sta->ibss_sta_added = 0; | ||
356 | 364 | ||
357 | init_timer(&rs_sta->rate_scale_flush); | ||
358 | rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; | 365 | rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; |
359 | rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; | 366 | rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; |
360 | 367 | ||
@@ -373,16 +380,18 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
373 | } | 380 | } |
374 | } | 381 | } |
375 | 382 | ||
376 | priv->sta_supp_rates = sta->supp_rates[sband->band]; | 383 | priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; |
377 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ | 384 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ |
378 | if (sband->band == IEEE80211_BAND_5GHZ) { | 385 | if (sband->band == IEEE80211_BAND_5GHZ) { |
379 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 386 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
380 | priv->sta_supp_rates = priv->sta_supp_rates << | 387 | priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << |
381 | IWL_FIRST_OFDM_RATE; | 388 | IWL_FIRST_OFDM_RATE; |
382 | } | 389 | } |
383 | 390 | ||
391 | out: | ||
392 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
384 | 393 | ||
385 | IWL_DEBUG_RATE(priv, "leave\n"); | 394 | IWL_DEBUG_INFO(priv, "leave\n"); |
386 | } | 395 | } |
387 | 396 | ||
388 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 397 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
@@ -406,6 +415,9 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
406 | 415 | ||
407 | rs_sta = &psta->rs_sta; | 416 | rs_sta = &psta->rs_sta; |
408 | 417 | ||
418 | spin_lock_init(&rs_sta->lock); | ||
419 | init_timer(&rs_sta->rate_scale_flush); | ||
420 | |||
409 | IWL_DEBUG_RATE(priv, "leave\n"); | 421 | IWL_DEBUG_RATE(priv, "leave\n"); |
410 | 422 | ||
411 | return rs_sta; | 423 | return rs_sta; |
@@ -414,13 +426,14 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
414 | static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, | 426 | static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, |
415 | void *priv_sta) | 427 | void *priv_sta) |
416 | { | 428 | { |
417 | struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; | 429 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
418 | struct iwl3945_rs_sta *rs_sta = &psta->rs_sta; | ||
419 | struct iwl_priv *priv __maybe_unused = rs_sta->priv; | ||
420 | 430 | ||
421 | IWL_DEBUG_RATE(priv, "enter\n"); | 431 | /* |
432 | * Be careful not to use any members of iwl3945_rs_sta (like trying | ||
433 | * to use iwl_priv to print out debugging) since it may not be fully | ||
434 | * initialized at this point. | ||
435 | */ | ||
422 | del_timer_sync(&rs_sta->rate_scale_flush); | 436 | del_timer_sync(&rs_sta->rate_scale_flush); |
423 | IWL_DEBUG_RATE(priv, "leave\n"); | ||
424 | } | 437 | } |
425 | 438 | ||
426 | 439 | ||
@@ -459,6 +472,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
459 | return; | 472 | return; |
460 | } | 473 | } |
461 | 474 | ||
475 | /* Treat uninitialized rate scaling data same as non-existing. */ | ||
476 | if (!rs_sta->priv) { | ||
477 | IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n"); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | |||
462 | rs_sta->tx_packets++; | 482 | rs_sta->tx_packets++; |
463 | 483 | ||
464 | scale_rate_index = first_index; | 484 | scale_rate_index = first_index; |
@@ -525,8 +545,6 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
525 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 545 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
526 | 546 | ||
527 | IWL_DEBUG_RATE(priv, "leave\n"); | 547 | IWL_DEBUG_RATE(priv, "leave\n"); |
528 | |||
529 | return; | ||
530 | } | 548 | } |
531 | 549 | ||
532 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | 550 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, |
@@ -626,14 +644,19 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
626 | u32 fail_count; | 644 | u32 fail_count; |
627 | s8 scale_action = 0; | 645 | s8 scale_action = 0; |
628 | unsigned long flags; | 646 | unsigned long flags; |
629 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
630 | u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; | 647 | u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; |
631 | s8 max_rate_idx = -1; | 648 | s8 max_rate_idx = -1; |
632 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 649 | struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; |
633 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 650 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
634 | 651 | ||
635 | IWL_DEBUG_RATE(priv, "enter\n"); | 652 | IWL_DEBUG_RATE(priv, "enter\n"); |
636 | 653 | ||
654 | /* Treat uninitialized rate scaling data same as non-existing. */ | ||
655 | if (rs_sta && !rs_sta->priv) { | ||
656 | IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n"); | ||
657 | priv_sta = NULL; | ||
658 | } | ||
659 | |||
637 | if (rate_control_send_low(sta, priv_sta, txrc)) | 660 | if (rate_control_send_low(sta, priv_sta, txrc)) |
638 | return; | 661 | return; |
639 | 662 | ||
@@ -651,20 +674,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
651 | if (sband->band == IEEE80211_BAND_5GHZ) | 674 | if (sband->band == IEEE80211_BAND_5GHZ) |
652 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; | 675 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; |
653 | 676 | ||
654 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && | ||
655 | !rs_sta->ibss_sta_added) { | ||
656 | u8 sta_id = iwl_find_station(priv, hdr->addr1); | ||
657 | |||
658 | if (sta_id == IWL_INVALID_STATION) { | ||
659 | IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", | ||
660 | hdr->addr1); | ||
661 | sta_id = iwl_add_station(priv, hdr->addr1, false, | ||
662 | CMD_ASYNC, NULL); | ||
663 | } | ||
664 | if (sta_id != IWL_INVALID_STATION) | ||
665 | rs_sta->ibss_sta_added = 1; | ||
666 | } | ||
667 | |||
668 | spin_lock_irqsave(&rs_sta->lock, flags); | 677 | spin_lock_irqsave(&rs_sta->lock, flags); |
669 | 678 | ||
670 | /* for recent assoc, choose best rate regarding | 679 | /* for recent assoc, choose best rate regarding |
@@ -884,12 +893,22 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta) | |||
884 | } | 893 | } |
885 | #endif | 894 | #endif |
886 | 895 | ||
896 | /* | ||
897 | * Initialization of rate scaling information is done by driver after | ||
898 | * the station is added. Since mac80211 calls this function before a | ||
899 | * station is added we ignore it. | ||
900 | */ | ||
901 | static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, | ||
902 | struct ieee80211_sta *sta, void *priv_sta) | ||
903 | { | ||
904 | } | ||
905 | |||
887 | static struct rate_control_ops rs_ops = { | 906 | static struct rate_control_ops rs_ops = { |
888 | .module = NULL, | 907 | .module = NULL, |
889 | .name = RS_NAME, | 908 | .name = RS_NAME, |
890 | .tx_status = rs_tx_status, | 909 | .tx_status = rs_tx_status, |
891 | .get_rate = rs_get_rate, | 910 | .get_rate = rs_get_rate, |
892 | .rate_init = rs_rate_init, | 911 | .rate_init = rs_rate_init_stub, |
893 | .alloc = rs_alloc, | 912 | .alloc = rs_alloc, |
894 | .free = rs_free, | 913 | .free = rs_free, |
895 | .alloc_sta = rs_alloc_sta, | 914 | .alloc_sta = rs_alloc_sta, |
@@ -900,7 +919,6 @@ static struct rate_control_ops rs_ops = { | |||
900 | #endif | 919 | #endif |
901 | 920 | ||
902 | }; | 921 | }; |
903 | |||
904 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | 922 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) |
905 | { | 923 | { |
906 | struct iwl_priv *priv = hw->priv; | 924 | struct iwl_priv *priv = hw->priv; |
@@ -917,6 +935,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
917 | sta = ieee80211_find_sta(priv->vif, | 935 | sta = ieee80211_find_sta(priv->vif, |
918 | priv->stations[sta_id].sta.sta.addr); | 936 | priv->stations[sta_id].sta.sta.addr); |
919 | if (!sta) { | 937 | if (!sta) { |
938 | IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); | ||
920 | rcu_read_unlock(); | 939 | rcu_read_unlock(); |
921 | return; | 940 | return; |
922 | } | 941 | } |
@@ -947,7 +966,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
947 | 966 | ||
948 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 967 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
949 | 968 | ||
950 | rssi = priv->last_rx_rssi; | 969 | rssi = priv->_3945.last_rx_rssi; |
951 | if (rssi == 0) | 970 | if (rssi == 0) |
952 | rssi = IWL_MIN_RSSI_VAL; | 971 | rssi = IWL_MIN_RSSI_VAL; |
953 | 972 | ||