diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 463 |
1 files changed, 333 insertions, 130 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d06462264147..4b46226ff350 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -83,7 +83,7 @@ struct iwl4965_rate_scale_data { | |||
83 | /** | 83 | /** |
84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates | 84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates |
85 | * | 85 | * |
86 | * There are two of these in struct iwl_rate_scale_priv, | 86 | * There are two of these in struct iwl4965_lq_sta, |
87 | * one for "active", and one for "search". | 87 | * one for "active", and one for "search". |
88 | */ | 88 | */ |
89 | struct iwl4965_scale_tbl_info { | 89 | struct iwl4965_scale_tbl_info { |
@@ -98,8 +98,23 @@ struct iwl4965_scale_tbl_info { | |||
98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | #ifdef CONFIG_IWL4965_HT | ||
102 | |||
103 | struct iwl4965_traffic_load { | ||
104 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
105 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
106 | * slice */ | ||
107 | u32 total; /* total num of packets during the | ||
108 | * last TID_MAX_TIME_DIFF */ | ||
109 | u8 queue_count; /* number of queues that has | ||
110 | * been used since the last cleanup */ | ||
111 | u8 head; /* start of the circular buffer */ | ||
112 | }; | ||
113 | |||
114 | #endif /* CONFIG_IWL4965_HT */ | ||
115 | |||
101 | /** | 116 | /** |
102 | * struct iwl_rate_scale_priv -- driver's rate scaling private structure | 117 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
103 | * | 118 | * |
104 | * Pointer to this gets passed back and forth between driver and mac80211. | 119 | * Pointer to this gets passed back and forth between driver and mac80211. |
105 | */ | 120 | */ |
@@ -124,7 +139,7 @@ struct iwl4965_lq_sta { | |||
124 | u8 valid_antenna; | 139 | u8 valid_antenna; |
125 | u8 is_green; | 140 | u8 is_green; |
126 | u8 is_dup; | 141 | u8 is_dup; |
127 | u8 phymode; | 142 | enum ieee80211_band band; |
128 | u8 ibss_sta_added; | 143 | u8 ibss_sta_added; |
129 | 144 | ||
130 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 145 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
@@ -136,9 +151,16 @@ struct iwl4965_lq_sta { | |||
136 | 151 | ||
137 | struct iwl4965_link_quality_cmd lq; | 152 | struct iwl4965_link_quality_cmd lq; |
138 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 153 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
154 | #ifdef CONFIG_IWL4965_HT | ||
155 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
156 | u8 tx_agg_tid_en; | ||
157 | #endif | ||
139 | #ifdef CONFIG_MAC80211_DEBUGFS | 158 | #ifdef CONFIG_MAC80211_DEBUGFS |
140 | struct dentry *rs_sta_dbgfs_scale_table_file; | 159 | struct dentry *rs_sta_dbgfs_scale_table_file; |
141 | struct dentry *rs_sta_dbgfs_stats_table_file; | 160 | struct dentry *rs_sta_dbgfs_stats_table_file; |
161 | #ifdef CONFIG_IWL4965_HT | ||
162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
163 | #endif | ||
142 | struct iwl4965_rate dbg_fixed; | 164 | struct iwl4965_rate dbg_fixed; |
143 | struct iwl4965_priv *drv; | 165 | struct iwl4965_priv *drv; |
144 | #endif | 166 | #endif |
@@ -269,6 +291,135 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
269 | window->stamp = 0; | 291 | window->stamp = 0; |
270 | } | 292 | } |
271 | 293 | ||
294 | #ifdef CONFIG_IWL4965_HT | ||
295 | /* | ||
296 | * removes the old data from the statistics. All data that is older than | ||
297 | * TID_MAX_TIME_DIFF, will be deleted. | ||
298 | */ | ||
299 | static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | ||
300 | { | ||
301 | /* The oldest age we want to keep */ | ||
302 | u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; | ||
303 | |||
304 | while (tl->queue_count && | ||
305 | (tl->time_stamp < oldest_time)) { | ||
306 | tl->total -= tl->packet_count[tl->head]; | ||
307 | tl->packet_count[tl->head] = 0; | ||
308 | tl->time_stamp += TID_QUEUE_CELL_SPACING; | ||
309 | tl->queue_count--; | ||
310 | tl->head++; | ||
311 | if (tl->head >= TID_QUEUE_MAX_SIZE) | ||
312 | tl->head = 0; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * increment traffic load value for tid and also remove | ||
318 | * any old values if passed the certain time period | ||
319 | */ | ||
320 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
321 | { | ||
322 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
323 | u32 time_diff; | ||
324 | s32 index; | ||
325 | struct iwl4965_traffic_load *tl = NULL; | ||
326 | |||
327 | if (tid >= TID_MAX_LOAD_COUNT) | ||
328 | return; | ||
329 | |||
330 | tl = &lq_data->load[tid]; | ||
331 | |||
332 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
333 | |||
334 | /* Happens only for the first packet. Initialize the data */ | ||
335 | if (!(tl->queue_count)) { | ||
336 | tl->total = 1; | ||
337 | tl->time_stamp = curr_time; | ||
338 | tl->queue_count = 1; | ||
339 | tl->head = 0; | ||
340 | tl->packet_count[0] = 1; | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
345 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
346 | |||
347 | /* The history is too long: remove data that is older than */ | ||
348 | /* TID_MAX_TIME_DIFF */ | ||
349 | if (index >= TID_QUEUE_MAX_SIZE) | ||
350 | rs_tl_rm_old_stats(tl, curr_time); | ||
351 | |||
352 | index = (tl->head + index) % TID_QUEUE_MAX_SIZE; | ||
353 | tl->packet_count[index] = tl->packet_count[index] + 1; | ||
354 | tl->total = tl->total + 1; | ||
355 | |||
356 | if ((index + 1) > tl->queue_count) | ||
357 | tl->queue_count = index + 1; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | get the traffic load value for tid | ||
362 | */ | ||
363 | static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
364 | { | ||
365 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
366 | u32 time_diff; | ||
367 | s32 index; | ||
368 | struct iwl4965_traffic_load *tl = NULL; | ||
369 | |||
370 | if (tid >= TID_MAX_LOAD_COUNT) | ||
371 | return 0; | ||
372 | |||
373 | tl = &(lq_data->load[tid]); | ||
374 | |||
375 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
376 | |||
377 | if (!(tl->queue_count)) | ||
378 | return 0; | ||
379 | |||
380 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
381 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
382 | |||
383 | /* The history is too long: remove data that is older than */ | ||
384 | /* TID_MAX_TIME_DIFF */ | ||
385 | if (index >= TID_QUEUE_MAX_SIZE) | ||
386 | rs_tl_rm_old_stats(tl, curr_time); | ||
387 | |||
388 | return tl->total; | ||
389 | } | ||
390 | |||
391 | static void rs_tl_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
392 | struct iwl4965_lq_sta *lq_data, u8 tid, | ||
393 | struct sta_info *sta) | ||
394 | { | ||
395 | unsigned long state; | ||
396 | DECLARE_MAC_BUF(mac); | ||
397 | |||
398 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
399 | state = sta->ampdu_mlme.tid_tx[tid].state; | ||
400 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
401 | |||
402 | if (state == HT_AGG_STATE_IDLE && | ||
403 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | ||
404 | IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", | ||
405 | print_mac(mac, sta->addr), tid); | ||
406 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void rs_tl_turn_on_agg(struct iwl4965_priv *priv, u8 tid, | ||
411 | struct iwl4965_lq_sta *lq_data, | ||
412 | struct sta_info *sta) | ||
413 | { | ||
414 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
415 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
416 | else if (tid == IWL_AGG_ALL_TID) | ||
417 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
418 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
419 | } | ||
420 | |||
421 | #endif /* CONFIG_IWLWIFI_HT */ | ||
422 | |||
272 | /** | 423 | /** |
273 | * rs_collect_tx_data - Update the success/failure sliding window | 424 | * rs_collect_tx_data - Update the success/failure sliding window |
274 | * | 425 | * |
@@ -277,7 +428,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
277 | * packets. | 428 | * packets. |
278 | */ | 429 | */ |
279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | 430 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, |
280 | int scale_index, s32 tpt, u32 status) | 431 | int scale_index, s32 tpt, int retries, |
432 | int successes) | ||
281 | { | 433 | { |
282 | struct iwl4965_rate_scale_data *window = NULL; | 434 | struct iwl4965_rate_scale_data *window = NULL; |
283 | u64 mask; | 435 | u64 mask; |
@@ -298,26 +450,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
298 | * subtract "1" from the success counter (this is the main reason | 450 | * subtract "1" from the success counter (this is the main reason |
299 | * we keep these bitmaps!). | 451 | * we keep these bitmaps!). |
300 | */ | 452 | */ |
301 | if (window->counter >= win_size) { | 453 | while (retries > 0) { |
302 | window->counter = win_size - 1; | 454 | if (window->counter >= win_size) { |
303 | mask = 1; | 455 | window->counter = win_size - 1; |
304 | mask = (mask << (win_size - 1)); | 456 | mask = 1; |
305 | if ((window->data & mask)) { | 457 | mask = (mask << (win_size - 1)); |
306 | window->data &= ~mask; | 458 | if (window->data & mask) { |
307 | window->success_counter = window->success_counter - 1; | 459 | window->data &= ~mask; |
460 | window->success_counter = | ||
461 | window->success_counter - 1; | ||
462 | } | ||
308 | } | 463 | } |
309 | } | ||
310 | 464 | ||
311 | /* Increment frames-attempted counter */ | 465 | /* Increment frames-attempted counter */ |
312 | window->counter = window->counter + 1; | 466 | window->counter++; |
467 | |||
468 | /* Shift bitmap by one frame (throw away oldest history), | ||
469 | * OR in "1", and increment "success" if this | ||
470 | * frame was successful. */ | ||
471 | mask = window->data; | ||
472 | window->data = (mask << 1); | ||
473 | if (successes > 0) { | ||
474 | window->success_counter = window->success_counter + 1; | ||
475 | window->data |= 0x1; | ||
476 | successes--; | ||
477 | } | ||
313 | 478 | ||
314 | /* Shift bitmap by one frame (throw away oldest history), | 479 | retries--; |
315 | * OR in "1", and increment "success" if this frame was successful. */ | ||
316 | mask = window->data; | ||
317 | window->data = (mask << 1); | ||
318 | if (status != 0) { | ||
319 | window->success_counter = window->success_counter + 1; | ||
320 | window->data |= 0x1; | ||
321 | } | 480 | } |
322 | 481 | ||
323 | /* Calculate current success ratio, avoid divide-by-0! */ | 482 | /* Calculate current success ratio, avoid divide-by-0! */ |
@@ -404,13 +563,14 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, | |||
404 | * fill "search" or "active" tx mode table. | 563 | * fill "search" or "active" tx mode table. |
405 | */ | 564 | */ |
406 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 565 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, |
407 | int phymode, struct iwl4965_scale_tbl_info *tbl, | 566 | enum ieee80211_band band, |
567 | struct iwl4965_scale_tbl_info *tbl, | ||
408 | int *rate_idx) | 568 | int *rate_idx) |
409 | { | 569 | { |
410 | int index; | 570 | int index; |
411 | u32 ant_msk; | 571 | u32 ant_msk; |
412 | 572 | ||
413 | index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags); | 573 | index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags); |
414 | 574 | ||
415 | if (index == IWL_RATE_INVALID) { | 575 | if (index == IWL_RATE_INVALID) { |
416 | *rate_idx = -1; | 576 | *rate_idx = -1; |
@@ -429,7 +589,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | |||
429 | tbl->lq_type = LQ_NONE; | 589 | tbl->lq_type = LQ_NONE; |
430 | else { | 590 | else { |
431 | 591 | ||
432 | if (phymode == MODE_IEEE80211A) | 592 | if (band == IEEE80211_BAND_5GHZ) |
433 | tbl->lq_type = LQ_A; | 593 | tbl->lq_type = LQ_A; |
434 | else | 594 | else |
435 | tbl->lq_type = LQ_G; | 595 | tbl->lq_type = LQ_G; |
@@ -607,7 +767,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
607 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { | 767 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { |
608 | switch_to_legacy = 1; | 768 | switch_to_legacy = 1; |
609 | scale_index = rs_ht_to_legacy[scale_index]; | 769 | scale_index = rs_ht_to_legacy[scale_index]; |
610 | if (lq_sta->phymode == MODE_IEEE80211A) | 770 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
611 | tbl->lq_type = LQ_A; | 771 | tbl->lq_type = LQ_A; |
612 | else | 772 | else |
613 | tbl->lq_type = LQ_G; | 773 | tbl->lq_type = LQ_G; |
@@ -625,7 +785,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
625 | /* Mask with station rate restriction */ | 785 | /* Mask with station rate restriction */ |
626 | if (is_legacy(tbl->lq_type)) { | 786 | if (is_legacy(tbl->lq_type)) { |
627 | /* supp_rates has no CCK bits in A mode */ | 787 | /* supp_rates has no CCK bits in A mode */ |
628 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 788 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
629 | rate_mask = (u16)(rate_mask & | 789 | rate_mask = (u16)(rate_mask & |
630 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 790 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
631 | else | 791 | else |
@@ -663,6 +823,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
663 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
664 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 824 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; |
665 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 825 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
826 | struct ieee80211_hw *hw = local_to_hw(local); | ||
666 | struct iwl4965_rate_scale_data *window = NULL; | 827 | struct iwl4965_rate_scale_data *window = NULL; |
667 | struct iwl4965_rate_scale_data *search_win = NULL; | 828 | struct iwl4965_rate_scale_data *search_win = NULL; |
668 | struct iwl4965_rate tx_mcs; | 829 | struct iwl4965_rate tx_mcs; |
@@ -677,28 +838,32 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
677 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) | 838 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) |
678 | return; | 839 | return; |
679 | 840 | ||
841 | /* This packet was aggregated but doesn't carry rate scale info */ | ||
842 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | ||
843 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | ||
844 | return; | ||
845 | |||
680 | retries = tx_resp->retry_count; | 846 | retries = tx_resp->retry_count; |
681 | 847 | ||
682 | if (retries > 15) | 848 | if (retries > 15) |
683 | retries = 15; | 849 | retries = 15; |
684 | 850 | ||
851 | rcu_read_lock(); | ||
685 | 852 | ||
686 | sta = sta_info_get(local, hdr->addr1); | 853 | sta = sta_info_get(local, hdr->addr1); |
687 | 854 | ||
688 | if (!sta || !sta->rate_ctrl_priv) { | 855 | if (!sta || !sta->rate_ctrl_priv) |
689 | if (sta) | 856 | goto out; |
690 | sta_info_put(sta); | 857 | |
691 | return; | ||
692 | } | ||
693 | 858 | ||
694 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 859 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
695 | 860 | ||
696 | if (!priv->lq_mngr.lq_ready) | 861 | if (!priv->lq_mngr.lq_ready) |
697 | return; | 862 | goto out; |
698 | 863 | ||
699 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 864 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
700 | !lq_sta->ibss_sta_added) | 865 | !lq_sta->ibss_sta_added) |
701 | return; | 866 | goto out; |
702 | 867 | ||
703 | table = &lq_sta->lq; | 868 | table = &lq_sta->lq; |
704 | active_index = lq_sta->active_tbl; | 869 | active_index = lq_sta->active_tbl; |
@@ -719,17 +884,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
719 | search_win = (struct iwl4965_rate_scale_data *) | 884 | search_win = (struct iwl4965_rate_scale_data *) |
720 | &(search_tbl->win[0]); | 885 | &(search_tbl->win[0]); |
721 | 886 | ||
722 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | ||
723 | |||
724 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | ||
725 | &tbl_type, &rs_index); | ||
726 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { | ||
727 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", | ||
728 | rs_index, tx_mcs.rate_n_flags); | ||
729 | sta_info_put(sta); | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | /* | 887 | /* |
734 | * Ignore this Tx frame response if its initial rate doesn't match | 888 | * Ignore this Tx frame response if its initial rate doesn't match |
735 | * that of latest Link Quality command. There may be stragglers | 889 | * that of latest Link Quality command. There may be stragglers |
@@ -738,14 +892,29 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
738 | * to check "search" mode, or a prior "search" mode after we've moved | 892 | * to check "search" mode, or a prior "search" mode after we've moved |
739 | * to a new "search" mode (which might become the new "active" mode). | 893 | * to a new "search" mode (which might become the new "active" mode). |
740 | */ | 894 | */ |
741 | if (retries && | 895 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags); |
742 | (tx_mcs.rate_n_flags != | 896 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
743 | le32_to_cpu(table->rs_table[0].rate_n_flags))) { | 897 | if (priv->band == IEEE80211_BAND_5GHZ) |
744 | IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n", | 898 | rs_index -= IWL_FIRST_OFDM_RATE; |
745 | tx_mcs.rate_n_flags, | 899 | |
746 | le32_to_cpu(table->rs_table[0].rate_n_flags)); | 900 | if ((tx_resp->control.tx_rate == NULL) || |
747 | sta_info_put(sta); | 901 | (tbl_type.is_SGI ^ |
748 | return; | 902 | !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) || |
903 | (tbl_type.is_fat ^ | ||
904 | !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) || | ||
905 | (tbl_type.is_dup ^ | ||
906 | !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || | ||
907 | (tbl_type.antenna_type ^ | ||
908 | tx_resp->control.antenna_sel_tx) || | ||
909 | (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ | ||
910 | !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || | ||
911 | (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ | ||
912 | !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || | ||
913 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != | ||
914 | tx_resp->control.tx_rate->bitrate)) { | ||
915 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", | ||
916 | tx_mcs.rate_n_flags); | ||
917 | goto out; | ||
749 | } | 918 | } |
750 | 919 | ||
751 | /* Update frame history window with "failure" for each Tx retry. */ | 920 | /* Update frame history window with "failure" for each Tx retry. */ |
@@ -754,7 +923,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
754 | * Each tx attempt steps one entry deeper in the rate table. */ | 923 | * Each tx attempt steps one entry deeper in the rate table. */ |
755 | tx_mcs.rate_n_flags = | 924 | tx_mcs.rate_n_flags = |
756 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 925 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
757 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 926 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
758 | &tbl_type, &rs_index); | 927 | &tbl_type, &rs_index); |
759 | 928 | ||
760 | /* If type matches "search" table, | 929 | /* If type matches "search" table, |
@@ -766,7 +935,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
766 | tpt = search_tbl->expected_tpt[rs_index]; | 935 | tpt = search_tbl->expected_tpt[rs_index]; |
767 | else | 936 | else |
768 | tpt = 0; | 937 | tpt = 0; |
769 | rs_collect_tx_data(search_win, rs_index, tpt, 0); | 938 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); |
770 | 939 | ||
771 | /* Else if type matches "current/active" table, | 940 | /* Else if type matches "current/active" table, |
772 | * add failure to "current/active" history */ | 941 | * add failure to "current/active" history */ |
@@ -777,7 +946,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
777 | tpt = curr_tbl->expected_tpt[rs_index]; | 946 | tpt = curr_tbl->expected_tpt[rs_index]; |
778 | else | 947 | else |
779 | tpt = 0; | 948 | tpt = 0; |
780 | rs_collect_tx_data(window, rs_index, tpt, 0); | 949 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); |
781 | } | 950 | } |
782 | 951 | ||
783 | /* If not searching for a new mode, increment failed counter | 952 | /* If not searching for a new mode, increment failed counter |
@@ -794,14 +963,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
794 | * if Tx was successful first try, use original rate, | 963 | * if Tx was successful first try, use original rate, |
795 | * else look up the rate that was, finally, successful. | 964 | * else look up the rate that was, finally, successful. |
796 | */ | 965 | */ |
797 | if (!tx_resp->retry_count) | 966 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); |
798 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 967 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
799 | else | ||
800 | tx_mcs.rate_n_flags = | ||
801 | le32_to_cpu(table->rs_table[index].rate_n_flags); | ||
802 | |||
803 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | ||
804 | &tbl_type, &rs_index); | ||
805 | 968 | ||
806 | /* Update frame history window with "success" if Tx got ACKed ... */ | 969 | /* Update frame history window with "success" if Tx got ACKed ... */ |
807 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) | 970 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) |
@@ -818,9 +981,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
818 | tpt = search_tbl->expected_tpt[rs_index]; | 981 | tpt = search_tbl->expected_tpt[rs_index]; |
819 | else | 982 | else |
820 | tpt = 0; | 983 | tpt = 0; |
821 | rs_collect_tx_data(search_win, | 984 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
822 | rs_index, tpt, status); | 985 | rs_collect_tx_data(search_win, rs_index, tpt, |
823 | 986 | tx_resp->ampdu_ack_len, | |
987 | tx_resp->ampdu_ack_map); | ||
988 | else | ||
989 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
990 | 1, status); | ||
824 | /* Else if type matches "current/active" table, | 991 | /* Else if type matches "current/active" table, |
825 | * add final tx status to "current/active" history */ | 992 | * add final tx status to "current/active" history */ |
826 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 993 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
@@ -830,21 +997,34 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
830 | tpt = curr_tbl->expected_tpt[rs_index]; | 997 | tpt = curr_tbl->expected_tpt[rs_index]; |
831 | else | 998 | else |
832 | tpt = 0; | 999 | tpt = 0; |
833 | rs_collect_tx_data(window, rs_index, tpt, status); | 1000 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
1001 | rs_collect_tx_data(window, rs_index, tpt, | ||
1002 | tx_resp->ampdu_ack_len, | ||
1003 | tx_resp->ampdu_ack_map); | ||
1004 | else | ||
1005 | rs_collect_tx_data(window, rs_index, tpt, | ||
1006 | 1, status); | ||
834 | } | 1007 | } |
835 | 1008 | ||
836 | /* If not searching for new mode, increment success/failed counter | 1009 | /* If not searching for new mode, increment success/failed counter |
837 | * ... these help determine when to start searching again */ | 1010 | * ... these help determine when to start searching again */ |
838 | if (lq_sta->stay_in_tbl) { | 1011 | if (lq_sta->stay_in_tbl) { |
839 | if (status) | 1012 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { |
840 | lq_sta->total_success++; | 1013 | lq_sta->total_success += tx_resp->ampdu_ack_map; |
841 | else | 1014 | lq_sta->total_failed += |
842 | lq_sta->total_failed++; | 1015 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); |
1016 | } else { | ||
1017 | if (status) | ||
1018 | lq_sta->total_success++; | ||
1019 | else | ||
1020 | lq_sta->total_failed++; | ||
1021 | } | ||
843 | } | 1022 | } |
844 | 1023 | ||
845 | /* See if there's a better rate or modulation mode to try. */ | 1024 | /* See if there's a better rate or modulation mode to try. */ |
846 | rs_rate_scale_perform(priv, dev, hdr, sta); | 1025 | rs_rate_scale_perform(priv, dev, hdr, sta); |
847 | sta_info_put(sta); | 1026 | out: |
1027 | rcu_read_unlock(); | ||
848 | return; | 1028 | return; |
849 | } | 1029 | } |
850 | 1030 | ||
@@ -1105,7 +1285,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv, | |||
1105 | return 0; | 1285 | return 0; |
1106 | #else | 1286 | #else |
1107 | return -1; | 1287 | return -1; |
1108 | #endif /*CONFIG_IWL4965_HT */ | 1288 | #endif /*CONFIG_IWL4965_HT */ |
1109 | } | 1289 | } |
1110 | 1290 | ||
1111 | /* | 1291 | /* |
@@ -1168,7 +1348,7 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv, | |||
1168 | #else | 1348 | #else |
1169 | return -1; | 1349 | return -1; |
1170 | 1350 | ||
1171 | #endif /*CONFIG_IWL4965_HT */ | 1351 | #endif /*CONFIG_IWL4965_HT */ |
1172 | } | 1352 | } |
1173 | 1353 | ||
1174 | /* | 1354 | /* |
@@ -1325,6 +1505,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1325 | break; | 1505 | break; |
1326 | case IWL_SISO_SWITCH_GI: | 1506 | case IWL_SISO_SWITCH_GI: |
1327 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1507 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); |
1508 | |||
1328 | memcpy(search_tbl, tbl, sz); | 1509 | memcpy(search_tbl, tbl, sz); |
1329 | search_tbl->action = 0; | 1510 | search_tbl->action = 0; |
1330 | if (search_tbl->is_SGI) | 1511 | if (search_tbl->is_SGI) |
@@ -1390,6 +1571,7 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | |||
1390 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1571 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1391 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1572 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); |
1392 | 1573 | ||
1574 | |||
1393 | /* Set up new search table for SISO */ | 1575 | /* Set up new search table for SISO */ |
1394 | memcpy(search_tbl, tbl, sz); | 1576 | memcpy(search_tbl, tbl, sz); |
1395 | search_tbl->lq_type = LQ_SISO; | 1577 | search_tbl->lq_type = LQ_SISO; |
@@ -1574,6 +1756,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1574 | u8 active_tbl = 0; | 1756 | u8 active_tbl = 0; |
1575 | u8 done_search = 0; | 1757 | u8 done_search = 0; |
1576 | u16 high_low; | 1758 | u16 high_low; |
1759 | #ifdef CONFIG_IWL4965_HT | ||
1760 | u8 tid = MAX_TID_COUNT; | ||
1761 | __le16 *qc; | ||
1762 | #endif | ||
1577 | 1763 | ||
1578 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1764 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1579 | 1765 | ||
@@ -1594,6 +1780,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1594 | } | 1780 | } |
1595 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1781 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1596 | 1782 | ||
1783 | #ifdef CONFIG_IWL4965_HT | ||
1784 | qc = ieee80211_get_qos_ctrl(hdr); | ||
1785 | if (qc) { | ||
1786 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1787 | rs_tl_add_packet(lq_sta, tid); | ||
1788 | } | ||
1789 | #endif | ||
1597 | /* | 1790 | /* |
1598 | * Select rate-scale / modulation-mode table to work with in | 1791 | * Select rate-scale / modulation-mode table to work with in |
1599 | * the rest of this function: "search" if searching for better | 1792 | * the rest of this function: "search" if searching for better |
@@ -1608,7 +1801,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1608 | is_green = lq_sta->is_green; | 1801 | is_green = lq_sta->is_green; |
1609 | 1802 | ||
1610 | /* current tx rate */ | 1803 | /* current tx rate */ |
1611 | index = sta->last_txrate; | 1804 | index = sta->last_txrate_idx; |
1612 | 1805 | ||
1613 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, | 1806 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, |
1614 | tbl->lq_type); | 1807 | tbl->lq_type); |
@@ -1621,7 +1814,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1621 | 1814 | ||
1622 | /* mask with station rate restriction */ | 1815 | /* mask with station rate restriction */ |
1623 | if (is_legacy(tbl->lq_type)) { | 1816 | if (is_legacy(tbl->lq_type)) { |
1624 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 1817 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1625 | /* supp_rates has no CCK bits in A mode */ | 1818 | /* supp_rates has no CCK bits in A mode */ |
1626 | rate_scale_index_msk = (u16) (rate_mask & | 1819 | rate_scale_index_msk = (u16) (rate_mask & |
1627 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 1820 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
@@ -1727,7 +1920,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1727 | tbl = &(lq_sta->lq_info[active_tbl]); | 1920 | tbl = &(lq_sta->lq_info[active_tbl]); |
1728 | 1921 | ||
1729 | /* Revert to "active" rate and throughput info */ | 1922 | /* Revert to "active" rate and throughput info */ |
1730 | index = iwl4965_rate_index_from_plcp( | 1923 | index = iwl4965_hwrate_to_plcp_idx( |
1731 | tbl->current_rate.rate_n_flags); | 1924 | tbl->current_rate.rate_n_flags); |
1732 | current_tpt = lq_sta->last_tpt; | 1925 | current_tpt = lq_sta->last_tpt; |
1733 | 1926 | ||
@@ -1883,7 +2076,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1883 | rs_rate_scale_clear_window(&(tbl->win[i])); | 2076 | rs_rate_scale_clear_window(&(tbl->win[i])); |
1884 | 2077 | ||
1885 | /* Use new "search" start rate */ | 2078 | /* Use new "search" start rate */ |
1886 | index = iwl4965_rate_index_from_plcp( | 2079 | index = iwl4965_hwrate_to_plcp_idx( |
1887 | tbl->current_rate.rate_n_flags); | 2080 | tbl->current_rate.rate_n_flags); |
1888 | 2081 | ||
1889 | IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", | 2082 | IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", |
@@ -1914,15 +2107,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1914 | * mode for a while before next round of mode comparisons. */ | 2107 | * mode for a while before next round of mode comparisons. */ |
1915 | if (lq_sta->enable_counter && | 2108 | if (lq_sta->enable_counter && |
1916 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2109 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
1917 | #ifdef CONFIG_IWL4965_HT_AGG | 2110 | #ifdef CONFIG_IWL4965_HT |
1918 | /* If appropriate, set up aggregation! */ | 2111 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
1919 | if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) && | 2112 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
1920 | (priv->lq_mngr.agg_ctrl.auto_agg)) { | 2113 | (tid != MAX_TID_COUNT)) { |
1921 | priv->lq_mngr.agg_ctrl.tid_retry = | 2114 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); |
1922 | TID_ALL_SPECIFIED; | 2115 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
1923 | schedule_work(&priv->agg_work); | ||
1924 | } | 2116 | } |
1925 | #endif /*CONFIG_IWL4965_HT_AGG */ | 2117 | #endif /*CONFIG_IWL4965_HT */ |
1926 | lq_sta->action_counter = 0; | 2118 | lq_sta->action_counter = 0; |
1927 | rs_set_stay_in_table(0, lq_sta); | 2119 | rs_set_stay_in_table(0, lq_sta); |
1928 | } | 2120 | } |
@@ -1942,15 +2134,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1942 | out: | 2134 | out: |
1943 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); | 2135 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); |
1944 | i = index; | 2136 | i = index; |
1945 | sta->last_txrate = i; | 2137 | sta->last_txrate_idx = i; |
1946 | 2138 | ||
1947 | /* sta->txrate is an index to A mode rates which start | 2139 | /* sta->txrate_idx is an index to A mode rates which start |
1948 | * at IWL_FIRST_OFDM_RATE | 2140 | * at IWL_FIRST_OFDM_RATE |
1949 | */ | 2141 | */ |
1950 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2142 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1951 | sta->txrate = i - IWL_FIRST_OFDM_RATE; | 2143 | sta->txrate_idx = i - IWL_FIRST_OFDM_RATE; |
1952 | else | 2144 | else |
1953 | sta->txrate = i; | 2145 | sta->txrate_idx = i; |
1954 | 2146 | ||
1955 | return; | 2147 | return; |
1956 | } | 2148 | } |
@@ -1972,7 +2164,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1972 | goto out; | 2164 | goto out; |
1973 | 2165 | ||
1974 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2166 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1975 | i = sta->last_txrate; | 2167 | i = sta->last_txrate_idx; |
1976 | 2168 | ||
1977 | if ((lq_sta->lq.sta_id == 0xff) && | 2169 | if ((lq_sta->lq.sta_id == 0xff) && |
1978 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 2170 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) |
@@ -1996,7 +2188,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1996 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; | 2188 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; |
1997 | 2189 | ||
1998 | tbl->antenna_type = ANT_AUX; | 2190 | tbl->antenna_type = ANT_AUX; |
1999 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx); | 2191 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); |
2000 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) | 2192 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) |
2001 | rs_toggle_antenna(&mcs_rate, tbl); | 2193 | rs_toggle_antenna(&mcs_rate, tbl); |
2002 | 2194 | ||
@@ -2010,7 +2202,8 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
2010 | } | 2202 | } |
2011 | 2203 | ||
2012 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 2204 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
2013 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 2205 | struct ieee80211_supported_band *sband, |
2206 | struct sk_buff *skb, | ||
2014 | struct rate_selection *sel) | 2207 | struct rate_selection *sel) |
2015 | { | 2208 | { |
2016 | 2209 | ||
@@ -2025,6 +2218,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2025 | 2218 | ||
2026 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); | 2219 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); |
2027 | 2220 | ||
2221 | rcu_read_lock(); | ||
2222 | |||
2028 | sta = sta_info_get(local, hdr->addr1); | 2223 | sta = sta_info_get(local, hdr->addr1); |
2029 | 2224 | ||
2030 | /* Send management frames and broadcast/multicast data using lowest | 2225 | /* Send management frames and broadcast/multicast data using lowest |
@@ -2032,14 +2227,12 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2032 | fc = le16_to_cpu(hdr->frame_control); | 2227 | fc = le16_to_cpu(hdr->frame_control); |
2033 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2228 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2034 | !sta || !sta->rate_ctrl_priv) { | 2229 | !sta || !sta->rate_ctrl_priv) { |
2035 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2230 | sel->rate = rate_lowest(local, sband, sta); |
2036 | if (sta) | 2231 | goto out; |
2037 | sta_info_put(sta); | ||
2038 | return; | ||
2039 | } | 2232 | } |
2040 | 2233 | ||
2041 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2234 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
2042 | i = sta->last_txrate; | 2235 | i = sta->last_txrate_idx; |
2043 | 2236 | ||
2044 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2237 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
2045 | !lq_sta->ibss_sta_added) { | 2238 | !lq_sta->ibss_sta_added) { |
@@ -2062,14 +2255,15 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2062 | goto done; | 2255 | goto done; |
2063 | } | 2256 | } |
2064 | 2257 | ||
2065 | done: | 2258 | done: |
2066 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2259 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2067 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2260 | sel->rate = rate_lowest(local, sband, sta); |
2068 | return; | 2261 | goto out; |
2069 | } | 2262 | } |
2070 | sta_info_put(sta); | ||
2071 | 2263 | ||
2072 | sel->rate = &priv->ieee_rates[i]; | 2264 | sel->rate = &priv->ieee_rates[i]; |
2265 | out: | ||
2266 | rcu_read_unlock(); | ||
2073 | } | 2267 | } |
2074 | 2268 | ||
2075 | static void *rs_alloc_sta(void *priv, gfp_t gfp) | 2269 | static void *rs_alloc_sta(void *priv, gfp_t gfp) |
@@ -2099,13 +2293,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2099 | { | 2293 | { |
2100 | int i, j; | 2294 | int i, j; |
2101 | struct ieee80211_conf *conf = &local->hw.conf; | 2295 | struct ieee80211_conf *conf = &local->hw.conf; |
2102 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; | 2296 | struct ieee80211_supported_band *sband; |
2103 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 2297 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; |
2104 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2298 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2105 | 2299 | ||
2300 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2301 | |||
2106 | lq_sta->flush_timer = 0; | 2302 | lq_sta->flush_timer = 0; |
2107 | lq_sta->supp_rates = sta->supp_rates; | 2303 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
2108 | sta->txrate = 3; | 2304 | sta->txrate_idx = 3; |
2109 | for (j = 0; j < LQ_SIZE; j++) | 2305 | for (j = 0; j < LQ_SIZE; j++) |
2110 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2306 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2111 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); | 2307 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); |
@@ -2140,15 +2336,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2140 | } | 2336 | } |
2141 | 2337 | ||
2142 | /* Find highest tx rate supported by hardware and destination station */ | 2338 | /* Find highest tx rate supported by hardware and destination station */ |
2143 | for (i = 0; i < mode->num_rates; i++) { | 2339 | for (i = 0; i < sband->n_bitrates; i++) |
2144 | if ((sta->supp_rates & BIT(i)) && | 2340 | if (sta->supp_rates[sband->band] & BIT(i)) |
2145 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) | 2341 | sta->txrate_idx = i; |
2146 | sta->txrate = i; | 2342 | |
2147 | } | 2343 | sta->last_txrate_idx = sta->txrate_idx; |
2148 | sta->last_txrate = sta->txrate; | 2344 | /* WTF is with this bogus comment? A doesn't have cck rates */ |
2149 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ | 2345 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ |
2150 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 2346 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
2151 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 2347 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2152 | 2348 | ||
2153 | lq_sta->is_dup = 0; | 2349 | lq_sta->is_dup = 0; |
2154 | lq_sta->valid_antenna = priv->valid_antenna; | 2350 | lq_sta->valid_antenna = priv->valid_antenna; |
@@ -2157,7 +2353,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2157 | lq_sta->active_rate = priv->active_rate; | 2353 | lq_sta->active_rate = priv->active_rate; |
2158 | lq_sta->active_rate &= ~(0x1000); | 2354 | lq_sta->active_rate &= ~(0x1000); |
2159 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2355 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2160 | lq_sta->phymode = priv->phymode; | 2356 | lq_sta->band = priv->band; |
2161 | #ifdef CONFIG_IWL4965_HT | 2357 | #ifdef CONFIG_IWL4965_HT |
2162 | /* | 2358 | /* |
2163 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2359 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
@@ -2180,6 +2376,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2180 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2376 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", |
2181 | lq_sta->active_siso_rate, | 2377 | lq_sta->active_siso_rate, |
2182 | lq_sta->active_mimo_rate); | 2378 | lq_sta->active_mimo_rate); |
2379 | /* as default allow aggregation for all tids */ | ||
2380 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | ||
2183 | #endif /*CONFIG_IWL4965_HT*/ | 2381 | #endif /*CONFIG_IWL4965_HT*/ |
2184 | #ifdef CONFIG_MAC80211_DEBUGFS | 2382 | #ifdef CONFIG_MAC80211_DEBUGFS |
2185 | lq_sta->drv = priv; | 2383 | lq_sta->drv = priv; |
@@ -2207,7 +2405,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2207 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); | 2405 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); |
2208 | 2406 | ||
2209 | /* Interpret rate_n_flags */ | 2407 | /* Interpret rate_n_flags */ |
2210 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode, | 2408 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, |
2211 | &tbl_type, &rate_idx); | 2409 | &tbl_type, &rate_idx); |
2212 | 2410 | ||
2213 | /* How many times should we repeat the initial rate? */ | 2411 | /* How many times should we repeat the initial rate? */ |
@@ -2261,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2261 | index++; | 2459 | index++; |
2262 | } | 2460 | } |
2263 | 2461 | ||
2264 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type, | 2462 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, |
2265 | &rate_idx); | 2463 | &rate_idx); |
2266 | 2464 | ||
2267 | /* Indicate to uCode which entries might be MIMO. | 2465 | /* Indicate to uCode which entries might be MIMO. |
@@ -2323,12 +2521,6 @@ static void rs_clear(void *priv_rate) | |||
2323 | IWL_DEBUG_RATE("enter\n"); | 2521 | IWL_DEBUG_RATE("enter\n"); |
2324 | 2522 | ||
2325 | priv->lq_mngr.lq_ready = 0; | 2523 | priv->lq_mngr.lq_ready = 0; |
2326 | #ifdef CONFIG_IWL4965_HT | ||
2327 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2328 | if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
2329 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); | ||
2330 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
2331 | #endif /* CONFIG_IWL4965_HT */ | ||
2332 | 2524 | ||
2333 | IWL_DEBUG_RATE("leave\n"); | 2525 | IWL_DEBUG_RATE("leave\n"); |
2334 | } | 2526 | } |
@@ -2354,7 +2546,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | |||
2354 | { | 2546 | { |
2355 | u32 base_rate; | 2547 | u32 base_rate; |
2356 | 2548 | ||
2357 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2549 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
2358 | base_rate = 0x800D; | 2550 | base_rate = 0x800D; |
2359 | else | 2551 | else |
2360 | base_rate = 0x820A; | 2552 | base_rate = 0x820A; |
@@ -2495,6 +2687,12 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2495 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2687 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2496 | debugfs_create_file("rate_stats_table", 0600, dir, | 2688 | debugfs_create_file("rate_stats_table", 0600, dir, |
2497 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2689 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2690 | #ifdef CONFIG_IWL4965_HT | ||
2691 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | ||
2692 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | ||
2693 | &lq_sta->tx_agg_tid_en); | ||
2694 | #endif | ||
2695 | |||
2498 | } | 2696 | } |
2499 | 2697 | ||
2500 | static void rs_remove_debugfs(void *priv, void *priv_sta) | 2698 | static void rs_remove_debugfs(void *priv, void *priv_sta) |
@@ -2502,6 +2700,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2502 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2700 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2503 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2701 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2504 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2702 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2703 | #ifdef CONFIG_IWL4965_HT | ||
2704 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | ||
2705 | #endif | ||
2505 | } | 2706 | } |
2506 | #endif | 2707 | #endif |
2507 | 2708 | ||
@@ -2534,13 +2735,15 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2534 | u32 max_time = 0; | 2735 | u32 max_time = 0; |
2535 | u8 lq_type, antenna; | 2736 | u8 lq_type, antenna; |
2536 | 2737 | ||
2738 | rcu_read_lock(); | ||
2739 | |||
2537 | sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); | 2740 | sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); |
2538 | if (!sta || !sta->rate_ctrl_priv) { | 2741 | if (!sta || !sta->rate_ctrl_priv) { |
2539 | if (sta) { | 2742 | if (sta) |
2540 | sta_info_put(sta); | ||
2541 | IWL_DEBUG_RATE("leave - no private rate data!\n"); | 2743 | IWL_DEBUG_RATE("leave - no private rate data!\n"); |
2542 | } else | 2744 | else |
2543 | IWL_DEBUG_RATE("leave - no station!\n"); | 2745 | IWL_DEBUG_RATE("leave - no station!\n"); |
2746 | rcu_read_unlock(); | ||
2544 | return sprintf(buf, "station %d not found\n", sta_id); | 2747 | return sprintf(buf, "station %d not found\n", sta_id); |
2545 | } | 2748 | } |
2546 | 2749 | ||
@@ -2605,9 +2808,9 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2605 | 2808 | ||
2606 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " | 2809 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " |
2607 | "active_search %d rate index %d\n", lq_type, antenna, | 2810 | "active_search %d rate index %d\n", lq_type, antenna, |
2608 | lq_sta->search_better_tbl, sta->last_txrate); | 2811 | lq_sta->search_better_tbl, sta->last_txrate_idx); |
2609 | 2812 | ||
2610 | sta_info_put(sta); | 2813 | rcu_read_unlock(); |
2611 | return cnt; | 2814 | return cnt; |
2612 | } | 2815 | } |
2613 | 2816 | ||