diff options
author | Abbas, Mohamed <mohamed.abbas@intel.com> | 2008-12-02 15:14:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-05 09:35:55 -0500 |
commit | 74221d07408c473721cce853ef4e0e66c0b326ba (patch) | |
tree | dddb0f775337cb8f00493bbb4483d6b851662cf1 | |
parent | c30e30e17dad86d5e161cf9774eb4d549cc13191 (diff) |
iwl3945: Fix iwl3945 rate scaling.
3945 rate scaling was broken in recent tree. This patch fix the following:
1- Get TX response info and update rates window.
2- Rate scaling selection.
3- Flush window timer.
Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 83 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 24 |
2 files changed, 52 insertions, 55 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 76100d5786fb..b03dd06ceabf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -117,9 +117,11 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | |||
117 | }; | 117 | }; |
118 | 118 | ||
119 | #define IWL_RATE_MAX_WINDOW 62 | 119 | #define IWL_RATE_MAX_WINDOW 62 |
120 | #define IWL_RATE_FLUSH (3*HZ/10) | 120 | #define IWL_RATE_FLUSH (3*HZ) |
121 | #define IWL_RATE_WIN_FLUSH (HZ/2) | 121 | #define IWL_RATE_WIN_FLUSH (HZ/2) |
122 | #define IWL_RATE_HIGH_TH 11520 | 122 | #define IWL_RATE_HIGH_TH 11520 |
123 | #define IWL_SUCCESS_UP_TH 8960 | ||
124 | #define IWL_SUCCESS_DOWN_TH 10880 | ||
123 | #define IWL_RATE_MIN_FAILURE_TH 8 | 125 | #define IWL_RATE_MIN_FAILURE_TH 8 |
124 | #define IWL_RATE_MIN_SUCCESS_TH 8 | 126 | #define IWL_RATE_MIN_SUCCESS_TH 8 |
125 | #define IWL_RATE_DECREASE_TH 1920 | 127 | #define IWL_RATE_DECREASE_TH 1920 |
@@ -206,6 +208,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) | |||
206 | 208 | ||
207 | #define IWL_RATE_FLUSH_MAX 5000 /* msec */ | 209 | #define IWL_RATE_FLUSH_MAX 5000 /* msec */ |
208 | #define IWL_RATE_FLUSH_MIN 50 /* msec */ | 210 | #define IWL_RATE_FLUSH_MIN 50 /* msec */ |
211 | #define IWL_AVERAGE_PACKETS 1500 | ||
209 | 212 | ||
210 | static void iwl3945_bg_rate_scale_flush(unsigned long data) | 213 | static void iwl3945_bg_rate_scale_flush(unsigned long data) |
211 | { | 214 | { |
@@ -220,8 +223,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
220 | 223 | ||
221 | spin_lock_irqsave(&rs_sta->lock, flags); | 224 | spin_lock_irqsave(&rs_sta->lock, flags); |
222 | 225 | ||
223 | rs_sta->flush_pending = 0; | ||
224 | |||
225 | /* Number of packets Rx'd since last time this timer ran */ | 226 | /* Number of packets Rx'd since last time this timer ran */ |
226 | packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; | 227 | packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; |
227 | 228 | ||
@@ -230,7 +231,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
230 | if (unflushed) { | 231 | if (unflushed) { |
231 | duration = | 232 | duration = |
232 | jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); | 233 | jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); |
233 | /* duration = jiffies_to_msecs(rs_sta->flush_time); */ | ||
234 | 234 | ||
235 | IWL_DEBUG_RATE("Tx'd %d packets in %dms\n", | 235 | IWL_DEBUG_RATE("Tx'd %d packets in %dms\n", |
236 | packet_count, duration); | 236 | packet_count, duration); |
@@ -242,9 +242,11 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
242 | pps = 0; | 242 | pps = 0; |
243 | 243 | ||
244 | if (pps) { | 244 | if (pps) { |
245 | duration = IWL_RATE_FLUSH_MAX / pps; | 245 | duration = (IWL_AVERAGE_PACKETS * 1000) / pps; |
246 | if (duration < IWL_RATE_FLUSH_MIN) | 246 | if (duration < IWL_RATE_FLUSH_MIN) |
247 | duration = IWL_RATE_FLUSH_MIN; | 247 | duration = IWL_RATE_FLUSH_MIN; |
248 | else if (duration > IWL_RATE_FLUSH_MAX) | ||
249 | duration = IWL_RATE_FLUSH_MAX; | ||
248 | } else | 250 | } else |
249 | duration = IWL_RATE_FLUSH_MAX; | 251 | duration = IWL_RATE_FLUSH_MAX; |
250 | 252 | ||
@@ -257,8 +259,10 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
257 | rs_sta->flush_time); | 259 | rs_sta->flush_time); |
258 | 260 | ||
259 | rs_sta->last_partial_flush = jiffies; | 261 | rs_sta->last_partial_flush = jiffies; |
262 | } else { | ||
263 | rs_sta->flush_time = IWL_RATE_FLUSH; | ||
264 | rs_sta->flush_pending = 0; | ||
260 | } | 265 | } |
261 | |||
262 | /* If there weren't any unflushed entries, we don't schedule the timer | 266 | /* If there weren't any unflushed entries, we don't schedule the timer |
263 | * to run again */ | 267 | * to run again */ |
264 | 268 | ||
@@ -278,17 +282,18 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) | |||
278 | */ | 282 | */ |
279 | static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | 283 | static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, |
280 | struct iwl3945_rate_scale_data *window, | 284 | struct iwl3945_rate_scale_data *window, |
281 | int success, int retries) | 285 | int success, int retries, int index) |
282 | { | 286 | { |
283 | unsigned long flags; | 287 | unsigned long flags; |
288 | s32 fail_count; | ||
284 | 289 | ||
285 | if (!retries) { | 290 | if (!retries) { |
286 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); | 291 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); |
287 | return; | 292 | return; |
288 | } | 293 | } |
289 | 294 | ||
295 | spin_lock_irqsave(&rs_sta->lock, flags); | ||
290 | while (retries--) { | 296 | while (retries--) { |
291 | spin_lock_irqsave(&rs_sta->lock, flags); | ||
292 | 297 | ||
293 | /* If we have filled up the window then subtract one from the | 298 | /* If we have filled up the window then subtract one from the |
294 | * success counter if the high-bit is counting toward | 299 | * success counter if the high-bit is counting toward |
@@ -316,8 +321,18 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
316 | /* Tag this window as having been updated */ | 321 | /* Tag this window as having been updated */ |
317 | window->stamp = jiffies; | 322 | window->stamp = jiffies; |
318 | 323 | ||
319 | spin_unlock_irqrestore(&rs_sta->lock, flags); | ||
320 | } | 324 | } |
325 | |||
326 | fail_count = window->counter - window->success_counter; | ||
327 | if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || | ||
328 | (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) | ||
329 | window->average_tpt = ((window->success_ratio * | ||
330 | rs_sta->expected_tpt[index] + 64) / 128); | ||
331 | else | ||
332 | window->average_tpt = IWL_INV_TPT; | ||
333 | |||
334 | spin_unlock_irqrestore(&rs_sta->lock, flags); | ||
335 | |||
321 | } | 336 | } |
322 | 337 | ||
323 | static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, | 338 | static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, |
@@ -429,19 +444,16 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
429 | struct ieee80211_sta *sta, void *priv_sta, | 444 | struct ieee80211_sta *sta, void *priv_sta, |
430 | struct sk_buff *skb) | 445 | struct sk_buff *skb) |
431 | { | 446 | { |
432 | u8 retries = 0, current_count; | 447 | s8 retries = 0, current_count; |
433 | int scale_rate_index, first_index, last_index; | 448 | int scale_rate_index, first_index, last_index; |
434 | unsigned long flags; | 449 | unsigned long flags; |
435 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 450 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; |
436 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 451 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
437 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 452 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
438 | int i; | ||
439 | 453 | ||
440 | IWL_DEBUG_RATE("enter\n"); | 454 | IWL_DEBUG_RATE("enter\n"); |
441 | 455 | ||
442 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) | 456 | retries = info->status.rates[0].count; |
443 | retries += info->status.rates[i].count; | ||
444 | retries--; | ||
445 | 457 | ||
446 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; | 458 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; |
447 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 459 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { |
@@ -469,9 +481,9 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
469 | * at which the frame was finally transmitted (or failed if no | 481 | * at which the frame was finally transmitted (or failed if no |
470 | * ACK) | 482 | * ACK) |
471 | */ | 483 | */ |
472 | while (retries > 0) { | 484 | while (retries > 1) { |
473 | if (retries < priv->retry_rate) { | 485 | if ((retries - 1) < priv->retry_rate) { |
474 | current_count = retries; | 486 | current_count = (retries - 1); |
475 | last_index = scale_rate_index; | 487 | last_index = scale_rate_index; |
476 | } else { | 488 | } else { |
477 | current_count = priv->retry_rate; | 489 | current_count = priv->retry_rate; |
@@ -483,15 +495,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
483 | * as was used for it (per current_count) */ | 495 | * as was used for it (per current_count) */ |
484 | iwl3945_collect_tx_data(rs_sta, | 496 | iwl3945_collect_tx_data(rs_sta, |
485 | &rs_sta->win[scale_rate_index], | 497 | &rs_sta->win[scale_rate_index], |
486 | 0, current_count); | 498 | 0, current_count, scale_rate_index); |
487 | IWL_DEBUG_RATE("Update rate %d for %d retries.\n", | 499 | IWL_DEBUG_RATE("Update rate %d for %d retries.\n", |
488 | scale_rate_index, current_count); | 500 | scale_rate_index, current_count); |
489 | 501 | ||
490 | retries -= current_count; | 502 | retries -= current_count; |
491 | 503 | ||
492 | if (retries) | 504 | scale_rate_index = last_index; |
493 | scale_rate_index = | ||
494 | iwl3945_rs_next_rate(priv, scale_rate_index); | ||
495 | } | 505 | } |
496 | 506 | ||
497 | 507 | ||
@@ -502,7 +512,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
502 | "success" : "failure"); | 512 | "success" : "failure"); |
503 | iwl3945_collect_tx_data(rs_sta, | 513 | iwl3945_collect_tx_data(rs_sta, |
504 | &rs_sta->win[last_index], | 514 | &rs_sta->win[last_index], |
505 | info->flags & IEEE80211_TX_STAT_ACK, 1); | 515 | info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); |
506 | 516 | ||
507 | /* We updated the rate scale window -- if its been more than | 517 | /* We updated the rate scale window -- if its been more than |
508 | * flush_time since the last run, schedule the flush | 518 | * flush_time since the last run, schedule the flush |
@@ -510,9 +520,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
510 | spin_lock_irqsave(&rs_sta->lock, flags); | 520 | spin_lock_irqsave(&rs_sta->lock, flags); |
511 | 521 | ||
512 | if (!rs_sta->flush_pending && | 522 | if (!rs_sta->flush_pending && |
513 | time_after(jiffies, rs_sta->last_partial_flush + | 523 | time_after(jiffies, rs_sta->last_flush + |
514 | rs_sta->flush_time)) { | 524 | rs_sta->flush_time)) { |
515 | 525 | ||
526 | rs_sta->last_partial_flush = jiffies; | ||
516 | rs_sta->flush_pending = 1; | 527 | rs_sta->flush_pending = 1; |
517 | mod_timer(&rs_sta->rate_scale_flush, | 528 | mod_timer(&rs_sta->rate_scale_flush, |
518 | jiffies + rs_sta->flush_time); | 529 | jiffies + rs_sta->flush_time); |
@@ -660,8 +671,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
660 | 671 | ||
661 | spin_lock_irqsave(&rs_sta->lock, flags); | 672 | spin_lock_irqsave(&rs_sta->lock, flags); |
662 | 673 | ||
674 | /* for recent assoc, choose best rate regarding | ||
675 | * to rssi value | ||
676 | */ | ||
663 | if (rs_sta->start_rate != IWL_RATE_INVALID) { | 677 | if (rs_sta->start_rate != IWL_RATE_INVALID) { |
664 | index = rs_sta->start_rate; | 678 | if (rs_sta->start_rate < index && |
679 | (rate_mask & (1 << rs_sta->start_rate))) | ||
680 | index = rs_sta->start_rate; | ||
665 | rs_sta->start_rate = IWL_RATE_INVALID; | 681 | rs_sta->start_rate = IWL_RATE_INVALID; |
666 | } | 682 | } |
667 | 683 | ||
@@ -671,7 +687,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
671 | 687 | ||
672 | if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && | 688 | if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && |
673 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { | 689 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { |
674 | window->average_tpt = IWL_INV_TPT; | ||
675 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 690 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
676 | 691 | ||
677 | IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " | 692 | IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " |
@@ -685,8 +700,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
685 | 700 | ||
686 | } | 701 | } |
687 | 702 | ||
688 | window->average_tpt = ((window->success_ratio * | ||
689 | rs_sta->expected_tpt[index] + 64) / 128); | ||
690 | current_tpt = window->average_tpt; | 703 | current_tpt = window->average_tpt; |
691 | 704 | ||
692 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, | 705 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, |
@@ -734,13 +747,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
734 | } | 747 | } |
735 | } | 748 | } |
736 | 749 | ||
737 | if ((window->success_ratio > IWL_RATE_HIGH_TH) || | 750 | if (scale_action == -1) { |
738 | (current_tpt > window->average_tpt)) { | 751 | if (window->success_ratio > IWL_SUCCESS_DOWN_TH) |
739 | IWL_DEBUG_RATE("No action -- success_ratio [%d] > HIGH_TH or " | 752 | scale_action = 0; |
740 | "current_tpt [%d] > average_tpt [%d]\n", | 753 | } else if (scale_action == 1) { |
741 | window->success_ratio, | 754 | if (window->success_ratio < IWL_SUCCESS_UP_TH) { |
742 | current_tpt, window->average_tpt); | 755 | IWL_DEBUG_RATE("No action -- success_ratio [%d] < " |
743 | scale_action = 0; | 756 | "SUCCESS UP\n", window->success_ratio); |
757 | scale_action = 0; | ||
758 | } | ||
744 | } | 759 | } |
745 | 760 | ||
746 | switch (scale_action) { | 761 | switch (scale_action) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 61500044f5da..d95a15fc2602 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -337,7 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
337 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 337 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
338 | u32 status = le32_to_cpu(tx_resp->status); | 338 | u32 status = le32_to_cpu(tx_resp->status); |
339 | int rate_idx; | 339 | int rate_idx; |
340 | int fail, i; | 340 | int fail; |
341 | 341 | ||
342 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { | 342 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { |
343 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 343 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -356,27 +356,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
356 | rate_idx -= IWL_FIRST_OFDM_RATE; | 356 | rate_idx -= IWL_FIRST_OFDM_RATE; |
357 | 357 | ||
358 | fail = tx_resp->failure_frame; | 358 | fail = tx_resp->failure_frame; |
359 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
360 | int next = iwl3945_rs_next_rate(priv, rate_idx); | ||
361 | 359 | ||
362 | info->status.rates[i].idx = rate_idx; | 360 | info->status.rates[0].idx = rate_idx; |
363 | 361 | info->status.rates[0].count = fail + 1; /* add final attempt */ | |
364 | /* | ||
365 | * Put remaining into the last count as best approximation | ||
366 | * of saying exactly what the hardware would have done... | ||
367 | */ | ||
368 | if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) { | ||
369 | info->status.rates[i].count = fail; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | info->status.rates[i].count = priv->retry_rate; | ||
374 | fail -= priv->retry_rate; | ||
375 | rate_idx = next; | ||
376 | if (fail <= 0) | ||
377 | break; | ||
378 | } | ||
379 | info->status.rates[i].count++; /* add final attempt */ | ||
380 | 362 | ||
381 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ | 363 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ |
382 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? | 364 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? |