diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
commit | db6d8c7a4027b48d797b369a53f8470aaeed7063 (patch) | |
tree | e140c104a89abc2154e1f41a7db8ebecbb6fa0b4 /drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |
parent | 3a533374283aea50eab3976d8a6d30532175f009 (diff) | |
parent | fb65a7c091529bfffb1262515252c0d0f6241c5c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (1232 commits)
iucv: Fix bad merging.
net_sched: Add size table for qdiscs
net_sched: Add accessor function for packet length for qdiscs
net_sched: Add qdisc_enqueue wrapper
highmem: Export totalhigh_pages.
ipv6 mcast: Omit redundant address family checks in ip6_mc_source().
net: Use standard structures for generic socket address structures.
ipv6 netns: Make several "global" sysctl variables namespace aware.
netns: Use net_eq() to compare net-namespaces for optimization.
ipv6: remove unused macros from net/ipv6.h
ipv6: remove unused parameter from ip6_ra_control
tcp: fix kernel panic with listening_get_next
tcp: Remove redundant checks when setting eff_sacks
tcp: options clean up
tcp: Fix MD5 signatures for non-linear skbs
sctp: Update sctp global memory limit allocations.
sctp: remove unnecessary byteshifting, calculate directly in big-endian
sctp: Allow only 1 listening socket with SO_REUSEADDR
sctp: Do not leak memory on multiple listen() calls
sctp: Support ipv6only AF_INET6 sockets.
...
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 1233 |
1 files changed, 580 insertions, 653 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 3a7f0cb710ec..3ccb84aa5dbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
29 | #include <linux/wireless.h> | 29 | #include <linux/wireless.h> |
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | #include <net/ieee80211.h> | ||
32 | 31 | ||
33 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
34 | #include <linux/etherdevice.h> | 33 | #include <linux/etherdevice.h> |
@@ -38,13 +37,14 @@ | |||
38 | 37 | ||
39 | #include "../net/mac80211/rate.h" | 38 | #include "../net/mac80211/rate.h" |
40 | 39 | ||
41 | #include "iwl-4965.h" | 40 | #include "iwl-dev.h" |
41 | #include "iwl-sta.h" | ||
42 | #include "iwl-core.h" | 42 | #include "iwl-core.h" |
43 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
44 | 44 | ||
45 | #define RS_NAME "iwl-4965-rs" | 45 | #define RS_NAME "iwl-4965-rs" |
46 | 46 | ||
47 | #define NUM_TRY_BEFORE_ANTENNA_TOGGLE 1 | 47 | #define NUM_TRY_BEFORE_ANT_TOGGLE 1 |
48 | #define IWL_NUMBER_TRY 1 | 48 | #define IWL_NUMBER_TRY 1 |
49 | #define IWL_HT_NUMBER_TRY 3 | 49 | #define IWL_HT_NUMBER_TRY 3 |
50 | 50 | ||
@@ -65,9 +65,16 @@ static u8 rs_ht_to_legacy[] = { | |||
65 | IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX | 65 | IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct iwl4965_rate { | 68 | static const u8 ant_toggle_lookup[] = { |
69 | u32 rate_n_flags; | 69 | /*ANT_NONE -> */ ANT_NONE, |
70 | } __attribute__ ((packed)); | 70 | /*ANT_A -> */ ANT_B, |
71 | /*ANT_B -> */ ANT_C, | ||
72 | /*ANT_AB -> */ ANT_BC, | ||
73 | /*ANT_C -> */ ANT_A, | ||
74 | /*ANT_AC -> */ ANT_AB, | ||
75 | /*ANT_BC -> */ ANT_AC, | ||
76 | /*ANT_ABC -> */ ANT_ABC, | ||
77 | }; | ||
71 | 78 | ||
72 | /** | 79 | /** |
73 | * struct iwl4965_rate_scale_data -- tx success history for one rate | 80 | * struct iwl4965_rate_scale_data -- tx success history for one rate |
@@ -88,19 +95,17 @@ struct iwl4965_rate_scale_data { | |||
88 | * one for "active", and one for "search". | 95 | * one for "active", and one for "search". |
89 | */ | 96 | */ |
90 | struct iwl4965_scale_tbl_info { | 97 | struct iwl4965_scale_tbl_info { |
91 | enum iwl4965_table_type lq_type; | 98 | enum iwl_table_type lq_type; |
92 | enum iwl4965_antenna_type antenna_type; | 99 | u8 ant_type; |
93 | u8 is_SGI; /* 1 = short guard interval */ | 100 | u8 is_SGI; /* 1 = short guard interval */ |
94 | u8 is_fat; /* 1 = 40 MHz channel width */ | 101 | u8 is_fat; /* 1 = 40 MHz channel width */ |
95 | u8 is_dup; /* 1 = duplicated data streams */ | 102 | u8 is_dup; /* 1 = duplicated data streams */ |
96 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ | 103 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ |
97 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ | 104 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ |
98 | struct iwl4965_rate current_rate; /* rate_n_flags, uCode API format */ | 105 | u32 current_rate; /* rate_n_flags, uCode API format */ |
99 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 106 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
100 | }; | 107 | }; |
101 | 108 | ||
102 | #ifdef CONFIG_IWL4965_HT | ||
103 | |||
104 | struct iwl4965_traffic_load { | 109 | struct iwl4965_traffic_load { |
105 | unsigned long time_stamp; /* age of the oldest statistics */ | 110 | unsigned long time_stamp; /* age of the oldest statistics */ |
106 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | 111 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time |
@@ -112,8 +117,6 @@ struct iwl4965_traffic_load { | |||
112 | u8 head; /* start of the circular buffer */ | 117 | u8 head; /* start of the circular buffer */ |
113 | }; | 118 | }; |
114 | 119 | ||
115 | #endif /* CONFIG_IWL4965_HT */ | ||
116 | |||
117 | /** | 120 | /** |
118 | * struct iwl4965_lq_sta -- driver's rate scaling private structure | 121 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
119 | * | 122 | * |
@@ -136,8 +139,6 @@ struct iwl4965_lq_sta { | |||
136 | u32 flush_timer; /* time staying in mode before new search */ | 139 | u32 flush_timer; /* time staying in mode before new search */ |
137 | 140 | ||
138 | u8 action_counter; /* # mode-switch actions tried */ | 141 | u8 action_counter; /* # mode-switch actions tried */ |
139 | u8 antenna; | ||
140 | u8 valid_antenna; | ||
141 | u8 is_green; | 142 | u8 is_green; |
142 | u8 is_dup; | 143 | u8 is_dup; |
143 | enum ieee80211_band band; | 144 | enum ieee80211_band band; |
@@ -145,24 +146,21 @@ struct iwl4965_lq_sta { | |||
145 | 146 | ||
146 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 147 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
147 | u32 supp_rates; | 148 | u32 supp_rates; |
148 | u16 active_rate; | 149 | u16 active_legacy_rate; |
149 | u16 active_siso_rate; | 150 | u16 active_siso_rate; |
150 | u16 active_mimo_rate; | 151 | u16 active_mimo2_rate; |
152 | u16 active_mimo3_rate; | ||
151 | u16 active_rate_basic; | 153 | u16 active_rate_basic; |
152 | 154 | ||
153 | struct iwl_link_quality_cmd lq; | 155 | struct iwl_link_quality_cmd lq; |
154 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 156 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
155 | #ifdef CONFIG_IWL4965_HT | ||
156 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | 157 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; |
157 | u8 tx_agg_tid_en; | 158 | u8 tx_agg_tid_en; |
158 | #endif | ||
159 | #ifdef CONFIG_MAC80211_DEBUGFS | 159 | #ifdef CONFIG_MAC80211_DEBUGFS |
160 | struct dentry *rs_sta_dbgfs_scale_table_file; | 160 | struct dentry *rs_sta_dbgfs_scale_table_file; |
161 | struct dentry *rs_sta_dbgfs_stats_table_file; | 161 | struct dentry *rs_sta_dbgfs_stats_table_file; |
162 | #ifdef CONFIG_IWL4965_HT | ||
163 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | 162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; |
164 | #endif | 163 | u32 dbg_fixed_rate; |
165 | struct iwl4965_rate dbg_fixed; | ||
166 | #endif | 164 | #endif |
167 | struct iwl_priv *drv; | 165 | struct iwl_priv *drv; |
168 | }; | 166 | }; |
@@ -171,17 +169,17 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
171 | struct net_device *dev, | 169 | struct net_device *dev, |
172 | struct ieee80211_hdr *hdr, | 170 | struct ieee80211_hdr *hdr, |
173 | struct sta_info *sta); | 171 | struct sta_info *sta); |
174 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 172 | static void rs_fill_link_cmd(const struct iwl_priv *priv, |
175 | struct iwl4965_rate *tx_mcs, | 173 | struct iwl4965_lq_sta *lq_sta, |
176 | struct iwl_link_quality_cmd *tbl); | 174 | u32 rate_n_flags); |
177 | 175 | ||
178 | 176 | ||
179 | #ifdef CONFIG_MAC80211_DEBUGFS | 177 | #ifdef CONFIG_MAC80211_DEBUGFS |
180 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 178 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, |
181 | struct iwl4965_rate *mcs, int index); | 179 | u32 *rate_n_flags, int index); |
182 | #else | 180 | #else |
183 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 181 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, |
184 | struct iwl4965_rate *mcs, int index) | 182 | u32 *rate_n_flags, int index) |
185 | {} | 183 | {} |
186 | #endif | 184 | #endif |
187 | 185 | ||
@@ -190,6 +188,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | |||
190 | * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits | 188 | * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits |
191 | * "G" is the only table that supports CCK (the first 4 rates). | 189 | * "G" is the only table that supports CCK (the first 4 rates). |
192 | */ | 190 | */ |
191 | /*FIXME:RS:need to spearate tables for MIMO2/MIMO3*/ | ||
193 | static s32 expected_tpt_A[IWL_RATE_COUNT] = { | 192 | static s32 expected_tpt_A[IWL_RATE_COUNT] = { |
194 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 | 193 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 |
195 | }; | 194 | }; |
@@ -230,7 +229,7 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { | |||
230 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 | 229 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 |
231 | }; | 230 | }; |
232 | 231 | ||
233 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) | 232 | static inline u8 rs_extract_rate(u32 rate_n_flags) |
234 | { | 233 | { |
235 | return (u8)(rate_n_flags & 0xFF); | 234 | return (u8)(rate_n_flags & 0xFF); |
236 | } | 235 | } |
@@ -245,7 +244,11 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
245 | window->stamp = 0; | 244 | window->stamp = 0; |
246 | } | 245 | } |
247 | 246 | ||
248 | #ifdef CONFIG_IWL4965_HT | 247 | static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) |
248 | { | ||
249 | return ((ant_type & valid_antenna) == ant_type); | ||
250 | } | ||
251 | |||
249 | /* | 252 | /* |
250 | * removes the old data from the statistics. All data that is older than | 253 | * removes the old data from the statistics. All data that is older than |
251 | * TID_MAX_TIME_DIFF, will be deleted. | 254 | * TID_MAX_TIME_DIFF, will be deleted. |
@@ -271,15 +274,21 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | |||
271 | * increment traffic load value for tid and also remove | 274 | * increment traffic load value for tid and also remove |
272 | * any old values if passed the certain time period | 275 | * any old values if passed the certain time period |
273 | */ | 276 | */ |
274 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | 277 | static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, |
278 | struct ieee80211_hdr *hdr) | ||
275 | { | 279 | { |
276 | u32 curr_time = jiffies_to_msecs(jiffies); | 280 | u32 curr_time = jiffies_to_msecs(jiffies); |
277 | u32 time_diff; | 281 | u32 time_diff; |
278 | s32 index; | 282 | s32 index; |
279 | struct iwl4965_traffic_load *tl = NULL; | 283 | struct iwl4965_traffic_load *tl = NULL; |
284 | __le16 fc = hdr->frame_control; | ||
285 | u8 tid; | ||
280 | 286 | ||
281 | if (tid >= TID_MAX_LOAD_COUNT) | 287 | if (ieee80211_is_data_qos(fc)) { |
282 | return; | 288 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
289 | tid = qc[0] & 0xf; | ||
290 | } else | ||
291 | return MAX_TID_COUNT; | ||
283 | 292 | ||
284 | tl = &lq_data->load[tid]; | 293 | tl = &lq_data->load[tid]; |
285 | 294 | ||
@@ -292,7 +301,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | |||
292 | tl->queue_count = 1; | 301 | tl->queue_count = 1; |
293 | tl->head = 0; | 302 | tl->head = 0; |
294 | tl->packet_count[0] = 1; | 303 | tl->packet_count[0] = 1; |
295 | return; | 304 | return MAX_TID_COUNT; |
296 | } | 305 | } |
297 | 306 | ||
298 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | 307 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); |
@@ -309,6 +318,8 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | |||
309 | 318 | ||
310 | if ((index + 1) > tl->queue_count) | 319 | if ((index + 1) > tl->queue_count) |
311 | tl->queue_count = index + 1; | 320 | tl->queue_count = index + 1; |
321 | |||
322 | return tid; | ||
312 | } | 323 | } |
313 | 324 | ||
314 | /* | 325 | /* |
@@ -349,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
349 | unsigned long state; | 360 | unsigned long state; |
350 | DECLARE_MAC_BUF(mac); | 361 | DECLARE_MAC_BUF(mac); |
351 | 362 | ||
352 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 363 | spin_lock_bh(&sta->lock); |
353 | state = sta->ampdu_mlme.tid_state_tx[tid]; | 364 | state = sta->ampdu_mlme.tid_state_tx[tid]; |
354 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 365 | spin_unlock_bh(&sta->lock); |
355 | 366 | ||
356 | if (state == HT_AGG_STATE_IDLE && | 367 | if (state == HT_AGG_STATE_IDLE && |
357 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 368 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
@@ -372,7 +383,12 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, | |||
372 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | 383 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); |
373 | } | 384 | } |
374 | 385 | ||
375 | #endif /* CONFIG_IWLWIFI_HT */ | 386 | static inline int get_num_of_ant_from_rate(u32 rate_n_flags) |
387 | { | ||
388 | return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) + | ||
389 | !!(rate_n_flags & RATE_MCS_ANT_B_MSK) + | ||
390 | !!(rate_n_flags & RATE_MCS_ANT_C_MSK)); | ||
391 | } | ||
376 | 392 | ||
377 | /** | 393 | /** |
378 | * rs_collect_tx_data - Update the success/failure sliding window | 394 | * rs_collect_tx_data - Update the success/failure sliding window |
@@ -386,8 +402,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
386 | int successes) | 402 | int successes) |
387 | { | 403 | { |
388 | struct iwl4965_rate_scale_data *window = NULL; | 404 | struct iwl4965_rate_scale_data *window = NULL; |
389 | u64 mask; | 405 | static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); |
390 | u8 win_size = IWL_RATE_MAX_WINDOW; | ||
391 | s32 fail_count; | 406 | s32 fail_count; |
392 | 407 | ||
393 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) | 408 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) |
@@ -405,14 +420,14 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
405 | * we keep these bitmaps!). | 420 | * we keep these bitmaps!). |
406 | */ | 421 | */ |
407 | while (retries > 0) { | 422 | while (retries > 0) { |
408 | if (window->counter >= win_size) { | 423 | if (window->counter >= IWL_RATE_MAX_WINDOW) { |
409 | window->counter = win_size - 1; | 424 | |
410 | mask = 1; | 425 | /* remove earliest */ |
411 | mask = (mask << (win_size - 1)); | 426 | window->counter = IWL_RATE_MAX_WINDOW - 1; |
427 | |||
412 | if (window->data & mask) { | 428 | if (window->data & mask) { |
413 | window->data &= ~mask; | 429 | window->data &= ~mask; |
414 | window->success_counter = | 430 | window->success_counter--; |
415 | window->success_counter - 1; | ||
416 | } | 431 | } |
417 | } | 432 | } |
418 | 433 | ||
@@ -422,10 +437,9 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
422 | /* Shift bitmap by one frame (throw away oldest history), | 437 | /* Shift bitmap by one frame (throw away oldest history), |
423 | * OR in "1", and increment "success" if this | 438 | * OR in "1", and increment "success" if this |
424 | * frame was successful. */ | 439 | * frame was successful. */ |
425 | mask = window->data; | 440 | window->data <<= 1;; |
426 | window->data = (mask << 1); | ||
427 | if (successes > 0) { | 441 | if (successes > 0) { |
428 | window->success_counter = window->success_counter + 1; | 442 | window->success_counter++; |
429 | window->data |= 0x1; | 443 | window->data |= 0x1; |
430 | successes--; | 444 | successes--; |
431 | } | 445 | } |
@@ -458,168 +472,162 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
458 | /* | 472 | /* |
459 | * Fill uCode API rate_n_flags field, based on "search" or "active" table. | 473 | * Fill uCode API rate_n_flags field, based on "search" or "active" table. |
460 | */ | 474 | */ |
461 | static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, | 475 | /* FIXME:RS:remove this function and put the flags statically in the table */ |
462 | struct iwl4965_scale_tbl_info *tbl, | 476 | static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl, |
463 | int index, u8 use_green) | 477 | int index, u8 use_green) |
464 | { | 478 | { |
479 | u32 rate_n_flags = 0; | ||
480 | |||
465 | if (is_legacy(tbl->lq_type)) { | 481 | if (is_legacy(tbl->lq_type)) { |
466 | mcs_rate->rate_n_flags = iwl4965_rates[index].plcp; | 482 | rate_n_flags = iwl_rates[index].plcp; |
467 | if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) | 483 | if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) |
468 | mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK; | 484 | rate_n_flags |= RATE_MCS_CCK_MSK; |
469 | 485 | ||
470 | } else if (is_siso(tbl->lq_type)) { | 486 | } else if (is_Ht(tbl->lq_type)) { |
471 | if (index > IWL_LAST_OFDM_RATE) | 487 | if (index > IWL_LAST_OFDM_RATE) { |
488 | IWL_ERROR("invalid HT rate index %d\n", index); | ||
472 | index = IWL_LAST_OFDM_RATE; | 489 | index = IWL_LAST_OFDM_RATE; |
473 | mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso | | 490 | } |
474 | RATE_MCS_HT_MSK; | 491 | rate_n_flags = RATE_MCS_HT_MSK; |
475 | } else { | ||
476 | if (index > IWL_LAST_OFDM_RATE) | ||
477 | index = IWL_LAST_OFDM_RATE; | ||
478 | mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo | | ||
479 | RATE_MCS_HT_MSK; | ||
480 | } | ||
481 | |||
482 | switch (tbl->antenna_type) { | ||
483 | case ANT_BOTH: | ||
484 | mcs_rate->rate_n_flags |= RATE_MCS_ANT_AB_MSK; | ||
485 | break; | ||
486 | case ANT_MAIN: | ||
487 | mcs_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK; | ||
488 | break; | ||
489 | case ANT_AUX: | ||
490 | mcs_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK; | ||
491 | break; | ||
492 | case ANT_NONE: | ||
493 | break; | ||
494 | } | ||
495 | |||
496 | if (is_legacy(tbl->lq_type)) | ||
497 | return; | ||
498 | 492 | ||
499 | if (tbl->is_fat) { | 493 | if (is_siso(tbl->lq_type)) |
500 | if (tbl->is_dup) | 494 | rate_n_flags |= iwl_rates[index].plcp_siso; |
501 | mcs_rate->rate_n_flags |= RATE_MCS_DUP_MSK; | 495 | else if (is_mimo2(tbl->lq_type)) |
496 | rate_n_flags |= iwl_rates[index].plcp_mimo2; | ||
502 | else | 497 | else |
503 | mcs_rate->rate_n_flags |= RATE_MCS_FAT_MSK; | 498 | rate_n_flags |= iwl_rates[index].plcp_mimo3; |
499 | } else { | ||
500 | IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type); | ||
504 | } | 501 | } |
505 | if (tbl->is_SGI) | ||
506 | mcs_rate->rate_n_flags |= RATE_MCS_SGI_MSK; | ||
507 | 502 | ||
508 | if (use_green) { | 503 | rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & |
509 | mcs_rate->rate_n_flags |= RATE_MCS_GF_MSK; | 504 | RATE_MCS_ANT_ABC_MSK); |
510 | if (is_siso(tbl->lq_type)) | 505 | |
511 | mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK; | 506 | if (is_Ht(tbl->lq_type)) { |
507 | if (tbl->is_fat) { | ||
508 | if (tbl->is_dup) | ||
509 | rate_n_flags |= RATE_MCS_DUP_MSK; | ||
510 | else | ||
511 | rate_n_flags |= RATE_MCS_FAT_MSK; | ||
512 | } | ||
513 | if (tbl->is_SGI) | ||
514 | rate_n_flags |= RATE_MCS_SGI_MSK; | ||
515 | |||
516 | if (use_green) { | ||
517 | rate_n_flags |= RATE_MCS_GF_MSK; | ||
518 | if (is_siso(tbl->lq_type) && tbl->is_SGI) { | ||
519 | rate_n_flags &= ~RATE_MCS_SGI_MSK; | ||
520 | IWL_ERROR("GF was set with SGI:SISO\n"); | ||
521 | } | ||
522 | } | ||
512 | } | 523 | } |
524 | return rate_n_flags; | ||
513 | } | 525 | } |
514 | 526 | ||
515 | /* | 527 | /* |
516 | * Interpret uCode API's rate_n_flags format, | 528 | * Interpret uCode API's rate_n_flags format, |
517 | * fill "search" or "active" tx mode table. | 529 | * fill "search" or "active" tx mode table. |
518 | */ | 530 | */ |
519 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 531 | static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, |
520 | enum ieee80211_band band, | 532 | enum ieee80211_band band, |
521 | struct iwl4965_scale_tbl_info *tbl, | 533 | struct iwl4965_scale_tbl_info *tbl, |
522 | int *rate_idx) | 534 | int *rate_idx) |
523 | { | 535 | { |
524 | int index; | 536 | u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); |
525 | u32 ant_msk; | 537 | u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); |
538 | u8 mcs; | ||
526 | 539 | ||
527 | index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags); | 540 | *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); |
528 | 541 | ||
529 | if (index == IWL_RATE_INVALID) { | 542 | if (*rate_idx == IWL_RATE_INVALID) { |
530 | *rate_idx = -1; | 543 | *rate_idx = -1; |
531 | return -EINVAL; | 544 | return -EINVAL; |
532 | } | 545 | } |
533 | tbl->is_SGI = 0; /* default legacy setup */ | 546 | tbl->is_SGI = 0; /* default legacy setup */ |
534 | tbl->is_fat = 0; | 547 | tbl->is_fat = 0; |
535 | tbl->is_dup = 0; | 548 | tbl->is_dup = 0; |
536 | tbl->antenna_type = ANT_BOTH; /* default MIMO setup */ | 549 | tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); |
550 | tbl->lq_type = LQ_NONE; | ||
537 | 551 | ||
538 | /* legacy rate format */ | 552 | /* legacy rate format */ |
539 | if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) { | 553 | if (!(rate_n_flags & RATE_MCS_HT_MSK)) { |
540 | ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK); | 554 | if (num_of_ant == 1) { |
541 | |||
542 | if (ant_msk == RATE_MCS_ANT_AB_MSK) | ||
543 | tbl->lq_type = LQ_NONE; | ||
544 | else { | ||
545 | |||
546 | if (band == IEEE80211_BAND_5GHZ) | 555 | if (band == IEEE80211_BAND_5GHZ) |
547 | tbl->lq_type = LQ_A; | 556 | tbl->lq_type = LQ_A; |
548 | else | 557 | else |
549 | tbl->lq_type = LQ_G; | 558 | tbl->lq_type = LQ_G; |
550 | |||
551 | if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK) | ||
552 | tbl->antenna_type = ANT_MAIN; | ||
553 | else | ||
554 | tbl->antenna_type = ANT_AUX; | ||
555 | } | ||
556 | *rate_idx = index; | ||
557 | |||
558 | /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */ | ||
559 | } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags) | ||
560 | <= IWL_RATE_SISO_60M_PLCP) { | ||
561 | tbl->lq_type = LQ_SISO; | ||
562 | |||
563 | ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK); | ||
564 | if (ant_msk == RATE_MCS_ANT_AB_MSK) | ||
565 | tbl->lq_type = LQ_NONE; | ||
566 | else { | ||
567 | if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK) | ||
568 | tbl->antenna_type = ANT_MAIN; | ||
569 | else | ||
570 | tbl->antenna_type = ANT_AUX; | ||
571 | } | 559 | } |
572 | if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) | 560 | /* HT rate format */ |
573 | tbl->is_SGI = 1; | ||
574 | |||
575 | if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) || | ||
576 | (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)) | ||
577 | tbl->is_fat = 1; | ||
578 | |||
579 | if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK) | ||
580 | tbl->is_dup = 1; | ||
581 | |||
582 | *rate_idx = index; | ||
583 | |||
584 | /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */ | ||
585 | } else { | 561 | } else { |
586 | tbl->lq_type = LQ_MIMO; | 562 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
587 | if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) | ||
588 | tbl->is_SGI = 1; | 563 | tbl->is_SGI = 1; |
589 | 564 | ||
590 | if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) || | 565 | if ((rate_n_flags & RATE_MCS_FAT_MSK) || |
591 | (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)) | 566 | (rate_n_flags & RATE_MCS_DUP_MSK)) |
592 | tbl->is_fat = 1; | 567 | tbl->is_fat = 1; |
593 | 568 | ||
594 | if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK) | 569 | if (rate_n_flags & RATE_MCS_DUP_MSK) |
595 | tbl->is_dup = 1; | 570 | tbl->is_dup = 1; |
596 | *rate_idx = index; | 571 | |
572 | mcs = rs_extract_rate(rate_n_flags); | ||
573 | |||
574 | /* SISO */ | ||
575 | if (mcs <= IWL_RATE_SISO_60M_PLCP) { | ||
576 | if (num_of_ant == 1) | ||
577 | tbl->lq_type = LQ_SISO; /*else NONE*/ | ||
578 | /* MIMO2 */ | ||
579 | } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) { | ||
580 | if (num_of_ant == 2) | ||
581 | tbl->lq_type = LQ_MIMO2; | ||
582 | /* MIMO3 */ | ||
583 | } else { | ||
584 | if (num_of_ant == 3) | ||
585 | tbl->lq_type = LQ_MIMO3; | ||
586 | } | ||
597 | } | 587 | } |
598 | return 0; | 588 | return 0; |
599 | } | 589 | } |
600 | 590 | ||
601 | static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, | 591 | /* switch to another antenna/antennas and return 1 */ |
602 | struct iwl4965_scale_tbl_info *tbl) | 592 | /* if no other valid antenna found, return 0 */ |
593 | static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | ||
594 | struct iwl4965_scale_tbl_info *tbl) | ||
603 | { | 595 | { |
604 | if (tbl->antenna_type == ANT_AUX) { | 596 | u8 new_ant_type; |
605 | tbl->antenna_type = ANT_MAIN; | 597 | |
606 | new_rate->rate_n_flags &= ~RATE_MCS_ANT_B_MSK; | 598 | if (!tbl->ant_type || tbl->ant_type > ANT_ABC) |
607 | new_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK; | 599 | return 0; |
608 | } else { | 600 | |
609 | tbl->antenna_type = ANT_AUX; | 601 | if (!rs_is_valid_ant(valid_ant, tbl->ant_type)) |
610 | new_rate->rate_n_flags &= ~RATE_MCS_ANT_A_MSK; | 602 | return 0; |
611 | new_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK; | 603 | |
612 | } | 604 | new_ant_type = ant_toggle_lookup[tbl->ant_type]; |
605 | |||
606 | while ((new_ant_type != tbl->ant_type) && | ||
607 | !rs_is_valid_ant(valid_ant, new_ant_type)) | ||
608 | new_ant_type = ant_toggle_lookup[new_ant_type]; | ||
609 | |||
610 | if (new_ant_type == tbl->ant_type) | ||
611 | return 0; | ||
612 | |||
613 | tbl->ant_type = new_ant_type; | ||
614 | *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; | ||
615 | *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS; | ||
616 | return 1; | ||
613 | } | 617 | } |
614 | 618 | ||
615 | static inline u8 rs_use_green(struct iwl_priv *priv, | 619 | /* FIXME:RS: in 4965 we don't use greenfield at all */ |
616 | struct ieee80211_conf *conf) | 620 | /* FIXME:RS: don't use greenfield for now in TX */ |
621 | #if 0 | ||
622 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) | ||
617 | { | 623 | { |
618 | #ifdef CONFIG_IWL4965_HT | ||
619 | return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && | 624 | return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && |
620 | priv->current_ht_config.is_green_field && | 625 | priv->current_ht_config.is_green_field && |
621 | !priv->current_ht_config.non_GF_STA_present); | 626 | !priv->current_ht_config.non_GF_STA_present); |
622 | #endif /* CONFIG_IWL4965_HT */ | 627 | } |
628 | #endif | ||
629 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) | ||
630 | { | ||
623 | return 0; | 631 | return 0; |
624 | } | 632 | } |
625 | 633 | ||
@@ -630,27 +638,28 @@ static inline u8 rs_use_green(struct iwl_priv *priv, | |||
630 | * basic available rates. | 638 | * basic available rates. |
631 | * | 639 | * |
632 | */ | 640 | */ |
633 | static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, | 641 | static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, |
634 | struct ieee80211_hdr *hdr, | 642 | struct ieee80211_hdr *hdr, |
635 | enum iwl4965_table_type rate_type, | 643 | enum iwl_table_type rate_type) |
636 | u16 *data_rate) | ||
637 | { | 644 | { |
638 | if (is_legacy(rate_type)) | 645 | if (hdr && is_multicast_ether_addr(hdr->addr1) && |
639 | *data_rate = lq_sta->active_rate; | 646 | lq_sta->active_rate_basic) |
640 | else { | 647 | return lq_sta->active_rate_basic; |
648 | |||
649 | if (is_legacy(rate_type)) { | ||
650 | return lq_sta->active_legacy_rate; | ||
651 | } else { | ||
641 | if (is_siso(rate_type)) | 652 | if (is_siso(rate_type)) |
642 | *data_rate = lq_sta->active_siso_rate; | 653 | return lq_sta->active_siso_rate; |
654 | else if (is_mimo2(rate_type)) | ||
655 | return lq_sta->active_mimo2_rate; | ||
643 | else | 656 | else |
644 | *data_rate = lq_sta->active_mimo_rate; | 657 | return lq_sta->active_mimo3_rate; |
645 | } | ||
646 | |||
647 | if (hdr && is_multicast_ether_addr(hdr->addr1) && | ||
648 | lq_sta->active_rate_basic) { | ||
649 | *data_rate = lq_sta->active_rate_basic; | ||
650 | } | 658 | } |
651 | } | 659 | } |
652 | 660 | ||
653 | static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) | 661 | static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, |
662 | int rate_type) | ||
654 | { | 663 | { |
655 | u8 high = IWL_RATE_INVALID; | 664 | u8 high = IWL_RATE_INVALID; |
656 | u8 low = IWL_RATE_INVALID; | 665 | u8 low = IWL_RATE_INVALID; |
@@ -684,7 +693,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) | |||
684 | 693 | ||
685 | low = index; | 694 | low = index; |
686 | while (low != IWL_RATE_INVALID) { | 695 | while (low != IWL_RATE_INVALID) { |
687 | low = iwl4965_rates[low].prev_rs; | 696 | low = iwl_rates[low].prev_rs; |
688 | if (low == IWL_RATE_INVALID) | 697 | if (low == IWL_RATE_INVALID) |
689 | break; | 698 | break; |
690 | if (rate_mask & (1 << low)) | 699 | if (rate_mask & (1 << low)) |
@@ -694,7 +703,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) | |||
694 | 703 | ||
695 | high = index; | 704 | high = index; |
696 | while (high != IWL_RATE_INVALID) { | 705 | while (high != IWL_RATE_INVALID) { |
697 | high = iwl4965_rates[high].next_rs; | 706 | high = iwl_rates[high].next_rs; |
698 | if (high == IWL_RATE_INVALID) | 707 | if (high == IWL_RATE_INVALID) |
699 | break; | 708 | break; |
700 | if (rate_mask & (1 << high)) | 709 | if (rate_mask & (1 << high)) |
@@ -705,9 +714,9 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) | |||
705 | return (high << 8) | low; | 714 | return (high << 8) | low; |
706 | } | 715 | } |
707 | 716 | ||
708 | static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | 717 | static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, |
709 | struct iwl4965_scale_tbl_info *tbl, u8 scale_index, | 718 | struct iwl4965_scale_tbl_info *tbl, u8 scale_index, |
710 | u8 ht_possible, struct iwl4965_rate *mcs_rate) | 719 | u8 ht_possible) |
711 | { | 720 | { |
712 | s32 low; | 721 | s32 low; |
713 | u16 rate_mask; | 722 | u16 rate_mask; |
@@ -726,15 +735,14 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
726 | else | 735 | else |
727 | tbl->lq_type = LQ_G; | 736 | tbl->lq_type = LQ_G; |
728 | 737 | ||
729 | if ((tbl->antenna_type == ANT_BOTH) || | 738 | if (num_of_ant(tbl->ant_type) > 1) |
730 | (tbl->antenna_type == ANT_NONE)) | 739 | tbl->ant_type = ANT_A;/*FIXME:RS*/ |
731 | tbl->antenna_type = ANT_MAIN; | ||
732 | 740 | ||
733 | tbl->is_fat = 0; | 741 | tbl->is_fat = 0; |
734 | tbl->is_SGI = 0; | 742 | tbl->is_SGI = 0; |
735 | } | 743 | } |
736 | 744 | ||
737 | rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, &rate_mask); | 745 | rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); |
738 | 746 | ||
739 | /* Mask with station rate restriction */ | 747 | /* Mask with station rate restriction */ |
740 | if (is_legacy(tbl->lq_type)) { | 748 | if (is_legacy(tbl->lq_type)) { |
@@ -748,25 +756,26 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
748 | 756 | ||
749 | /* If we switched from HT to legacy, check current rate */ | 757 | /* If we switched from HT to legacy, check current rate */ |
750 | if (switch_to_legacy && (rate_mask & (1 << scale_index))) { | 758 | if (switch_to_legacy && (rate_mask & (1 << scale_index))) { |
751 | rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); | 759 | low = scale_index; |
752 | return; | 760 | goto out; |
753 | } | 761 | } |
754 | 762 | ||
755 | high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type); | 763 | high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask, |
764 | tbl->lq_type); | ||
756 | low = high_low & 0xff; | 765 | low = high_low & 0xff; |
757 | 766 | ||
758 | if (low != IWL_RATE_INVALID) | 767 | if (low == IWL_RATE_INVALID) |
759 | rs_mcs_from_tbl(mcs_rate, tbl, low, is_green); | 768 | low = scale_index; |
760 | else | 769 | |
761 | rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); | 770 | out: |
771 | return rate_n_flags_from_tbl(tbl, low, is_green); | ||
762 | } | 772 | } |
763 | 773 | ||
764 | /* | 774 | /* |
765 | * mac80211 sends us Tx status | 775 | * mac80211 sends us Tx status |
766 | */ | 776 | */ |
767 | static void rs_tx_status(void *priv_rate, struct net_device *dev, | 777 | static void rs_tx_status(void *priv_rate, struct net_device *dev, |
768 | struct sk_buff *skb, | 778 | struct sk_buff *skb) |
769 | struct ieee80211_tx_status *tx_resp) | ||
770 | { | 779 | { |
771 | int status; | 780 | int status; |
772 | u8 retries; | 781 | u8 retries; |
@@ -778,13 +787,14 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
778 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; | 787 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
779 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 788 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
780 | struct ieee80211_hw *hw = local_to_hw(local); | 789 | struct ieee80211_hw *hw = local_to_hw(local); |
790 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
781 | struct iwl4965_rate_scale_data *window = NULL; | 791 | struct iwl4965_rate_scale_data *window = NULL; |
782 | struct iwl4965_rate_scale_data *search_win = NULL; | 792 | struct iwl4965_rate_scale_data *search_win = NULL; |
783 | struct iwl4965_rate tx_mcs; | 793 | u32 tx_rate; |
784 | struct iwl4965_scale_tbl_info tbl_type; | 794 | struct iwl4965_scale_tbl_info tbl_type; |
785 | struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; | 795 | struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; |
786 | u8 active_index = 0; | 796 | u8 active_index = 0; |
787 | u16 fc = le16_to_cpu(hdr->frame_control); | 797 | __le16 fc = hdr->frame_control; |
788 | s32 tpt = 0; | 798 | s32 tpt = 0; |
789 | 799 | ||
790 | IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); | 800 | IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); |
@@ -793,11 +803,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
793 | return; | 803 | return; |
794 | 804 | ||
795 | /* This packet was aggregated but doesn't carry rate scale info */ | 805 | /* This packet was aggregated but doesn't carry rate scale info */ |
796 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | 806 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && |
797 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | 807 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
798 | return; | 808 | return; |
799 | 809 | ||
800 | retries = tx_resp->retry_count; | 810 | retries = info->status.retry_count; |
801 | 811 | ||
802 | if (retries > 15) | 812 | if (retries > 15) |
803 | retries = 15; | 813 | retries = 15; |
@@ -812,9 +822,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
812 | 822 | ||
813 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 823 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
814 | 824 | ||
815 | if (!priv->lq_mngr.lq_ready) | ||
816 | goto out; | ||
817 | |||
818 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 825 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
819 | !lq_sta->ibss_sta_added) | 826 | !lq_sta->ibss_sta_added) |
820 | goto out; | 827 | goto out; |
@@ -822,15 +829,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
822 | table = &lq_sta->lq; | 829 | table = &lq_sta->lq; |
823 | active_index = lq_sta->active_tbl; | 830 | active_index = lq_sta->active_tbl; |
824 | 831 | ||
825 | /* Get mac80211 antenna info */ | ||
826 | lq_sta->antenna = | ||
827 | (lq_sta->valid_antenna & local->hw.conf.antenna_sel_tx); | ||
828 | if (!lq_sta->antenna) | ||
829 | lq_sta->antenna = lq_sta->valid_antenna; | ||
830 | |||
831 | /* Ignore mac80211 antenna info for now */ | ||
832 | lq_sta->antenna = lq_sta->valid_antenna; | ||
833 | |||
834 | curr_tbl = &(lq_sta->lq_info[active_index]); | 832 | curr_tbl = &(lq_sta->lq_info[active_index]); |
835 | search_tbl = &(lq_sta->lq_info[(1 - active_index)]); | 833 | search_tbl = &(lq_sta->lq_info[(1 - active_index)]); |
836 | window = (struct iwl4965_rate_scale_data *) | 834 | window = (struct iwl4965_rate_scale_data *) |
@@ -846,28 +844,26 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
846 | * to check "search" mode, or a prior "search" mode after we've moved | 844 | * to check "search" mode, or a prior "search" mode after we've moved |
847 | * to a new "search" mode (which might become the new "active" mode). | 845 | * to a new "search" mode (which might become the new "active" mode). |
848 | */ | 846 | */ |
849 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags); | 847 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); |
850 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); | 848 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); |
851 | if (priv->band == IEEE80211_BAND_5GHZ) | 849 | if (priv->band == IEEE80211_BAND_5GHZ) |
852 | rs_index -= IWL_FIRST_OFDM_RATE; | 850 | rs_index -= IWL_FIRST_OFDM_RATE; |
853 | 851 | ||
854 | if ((tx_resp->control.tx_rate == NULL) || | 852 | if ((info->tx_rate_idx < 0) || |
855 | (tbl_type.is_SGI ^ | 853 | (tbl_type.is_SGI ^ |
856 | !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) || | 854 | !!(info->flags & IEEE80211_TX_CTL_SHORT_GI)) || |
857 | (tbl_type.is_fat ^ | 855 | (tbl_type.is_fat ^ |
858 | !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) || | 856 | !!(info->flags & IEEE80211_TX_CTL_40_MHZ_WIDTH)) || |
859 | (tbl_type.is_dup ^ | 857 | (tbl_type.is_dup ^ |
860 | !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || | 858 | !!(info->flags & IEEE80211_TX_CTL_DUP_DATA)) || |
861 | (tbl_type.antenna_type ^ | 859 | (tbl_type.ant_type ^ info->antenna_sel_tx) || |
862 | tx_resp->control.antenna_sel_tx) || | 860 | (!!(tx_rate & RATE_MCS_HT_MSK) ^ |
863 | (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ | 861 | !!(info->flags & IEEE80211_TX_CTL_OFDM_HT)) || |
864 | !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || | 862 | (!!(tx_rate & RATE_MCS_GF_MSK) ^ |
865 | (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ | 863 | !!(info->flags & IEEE80211_TX_CTL_GREEN_FIELD)) || |
866 | !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || | ||
867 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != | 864 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != |
868 | tx_resp->control.tx_rate->bitrate)) { | 865 | hw->wiphy->bands[info->band]->bitrates[info->tx_rate_idx].bitrate)) { |
869 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", | 866 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate); |
870 | tx_mcs.rate_n_flags); | ||
871 | goto out; | 867 | goto out; |
872 | } | 868 | } |
873 | 869 | ||
@@ -875,15 +871,14 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
875 | while (retries) { | 871 | while (retries) { |
876 | /* Look up the rate and other info used for each tx attempt. | 872 | /* Look up the rate and other info used for each tx attempt. |
877 | * Each tx attempt steps one entry deeper in the rate table. */ | 873 | * Each tx attempt steps one entry deeper in the rate table. */ |
878 | tx_mcs.rate_n_flags = | 874 | tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); |
879 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 875 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, |
880 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, | ||
881 | &tbl_type, &rs_index); | 876 | &tbl_type, &rs_index); |
882 | 877 | ||
883 | /* If type matches "search" table, | 878 | /* If type matches "search" table, |
884 | * add failure to "search" history */ | 879 | * add failure to "search" history */ |
885 | if ((tbl_type.lq_type == search_tbl->lq_type) && | 880 | if ((tbl_type.lq_type == search_tbl->lq_type) && |
886 | (tbl_type.antenna_type == search_tbl->antenna_type) && | 881 | (tbl_type.ant_type == search_tbl->ant_type) && |
887 | (tbl_type.is_SGI == search_tbl->is_SGI)) { | 882 | (tbl_type.is_SGI == search_tbl->is_SGI)) { |
888 | if (search_tbl->expected_tpt) | 883 | if (search_tbl->expected_tpt) |
889 | tpt = search_tbl->expected_tpt[rs_index]; | 884 | tpt = search_tbl->expected_tpt[rs_index]; |
@@ -894,7 +889,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
894 | /* Else if type matches "current/active" table, | 889 | /* Else if type matches "current/active" table, |
895 | * add failure to "current/active" history */ | 890 | * add failure to "current/active" history */ |
896 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 891 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
897 | (tbl_type.antenna_type == curr_tbl->antenna_type) && | 892 | (tbl_type.ant_type == curr_tbl->ant_type) && |
898 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { | 893 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { |
899 | if (curr_tbl->expected_tpt) | 894 | if (curr_tbl->expected_tpt) |
900 | tpt = curr_tbl->expected_tpt[rs_index]; | 895 | tpt = curr_tbl->expected_tpt[rs_index]; |
@@ -917,44 +912,41 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
917 | * if Tx was successful first try, use original rate, | 912 | * if Tx was successful first try, use original rate, |
918 | * else look up the rate that was, finally, successful. | 913 | * else look up the rate that was, finally, successful. |
919 | */ | 914 | */ |
920 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); | 915 | tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); |
921 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); | 916 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); |
922 | 917 | ||
923 | /* Update frame history window with "success" if Tx got ACKed ... */ | 918 | /* Update frame history window with "success" if Tx got ACKed ... */ |
924 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) | 919 | status = !!(info->flags & IEEE80211_TX_STAT_ACK); |
925 | status = 1; | ||
926 | else | ||
927 | status = 0; | ||
928 | 920 | ||
929 | /* If type matches "search" table, | 921 | /* If type matches "search" table, |
930 | * add final tx status to "search" history */ | 922 | * add final tx status to "search" history */ |
931 | if ((tbl_type.lq_type == search_tbl->lq_type) && | 923 | if ((tbl_type.lq_type == search_tbl->lq_type) && |
932 | (tbl_type.antenna_type == search_tbl->antenna_type) && | 924 | (tbl_type.ant_type == search_tbl->ant_type) && |
933 | (tbl_type.is_SGI == search_tbl->is_SGI)) { | 925 | (tbl_type.is_SGI == search_tbl->is_SGI)) { |
934 | if (search_tbl->expected_tpt) | 926 | if (search_tbl->expected_tpt) |
935 | tpt = search_tbl->expected_tpt[rs_index]; | 927 | tpt = search_tbl->expected_tpt[rs_index]; |
936 | else | 928 | else |
937 | tpt = 0; | 929 | tpt = 0; |
938 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) | 930 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
939 | rs_collect_tx_data(search_win, rs_index, tpt, | 931 | rs_collect_tx_data(search_win, rs_index, tpt, |
940 | tx_resp->ampdu_ack_len, | 932 | info->status.ampdu_ack_len, |
941 | tx_resp->ampdu_ack_map); | 933 | info->status.ampdu_ack_map); |
942 | else | 934 | else |
943 | rs_collect_tx_data(search_win, rs_index, tpt, | 935 | rs_collect_tx_data(search_win, rs_index, tpt, |
944 | 1, status); | 936 | 1, status); |
945 | /* Else if type matches "current/active" table, | 937 | /* Else if type matches "current/active" table, |
946 | * add final tx status to "current/active" history */ | 938 | * add final tx status to "current/active" history */ |
947 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 939 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
948 | (tbl_type.antenna_type == curr_tbl->antenna_type) && | 940 | (tbl_type.ant_type == curr_tbl->ant_type) && |
949 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { | 941 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { |
950 | if (curr_tbl->expected_tpt) | 942 | if (curr_tbl->expected_tpt) |
951 | tpt = curr_tbl->expected_tpt[rs_index]; | 943 | tpt = curr_tbl->expected_tpt[rs_index]; |
952 | else | 944 | else |
953 | tpt = 0; | 945 | tpt = 0; |
954 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) | 946 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
955 | rs_collect_tx_data(window, rs_index, tpt, | 947 | rs_collect_tx_data(window, rs_index, tpt, |
956 | tx_resp->ampdu_ack_len, | 948 | info->status.ampdu_ack_len, |
957 | tx_resp->ampdu_ack_map); | 949 | info->status.ampdu_ack_map); |
958 | else | 950 | else |
959 | rs_collect_tx_data(window, rs_index, tpt, | 951 | rs_collect_tx_data(window, rs_index, tpt, |
960 | 1, status); | 952 | 1, status); |
@@ -963,10 +955,10 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
963 | /* If not searching for new mode, increment success/failed counter | 955 | /* If not searching for new mode, increment success/failed counter |
964 | * ... these help determine when to start searching again */ | 956 | * ... these help determine when to start searching again */ |
965 | if (lq_sta->stay_in_tbl) { | 957 | if (lq_sta->stay_in_tbl) { |
966 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { | 958 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
967 | lq_sta->total_success += tx_resp->ampdu_ack_map; | 959 | lq_sta->total_success += info->status.ampdu_ack_map; |
968 | lq_sta->total_failed += | 960 | lq_sta->total_failed += |
969 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); | 961 | (info->status.ampdu_ack_len - info->status.ampdu_ack_map); |
970 | } else { | 962 | } else { |
971 | if (status) | 963 | if (status) |
972 | lq_sta->total_success++; | 964 | lq_sta->total_success++; |
@@ -982,30 +974,6 @@ out: | |||
982 | return; | 974 | return; |
983 | } | 975 | } |
984 | 976 | ||
985 | static u8 rs_is_ant_connected(u8 valid_antenna, | ||
986 | enum iwl4965_antenna_type antenna_type) | ||
987 | { | ||
988 | if (antenna_type == ANT_AUX) | ||
989 | return ((valid_antenna & 0x2) ? 1:0); | ||
990 | else if (antenna_type == ANT_MAIN) | ||
991 | return ((valid_antenna & 0x1) ? 1:0); | ||
992 | else if (antenna_type == ANT_BOTH) | ||
993 | return ((valid_antenna & 0x3) == 0x3); | ||
994 | |||
995 | return 1; | ||
996 | } | ||
997 | |||
998 | static u8 rs_is_other_ant_connected(u8 valid_antenna, | ||
999 | enum iwl4965_antenna_type antenna_type) | ||
1000 | { | ||
1001 | if (antenna_type == ANT_AUX) | ||
1002 | return rs_is_ant_connected(valid_antenna, ANT_MAIN); | ||
1003 | else | ||
1004 | return rs_is_ant_connected(valid_antenna, ANT_AUX); | ||
1005 | |||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | /* | 977 | /* |
1010 | * Begin a period of staying with a selected modulation mode. | 978 | * Begin a period of staying with a selected modulation mode. |
1011 | * Set "stay_in_tbl" flag to prevent any mode switches. | 979 | * Set "stay_in_tbl" flag to prevent any mode switches. |
@@ -1014,10 +982,10 @@ static u8 rs_is_other_ant_connected(u8 valid_antenna, | |||
1014 | * These control how long we stay using same modulation mode before | 982 | * These control how long we stay using same modulation mode before |
1015 | * searching for a new mode. | 983 | * searching for a new mode. |
1016 | */ | 984 | */ |
1017 | static void rs_set_stay_in_table(u8 is_legacy, | 985 | static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, |
1018 | struct iwl4965_lq_sta *lq_sta) | 986 | struct iwl4965_lq_sta *lq_sta) |
1019 | { | 987 | { |
1020 | IWL_DEBUG_HT("we are staying in the same table\n"); | 988 | IWL_DEBUG_RATE("we are staying in the same table\n"); |
1021 | lq_sta->stay_in_tbl = 1; /* only place this gets set */ | 989 | lq_sta->stay_in_tbl = 1; /* only place this gets set */ |
1022 | if (is_legacy) { | 990 | if (is_legacy) { |
1023 | lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; | 991 | lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; |
@@ -1036,7 +1004,7 @@ static void rs_set_stay_in_table(u8 is_legacy, | |||
1036 | /* | 1004 | /* |
1037 | * Find correct throughput table for given mode of modulation | 1005 | * Find correct throughput table for given mode of modulation |
1038 | */ | 1006 | */ |
1039 | static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | 1007 | static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, |
1040 | struct iwl4965_scale_tbl_info *tbl) | 1008 | struct iwl4965_scale_tbl_info *tbl) |
1041 | { | 1009 | { |
1042 | if (is_legacy(tbl->lq_type)) { | 1010 | if (is_legacy(tbl->lq_type)) { |
@@ -1055,7 +1023,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | |||
1055 | else | 1023 | else |
1056 | tbl->expected_tpt = expected_tpt_siso20MHz; | 1024 | tbl->expected_tpt = expected_tpt_siso20MHz; |
1057 | 1025 | ||
1058 | } else if (is_mimo(tbl->lq_type)) { | 1026 | } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */ |
1059 | if (tbl->is_fat && !lq_sta->is_dup) | 1027 | if (tbl->is_fat && !lq_sta->is_dup) |
1060 | if (tbl->is_SGI) | 1028 | if (tbl->is_SGI) |
1061 | tbl->expected_tpt = expected_tpt_mimo40MHzSGI; | 1029 | tbl->expected_tpt = expected_tpt_mimo40MHzSGI; |
@@ -1069,7 +1037,6 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | |||
1069 | tbl->expected_tpt = expected_tpt_G; | 1037 | tbl->expected_tpt = expected_tpt_G; |
1070 | } | 1038 | } |
1071 | 1039 | ||
1072 | #ifdef CONFIG_IWL4965_HT | ||
1073 | /* | 1040 | /* |
1074 | * Find starting rate for new "search" high-throughput mode of modulation. | 1041 | * Find starting rate for new "search" high-throughput mode of modulation. |
1075 | * Goal is to find lowest expected rate (under perfect conditions) that is | 1042 | * Goal is to find lowest expected rate (under perfect conditions) that is |
@@ -1085,7 +1052,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | |||
1085 | static s32 rs_get_best_rate(struct iwl_priv *priv, | 1052 | static s32 rs_get_best_rate(struct iwl_priv *priv, |
1086 | struct iwl4965_lq_sta *lq_sta, | 1053 | struct iwl4965_lq_sta *lq_sta, |
1087 | struct iwl4965_scale_tbl_info *tbl, /* "search" */ | 1054 | struct iwl4965_scale_tbl_info *tbl, /* "search" */ |
1088 | u16 rate_mask, s8 index, s8 rate) | 1055 | u16 rate_mask, s8 index) |
1089 | { | 1056 | { |
1090 | /* "active" values */ | 1057 | /* "active" values */ |
1091 | struct iwl4965_scale_tbl_info *active_tbl = | 1058 | struct iwl4965_scale_tbl_info *active_tbl = |
@@ -1098,11 +1065,13 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1098 | 1065 | ||
1099 | s32 new_rate, high, low, start_hi; | 1066 | s32 new_rate, high, low, start_hi; |
1100 | u16 high_low; | 1067 | u16 high_low; |
1068 | s8 rate = index; | ||
1101 | 1069 | ||
1102 | new_rate = high = low = start_hi = IWL_RATE_INVALID; | 1070 | new_rate = high = low = start_hi = IWL_RATE_INVALID; |
1103 | 1071 | ||
1104 | for (; ;) { | 1072 | for (; ;) { |
1105 | high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type); | 1073 | high_low = rs_get_adjacent_rate(priv, rate, rate_mask, |
1074 | tbl->lq_type); | ||
1106 | 1075 | ||
1107 | low = high_low & 0xff; | 1076 | low = high_low & 0xff; |
1108 | high = (high_low >> 8) & 0xff; | 1077 | high = (high_low >> 8) & 0xff; |
@@ -1169,23 +1138,16 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1169 | 1138 | ||
1170 | return new_rate; | 1139 | return new_rate; |
1171 | } | 1140 | } |
1172 | #endif /* CONFIG_IWL4965_HT */ | ||
1173 | |||
1174 | static inline u8 rs_is_both_ant_supp(u8 valid_antenna) | ||
1175 | { | ||
1176 | return (rs_is_ant_connected(valid_antenna, ANT_BOTH)); | ||
1177 | } | ||
1178 | 1141 | ||
1179 | /* | 1142 | /* |
1180 | * Set up search table for MIMO | 1143 | * Set up search table for MIMO |
1181 | */ | 1144 | */ |
1182 | static int rs_switch_to_mimo(struct iwl_priv *priv, | 1145 | static int rs_switch_to_mimo2(struct iwl_priv *priv, |
1183 | struct iwl4965_lq_sta *lq_sta, | 1146 | struct iwl4965_lq_sta *lq_sta, |
1184 | struct ieee80211_conf *conf, | 1147 | struct ieee80211_conf *conf, |
1185 | struct sta_info *sta, | 1148 | struct sta_info *sta, |
1186 | struct iwl4965_scale_tbl_info *tbl, int index) | 1149 | struct iwl4965_scale_tbl_info *tbl, int index) |
1187 | { | 1150 | { |
1188 | #ifdef CONFIG_IWL4965_HT | ||
1189 | u16 rate_mask; | 1151 | u16 rate_mask; |
1190 | s32 rate; | 1152 | s32 rate; |
1191 | s8 is_green = lq_sta->is_green; | 1153 | s8 is_green = lq_sta->is_green; |
@@ -1194,26 +1156,27 @@ static int rs_switch_to_mimo(struct iwl_priv *priv, | |||
1194 | !sta->ht_info.ht_supported) | 1156 | !sta->ht_info.ht_supported) |
1195 | return -1; | 1157 | return -1; |
1196 | 1158 | ||
1197 | IWL_DEBUG_HT("LQ: try to switch to MIMO\n"); | ||
1198 | tbl->lq_type = LQ_MIMO; | ||
1199 | rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, | ||
1200 | &rate_mask); | ||
1201 | |||
1202 | if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) | 1159 | if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) |
1203 | return -1; | 1160 | return -1; |
1204 | 1161 | ||
1205 | /* Need both Tx chains/antennas to support MIMO */ | 1162 | /* Need both Tx chains/antennas to support MIMO */ |
1206 | if (!rs_is_both_ant_supp(lq_sta->antenna)) | 1163 | if (priv->hw_params.tx_chains_num < 2) |
1207 | return -1; | 1164 | return -1; |
1208 | 1165 | ||
1166 | IWL_DEBUG_RATE("LQ: try to switch to MIMO2\n"); | ||
1167 | |||
1168 | tbl->lq_type = LQ_MIMO2; | ||
1209 | tbl->is_dup = lq_sta->is_dup; | 1169 | tbl->is_dup = lq_sta->is_dup; |
1210 | tbl->action = 0; | 1170 | tbl->action = 0; |
1171 | rate_mask = lq_sta->active_mimo2_rate; | ||
1172 | |||
1211 | if (priv->current_ht_config.supported_chan_width | 1173 | if (priv->current_ht_config.supported_chan_width |
1212 | == IWL_CHANNEL_WIDTH_40MHZ) | 1174 | == IWL_CHANNEL_WIDTH_40MHZ) |
1213 | tbl->is_fat = 1; | 1175 | tbl->is_fat = 1; |
1214 | else | 1176 | else |
1215 | tbl->is_fat = 0; | 1177 | tbl->is_fat = 0; |
1216 | 1178 | ||
1179 | /* FIXME: - don't toggle SGI here | ||
1217 | if (tbl->is_fat) { | 1180 | if (tbl->is_fat) { |
1218 | if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) | 1181 | if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) |
1219 | tbl->is_SGI = 1; | 1182 | tbl->is_SGI = 1; |
@@ -1223,22 +1186,24 @@ static int rs_switch_to_mimo(struct iwl_priv *priv, | |||
1223 | tbl->is_SGI = 1; | 1186 | tbl->is_SGI = 1; |
1224 | else | 1187 | else |
1225 | tbl->is_SGI = 0; | 1188 | tbl->is_SGI = 0; |
1189 | */ | ||
1190 | |||
1191 | rs_set_expected_tpt_table(lq_sta, tbl); | ||
1226 | 1192 | ||
1227 | rs_get_expected_tpt_table(lq_sta, tbl); | 1193 | rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); |
1228 | 1194 | ||
1229 | rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index); | 1195 | IWL_DEBUG_RATE("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask); |
1230 | 1196 | ||
1231 | IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask); | 1197 | if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { |
1232 | if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) | 1198 | IWL_DEBUG_RATE("Can't switch with index %d rate mask %x\n", |
1199 | rate, rate_mask); | ||
1233 | return -1; | 1200 | return -1; |
1234 | rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green); | 1201 | } |
1202 | tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green); | ||
1235 | 1203 | ||
1236 | IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", | 1204 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", |
1237 | tbl->current_rate.rate_n_flags, is_green); | 1205 | tbl->current_rate, is_green); |
1238 | return 0; | 1206 | return 0; |
1239 | #else | ||
1240 | return -1; | ||
1241 | #endif /*CONFIG_IWL4965_HT */ | ||
1242 | } | 1207 | } |
1243 | 1208 | ||
1244 | /* | 1209 | /* |
@@ -1250,21 +1215,20 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1250 | struct sta_info *sta, | 1215 | struct sta_info *sta, |
1251 | struct iwl4965_scale_tbl_info *tbl, int index) | 1216 | struct iwl4965_scale_tbl_info *tbl, int index) |
1252 | { | 1217 | { |
1253 | #ifdef CONFIG_IWL4965_HT | ||
1254 | u16 rate_mask; | 1218 | u16 rate_mask; |
1255 | u8 is_green = lq_sta->is_green; | 1219 | u8 is_green = lq_sta->is_green; |
1256 | s32 rate; | 1220 | s32 rate; |
1257 | 1221 | ||
1258 | IWL_DEBUG_HT("LQ: try to switch to SISO\n"); | ||
1259 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || | 1222 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || |
1260 | !sta->ht_info.ht_supported) | 1223 | !sta->ht_info.ht_supported) |
1261 | return -1; | 1224 | return -1; |
1262 | 1225 | ||
1226 | IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); | ||
1227 | |||
1263 | tbl->is_dup = lq_sta->is_dup; | 1228 | tbl->is_dup = lq_sta->is_dup; |
1264 | tbl->lq_type = LQ_SISO; | 1229 | tbl->lq_type = LQ_SISO; |
1265 | tbl->action = 0; | 1230 | tbl->action = 0; |
1266 | rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, | 1231 | rate_mask = lq_sta->active_siso_rate; |
1267 | &rate_mask); | ||
1268 | 1232 | ||
1269 | if (priv->current_ht_config.supported_chan_width | 1233 | if (priv->current_ht_config.supported_chan_width |
1270 | == IWL_CHANNEL_WIDTH_40MHZ) | 1234 | == IWL_CHANNEL_WIDTH_40MHZ) |
@@ -1272,6 +1236,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1272 | else | 1236 | else |
1273 | tbl->is_fat = 0; | 1237 | tbl->is_fat = 0; |
1274 | 1238 | ||
1239 | /* FIXME: - don't toggle SGI here | ||
1275 | if (tbl->is_fat) { | 1240 | if (tbl->is_fat) { |
1276 | if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) | 1241 | if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) |
1277 | tbl->is_SGI = 1; | 1242 | tbl->is_SGI = 1; |
@@ -1281,27 +1246,24 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1281 | tbl->is_SGI = 1; | 1246 | tbl->is_SGI = 1; |
1282 | else | 1247 | else |
1283 | tbl->is_SGI = 0; | 1248 | tbl->is_SGI = 0; |
1249 | */ | ||
1284 | 1250 | ||
1285 | if (is_green) | 1251 | if (is_green) |
1286 | tbl->is_SGI = 0; | 1252 | tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/ |
1287 | 1253 | ||
1288 | rs_get_expected_tpt_table(lq_sta, tbl); | 1254 | rs_set_expected_tpt_table(lq_sta, tbl); |
1289 | rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index); | 1255 | rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); |
1290 | 1256 | ||
1291 | IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask); | 1257 | IWL_DEBUG_RATE("LQ: get best rate %d mask %X\n", rate, rate_mask); |
1292 | if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { | 1258 | if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { |
1293 | IWL_DEBUG_HT("can not switch with index %d rate mask %x\n", | 1259 | IWL_DEBUG_RATE("can not switch with index %d rate mask %x\n", |
1294 | rate, rate_mask); | 1260 | rate, rate_mask); |
1295 | return -1; | 1261 | return -1; |
1296 | } | 1262 | } |
1297 | rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green); | 1263 | tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green); |
1298 | IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", | 1264 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", |
1299 | tbl->current_rate.rate_n_flags, is_green); | 1265 | tbl->current_rate, is_green); |
1300 | return 0; | 1266 | return 0; |
1301 | #else | ||
1302 | return -1; | ||
1303 | |||
1304 | #endif /*CONFIG_IWL4965_HT */ | ||
1305 | } | 1267 | } |
1306 | 1268 | ||
1307 | /* | 1269 | /* |
@@ -1313,7 +1275,6 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1313 | struct sta_info *sta, | 1275 | struct sta_info *sta, |
1314 | int index) | 1276 | int index) |
1315 | { | 1277 | { |
1316 | int ret = 0; | ||
1317 | struct iwl4965_scale_tbl_info *tbl = | 1278 | struct iwl4965_scale_tbl_info *tbl = |
1318 | &(lq_sta->lq_info[lq_sta->active_tbl]); | 1279 | &(lq_sta->lq_info[lq_sta->active_tbl]); |
1319 | struct iwl4965_scale_tbl_info *search_tbl = | 1280 | struct iwl4965_scale_tbl_info *search_tbl = |
@@ -1322,41 +1283,35 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1322 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - | 1283 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - |
1323 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); | 1284 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); |
1324 | u8 start_action = tbl->action; | 1285 | u8 start_action = tbl->action; |
1286 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | ||
1287 | int ret = 0; | ||
1325 | 1288 | ||
1326 | for (; ;) { | 1289 | for (; ;) { |
1327 | switch (tbl->action) { | 1290 | switch (tbl->action) { |
1328 | case IWL_LEGACY_SWITCH_ANTENNA: | 1291 | case IWL_LEGACY_SWITCH_ANTENNA: |
1329 | IWL_DEBUG_HT("LQ Legacy switch Antenna\n"); | 1292 | IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n"); |
1330 | 1293 | ||
1331 | search_tbl->lq_type = LQ_NONE; | ||
1332 | lq_sta->action_counter++; | 1294 | lq_sta->action_counter++; |
1333 | 1295 | ||
1334 | /* Don't change antenna if success has been great */ | 1296 | /* Don't change antenna if success has been great */ |
1335 | if (window->success_ratio >= IWL_RS_GOOD_RATIO) | 1297 | if (window->success_ratio >= IWL_RS_GOOD_RATIO) |
1336 | break; | 1298 | break; |
1337 | 1299 | ||
1338 | /* Don't change antenna if other one is not connected */ | ||
1339 | if (!rs_is_other_ant_connected(lq_sta->antenna, | ||
1340 | tbl->antenna_type)) | ||
1341 | break; | ||
1342 | |||
1343 | /* Set up search table to try other antenna */ | 1300 | /* Set up search table to try other antenna */ |
1344 | memcpy(search_tbl, tbl, sz); | 1301 | memcpy(search_tbl, tbl, sz); |
1345 | 1302 | ||
1346 | rs_toggle_antenna(&(search_tbl->current_rate), | 1303 | if (rs_toggle_antenna(valid_tx_ant, |
1347 | search_tbl); | 1304 | &search_tbl->current_rate, search_tbl)) { |
1348 | rs_get_expected_tpt_table(lq_sta, search_tbl); | 1305 | lq_sta->search_better_tbl = 1; |
1349 | lq_sta->search_better_tbl = 1; | 1306 | goto out; |
1350 | goto out; | 1307 | } |
1351 | 1308 | break; | |
1352 | case IWL_LEGACY_SWITCH_SISO: | 1309 | case IWL_LEGACY_SWITCH_SISO: |
1353 | IWL_DEBUG_HT("LQ: Legacy switch to SISO\n"); | 1310 | IWL_DEBUG_RATE("LQ: Legacy switch to SISO\n"); |
1354 | 1311 | ||
1355 | /* Set up search table to try SISO */ | 1312 | /* Set up search table to try SISO */ |
1356 | memcpy(search_tbl, tbl, sz); | 1313 | memcpy(search_tbl, tbl, sz); |
1357 | search_tbl->lq_type = LQ_SISO; | ||
1358 | search_tbl->is_SGI = 0; | 1314 | search_tbl->is_SGI = 0; |
1359 | search_tbl->is_fat = 0; | ||
1360 | ret = rs_switch_to_siso(priv, lq_sta, conf, sta, | 1315 | ret = rs_switch_to_siso(priv, lq_sta, conf, sta, |
1361 | search_tbl, index); | 1316 | search_tbl, index); |
1362 | if (!ret) { | 1317 | if (!ret) { |
@@ -1366,16 +1321,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1366 | } | 1321 | } |
1367 | 1322 | ||
1368 | break; | 1323 | break; |
1369 | case IWL_LEGACY_SWITCH_MIMO: | 1324 | case IWL_LEGACY_SWITCH_MIMO2: |
1370 | IWL_DEBUG_HT("LQ: Legacy switch MIMO\n"); | 1325 | IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n"); |
1371 | 1326 | ||
1372 | /* Set up search table to try MIMO */ | 1327 | /* Set up search table to try MIMO */ |
1373 | memcpy(search_tbl, tbl, sz); | 1328 | memcpy(search_tbl, tbl, sz); |
1374 | search_tbl->lq_type = LQ_MIMO; | ||
1375 | search_tbl->is_SGI = 0; | 1329 | search_tbl->is_SGI = 0; |
1376 | search_tbl->is_fat = 0; | 1330 | search_tbl->ant_type = ANT_AB;/*FIXME:RS*/ |
1377 | search_tbl->antenna_type = ANT_BOTH; | 1331 | /*FIXME:RS:need to check ant validity*/ |
1378 | ret = rs_switch_to_mimo(priv, lq_sta, conf, sta, | 1332 | ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, |
1379 | search_tbl, index); | 1333 | search_tbl, index); |
1380 | if (!ret) { | 1334 | if (!ret) { |
1381 | lq_sta->search_better_tbl = 1; | 1335 | lq_sta->search_better_tbl = 1; |
@@ -1385,7 +1339,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1385 | break; | 1339 | break; |
1386 | } | 1340 | } |
1387 | tbl->action++; | 1341 | tbl->action++; |
1388 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO) | 1342 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) |
1389 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA; | 1343 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA; |
1390 | 1344 | ||
1391 | if (tbl->action == start_action) | 1345 | if (tbl->action == start_action) |
@@ -1396,7 +1350,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1396 | 1350 | ||
1397 | out: | 1351 | out: |
1398 | tbl->action++; | 1352 | tbl->action++; |
1399 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO) | 1353 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) |
1400 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA; | 1354 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA; |
1401 | return 0; | 1355 | return 0; |
1402 | 1356 | ||
@@ -1411,7 +1365,6 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1411 | struct sta_info *sta, | 1365 | struct sta_info *sta, |
1412 | int index) | 1366 | int index) |
1413 | { | 1367 | { |
1414 | int ret; | ||
1415 | u8 is_green = lq_sta->is_green; | 1368 | u8 is_green = lq_sta->is_green; |
1416 | struct iwl4965_scale_tbl_info *tbl = | 1369 | struct iwl4965_scale_tbl_info *tbl = |
1417 | &(lq_sta->lq_info[lq_sta->active_tbl]); | 1370 | &(lq_sta->lq_info[lq_sta->active_tbl]); |
@@ -1421,35 +1374,30 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1421 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - | 1374 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - |
1422 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); | 1375 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); |
1423 | u8 start_action = tbl->action; | 1376 | u8 start_action = tbl->action; |
1377 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | ||
1378 | int ret; | ||
1424 | 1379 | ||
1425 | for (;;) { | 1380 | for (;;) { |
1426 | lq_sta->action_counter++; | 1381 | lq_sta->action_counter++; |
1427 | switch (tbl->action) { | 1382 | switch (tbl->action) { |
1428 | case IWL_SISO_SWITCH_ANTENNA: | 1383 | case IWL_SISO_SWITCH_ANTENNA: |
1429 | IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n"); | 1384 | IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n"); |
1430 | search_tbl->lq_type = LQ_NONE; | ||
1431 | if (window->success_ratio >= IWL_RS_GOOD_RATIO) | 1385 | if (window->success_ratio >= IWL_RS_GOOD_RATIO) |
1432 | break; | 1386 | break; |
1433 | if (!rs_is_other_ant_connected(lq_sta->antenna, | ||
1434 | tbl->antenna_type)) | ||
1435 | break; | ||
1436 | 1387 | ||
1437 | memcpy(search_tbl, tbl, sz); | 1388 | memcpy(search_tbl, tbl, sz); |
1438 | search_tbl->action = IWL_SISO_SWITCH_MIMO; | 1389 | if (rs_toggle_antenna(valid_tx_ant, |
1439 | rs_toggle_antenna(&(search_tbl->current_rate), | 1390 | &search_tbl->current_rate, search_tbl)) { |
1440 | search_tbl); | 1391 | lq_sta->search_better_tbl = 1; |
1441 | lq_sta->search_better_tbl = 1; | 1392 | goto out; |
1442 | 1393 | } | |
1443 | goto out; | 1394 | break; |
1444 | 1395 | case IWL_SISO_SWITCH_MIMO2: | |
1445 | case IWL_SISO_SWITCH_MIMO: | 1396 | IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n"); |
1446 | IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO FROM SISO\n"); | ||
1447 | memcpy(search_tbl, tbl, sz); | 1397 | memcpy(search_tbl, tbl, sz); |
1448 | search_tbl->lq_type = LQ_MIMO; | ||
1449 | search_tbl->is_SGI = 0; | 1398 | search_tbl->is_SGI = 0; |
1450 | search_tbl->is_fat = 0; | 1399 | search_tbl->ant_type = ANT_AB; /*FIXME:RS*/ |
1451 | search_tbl->antenna_type = ANT_BOTH; | 1400 | ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, |
1452 | ret = rs_switch_to_mimo(priv, lq_sta, conf, sta, | ||
1453 | search_tbl, index); | 1401 | search_tbl, index); |
1454 | if (!ret) { | 1402 | if (!ret) { |
1455 | lq_sta->search_better_tbl = 1; | 1403 | lq_sta->search_better_tbl = 1; |
@@ -1457,29 +1405,34 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1457 | } | 1405 | } |
1458 | break; | 1406 | break; |
1459 | case IWL_SISO_SWITCH_GI: | 1407 | case IWL_SISO_SWITCH_GI: |
1460 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1408 | if (!tbl->is_fat && |
1409 | !(priv->current_ht_config.sgf & | ||
1410 | HT_SHORT_GI_20MHZ)) | ||
1411 | break; | ||
1412 | if (tbl->is_fat && | ||
1413 | !(priv->current_ht_config.sgf & | ||
1414 | HT_SHORT_GI_40MHZ)) | ||
1415 | break; | ||
1416 | |||
1417 | IWL_DEBUG_RATE("LQ: SISO toggle SGI/NGI\n"); | ||
1461 | 1418 | ||
1462 | memcpy(search_tbl, tbl, sz); | 1419 | memcpy(search_tbl, tbl, sz); |
1463 | search_tbl->action = 0; | 1420 | if (is_green) { |
1464 | if (search_tbl->is_SGI) | 1421 | if (!tbl->is_SGI) |
1465 | search_tbl->is_SGI = 0; | 1422 | break; |
1466 | else if (!is_green) | 1423 | else |
1467 | search_tbl->is_SGI = 1; | 1424 | IWL_ERROR("SGI was set in GF+SISO\n"); |
1468 | else | 1425 | } |
1469 | break; | 1426 | search_tbl->is_SGI = !tbl->is_SGI; |
1470 | lq_sta->search_better_tbl = 1; | 1427 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
1471 | if ((tbl->lq_type == LQ_SISO) && | 1428 | if (tbl->is_SGI) { |
1472 | (tbl->is_SGI)) { | ||
1473 | s32 tpt = lq_sta->last_tpt / 100; | 1429 | s32 tpt = lq_sta->last_tpt / 100; |
1474 | if (((!tbl->is_fat) && | 1430 | if (tpt >= search_tbl->expected_tpt[index]) |
1475 | (tpt >= expected_tpt_siso20MHz[index])) || | 1431 | break; |
1476 | ((tbl->is_fat) && | ||
1477 | (tpt >= expected_tpt_siso40MHz[index]))) | ||
1478 | lq_sta->search_better_tbl = 0; | ||
1479 | } | 1432 | } |
1480 | rs_get_expected_tpt_table(lq_sta, search_tbl); | 1433 | search_tbl->current_rate = rate_n_flags_from_tbl( |
1481 | rs_mcs_from_tbl(&search_tbl->current_rate, | 1434 | search_tbl, index, is_green); |
1482 | search_tbl, index, is_green); | 1435 | lq_sta->search_better_tbl = 1; |
1483 | goto out; | 1436 | goto out; |
1484 | } | 1437 | } |
1485 | tbl->action++; | 1438 | tbl->action++; |
@@ -1507,7 +1460,6 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, | |||
1507 | struct sta_info *sta, | 1460 | struct sta_info *sta, |
1508 | int index) | 1461 | int index) |
1509 | { | 1462 | { |
1510 | int ret; | ||
1511 | s8 is_green = lq_sta->is_green; | 1463 | s8 is_green = lq_sta->is_green; |
1512 | struct iwl4965_scale_tbl_info *tbl = | 1464 | struct iwl4965_scale_tbl_info *tbl = |
1513 | &(lq_sta->lq_info[lq_sta->active_tbl]); | 1465 | &(lq_sta->lq_info[lq_sta->active_tbl]); |
@@ -1516,24 +1468,24 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, | |||
1516 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - | 1468 | u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - |
1517 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); | 1469 | (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); |
1518 | u8 start_action = tbl->action; | 1470 | u8 start_action = tbl->action; |
1471 | /*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/ | ||
1472 | int ret; | ||
1519 | 1473 | ||
1520 | for (;;) { | 1474 | for (;;) { |
1521 | lq_sta->action_counter++; | 1475 | lq_sta->action_counter++; |
1522 | switch (tbl->action) { | 1476 | switch (tbl->action) { |
1523 | case IWL_MIMO_SWITCH_ANTENNA_A: | 1477 | case IWL_MIMO_SWITCH_ANTENNA_A: |
1524 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1478 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1525 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1479 | IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n"); |
1526 | |||
1527 | 1480 | ||
1528 | /* Set up new search table for SISO */ | 1481 | /* Set up new search table for SISO */ |
1529 | memcpy(search_tbl, tbl, sz); | 1482 | memcpy(search_tbl, tbl, sz); |
1530 | search_tbl->lq_type = LQ_SISO; | 1483 | |
1531 | search_tbl->is_SGI = 0; | 1484 | /*FIXME:RS:need to check ant validity + C*/ |
1532 | search_tbl->is_fat = 0; | ||
1533 | if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A) | 1485 | if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A) |
1534 | search_tbl->antenna_type = ANT_MAIN; | 1486 | search_tbl->ant_type = ANT_A; |
1535 | else | 1487 | else |
1536 | search_tbl->antenna_type = ANT_AUX; | 1488 | search_tbl->ant_type = ANT_B; |
1537 | 1489 | ||
1538 | ret = rs_switch_to_siso(priv, lq_sta, conf, sta, | 1490 | ret = rs_switch_to_siso(priv, lq_sta, conf, sta, |
1539 | search_tbl, index); | 1491 | search_tbl, index); |
@@ -1544,37 +1496,35 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, | |||
1544 | break; | 1496 | break; |
1545 | 1497 | ||
1546 | case IWL_MIMO_SWITCH_GI: | 1498 | case IWL_MIMO_SWITCH_GI: |
1547 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n"); | 1499 | if (!tbl->is_fat && |
1500 | !(priv->current_ht_config.sgf & | ||
1501 | HT_SHORT_GI_20MHZ)) | ||
1502 | break; | ||
1503 | if (tbl->is_fat && | ||
1504 | !(priv->current_ht_config.sgf & | ||
1505 | HT_SHORT_GI_40MHZ)) | ||
1506 | break; | ||
1507 | |||
1508 | IWL_DEBUG_RATE("LQ: MIMO toggle SGI/NGI\n"); | ||
1548 | 1509 | ||
1549 | /* Set up new search table for MIMO */ | 1510 | /* Set up new search table for MIMO */ |
1550 | memcpy(search_tbl, tbl, sz); | 1511 | memcpy(search_tbl, tbl, sz); |
1551 | search_tbl->lq_type = LQ_MIMO; | 1512 | search_tbl->is_SGI = !tbl->is_SGI; |
1552 | search_tbl->antenna_type = ANT_BOTH; | 1513 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
1553 | search_tbl->action = 0; | ||
1554 | if (search_tbl->is_SGI) | ||
1555 | search_tbl->is_SGI = 0; | ||
1556 | else | ||
1557 | search_tbl->is_SGI = 1; | ||
1558 | lq_sta->search_better_tbl = 1; | ||
1559 | |||
1560 | /* | 1514 | /* |
1561 | * If active table already uses the fastest possible | 1515 | * If active table already uses the fastest possible |
1562 | * modulation (dual stream with short guard interval), | 1516 | * modulation (dual stream with short guard interval), |
1563 | * and it's working well, there's no need to look | 1517 | * and it's working well, there's no need to look |
1564 | * for a better type of modulation! | 1518 | * for a better type of modulation! |
1565 | */ | 1519 | */ |
1566 | if ((tbl->lq_type == LQ_MIMO) && | 1520 | if (tbl->is_SGI) { |
1567 | (tbl->is_SGI)) { | ||
1568 | s32 tpt = lq_sta->last_tpt / 100; | 1521 | s32 tpt = lq_sta->last_tpt / 100; |
1569 | if (((!tbl->is_fat) && | 1522 | if (tpt >= search_tbl->expected_tpt[index]) |
1570 | (tpt >= expected_tpt_mimo20MHz[index])) || | 1523 | break; |
1571 | ((tbl->is_fat) && | ||
1572 | (tpt >= expected_tpt_mimo40MHz[index]))) | ||
1573 | lq_sta->search_better_tbl = 0; | ||
1574 | } | 1524 | } |
1575 | rs_get_expected_tpt_table(lq_sta, search_tbl); | 1525 | search_tbl->current_rate = rate_n_flags_from_tbl( |
1576 | rs_mcs_from_tbl(&search_tbl->current_rate, | 1526 | search_tbl, index, is_green); |
1577 | search_tbl, index, is_green); | 1527 | lq_sta->search_better_tbl = 1; |
1578 | goto out; | 1528 | goto out; |
1579 | 1529 | ||
1580 | } | 1530 | } |
@@ -1608,7 +1558,9 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1608 | int i; | 1558 | int i; |
1609 | int active_tbl; | 1559 | int active_tbl; |
1610 | int flush_interval_passed = 0; | 1560 | int flush_interval_passed = 0; |
1561 | struct iwl_priv *priv; | ||
1611 | 1562 | ||
1563 | priv = lq_sta->drv; | ||
1612 | active_tbl = lq_sta->active_tbl; | 1564 | active_tbl = lq_sta->active_tbl; |
1613 | 1565 | ||
1614 | tbl = &(lq_sta->lq_info[active_tbl]); | 1566 | tbl = &(lq_sta->lq_info[active_tbl]); |
@@ -1623,9 +1575,6 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1623 | (unsigned long)(lq_sta->flush_timer + | 1575 | (unsigned long)(lq_sta->flush_timer + |
1624 | IWL_RATE_SCALE_FLUSH_INTVL)); | 1576 | IWL_RATE_SCALE_FLUSH_INTVL)); |
1625 | 1577 | ||
1626 | /* For now, disable the elapsed time criterion */ | ||
1627 | flush_interval_passed = 0; | ||
1628 | |||
1629 | /* | 1578 | /* |
1630 | * Check if we should allow search for new modulation mode. | 1579 | * Check if we should allow search for new modulation mode. |
1631 | * If many frames have failed or succeeded, or we've used | 1580 | * If many frames have failed or succeeded, or we've used |
@@ -1638,7 +1587,7 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1638 | (lq_sta->total_success > lq_sta->max_success_limit) || | 1587 | (lq_sta->total_success > lq_sta->max_success_limit) || |
1639 | ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) | 1588 | ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) |
1640 | && (flush_interval_passed))) { | 1589 | && (flush_interval_passed))) { |
1641 | IWL_DEBUG_HT("LQ: stay is expired %d %d %d\n:", | 1590 | IWL_DEBUG_RATE("LQ: stay is expired %d %d %d\n:", |
1642 | lq_sta->total_failed, | 1591 | lq_sta->total_failed, |
1643 | lq_sta->total_success, | 1592 | lq_sta->total_success, |
1644 | flush_interval_passed); | 1593 | flush_interval_passed); |
@@ -1661,7 +1610,7 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1661 | lq_sta->table_count_limit) { | 1610 | lq_sta->table_count_limit) { |
1662 | lq_sta->table_count = 0; | 1611 | lq_sta->table_count = 0; |
1663 | 1612 | ||
1664 | IWL_DEBUG_HT("LQ: stay in table clear win\n"); | 1613 | IWL_DEBUG_RATE("LQ: stay in table clear win\n"); |
1665 | for (i = 0; i < IWL_RATE_COUNT; i++) | 1614 | for (i = 0; i < IWL_RATE_COUNT; i++) |
1666 | rs_rate_scale_clear_window( | 1615 | rs_rate_scale_clear_window( |
1667 | &(tbl->win[i])); | 1616 | &(tbl->win[i])); |
@@ -1699,24 +1648,23 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1699 | int high_tpt = IWL_INVALID_VALUE; | 1648 | int high_tpt = IWL_INVALID_VALUE; |
1700 | u32 fail_count; | 1649 | u32 fail_count; |
1701 | s8 scale_action = 0; | 1650 | s8 scale_action = 0; |
1702 | u16 fc, rate_mask; | 1651 | __le16 fc; |
1652 | u16 rate_mask; | ||
1703 | u8 update_lq = 0; | 1653 | u8 update_lq = 0; |
1704 | struct iwl4965_lq_sta *lq_sta; | 1654 | struct iwl4965_lq_sta *lq_sta; |
1705 | struct iwl4965_scale_tbl_info *tbl, *tbl1; | 1655 | struct iwl4965_scale_tbl_info *tbl, *tbl1; |
1706 | u16 rate_scale_index_msk = 0; | 1656 | u16 rate_scale_index_msk = 0; |
1707 | struct iwl4965_rate mcs_rate; | 1657 | u32 rate; |
1708 | u8 is_green = 0; | 1658 | u8 is_green = 0; |
1709 | u8 active_tbl = 0; | 1659 | u8 active_tbl = 0; |
1710 | u8 done_search = 0; | 1660 | u8 done_search = 0; |
1711 | u16 high_low; | 1661 | u16 high_low; |
1712 | #ifdef CONFIG_IWL4965_HT | 1662 | s32 sr; |
1713 | u8 tid = MAX_TID_COUNT; | 1663 | u8 tid = MAX_TID_COUNT; |
1714 | __le16 *qc; | ||
1715 | #endif | ||
1716 | 1664 | ||
1717 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1665 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1718 | 1666 | ||
1719 | fc = le16_to_cpu(hdr->frame_control); | 1667 | fc = hdr->frame_control; |
1720 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { | 1668 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { |
1721 | /* Send management frames and broadcast/multicast data using | 1669 | /* Send management frames and broadcast/multicast data using |
1722 | * lowest rate. */ | 1670 | * lowest rate. */ |
@@ -1727,19 +1675,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1727 | if (!sta || !sta->rate_ctrl_priv) | 1675 | if (!sta || !sta->rate_ctrl_priv) |
1728 | return; | 1676 | return; |
1729 | 1677 | ||
1730 | if (!priv->lq_mngr.lq_ready) { | ||
1731 | IWL_DEBUG_RATE("still rate scaling not ready\n"); | ||
1732 | return; | ||
1733 | } | ||
1734 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1678 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1735 | 1679 | ||
1736 | #ifdef CONFIG_IWL4965_HT | 1680 | tid = rs_tl_add_packet(lq_sta, hdr); |
1737 | qc = ieee80211_get_qos_ctrl(hdr); | 1681 | |
1738 | if (qc) { | ||
1739 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1740 | rs_tl_add_packet(lq_sta, tid); | ||
1741 | } | ||
1742 | #endif | ||
1743 | /* | 1682 | /* |
1744 | * Select rate-scale / modulation-mode table to work with in | 1683 | * Select rate-scale / modulation-mode table to work with in |
1745 | * the rest of this function: "search" if searching for better | 1684 | * the rest of this function: "search" if searching for better |
@@ -1760,8 +1699,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1760 | tbl->lq_type); | 1699 | tbl->lq_type); |
1761 | 1700 | ||
1762 | /* rates available for this association, and for modulation mode */ | 1701 | /* rates available for this association, and for modulation mode */ |
1763 | rs_get_supported_rates(lq_sta, hdr, tbl->lq_type, | 1702 | rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); |
1764 | &rate_mask); | ||
1765 | 1703 | ||
1766 | IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask); | 1704 | IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask); |
1767 | 1705 | ||
@@ -1781,27 +1719,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1781 | if (!rate_scale_index_msk) | 1719 | if (!rate_scale_index_msk) |
1782 | rate_scale_index_msk = rate_mask; | 1720 | rate_scale_index_msk = rate_mask; |
1783 | 1721 | ||
1784 | /* If current rate is no longer supported on current association, | 1722 | if (!((1 << index) & rate_scale_index_msk)) { |
1785 | * or user changed preferences for rates, find a new supported rate. */ | 1723 | IWL_ERROR("Current Rate is not valid\n"); |
1786 | if (index < 0 || !((1 << index) & rate_scale_index_msk)) { | 1724 | return; |
1787 | index = IWL_INVALID_VALUE; | ||
1788 | update_lq = 1; | ||
1789 | |||
1790 | /* get the highest available rate */ | ||
1791 | for (i = 0; i <= IWL_RATE_COUNT; i++) { | ||
1792 | if ((1 << i) & rate_scale_index_msk) | ||
1793 | index = i; | ||
1794 | } | ||
1795 | |||
1796 | if (index == IWL_INVALID_VALUE) { | ||
1797 | IWL_WARNING("Can not find a suitable rate\n"); | ||
1798 | return; | ||
1799 | } | ||
1800 | } | 1725 | } |
1801 | 1726 | ||
1802 | /* Get expected throughput table and history window for current rate */ | 1727 | /* Get expected throughput table and history window for current rate */ |
1803 | if (!tbl->expected_tpt) | 1728 | if (!tbl->expected_tpt) { |
1804 | rs_get_expected_tpt_table(lq_sta, tbl); | 1729 | IWL_ERROR("tbl->expected_tpt is NULL\n"); |
1730 | return; | ||
1731 | } | ||
1805 | 1732 | ||
1806 | window = &(tbl->win[index]); | 1733 | window = &(tbl->win[index]); |
1807 | 1734 | ||
@@ -1813,10 +1740,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1813 | * in current association (use new rate found above). | 1740 | * in current association (use new rate found above). |
1814 | */ | 1741 | */ |
1815 | fail_count = window->counter - window->success_counter; | 1742 | fail_count = window->counter - window->success_counter; |
1816 | if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && | 1743 | if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && |
1817 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) | 1744 | (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { |
1818 | || (tbl->expected_tpt == NULL)) { | 1745 | IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d " |
1819 | IWL_DEBUG_RATE("LQ: still below TH succ %d total %d " | ||
1820 | "for index %d\n", | 1746 | "for index %d\n", |
1821 | window->success_counter, window->counter, index); | 1747 | window->success_counter, window->counter, index); |
1822 | 1748 | ||
@@ -1827,44 +1753,51 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1827 | * or search for a new one? */ | 1753 | * or search for a new one? */ |
1828 | rs_stay_in_table(lq_sta); | 1754 | rs_stay_in_table(lq_sta); |
1829 | 1755 | ||
1830 | /* Set up new rate table in uCode, if needed */ | ||
1831 | if (update_lq) { | ||
1832 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | ||
1833 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | ||
1834 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | ||
1835 | } | ||
1836 | goto out; | 1756 | goto out; |
1837 | 1757 | ||
1838 | /* Else we have enough samples; calculate estimate of | 1758 | /* Else we have enough samples; calculate estimate of |
1839 | * actual average throughput */ | 1759 | * actual average throughput */ |
1840 | } else | 1760 | } else { |
1841 | window->average_tpt = ((window->success_ratio * | 1761 | /*FIXME:RS remove this else if we don't get this error*/ |
1762 | if (window->average_tpt != ((window->success_ratio * | ||
1763 | tbl->expected_tpt[index] + 64) / 128)) { | ||
1764 | IWL_ERROR("expected_tpt should have been calculated" | ||
1765 | " by now\n"); | ||
1766 | window->average_tpt = ((window->success_ratio * | ||
1842 | tbl->expected_tpt[index] + 64) / 128); | 1767 | tbl->expected_tpt[index] + 64) / 128); |
1768 | } | ||
1769 | } | ||
1843 | 1770 | ||
1844 | /* If we are searching for better modulation mode, check success. */ | 1771 | /* If we are searching for better modulation mode, check success. */ |
1845 | if (lq_sta->search_better_tbl) { | 1772 | if (lq_sta->search_better_tbl) { |
1846 | int success_limit = IWL_RATE_SCALE_SWITCH; | ||
1847 | 1773 | ||
1848 | /* If good success, continue using the "search" mode; | 1774 | /* If good success, continue using the "search" mode; |
1849 | * no need to send new link quality command, since we're | 1775 | * no need to send new link quality command, since we're |
1850 | * continuing to use the setup that we've been trying. */ | 1776 | * continuing to use the setup that we've been trying. */ |
1851 | if ((window->success_ratio > success_limit) || | 1777 | if (window->average_tpt > lq_sta->last_tpt) { |
1852 | (window->average_tpt > lq_sta->last_tpt)) { | 1778 | |
1853 | if (!is_legacy(tbl->lq_type)) { | 1779 | IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE " |
1854 | IWL_DEBUG_HT("LQ: we are switching to HT" | 1780 | "suc=%d cur-tpt=%d old-tpt=%d\n", |
1855 | " rate suc %d current tpt %d" | 1781 | window->success_ratio, |
1856 | " old tpt %d\n", | 1782 | window->average_tpt, |
1857 | window->success_ratio, | 1783 | lq_sta->last_tpt); |
1858 | window->average_tpt, | 1784 | |
1859 | lq_sta->last_tpt); | 1785 | if (!is_legacy(tbl->lq_type)) |
1860 | lq_sta->enable_counter = 1; | 1786 | lq_sta->enable_counter = 1; |
1861 | } | 1787 | |
1862 | /* Swap tables; "search" becomes "active" */ | 1788 | /* Swap tables; "search" becomes "active" */ |
1863 | lq_sta->active_tbl = active_tbl; | 1789 | lq_sta->active_tbl = active_tbl; |
1864 | current_tpt = window->average_tpt; | 1790 | current_tpt = window->average_tpt; |
1865 | 1791 | ||
1866 | /* Else poor success; go back to mode in "active" table */ | 1792 | /* Else poor success; go back to mode in "active" table */ |
1867 | } else { | 1793 | } else { |
1794 | |||
1795 | IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE " | ||
1796 | "suc=%d cur-tpt=%d old-tpt=%d\n", | ||
1797 | window->success_ratio, | ||
1798 | window->average_tpt, | ||
1799 | lq_sta->last_tpt); | ||
1800 | |||
1868 | /* Nullify "search" table */ | 1801 | /* Nullify "search" table */ |
1869 | tbl->lq_type = LQ_NONE; | 1802 | tbl->lq_type = LQ_NONE; |
1870 | 1803 | ||
@@ -1873,13 +1806,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1873 | tbl = &(lq_sta->lq_info[active_tbl]); | 1806 | tbl = &(lq_sta->lq_info[active_tbl]); |
1874 | 1807 | ||
1875 | /* Revert to "active" rate and throughput info */ | 1808 | /* Revert to "active" rate and throughput info */ |
1876 | index = iwl4965_hwrate_to_plcp_idx( | 1809 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); |
1877 | tbl->current_rate.rate_n_flags); | ||
1878 | current_tpt = lq_sta->last_tpt; | 1810 | current_tpt = lq_sta->last_tpt; |
1879 | 1811 | ||
1880 | /* Need to set up a new rate table in uCode */ | 1812 | /* Need to set up a new rate table in uCode */ |
1881 | update_lq = 1; | 1813 | update_lq = 1; |
1882 | IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n"); | ||
1883 | } | 1814 | } |
1884 | 1815 | ||
1885 | /* Either way, we've made a decision; modulation mode | 1816 | /* Either way, we've made a decision; modulation mode |
@@ -1891,11 +1822,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1891 | 1822 | ||
1892 | /* (Else) not in search of better modulation mode, try for better | 1823 | /* (Else) not in search of better modulation mode, try for better |
1893 | * starting rate, while staying in this mode. */ | 1824 | * starting rate, while staying in this mode. */ |
1894 | high_low = rs_get_adjacent_rate(index, rate_scale_index_msk, | 1825 | high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk, |
1895 | tbl->lq_type); | 1826 | tbl->lq_type); |
1896 | low = high_low & 0xff; | 1827 | low = high_low & 0xff; |
1897 | high = (high_low >> 8) & 0xff; | 1828 | high = (high_low >> 8) & 0xff; |
1898 | 1829 | ||
1830 | sr = window->success_ratio; | ||
1831 | |||
1899 | /* Collect measured throughputs for current and adjacent rates */ | 1832 | /* Collect measured throughputs for current and adjacent rates */ |
1900 | current_tpt = window->average_tpt; | 1833 | current_tpt = window->average_tpt; |
1901 | if (low != IWL_RATE_INVALID) | 1834 | if (low != IWL_RATE_INVALID) |
@@ -1903,19 +1836,22 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1903 | if (high != IWL_RATE_INVALID) | 1836 | if (high != IWL_RATE_INVALID) |
1904 | high_tpt = tbl->win[high].average_tpt; | 1837 | high_tpt = tbl->win[high].average_tpt; |
1905 | 1838 | ||
1906 | /* Assume rate increase */ | 1839 | scale_action = 0; |
1907 | scale_action = 1; | ||
1908 | 1840 | ||
1909 | /* Too many failures, decrease rate */ | 1841 | /* Too many failures, decrease rate */ |
1910 | if ((window->success_ratio <= IWL_RATE_DECREASE_TH) || | 1842 | if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { |
1911 | (current_tpt == 0)) { | ||
1912 | IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); | 1843 | IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); |
1913 | scale_action = -1; | 1844 | scale_action = -1; |
1914 | 1845 | ||
1915 | /* No throughput measured yet for adjacent rates; try increase. */ | 1846 | /* No throughput measured yet for adjacent rates; try increase. */ |
1916 | } else if ((low_tpt == IWL_INVALID_VALUE) && | 1847 | } else if ((low_tpt == IWL_INVALID_VALUE) && |
1917 | (high_tpt == IWL_INVALID_VALUE)) | 1848 | (high_tpt == IWL_INVALID_VALUE)) { |
1918 | scale_action = 1; | 1849 | |
1850 | if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) | ||
1851 | scale_action = 1; | ||
1852 | else if (low != IWL_RATE_INVALID) | ||
1853 | scale_action = -1; | ||
1854 | } | ||
1919 | 1855 | ||
1920 | /* Both adjacent throughputs are measured, but neither one has better | 1856 | /* Both adjacent throughputs are measured, but neither one has better |
1921 | * throughput; we're using the best rate, don't change it! */ | 1857 | * throughput; we're using the best rate, don't change it! */ |
@@ -1931,9 +1867,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1931 | /* Higher adjacent rate's throughput is measured */ | 1867 | /* Higher adjacent rate's throughput is measured */ |
1932 | if (high_tpt != IWL_INVALID_VALUE) { | 1868 | if (high_tpt != IWL_INVALID_VALUE) { |
1933 | /* Higher rate has better throughput */ | 1869 | /* Higher rate has better throughput */ |
1934 | if (high_tpt > current_tpt) | 1870 | if (high_tpt > current_tpt && |
1871 | sr >= IWL_RATE_INCREASE_TH) { | ||
1935 | scale_action = 1; | 1872 | scale_action = 1; |
1936 | else { | 1873 | } else { |
1937 | IWL_DEBUG_RATE | 1874 | IWL_DEBUG_RATE |
1938 | ("decrease rate because of high tpt\n"); | 1875 | ("decrease rate because of high tpt\n"); |
1939 | scale_action = -1; | 1876 | scale_action = -1; |
@@ -1946,23 +1883,17 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1946 | IWL_DEBUG_RATE | 1883 | IWL_DEBUG_RATE |
1947 | ("decrease rate because of low tpt\n"); | 1884 | ("decrease rate because of low tpt\n"); |
1948 | scale_action = -1; | 1885 | scale_action = -1; |
1949 | } else | 1886 | } else if (sr >= IWL_RATE_INCREASE_TH) { |
1950 | scale_action = 1; | 1887 | scale_action = 1; |
1888 | } | ||
1951 | } | 1889 | } |
1952 | } | 1890 | } |
1953 | 1891 | ||
1954 | /* Sanity check; asked for decrease, but success rate or throughput | 1892 | /* Sanity check; asked for decrease, but success rate or throughput |
1955 | * has been good at old rate. Don't change it. */ | 1893 | * has been good at old rate. Don't change it. */ |
1956 | if (scale_action == -1) { | 1894 | if ((scale_action == -1) && (low != IWL_RATE_INVALID) && |
1957 | if ((low != IWL_RATE_INVALID) && | 1895 | ((sr > IWL_RATE_HIGH_TH) || |
1958 | ((window->success_ratio > IWL_RATE_HIGH_TH) || | ||
1959 | (current_tpt > (100 * tbl->expected_tpt[low])))) | 1896 | (current_tpt > (100 * tbl->expected_tpt[low])))) |
1960 | scale_action = 0; | ||
1961 | |||
1962 | /* Sanity check; asked for increase, but success rate has not been great | ||
1963 | * even at old rate, higher rate will be worse. Don't change it. */ | ||
1964 | } else if ((scale_action == 1) && | ||
1965 | (window->success_ratio < IWL_RATE_INCREASE_TH)) | ||
1966 | scale_action = 0; | 1897 | scale_action = 0; |
1967 | 1898 | ||
1968 | switch (scale_action) { | 1899 | switch (scale_action) { |
@@ -1987,15 +1918,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1987 | break; | 1918 | break; |
1988 | } | 1919 | } |
1989 | 1920 | ||
1990 | IWL_DEBUG_HT("choose rate scale index %d action %d low %d " | 1921 | IWL_DEBUG_RATE("choose rate scale index %d action %d low %d " |
1991 | "high %d type %d\n", | 1922 | "high %d type %d\n", |
1992 | index, scale_action, low, high, tbl->lq_type); | 1923 | index, scale_action, low, high, tbl->lq_type); |
1993 | 1924 | ||
1994 | lq_update: | 1925 | lq_update: |
1995 | /* Replace uCode's rate table for the destination station. */ | 1926 | /* Replace uCode's rate table for the destination station. */ |
1996 | if (update_lq) { | 1927 | if (update_lq) { |
1997 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | 1928 | rate = rate_n_flags_from_tbl(tbl, index, is_green); |
1998 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 1929 | rs_fill_link_cmd(priv, lq_sta, rate); |
1999 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 1930 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2000 | } | 1931 | } |
2001 | 1932 | ||
@@ -2029,13 +1960,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2029 | rs_rate_scale_clear_window(&(tbl->win[i])); | 1960 | rs_rate_scale_clear_window(&(tbl->win[i])); |
2030 | 1961 | ||
2031 | /* Use new "search" start rate */ | 1962 | /* Use new "search" start rate */ |
2032 | index = iwl4965_hwrate_to_plcp_idx( | 1963 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); |
2033 | tbl->current_rate.rate_n_flags); | ||
2034 | 1964 | ||
2035 | IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", | 1965 | IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n", |
2036 | tbl->current_rate.rate_n_flags, index); | 1966 | tbl->current_rate, index); |
2037 | rs_fill_link_cmd(lq_sta, &tbl->current_rate, | 1967 | rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); |
2038 | &lq_sta->lq); | ||
2039 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 1968 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2040 | } | 1969 | } |
2041 | 1970 | ||
@@ -2046,13 +1975,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2046 | * before next round of mode comparisons. */ | 1975 | * before next round of mode comparisons. */ |
2047 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); | 1976 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2048 | if (is_legacy(tbl1->lq_type) && | 1977 | if (is_legacy(tbl1->lq_type) && |
2049 | #ifdef CONFIG_IWL4965_HT | ||
2050 | (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && | 1978 | (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && |
2051 | #endif | ||
2052 | (lq_sta->action_counter >= 1)) { | 1979 | (lq_sta->action_counter >= 1)) { |
2053 | lq_sta->action_counter = 0; | 1980 | lq_sta->action_counter = 0; |
2054 | IWL_DEBUG_HT("LQ: STAY in legacy table\n"); | 1981 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); |
2055 | rs_set_stay_in_table(1, lq_sta); | 1982 | rs_set_stay_in_table(priv, 1, lq_sta); |
2056 | } | 1983 | } |
2057 | 1984 | ||
2058 | /* If we're in an HT mode, and all 3 mode switch actions | 1985 | /* If we're in an HT mode, and all 3 mode switch actions |
@@ -2060,16 +1987,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2060 | * mode for a while before next round of mode comparisons. */ | 1987 | * mode for a while before next round of mode comparisons. */ |
2061 | if (lq_sta->enable_counter && | 1988 | if (lq_sta->enable_counter && |
2062 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 1989 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
2063 | #ifdef CONFIG_IWL4965_HT | ||
2064 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && | 1990 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
2065 | (lq_sta->tx_agg_tid_en & (1 << tid)) && | 1991 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
2066 | (tid != MAX_TID_COUNT)) { | 1992 | (tid != MAX_TID_COUNT)) { |
2067 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); | 1993 | IWL_DEBUG_RATE("try to aggregate tid %d\n", tid); |
2068 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); | 1994 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
2069 | } | 1995 | } |
2070 | #endif /*CONFIG_IWL4965_HT */ | ||
2071 | lq_sta->action_counter = 0; | 1996 | lq_sta->action_counter = 0; |
2072 | rs_set_stay_in_table(0, lq_sta); | 1997 | rs_set_stay_in_table(priv, 0, lq_sta); |
2073 | } | 1998 | } |
2074 | 1999 | ||
2075 | /* | 2000 | /* |
@@ -2085,7 +2010,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2085 | } | 2010 | } |
2086 | 2011 | ||
2087 | out: | 2012 | out: |
2088 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); | 2013 | tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green); |
2089 | i = index; | 2014 | i = index; |
2090 | sta->last_txrate_idx = i; | 2015 | sta->last_txrate_idx = i; |
2091 | 2016 | ||
@@ -2105,13 +2030,14 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2105 | struct ieee80211_conf *conf, | 2030 | struct ieee80211_conf *conf, |
2106 | struct sta_info *sta) | 2031 | struct sta_info *sta) |
2107 | { | 2032 | { |
2108 | int i; | ||
2109 | struct iwl4965_lq_sta *lq_sta; | 2033 | struct iwl4965_lq_sta *lq_sta; |
2110 | struct iwl4965_scale_tbl_info *tbl; | 2034 | struct iwl4965_scale_tbl_info *tbl; |
2111 | u8 active_tbl = 0; | ||
2112 | int rate_idx; | 2035 | int rate_idx; |
2036 | int i; | ||
2037 | u32 rate; | ||
2113 | u8 use_green = rs_use_green(priv, conf); | 2038 | u8 use_green = rs_use_green(priv, conf); |
2114 | struct iwl4965_rate mcs_rate; | 2039 | u8 active_tbl = 0; |
2040 | u8 valid_tx_ant; | ||
2115 | 2041 | ||
2116 | if (!sta || !sta->rate_ctrl_priv) | 2042 | if (!sta || !sta->rate_ctrl_priv) |
2117 | goto out; | 2043 | goto out; |
@@ -2123,6 +2049,8 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2123 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 2049 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) |
2124 | goto out; | 2050 | goto out; |
2125 | 2051 | ||
2052 | valid_tx_ant = priv->hw_params.valid_tx_ant; | ||
2053 | |||
2126 | if (!lq_sta->search_better_tbl) | 2054 | if (!lq_sta->search_better_tbl) |
2127 | active_tbl = lq_sta->active_tbl; | 2055 | active_tbl = lq_sta->active_tbl; |
2128 | else | 2056 | else |
@@ -2133,22 +2061,23 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2133 | if ((i < 0) || (i >= IWL_RATE_COUNT)) | 2061 | if ((i < 0) || (i >= IWL_RATE_COUNT)) |
2134 | i = 0; | 2062 | i = 0; |
2135 | 2063 | ||
2136 | mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ; | 2064 | /* FIXME:RS: This is also wrong in 4965 */ |
2137 | mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK; | 2065 | rate = iwl_rates[i].plcp; |
2138 | mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK; | 2066 | rate |= RATE_MCS_ANT_B_MSK; |
2067 | rate &= ~RATE_MCS_ANT_A_MSK; | ||
2139 | 2068 | ||
2140 | if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) | 2069 | if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) |
2141 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; | 2070 | rate |= RATE_MCS_CCK_MSK; |
2142 | 2071 | ||
2143 | tbl->antenna_type = ANT_AUX; | 2072 | tbl->ant_type = ANT_B; |
2144 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); | 2073 | rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx); |
2145 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) | 2074 | if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) |
2146 | rs_toggle_antenna(&mcs_rate, tbl); | 2075 | rs_toggle_antenna(valid_tx_ant, &rate, tbl); |
2147 | 2076 | ||
2148 | rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green); | 2077 | rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green); |
2149 | tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; | 2078 | tbl->current_rate = rate; |
2150 | rs_get_expected_tpt_table(lq_sta, tbl); | 2079 | rs_set_expected_tpt_table(lq_sta, tbl); |
2151 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 2080 | rs_fill_link_cmd(NULL, lq_sta, rate); |
2152 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2081 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2153 | out: | 2082 | out: |
2154 | return; | 2083 | return; |
@@ -2165,7 +2094,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2165 | struct ieee80211_conf *conf = &local->hw.conf; | 2094 | struct ieee80211_conf *conf = &local->hw.conf; |
2166 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2095 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2167 | struct sta_info *sta; | 2096 | struct sta_info *sta; |
2168 | u16 fc; | 2097 | __le16 fc; |
2169 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; | 2098 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
2170 | struct iwl4965_lq_sta *lq_sta; | 2099 | struct iwl4965_lq_sta *lq_sta; |
2171 | 2100 | ||
@@ -2177,10 +2106,10 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2177 | 2106 | ||
2178 | /* Send management frames and broadcast/multicast data using lowest | 2107 | /* Send management frames and broadcast/multicast data using lowest |
2179 | * rate. */ | 2108 | * rate. */ |
2180 | fc = le16_to_cpu(hdr->frame_control); | 2109 | fc = hdr->frame_control; |
2181 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2110 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2182 | !sta || !sta->rate_ctrl_priv) { | 2111 | !sta || !sta->rate_ctrl_priv) { |
2183 | sel->rate = rate_lowest(local, sband, sta); | 2112 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
2184 | goto out; | 2113 | goto out; |
2185 | } | 2114 | } |
2186 | 2115 | ||
@@ -2189,13 +2118,13 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2189 | 2118 | ||
2190 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2119 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
2191 | !lq_sta->ibss_sta_added) { | 2120 | !lq_sta->ibss_sta_added) { |
2192 | u8 sta_id = iwl4965_hw_find_station(priv, hdr->addr1); | 2121 | u8 sta_id = iwl_find_station(priv, hdr->addr1); |
2193 | DECLARE_MAC_BUF(mac); | 2122 | DECLARE_MAC_BUF(mac); |
2194 | 2123 | ||
2195 | if (sta_id == IWL_INVALID_STATION) { | 2124 | if (sta_id == IWL_INVALID_STATION) { |
2196 | IWL_DEBUG_RATE("LQ: ADD station %s\n", | 2125 | IWL_DEBUG_RATE("LQ: ADD station %s\n", |
2197 | print_mac(mac, hdr->addr1)); | 2126 | print_mac(mac, hdr->addr1)); |
2198 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, | 2127 | sta_id = iwl_add_station_flags(priv, hdr->addr1, |
2199 | 0, CMD_ASYNC, NULL); | 2128 | 0, CMD_ASYNC, NULL); |
2200 | } | 2129 | } |
2201 | if ((sta_id != IWL_INVALID_STATION)) { | 2130 | if ((sta_id != IWL_INVALID_STATION)) { |
@@ -2204,26 +2133,27 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2204 | lq_sta->ibss_sta_added = 1; | 2133 | lq_sta->ibss_sta_added = 1; |
2205 | rs_initialize_lq(priv, conf, sta); | 2134 | rs_initialize_lq(priv, conf, sta); |
2206 | } | 2135 | } |
2207 | if (!lq_sta->ibss_sta_added) | ||
2208 | goto done; | ||
2209 | } | 2136 | } |
2210 | 2137 | ||
2211 | done: | ||
2212 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2138 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2213 | sel->rate = rate_lowest(local, sband, sta); | 2139 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
2214 | goto out; | 2140 | goto out; |
2215 | } | 2141 | } |
2216 | 2142 | ||
2217 | sel->rate = &priv->ieee_rates[i]; | 2143 | if (sband->band == IEEE80211_BAND_5GHZ) |
2144 | i -= IWL_FIRST_OFDM_RATE; | ||
2145 | sel->rate_idx = i; | ||
2218 | out: | 2146 | out: |
2219 | rcu_read_unlock(); | 2147 | rcu_read_unlock(); |
2220 | } | 2148 | } |
2221 | 2149 | ||
2222 | static void *rs_alloc_sta(void *priv, gfp_t gfp) | 2150 | static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) |
2223 | { | 2151 | { |
2224 | struct iwl4965_lq_sta *lq_sta; | 2152 | struct iwl4965_lq_sta *lq_sta; |
2153 | struct iwl_priv *priv; | ||
2225 | int i, j; | 2154 | int i, j; |
2226 | 2155 | ||
2156 | priv = (struct iwl_priv *)priv_rate; | ||
2227 | IWL_DEBUG_RATE("create station rate scale window\n"); | 2157 | IWL_DEBUG_RATE("create station rate scale window\n"); |
2228 | 2158 | ||
2229 | lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); | 2159 | lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); |
@@ -2259,7 +2189,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2259 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2189 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2260 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); | 2190 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); |
2261 | 2191 | ||
2262 | IWL_DEBUG_RATE("rate scale global init\n"); | 2192 | IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n"); |
2263 | /* TODO: what is a good starting rate for STA? About middle? Maybe not | 2193 | /* TODO: what is a good starting rate for STA? About middle? Maybe not |
2264 | * the lowest or the highest rate.. Could consider using RSSI from | 2194 | * the lowest or the highest rate.. Could consider using RSSI from |
2265 | * previous packets? Need to have IEEE 802.1X auth succeed immediately | 2195 | * previous packets? Need to have IEEE 802.1X auth succeed immediately |
@@ -2267,17 +2197,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2267 | 2197 | ||
2268 | lq_sta->ibss_sta_added = 0; | 2198 | lq_sta->ibss_sta_added = 0; |
2269 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 2199 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { |
2270 | u8 sta_id = iwl4965_hw_find_station(priv, sta->addr); | 2200 | u8 sta_id = iwl_find_station(priv, sta->addr); |
2271 | DECLARE_MAC_BUF(mac); | 2201 | DECLARE_MAC_BUF(mac); |
2272 | 2202 | ||
2273 | /* for IBSS the call are from tasklet */ | 2203 | /* for IBSS the call are from tasklet */ |
2274 | IWL_DEBUG_HT("LQ: ADD station %s\n", | 2204 | IWL_DEBUG_RATE("LQ: ADD station %s\n", |
2275 | print_mac(mac, sta->addr)); | 2205 | print_mac(mac, sta->addr)); |
2276 | 2206 | ||
2277 | if (sta_id == IWL_INVALID_STATION) { | 2207 | if (sta_id == IWL_INVALID_STATION) { |
2278 | IWL_DEBUG_RATE("LQ: ADD station %s\n", | 2208 | IWL_DEBUG_RATE("LQ: ADD station %s\n", |
2279 | print_mac(mac, sta->addr)); | 2209 | print_mac(mac, sta->addr)); |
2280 | sta_id = iwl4965_add_station_flags(priv, sta->addr, | 2210 | sta_id = iwl_add_station_flags(priv, sta->addr, |
2281 | 0, CMD_ASYNC, NULL); | 2211 | 0, CMD_ASYNC, NULL); |
2282 | } | 2212 | } |
2283 | if ((sta_id != IWL_INVALID_STATION)) { | 2213 | if ((sta_id != IWL_INVALID_STATION)) { |
@@ -2300,92 +2230,95 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2300 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 2230 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2301 | 2231 | ||
2302 | lq_sta->is_dup = 0; | 2232 | lq_sta->is_dup = 0; |
2303 | lq_sta->valid_antenna = priv->valid_antenna; | ||
2304 | lq_sta->antenna = priv->antenna; | ||
2305 | lq_sta->is_green = rs_use_green(priv, conf); | 2233 | lq_sta->is_green = rs_use_green(priv, conf); |
2306 | lq_sta->active_rate = priv->active_rate; | 2234 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); |
2307 | lq_sta->active_rate &= ~(0x1000); | ||
2308 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2235 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2309 | lq_sta->band = priv->band; | 2236 | lq_sta->band = priv->band; |
2310 | #ifdef CONFIG_IWL4965_HT | ||
2311 | /* | 2237 | /* |
2312 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2238 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
2313 | * supp_rates[] does not; shift to convert format, force 9 MBits off. | 2239 | * supp_rates[] does not; shift to convert format, force 9 MBits off. |
2314 | */ | 2240 | */ |
2315 | lq_sta->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0] << 1); | 2241 | lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1; |
2316 | lq_sta->active_siso_rate |= | 2242 | lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1; |
2317 | (priv->current_ht_config.supp_mcs_set[0] & 0x1); | ||
2318 | lq_sta->active_siso_rate &= ~((u16)0x2); | 2243 | lq_sta->active_siso_rate &= ~((u16)0x2); |
2319 | lq_sta->active_siso_rate = | 2244 | lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; |
2320 | lq_sta->active_siso_rate << IWL_FIRST_OFDM_RATE; | ||
2321 | 2245 | ||
2322 | /* Same here */ | 2246 | /* Same here */ |
2323 | lq_sta->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1] << 1); | 2247 | lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1; |
2324 | lq_sta->active_mimo_rate |= | 2248 | lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1; |
2325 | (priv->current_ht_config.supp_mcs_set[1] & 0x1); | 2249 | lq_sta->active_mimo2_rate &= ~((u16)0x2); |
2326 | lq_sta->active_mimo_rate &= ~((u16)0x2); | 2250 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; |
2327 | lq_sta->active_mimo_rate = | 2251 | |
2328 | lq_sta->active_mimo_rate << IWL_FIRST_OFDM_RATE; | 2252 | lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1; |
2329 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2253 | lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1; |
2254 | lq_sta->active_mimo3_rate &= ~((u16)0x2); | ||
2255 | lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; | ||
2256 | |||
2257 | IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n", | ||
2330 | lq_sta->active_siso_rate, | 2258 | lq_sta->active_siso_rate, |
2331 | lq_sta->active_mimo_rate); | 2259 | lq_sta->active_mimo2_rate, |
2260 | lq_sta->active_mimo3_rate); | ||
2261 | |||
2262 | /* These values will be overriden later */ | ||
2263 | lq_sta->lq.general_params.single_stream_ant_msk = ANT_A; | ||
2264 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; | ||
2265 | |||
2332 | /* as default allow aggregation for all tids */ | 2266 | /* as default allow aggregation for all tids */ |
2333 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | 2267 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; |
2334 | #endif /*CONFIG_IWL4965_HT*/ | ||
2335 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
2336 | lq_sta->drv = priv; | 2268 | lq_sta->drv = priv; |
2337 | #endif | ||
2338 | |||
2339 | if (priv->assoc_station_added) | ||
2340 | priv->lq_mngr.lq_ready = 1; | ||
2341 | 2269 | ||
2342 | rs_initialize_lq(priv, conf, sta); | 2270 | rs_initialize_lq(priv, conf, sta); |
2343 | } | 2271 | } |
2344 | 2272 | ||
2345 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 2273 | static void rs_fill_link_cmd(const struct iwl_priv *priv, |
2346 | struct iwl4965_rate *tx_mcs, | 2274 | struct iwl4965_lq_sta *lq_sta, |
2347 | struct iwl_link_quality_cmd *lq_cmd) | 2275 | u32 new_rate) |
2348 | { | 2276 | { |
2277 | struct iwl4965_scale_tbl_info tbl_type; | ||
2349 | int index = 0; | 2278 | int index = 0; |
2350 | int rate_idx; | 2279 | int rate_idx; |
2351 | int repeat_rate = 0; | 2280 | int repeat_rate = 0; |
2352 | u8 ant_toggle_count = 0; | 2281 | u8 ant_toggle_cnt = 0; |
2353 | u8 use_ht_possible = 1; | 2282 | u8 use_ht_possible = 1; |
2354 | struct iwl4965_rate new_rate; | 2283 | u8 valid_tx_ant = 0; |
2355 | struct iwl4965_scale_tbl_info tbl_type = { 0 }; | 2284 | struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; |
2356 | 2285 | ||
2357 | /* Override starting rate (index 0) if needed for debug purposes */ | 2286 | /* Override starting rate (index 0) if needed for debug purposes */ |
2358 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); | 2287 | rs_dbgfs_set_mcs(lq_sta, &new_rate, index); |
2359 | 2288 | ||
2360 | /* Interpret rate_n_flags */ | 2289 | /* Interpret new_rate (rate_n_flags) */ |
2361 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, | 2290 | memset(&tbl_type, 0, sizeof(tbl_type)); |
2291 | rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, | ||
2362 | &tbl_type, &rate_idx); | 2292 | &tbl_type, &rate_idx); |
2363 | 2293 | ||
2364 | /* How many times should we repeat the initial rate? */ | 2294 | /* How many times should we repeat the initial rate? */ |
2365 | if (is_legacy(tbl_type.lq_type)) { | 2295 | if (is_legacy(tbl_type.lq_type)) { |
2366 | ant_toggle_count = 1; | 2296 | ant_toggle_cnt = 1; |
2367 | repeat_rate = IWL_NUMBER_TRY; | 2297 | repeat_rate = IWL_NUMBER_TRY; |
2368 | } else | 2298 | } else { |
2369 | repeat_rate = IWL_HT_NUMBER_TRY; | 2299 | repeat_rate = IWL_HT_NUMBER_TRY; |
2300 | } | ||
2370 | 2301 | ||
2371 | lq_cmd->general_params.mimo_delimiter = | 2302 | lq_cmd->general_params.mimo_delimiter = |
2372 | is_mimo(tbl_type.lq_type) ? 1 : 0; | 2303 | is_mimo(tbl_type.lq_type) ? 1 : 0; |
2373 | 2304 | ||
2374 | /* Fill 1st table entry (index 0) */ | 2305 | /* Fill 1st table entry (index 0) */ |
2375 | lq_cmd->rs_table[index].rate_n_flags = | 2306 | lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); |
2376 | cpu_to_le32(tx_mcs->rate_n_flags); | ||
2377 | new_rate.rate_n_flags = tx_mcs->rate_n_flags; | ||
2378 | 2307 | ||
2379 | if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN)) | 2308 | if (num_of_ant(tbl_type.ant_type) == 1) { |
2380 | lq_cmd->general_params.single_stream_ant_msk | 2309 | lq_cmd->general_params.single_stream_ant_msk = |
2381 | = LINK_QUAL_ANT_A_MSK; | 2310 | tbl_type.ant_type; |
2382 | else | 2311 | } else if (num_of_ant(tbl_type.ant_type) == 2) { |
2383 | lq_cmd->general_params.single_stream_ant_msk | 2312 | lq_cmd->general_params.dual_stream_ant_msk = |
2384 | = LINK_QUAL_ANT_B_MSK; | 2313 | tbl_type.ant_type; |
2314 | } /* otherwise we don't modify the existing value */ | ||
2385 | 2315 | ||
2386 | index++; | 2316 | index++; |
2387 | repeat_rate--; | 2317 | repeat_rate--; |
2388 | 2318 | ||
2319 | if (priv) | ||
2320 | valid_tx_ant = priv->hw_params.valid_tx_ant; | ||
2321 | |||
2389 | /* Fill rest of rate table */ | 2322 | /* Fill rest of rate table */ |
2390 | while (index < LINK_QUAL_MAX_RETRY_NUM) { | 2323 | while (index < LINK_QUAL_MAX_RETRY_NUM) { |
2391 | /* Repeat initial/next rate. | 2324 | /* Repeat initial/next rate. |
@@ -2393,26 +2326,25 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2393 | * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ | 2326 | * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ |
2394 | while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { | 2327 | while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { |
2395 | if (is_legacy(tbl_type.lq_type)) { | 2328 | if (is_legacy(tbl_type.lq_type)) { |
2396 | if (ant_toggle_count < | 2329 | if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) |
2397 | NUM_TRY_BEFORE_ANTENNA_TOGGLE) | 2330 | ant_toggle_cnt++; |
2398 | ant_toggle_count++; | 2331 | else if (priv && |
2399 | else { | 2332 | rs_toggle_antenna(valid_tx_ant, |
2400 | rs_toggle_antenna(&new_rate, &tbl_type); | 2333 | &new_rate, &tbl_type)) |
2401 | ant_toggle_count = 1; | 2334 | ant_toggle_cnt = 1; |
2402 | } | 2335 | } |
2403 | } | ||
2404 | 2336 | ||
2405 | /* Override next rate if needed for debug purposes */ | 2337 | /* Override next rate if needed for debug purposes */ |
2406 | rs_dbgfs_set_mcs(lq_sta, &new_rate, index); | 2338 | rs_dbgfs_set_mcs(lq_sta, &new_rate, index); |
2407 | 2339 | ||
2408 | /* Fill next table entry */ | 2340 | /* Fill next table entry */ |
2409 | lq_cmd->rs_table[index].rate_n_flags = | 2341 | lq_cmd->rs_table[index].rate_n_flags = |
2410 | cpu_to_le32(new_rate.rate_n_flags); | 2342 | cpu_to_le32(new_rate); |
2411 | repeat_rate--; | 2343 | repeat_rate--; |
2412 | index++; | 2344 | index++; |
2413 | } | 2345 | } |
2414 | 2346 | ||
2415 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, | 2347 | rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, |
2416 | &rate_idx); | 2348 | &rate_idx); |
2417 | 2349 | ||
2418 | /* Indicate to uCode which entries might be MIMO. | 2350 | /* Indicate to uCode which entries might be MIMO. |
@@ -2422,20 +2354,22 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2422 | lq_cmd->general_params.mimo_delimiter = index; | 2354 | lq_cmd->general_params.mimo_delimiter = index; |
2423 | 2355 | ||
2424 | /* Get next rate */ | 2356 | /* Get next rate */ |
2425 | rs_get_lower_rate(lq_sta, &tbl_type, rate_idx, | 2357 | new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx, |
2426 | use_ht_possible, &new_rate); | 2358 | use_ht_possible); |
2427 | 2359 | ||
2428 | /* How many times should we repeat the next rate? */ | 2360 | /* How many times should we repeat the next rate? */ |
2429 | if (is_legacy(tbl_type.lq_type)) { | 2361 | if (is_legacy(tbl_type.lq_type)) { |
2430 | if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE) | 2362 | if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) |
2431 | ant_toggle_count++; | 2363 | ant_toggle_cnt++; |
2432 | else { | 2364 | else if (priv && |
2433 | rs_toggle_antenna(&new_rate, &tbl_type); | 2365 | rs_toggle_antenna(valid_tx_ant, |
2434 | ant_toggle_count = 1; | 2366 | &new_rate, &tbl_type)) |
2435 | } | 2367 | ant_toggle_cnt = 1; |
2368 | |||
2436 | repeat_rate = IWL_NUMBER_TRY; | 2369 | repeat_rate = IWL_NUMBER_TRY; |
2437 | } else | 2370 | } else { |
2438 | repeat_rate = IWL_HT_NUMBER_TRY; | 2371 | repeat_rate = IWL_HT_NUMBER_TRY; |
2372 | } | ||
2439 | 2373 | ||
2440 | /* Don't allow HT rates after next pass. | 2374 | /* Don't allow HT rates after next pass. |
2441 | * rs_get_lower_rate() will change type to LQ_A or LQ_G. */ | 2375 | * rs_get_lower_rate() will change type to LQ_A or LQ_G. */ |
@@ -2445,14 +2379,13 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2445 | rs_dbgfs_set_mcs(lq_sta, &new_rate, index); | 2379 | rs_dbgfs_set_mcs(lq_sta, &new_rate, index); |
2446 | 2380 | ||
2447 | /* Fill next table entry */ | 2381 | /* Fill next table entry */ |
2448 | lq_cmd->rs_table[index].rate_n_flags = | 2382 | lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); |
2449 | cpu_to_le32(new_rate.rate_n_flags); | ||
2450 | 2383 | ||
2451 | index++; | 2384 | index++; |
2452 | repeat_rate--; | 2385 | repeat_rate--; |
2453 | } | 2386 | } |
2454 | 2387 | ||
2455 | lq_cmd->general_params.dual_stream_ant_msk = 3; | 2388 | lq_cmd->agg_params.agg_frame_cnt_limit = 64; |
2456 | lq_cmd->agg_params.agg_dis_start_th = 3; | 2389 | lq_cmd->agg_params.agg_dis_start_th = 3; |
2457 | lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); | 2390 | lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); |
2458 | } | 2391 | } |
@@ -2473,15 +2406,17 @@ static void rs_clear(void *priv_rate) | |||
2473 | 2406 | ||
2474 | IWL_DEBUG_RATE("enter\n"); | 2407 | IWL_DEBUG_RATE("enter\n"); |
2475 | 2408 | ||
2476 | priv->lq_mngr.lq_ready = 0; | 2409 | /* TODO - add rate scale state reset */ |
2477 | 2410 | ||
2478 | IWL_DEBUG_RATE("leave\n"); | 2411 | IWL_DEBUG_RATE("leave\n"); |
2479 | } | 2412 | } |
2480 | 2413 | ||
2481 | static void rs_free_sta(void *priv, void *priv_sta) | 2414 | static void rs_free_sta(void *priv_rate, void *priv_sta) |
2482 | { | 2415 | { |
2483 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2416 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2417 | struct iwl_priv *priv; | ||
2484 | 2418 | ||
2419 | priv = (struct iwl_priv *)priv_rate; | ||
2485 | IWL_DEBUG_RATE("enter\n"); | 2420 | IWL_DEBUG_RATE("enter\n"); |
2486 | kfree(lq_sta); | 2421 | kfree(lq_sta); |
2487 | IWL_DEBUG_RATE("leave\n"); | 2422 | IWL_DEBUG_RATE("leave\n"); |
@@ -2495,54 +2430,56 @@ static int open_file_generic(struct inode *inode, struct file *file) | |||
2495 | return 0; | 2430 | return 0; |
2496 | } | 2431 | } |
2497 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 2432 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, |
2498 | struct iwl4965_rate *mcs, int index) | 2433 | u32 *rate_n_flags, int index) |
2499 | { | 2434 | { |
2500 | u32 base_rate; | 2435 | struct iwl_priv *priv; |
2501 | 2436 | ||
2502 | if (lq_sta->band == IEEE80211_BAND_5GHZ) | 2437 | priv = lq_sta->drv; |
2503 | base_rate = 0x800D; | 2438 | if (lq_sta->dbg_fixed_rate) { |
2504 | else | 2439 | if (index < 12) { |
2505 | base_rate = 0x820A; | 2440 | *rate_n_flags = lq_sta->dbg_fixed_rate; |
2506 | 2441 | } else { | |
2507 | if (lq_sta->dbg_fixed.rate_n_flags) { | 2442 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
2508 | if (index < 12) | 2443 | *rate_n_flags = 0x800D; |
2509 | mcs->rate_n_flags = lq_sta->dbg_fixed.rate_n_flags; | 2444 | else |
2510 | else | 2445 | *rate_n_flags = 0x820A; |
2511 | mcs->rate_n_flags = base_rate; | 2446 | } |
2512 | IWL_DEBUG_RATE("Fixed rate ON\n"); | 2447 | IWL_DEBUG_RATE("Fixed rate ON\n"); |
2513 | return; | 2448 | } else { |
2449 | IWL_DEBUG_RATE("Fixed rate OFF\n"); | ||
2514 | } | 2450 | } |
2515 | |||
2516 | IWL_DEBUG_RATE("Fixed rate OFF\n"); | ||
2517 | } | 2451 | } |
2518 | 2452 | ||
2519 | static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | 2453 | static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, |
2520 | const char __user *user_buf, size_t count, loff_t *ppos) | 2454 | const char __user *user_buf, size_t count, loff_t *ppos) |
2521 | { | 2455 | { |
2522 | struct iwl4965_lq_sta *lq_sta = file->private_data; | 2456 | struct iwl4965_lq_sta *lq_sta = file->private_data; |
2457 | struct iwl_priv *priv; | ||
2523 | char buf[64]; | 2458 | char buf[64]; |
2524 | int buf_size; | 2459 | int buf_size; |
2525 | u32 parsed_rate; | 2460 | u32 parsed_rate; |
2526 | 2461 | ||
2462 | priv = lq_sta->drv; | ||
2527 | memset(buf, 0, sizeof(buf)); | 2463 | memset(buf, 0, sizeof(buf)); |
2528 | buf_size = min(count, sizeof(buf) - 1); | 2464 | buf_size = min(count, sizeof(buf) - 1); |
2529 | if (copy_from_user(buf, user_buf, buf_size)) | 2465 | if (copy_from_user(buf, user_buf, buf_size)) |
2530 | return -EFAULT; | 2466 | return -EFAULT; |
2531 | 2467 | ||
2532 | if (sscanf(buf, "%x", &parsed_rate) == 1) | 2468 | if (sscanf(buf, "%x", &parsed_rate) == 1) |
2533 | lq_sta->dbg_fixed.rate_n_flags = parsed_rate; | 2469 | lq_sta->dbg_fixed_rate = parsed_rate; |
2534 | else | 2470 | else |
2535 | lq_sta->dbg_fixed.rate_n_flags = 0; | 2471 | lq_sta->dbg_fixed_rate = 0; |
2536 | 2472 | ||
2537 | lq_sta->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ | 2473 | lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ |
2538 | lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | 2474 | lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ |
2539 | lq_sta->active_mimo_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | 2475 | lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ |
2476 | lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | ||
2540 | 2477 | ||
2541 | IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", | 2478 | IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", |
2542 | lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags); | 2479 | lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); |
2543 | 2480 | ||
2544 | if (lq_sta->dbg_fixed.rate_n_flags) { | 2481 | if (lq_sta->dbg_fixed_rate) { |
2545 | rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); | 2482 | rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); |
2546 | iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); | 2483 | iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); |
2547 | } | 2484 | } |
2548 | 2485 | ||
@@ -2561,9 +2498,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
2561 | desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); | 2498 | desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); |
2562 | desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", | 2499 | desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", |
2563 | lq_sta->total_failed, lq_sta->total_success, | 2500 | lq_sta->total_failed, lq_sta->total_success, |
2564 | lq_sta->active_rate); | 2501 | lq_sta->active_legacy_rate); |
2565 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 2502 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
2566 | lq_sta->dbg_fixed.rate_n_flags); | 2503 | lq_sta->dbg_fixed_rate); |
2567 | desc += sprintf(buff+desc, "general:" | 2504 | desc += sprintf(buff+desc, "general:" |
2568 | "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", | 2505 | "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", |
2569 | lq_sta->lq.general_params.flags, | 2506 | lq_sta->lq.general_params.flags, |
@@ -2613,7 +2550,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, | |||
2613 | lq_sta->lq_info[i].is_SGI, | 2550 | lq_sta->lq_info[i].is_SGI, |
2614 | lq_sta->lq_info[i].is_fat, | 2551 | lq_sta->lq_info[i].is_fat, |
2615 | lq_sta->lq_info[i].is_dup, | 2552 | lq_sta->lq_info[i].is_dup, |
2616 | lq_sta->lq_info[i].current_rate.rate_n_flags); | 2553 | lq_sta->lq_info[i].current_rate); |
2617 | for (j = 0; j < IWL_RATE_COUNT; j++) { | 2554 | for (j = 0; j < IWL_RATE_COUNT; j++) { |
2618 | desc += sprintf(buff+desc, | 2555 | desc += sprintf(buff+desc, |
2619 | "counter=%d success=%d %%=%d\n", | 2556 | "counter=%d success=%d %%=%d\n", |
@@ -2640,11 +2577,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2640 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2577 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2641 | debugfs_create_file("rate_stats_table", 0600, dir, | 2578 | debugfs_create_file("rate_stats_table", 0600, dir, |
2642 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2579 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2643 | #ifdef CONFIG_IWL4965_HT | ||
2644 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 2580 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
2645 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | 2581 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, |
2646 | &lq_sta->tx_agg_tid_en); | 2582 | &lq_sta->tx_agg_tid_en); |
2647 | #endif | ||
2648 | 2583 | ||
2649 | } | 2584 | } |
2650 | 2585 | ||
@@ -2653,9 +2588,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2653 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2588 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2654 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2589 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2655 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2590 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2656 | #ifdef CONFIG_IWL4965_HT | ||
2657 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | 2591 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); |
2658 | #endif | ||
2659 | } | 2592 | } |
2660 | #endif | 2593 | #endif |
2661 | 2594 | ||
@@ -2703,7 +2636,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2703 | lq_sta = (void *)sta->rate_ctrl_priv; | 2636 | lq_sta = (void *)sta->rate_ctrl_priv; |
2704 | 2637 | ||
2705 | lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type; | 2638 | lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type; |
2706 | antenna = lq_sta->lq_info[lq_sta->active_tbl].antenna_type; | 2639 | antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type; |
2707 | 2640 | ||
2708 | if (is_legacy(lq_type)) | 2641 | if (is_legacy(lq_type)) |
2709 | i = IWL_RATE_54M_INDEX; | 2642 | i = IWL_RATE_54M_INDEX; |
@@ -2715,7 +2648,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2715 | int active = lq_sta->active_tbl; | 2648 | int active = lq_sta->active_tbl; |
2716 | 2649 | ||
2717 | cnt += | 2650 | cnt += |
2718 | sprintf(&buf[cnt], " %2dMbs: ", iwl4965_rates[i].ieee / 2); | 2651 | sprintf(&buf[cnt], " %2dMbs: ", iwl_rates[i].ieee / 2); |
2719 | 2652 | ||
2720 | mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1)); | 2653 | mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1)); |
2721 | for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1) | 2654 | for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1) |
@@ -2726,7 +2659,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2726 | samples += lq_sta->lq_info[active].win[i].counter; | 2659 | samples += lq_sta->lq_info[active].win[i].counter; |
2727 | good += lq_sta->lq_info[active].win[i].success_counter; | 2660 | good += lq_sta->lq_info[active].win[i].success_counter; |
2728 | success += lq_sta->lq_info[active].win[i].success_counter * | 2661 | success += lq_sta->lq_info[active].win[i].success_counter * |
2729 | iwl4965_rates[i].ieee; | 2662 | iwl_rates[i].ieee; |
2730 | 2663 | ||
2731 | if (lq_sta->lq_info[active].win[i].stamp) { | 2664 | if (lq_sta->lq_info[active].win[i].stamp) { |
2732 | int delta = | 2665 | int delta = |
@@ -2746,10 +2679,11 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2746 | i = j; | 2679 | i = j; |
2747 | } | 2680 | } |
2748 | 2681 | ||
2749 | /* Display the average rate of all samples taken. | 2682 | /* |
2750 | * | 2683 | * Display the average rate of all samples taken. |
2751 | * NOTE: We multiply # of samples by 2 since the IEEE measurement | 2684 | * NOTE: We multiply # of samples by 2 since the IEEE measurement |
2752 | * added from iwl4965_rates is actually 2X the rate */ | 2685 | * added from iwl_rates is actually 2X the rate. |
2686 | */ | ||
2753 | if (samples) | 2687 | if (samples) |
2754 | cnt += sprintf(&buf[cnt], | 2688 | cnt += sprintf(&buf[cnt], |
2755 | "\nAverage rate is %3d.%02dMbs over last %4dms\n" | 2689 | "\nAverage rate is %3d.%02dMbs over last %4dms\n" |
@@ -2767,13 +2701,6 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2767 | return cnt; | 2701 | return cnt; |
2768 | } | 2702 | } |
2769 | 2703 | ||
2770 | void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | ||
2771 | { | ||
2772 | struct iwl_priv *priv = hw->priv; | ||
2773 | |||
2774 | priv->lq_mngr.lq_ready = 1; | ||
2775 | } | ||
2776 | |||
2777 | int iwl4965_rate_control_register(void) | 2704 | int iwl4965_rate_control_register(void) |
2778 | { | 2705 | { |
2779 | return ieee80211_rate_control_register(&rs_ops); | 2706 | return ieee80211_rate_control_register(&rs_ops); |