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