diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 567 |
1 files changed, 362 insertions, 205 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d06462264147..b608e1ca8b40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -36,9 +36,10 @@ | |||
36 | 36 | ||
37 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
38 | 38 | ||
39 | #include "../net/mac80211/ieee80211_rate.h" | 39 | #include "../net/mac80211/rate.h" |
40 | 40 | ||
41 | #include "iwl-4965.h" | 41 | #include "iwl-4965.h" |
42 | #include "iwl-core.h" | ||
42 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
43 | 44 | ||
44 | #define RS_NAME "iwl-4965-rs" | 45 | #define RS_NAME "iwl-4965-rs" |
@@ -83,7 +84,7 @@ struct iwl4965_rate_scale_data { | |||
83 | /** | 84 | /** |
84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates | 85 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates |
85 | * | 86 | * |
86 | * There are two of these in struct iwl_rate_scale_priv, | 87 | * There are two of these in struct iwl4965_lq_sta, |
87 | * one for "active", and one for "search". | 88 | * one for "active", and one for "search". |
88 | */ | 89 | */ |
89 | struct iwl4965_scale_tbl_info { | 90 | struct iwl4965_scale_tbl_info { |
@@ -98,8 +99,23 @@ struct iwl4965_scale_tbl_info { | |||
98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 99 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
99 | }; | 100 | }; |
100 | 101 | ||
102 | #ifdef CONFIG_IWL4965_HT | ||
103 | |||
104 | struct iwl4965_traffic_load { | ||
105 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
106 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
107 | * slice */ | ||
108 | u32 total; /* total num of packets during the | ||
109 | * last TID_MAX_TIME_DIFF */ | ||
110 | u8 queue_count; /* number of queues that has | ||
111 | * been used since the last cleanup */ | ||
112 | u8 head; /* start of the circular buffer */ | ||
113 | }; | ||
114 | |||
115 | #endif /* CONFIG_IWL4965_HT */ | ||
116 | |||
101 | /** | 117 | /** |
102 | * struct iwl_rate_scale_priv -- driver's rate scaling private structure | 118 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
103 | * | 119 | * |
104 | * Pointer to this gets passed back and forth between driver and mac80211. | 120 | * Pointer to this gets passed back and forth between driver and mac80211. |
105 | */ | 121 | */ |
@@ -124,7 +140,7 @@ struct iwl4965_lq_sta { | |||
124 | u8 valid_antenna; | 140 | u8 valid_antenna; |
125 | u8 is_green; | 141 | u8 is_green; |
126 | u8 is_dup; | 142 | u8 is_dup; |
127 | u8 phymode; | 143 | enum ieee80211_band band; |
128 | u8 ibss_sta_added; | 144 | u8 ibss_sta_added; |
129 | 145 | ||
130 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 146 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
@@ -134,23 +150,30 @@ struct iwl4965_lq_sta { | |||
134 | u16 active_mimo_rate; | 150 | u16 active_mimo_rate; |
135 | u16 active_rate_basic; | 151 | u16 active_rate_basic; |
136 | 152 | ||
137 | struct iwl4965_link_quality_cmd lq; | 153 | struct iwl_link_quality_cmd lq; |
138 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 154 | 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 | u8 tx_agg_tid_en; | ||
158 | #endif | ||
139 | #ifdef CONFIG_MAC80211_DEBUGFS | 159 | #ifdef CONFIG_MAC80211_DEBUGFS |
140 | struct dentry *rs_sta_dbgfs_scale_table_file; | 160 | struct dentry *rs_sta_dbgfs_scale_table_file; |
141 | 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; | ||
164 | #endif | ||
142 | struct iwl4965_rate dbg_fixed; | 165 | struct iwl4965_rate dbg_fixed; |
143 | struct iwl4965_priv *drv; | 166 | struct iwl_priv *drv; |
144 | #endif | 167 | #endif |
145 | }; | 168 | }; |
146 | 169 | ||
147 | static void rs_rate_scale_perform(struct iwl4965_priv *priv, | 170 | static void rs_rate_scale_perform(struct iwl_priv *priv, |
148 | struct net_device *dev, | 171 | struct net_device *dev, |
149 | struct ieee80211_hdr *hdr, | 172 | struct ieee80211_hdr *hdr, |
150 | struct sta_info *sta); | 173 | struct sta_info *sta); |
151 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 174 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, |
152 | struct iwl4965_rate *tx_mcs, | 175 | struct iwl4965_rate *tx_mcs, |
153 | struct iwl4965_link_quality_cmd *tbl); | 176 | struct iwl_link_quality_cmd *tbl); |
154 | 177 | ||
155 | 178 | ||
156 | #ifdef CONFIG_MAC80211_DEBUGFS | 179 | #ifdef CONFIG_MAC80211_DEBUGFS |
@@ -207,68 +230,150 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { | |||
207 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 | 230 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 |
208 | }; | 231 | }; |
209 | 232 | ||
210 | static int iwl4965_lq_sync_callback(struct iwl4965_priv *priv, | 233 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) |
211 | struct iwl4965_cmd *cmd, struct sk_buff *skb) | ||
212 | { | 234 | { |
213 | /*We didn't cache the SKB; let the caller free it */ | 235 | return (u8)(rate_n_flags & 0xFF); |
214 | return 1; | ||
215 | } | 236 | } |
216 | 237 | ||
217 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) | 238 | static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) |
218 | { | 239 | { |
219 | return (u8)(rate_n_flags & 0xFF); | 240 | window->data = 0; |
241 | window->success_counter = 0; | ||
242 | window->success_ratio = IWL_INVALID_VALUE; | ||
243 | window->counter = 0; | ||
244 | window->average_tpt = IWL_INVALID_VALUE; | ||
245 | window->stamp = 0; | ||
220 | } | 246 | } |
221 | 247 | ||
222 | static int rs_send_lq_cmd(struct iwl4965_priv *priv, | 248 | #ifdef CONFIG_IWL4965_HT |
223 | struct iwl4965_link_quality_cmd *lq, u8 flags) | 249 | /* |
250 | * removes the old data from the statistics. All data that is older than | ||
251 | * TID_MAX_TIME_DIFF, will be deleted. | ||
252 | */ | ||
253 | static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | ||
224 | { | 254 | { |
225 | #ifdef CONFIG_IWL4965_DEBUG | 255 | /* The oldest age we want to keep */ |
226 | int i; | 256 | u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; |
227 | #endif | 257 | |
228 | struct iwl4965_host_cmd cmd = { | 258 | while (tl->queue_count && |
229 | .id = REPLY_TX_LINK_QUALITY_CMD, | 259 | (tl->time_stamp < oldest_time)) { |
230 | .len = sizeof(struct iwl4965_link_quality_cmd), | 260 | tl->total -= tl->packet_count[tl->head]; |
231 | .meta.flags = flags, | 261 | tl->packet_count[tl->head] = 0; |
232 | .data = lq, | 262 | tl->time_stamp += TID_QUEUE_CELL_SPACING; |
233 | }; | 263 | tl->queue_count--; |
234 | 264 | tl->head++; | |
235 | if ((lq->sta_id == 0xFF) && | 265 | if (tl->head >= TID_QUEUE_MAX_SIZE) |
236 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 266 | tl->head = 0; |
237 | return -EINVAL; | 267 | } |
268 | } | ||
269 | |||
270 | /* | ||
271 | * increment traffic load value for tid and also remove | ||
272 | * any old values if passed the certain time period | ||
273 | */ | ||
274 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
275 | { | ||
276 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
277 | u32 time_diff; | ||
278 | s32 index; | ||
279 | struct iwl4965_traffic_load *tl = NULL; | ||
238 | 280 | ||
239 | if (lq->sta_id == 0xFF) | 281 | if (tid >= TID_MAX_LOAD_COUNT) |
240 | lq->sta_id = IWL_AP_ID; | 282 | return; |
241 | 283 | ||
242 | IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id); | 284 | tl = &lq_data->load[tid]; |
243 | IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n", | ||
244 | lq->general_params.single_stream_ant_msk, | ||
245 | lq->general_params.dual_stream_ant_msk); | ||
246 | #ifdef CONFIG_IWL4965_DEBUG | ||
247 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | ||
248 | IWL_DEBUG_RATE("lq index %d 0x%X\n", | ||
249 | i, lq->rs_table[i].rate_n_flags); | ||
250 | #endif | ||
251 | 285 | ||
252 | if (flags & CMD_ASYNC) | 286 | curr_time -= curr_time % TID_ROUND_VALUE; |
253 | cmd.meta.u.callback = iwl4965_lq_sync_callback; | ||
254 | 287 | ||
255 | if (iwl4965_is_associated(priv) && priv->assoc_station_added && | 288 | /* Happens only for the first packet. Initialize the data */ |
256 | priv->lq_mngr.lq_ready) | 289 | if (!(tl->queue_count)) { |
257 | return iwl4965_send_cmd(priv, &cmd); | 290 | tl->total = 1; |
291 | tl->time_stamp = curr_time; | ||
292 | tl->queue_count = 1; | ||
293 | tl->head = 0; | ||
294 | tl->packet_count[0] = 1; | ||
295 | return; | ||
296 | } | ||
258 | 297 | ||
259 | return 0; | 298 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); |
299 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
300 | |||
301 | /* The history is too long: remove data that is older than */ | ||
302 | /* TID_MAX_TIME_DIFF */ | ||
303 | if (index >= TID_QUEUE_MAX_SIZE) | ||
304 | rs_tl_rm_old_stats(tl, curr_time); | ||
305 | |||
306 | index = (tl->head + index) % TID_QUEUE_MAX_SIZE; | ||
307 | tl->packet_count[index] = tl->packet_count[index] + 1; | ||
308 | tl->total = tl->total + 1; | ||
309 | |||
310 | if ((index + 1) > tl->queue_count) | ||
311 | tl->queue_count = index + 1; | ||
260 | } | 312 | } |
261 | 313 | ||
262 | static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | 314 | /* |
315 | get the traffic load value for tid | ||
316 | */ | ||
317 | static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
263 | { | 318 | { |
264 | window->data = 0; | 319 | u32 curr_time = jiffies_to_msecs(jiffies); |
265 | window->success_counter = 0; | 320 | u32 time_diff; |
266 | window->success_ratio = IWL_INVALID_VALUE; | 321 | s32 index; |
267 | window->counter = 0; | 322 | struct iwl4965_traffic_load *tl = NULL; |
268 | window->average_tpt = IWL_INVALID_VALUE; | 323 | |
269 | window->stamp = 0; | 324 | if (tid >= TID_MAX_LOAD_COUNT) |
325 | return 0; | ||
326 | |||
327 | tl = &(lq_data->load[tid]); | ||
328 | |||
329 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
330 | |||
331 | if (!(tl->queue_count)) | ||
332 | return 0; | ||
333 | |||
334 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
335 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
336 | |||
337 | /* The history is too long: remove data that is older than */ | ||
338 | /* TID_MAX_TIME_DIFF */ | ||
339 | if (index >= TID_QUEUE_MAX_SIZE) | ||
340 | rs_tl_rm_old_stats(tl, curr_time); | ||
341 | |||
342 | return tl->total; | ||
343 | } | ||
344 | |||
345 | static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | ||
346 | struct iwl4965_lq_sta *lq_data, u8 tid, | ||
347 | struct sta_info *sta) | ||
348 | { | ||
349 | unsigned long state; | ||
350 | DECLARE_MAC_BUF(mac); | ||
351 | |||
352 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
353 | state = sta->ampdu_mlme.tid_state_tx[tid]; | ||
354 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
355 | |||
356 | if (state == HT_AGG_STATE_IDLE && | ||
357 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | ||
358 | IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", | ||
359 | print_mac(mac, sta->addr), tid); | ||
360 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, | ||
365 | struct iwl4965_lq_sta *lq_data, | ||
366 | struct sta_info *sta) | ||
367 | { | ||
368 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
369 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
370 | else if (tid == IWL_AGG_ALL_TID) | ||
371 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
372 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
270 | } | 373 | } |
271 | 374 | ||
375 | #endif /* CONFIG_IWLWIFI_HT */ | ||
376 | |||
272 | /** | 377 | /** |
273 | * rs_collect_tx_data - Update the success/failure sliding window | 378 | * rs_collect_tx_data - Update the success/failure sliding window |
274 | * | 379 | * |
@@ -277,7 +382,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
277 | * packets. | 382 | * packets. |
278 | */ | 383 | */ |
279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | 384 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, |
280 | int scale_index, s32 tpt, u32 status) | 385 | int scale_index, s32 tpt, int retries, |
386 | int successes) | ||
281 | { | 387 | { |
282 | struct iwl4965_rate_scale_data *window = NULL; | 388 | struct iwl4965_rate_scale_data *window = NULL; |
283 | u64 mask; | 389 | u64 mask; |
@@ -298,26 +404,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
298 | * subtract "1" from the success counter (this is the main reason | 404 | * subtract "1" from the success counter (this is the main reason |
299 | * we keep these bitmaps!). | 405 | * we keep these bitmaps!). |
300 | */ | 406 | */ |
301 | if (window->counter >= win_size) { | 407 | while (retries > 0) { |
302 | window->counter = win_size - 1; | 408 | if (window->counter >= win_size) { |
303 | mask = 1; | 409 | window->counter = win_size - 1; |
304 | mask = (mask << (win_size - 1)); | 410 | mask = 1; |
305 | if ((window->data & mask)) { | 411 | mask = (mask << (win_size - 1)); |
306 | window->data &= ~mask; | 412 | if (window->data & mask) { |
307 | window->success_counter = window->success_counter - 1; | 413 | window->data &= ~mask; |
414 | window->success_counter = | ||
415 | window->success_counter - 1; | ||
416 | } | ||
308 | } | 417 | } |
309 | } | ||
310 | 418 | ||
311 | /* Increment frames-attempted counter */ | 419 | /* Increment frames-attempted counter */ |
312 | window->counter = window->counter + 1; | 420 | window->counter++; |
421 | |||
422 | /* Shift bitmap by one frame (throw away oldest history), | ||
423 | * OR in "1", and increment "success" if this | ||
424 | * frame was successful. */ | ||
425 | mask = window->data; | ||
426 | window->data = (mask << 1); | ||
427 | if (successes > 0) { | ||
428 | window->success_counter = window->success_counter + 1; | ||
429 | window->data |= 0x1; | ||
430 | successes--; | ||
431 | } | ||
313 | 432 | ||
314 | /* Shift bitmap by one frame (throw away oldest history), | 433 | retries--; |
315 | * OR in "1", and increment "success" if this frame was successful. */ | ||
316 | mask = window->data; | ||
317 | window->data = (mask << 1); | ||
318 | if (status != 0) { | ||
319 | window->success_counter = window->success_counter + 1; | ||
320 | window->data |= 0x1; | ||
321 | } | 434 | } |
322 | 435 | ||
323 | /* Calculate current success ratio, avoid divide-by-0! */ | 436 | /* Calculate current success ratio, avoid divide-by-0! */ |
@@ -404,13 +517,14 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, | |||
404 | * fill "search" or "active" tx mode table. | 517 | * fill "search" or "active" tx mode table. |
405 | */ | 518 | */ |
406 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 519 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, |
407 | int phymode, struct iwl4965_scale_tbl_info *tbl, | 520 | enum ieee80211_band band, |
521 | struct iwl4965_scale_tbl_info *tbl, | ||
408 | int *rate_idx) | 522 | int *rate_idx) |
409 | { | 523 | { |
410 | int index; | 524 | int index; |
411 | u32 ant_msk; | 525 | u32 ant_msk; |
412 | 526 | ||
413 | index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags); | 527 | index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags); |
414 | 528 | ||
415 | if (index == IWL_RATE_INVALID) { | 529 | if (index == IWL_RATE_INVALID) { |
416 | *rate_idx = -1; | 530 | *rate_idx = -1; |
@@ -429,7 +543,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | |||
429 | tbl->lq_type = LQ_NONE; | 543 | tbl->lq_type = LQ_NONE; |
430 | else { | 544 | else { |
431 | 545 | ||
432 | if (phymode == MODE_IEEE80211A) | 546 | if (band == IEEE80211_BAND_5GHZ) |
433 | tbl->lq_type = LQ_A; | 547 | tbl->lq_type = LQ_A; |
434 | else | 548 | else |
435 | tbl->lq_type = LQ_G; | 549 | tbl->lq_type = LQ_G; |
@@ -498,7 +612,7 @@ static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, | |||
498 | } | 612 | } |
499 | } | 613 | } |
500 | 614 | ||
501 | static inline u8 rs_use_green(struct iwl4965_priv *priv, | 615 | static inline u8 rs_use_green(struct iwl_priv *priv, |
502 | struct ieee80211_conf *conf) | 616 | struct ieee80211_conf *conf) |
503 | { | 617 | { |
504 | #ifdef CONFIG_IWL4965_HT | 618 | #ifdef CONFIG_IWL4965_HT |
@@ -607,7 +721,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
607 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { | 721 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { |
608 | switch_to_legacy = 1; | 722 | switch_to_legacy = 1; |
609 | scale_index = rs_ht_to_legacy[scale_index]; | 723 | scale_index = rs_ht_to_legacy[scale_index]; |
610 | if (lq_sta->phymode == MODE_IEEE80211A) | 724 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
611 | tbl->lq_type = LQ_A; | 725 | tbl->lq_type = LQ_A; |
612 | else | 726 | else |
613 | tbl->lq_type = LQ_G; | 727 | tbl->lq_type = LQ_G; |
@@ -625,7 +739,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
625 | /* Mask with station rate restriction */ | 739 | /* Mask with station rate restriction */ |
626 | if (is_legacy(tbl->lq_type)) { | 740 | if (is_legacy(tbl->lq_type)) { |
627 | /* supp_rates has no CCK bits in A mode */ | 741 | /* supp_rates has no CCK bits in A mode */ |
628 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 742 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
629 | rate_mask = (u16)(rate_mask & | 743 | rate_mask = (u16)(rate_mask & |
630 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 744 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
631 | else | 745 | else |
@@ -658,11 +772,12 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
658 | u8 retries; | 772 | u8 retries; |
659 | int rs_index, index = 0; | 773 | int rs_index, index = 0; |
660 | struct iwl4965_lq_sta *lq_sta; | 774 | struct iwl4965_lq_sta *lq_sta; |
661 | struct iwl4965_link_quality_cmd *table; | 775 | struct iwl_link_quality_cmd *table; |
662 | struct sta_info *sta; | 776 | struct sta_info *sta; |
663 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 777 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
664 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 778 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
665 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 779 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
780 | struct ieee80211_hw *hw = local_to_hw(local); | ||
666 | struct iwl4965_rate_scale_data *window = NULL; | 781 | struct iwl4965_rate_scale_data *window = NULL; |
667 | struct iwl4965_rate_scale_data *search_win = NULL; | 782 | struct iwl4965_rate_scale_data *search_win = NULL; |
668 | struct iwl4965_rate tx_mcs; | 783 | struct iwl4965_rate tx_mcs; |
@@ -677,28 +792,32 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
677 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) | 792 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) |
678 | return; | 793 | return; |
679 | 794 | ||
795 | /* This packet was aggregated but doesn't carry rate scale info */ | ||
796 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | ||
797 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | ||
798 | return; | ||
799 | |||
680 | retries = tx_resp->retry_count; | 800 | retries = tx_resp->retry_count; |
681 | 801 | ||
682 | if (retries > 15) | 802 | if (retries > 15) |
683 | retries = 15; | 803 | retries = 15; |
684 | 804 | ||
805 | rcu_read_lock(); | ||
685 | 806 | ||
686 | sta = sta_info_get(local, hdr->addr1); | 807 | sta = sta_info_get(local, hdr->addr1); |
687 | 808 | ||
688 | if (!sta || !sta->rate_ctrl_priv) { | 809 | if (!sta || !sta->rate_ctrl_priv) |
689 | if (sta) | 810 | goto out; |
690 | sta_info_put(sta); | 811 | |
691 | return; | ||
692 | } | ||
693 | 812 | ||
694 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 813 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
695 | 814 | ||
696 | if (!priv->lq_mngr.lq_ready) | 815 | if (!priv->lq_mngr.lq_ready) |
697 | return; | 816 | goto out; |
698 | 817 | ||
699 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 818 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
700 | !lq_sta->ibss_sta_added) | 819 | !lq_sta->ibss_sta_added) |
701 | return; | 820 | goto out; |
702 | 821 | ||
703 | table = &lq_sta->lq; | 822 | table = &lq_sta->lq; |
704 | active_index = lq_sta->active_tbl; | 823 | active_index = lq_sta->active_tbl; |
@@ -719,17 +838,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
719 | search_win = (struct iwl4965_rate_scale_data *) | 838 | search_win = (struct iwl4965_rate_scale_data *) |
720 | &(search_tbl->win[0]); | 839 | &(search_tbl->win[0]); |
721 | 840 | ||
722 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | ||
723 | |||
724 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | ||
725 | &tbl_type, &rs_index); | ||
726 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { | ||
727 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", | ||
728 | rs_index, tx_mcs.rate_n_flags); | ||
729 | sta_info_put(sta); | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | /* | 841 | /* |
734 | * Ignore this Tx frame response if its initial rate doesn't match | 842 | * Ignore this Tx frame response if its initial rate doesn't match |
735 | * that of latest Link Quality command. There may be stragglers | 843 | * that of latest Link Quality command. There may be stragglers |
@@ -738,14 +846,29 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
738 | * to check "search" mode, or a prior "search" mode after we've moved | 846 | * to check "search" mode, or a prior "search" mode after we've moved |
739 | * to a new "search" mode (which might become the new "active" mode). | 847 | * to a new "search" mode (which might become the new "active" mode). |
740 | */ | 848 | */ |
741 | if (retries && | 849 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags); |
742 | (tx_mcs.rate_n_flags != | 850 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
743 | le32_to_cpu(table->rs_table[0].rate_n_flags))) { | 851 | if (priv->band == IEEE80211_BAND_5GHZ) |
744 | IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n", | 852 | rs_index -= IWL_FIRST_OFDM_RATE; |
745 | tx_mcs.rate_n_flags, | 853 | |
746 | le32_to_cpu(table->rs_table[0].rate_n_flags)); | 854 | if ((tx_resp->control.tx_rate == NULL) || |
747 | sta_info_put(sta); | 855 | (tbl_type.is_SGI ^ |
748 | return; | 856 | !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) || |
857 | (tbl_type.is_fat ^ | ||
858 | !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) || | ||
859 | (tbl_type.is_dup ^ | ||
860 | !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || | ||
861 | (tbl_type.antenna_type ^ | ||
862 | tx_resp->control.antenna_sel_tx) || | ||
863 | (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ | ||
864 | !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || | ||
865 | (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ | ||
866 | !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || | ||
867 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != | ||
868 | tx_resp->control.tx_rate->bitrate)) { | ||
869 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", | ||
870 | tx_mcs.rate_n_flags); | ||
871 | goto out; | ||
749 | } | 872 | } |
750 | 873 | ||
751 | /* Update frame history window with "failure" for each Tx retry. */ | 874 | /* Update frame history window with "failure" for each Tx retry. */ |
@@ -754,7 +877,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
754 | * Each tx attempt steps one entry deeper in the rate table. */ | 877 | * Each tx attempt steps one entry deeper in the rate table. */ |
755 | tx_mcs.rate_n_flags = | 878 | tx_mcs.rate_n_flags = |
756 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 879 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
757 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 880 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
758 | &tbl_type, &rs_index); | 881 | &tbl_type, &rs_index); |
759 | 882 | ||
760 | /* If type matches "search" table, | 883 | /* If type matches "search" table, |
@@ -766,7 +889,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
766 | tpt = search_tbl->expected_tpt[rs_index]; | 889 | tpt = search_tbl->expected_tpt[rs_index]; |
767 | else | 890 | else |
768 | tpt = 0; | 891 | tpt = 0; |
769 | rs_collect_tx_data(search_win, rs_index, tpt, 0); | 892 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); |
770 | 893 | ||
771 | /* Else if type matches "current/active" table, | 894 | /* Else if type matches "current/active" table, |
772 | * add failure to "current/active" history */ | 895 | * add failure to "current/active" history */ |
@@ -777,7 +900,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
777 | tpt = curr_tbl->expected_tpt[rs_index]; | 900 | tpt = curr_tbl->expected_tpt[rs_index]; |
778 | else | 901 | else |
779 | tpt = 0; | 902 | tpt = 0; |
780 | rs_collect_tx_data(window, rs_index, tpt, 0); | 903 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); |
781 | } | 904 | } |
782 | 905 | ||
783 | /* If not searching for a new mode, increment failed counter | 906 | /* If not searching for a new mode, increment failed counter |
@@ -794,14 +917,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
794 | * if Tx was successful first try, use original rate, | 917 | * if Tx was successful first try, use original rate, |
795 | * else look up the rate that was, finally, successful. | 918 | * else look up the rate that was, finally, successful. |
796 | */ | 919 | */ |
797 | if (!tx_resp->retry_count) | 920 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); |
798 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 921 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
799 | else | ||
800 | tx_mcs.rate_n_flags = | ||
801 | le32_to_cpu(table->rs_table[index].rate_n_flags); | ||
802 | |||
803 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | ||
804 | &tbl_type, &rs_index); | ||
805 | 922 | ||
806 | /* Update frame history window with "success" if Tx got ACKed ... */ | 923 | /* Update frame history window with "success" if Tx got ACKed ... */ |
807 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) | 924 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) |
@@ -818,9 +935,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
818 | tpt = search_tbl->expected_tpt[rs_index]; | 935 | tpt = search_tbl->expected_tpt[rs_index]; |
819 | else | 936 | else |
820 | tpt = 0; | 937 | tpt = 0; |
821 | rs_collect_tx_data(search_win, | 938 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
822 | rs_index, tpt, status); | 939 | rs_collect_tx_data(search_win, rs_index, tpt, |
823 | 940 | tx_resp->ampdu_ack_len, | |
941 | tx_resp->ampdu_ack_map); | ||
942 | else | ||
943 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
944 | 1, status); | ||
824 | /* Else if type matches "current/active" table, | 945 | /* Else if type matches "current/active" table, |
825 | * add final tx status to "current/active" history */ | 946 | * add final tx status to "current/active" history */ |
826 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 947 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
@@ -830,21 +951,34 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
830 | tpt = curr_tbl->expected_tpt[rs_index]; | 951 | tpt = curr_tbl->expected_tpt[rs_index]; |
831 | else | 952 | else |
832 | tpt = 0; | 953 | tpt = 0; |
833 | rs_collect_tx_data(window, rs_index, tpt, status); | 954 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
955 | rs_collect_tx_data(window, rs_index, tpt, | ||
956 | tx_resp->ampdu_ack_len, | ||
957 | tx_resp->ampdu_ack_map); | ||
958 | else | ||
959 | rs_collect_tx_data(window, rs_index, tpt, | ||
960 | 1, status); | ||
834 | } | 961 | } |
835 | 962 | ||
836 | /* If not searching for new mode, increment success/failed counter | 963 | /* If not searching for new mode, increment success/failed counter |
837 | * ... these help determine when to start searching again */ | 964 | * ... these help determine when to start searching again */ |
838 | if (lq_sta->stay_in_tbl) { | 965 | if (lq_sta->stay_in_tbl) { |
839 | if (status) | 966 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { |
840 | lq_sta->total_success++; | 967 | lq_sta->total_success += tx_resp->ampdu_ack_map; |
841 | else | 968 | lq_sta->total_failed += |
842 | lq_sta->total_failed++; | 969 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); |
970 | } else { | ||
971 | if (status) | ||
972 | lq_sta->total_success++; | ||
973 | else | ||
974 | lq_sta->total_failed++; | ||
975 | } | ||
843 | } | 976 | } |
844 | 977 | ||
845 | /* See if there's a better rate or modulation mode to try. */ | 978 | /* See if there's a better rate or modulation mode to try. */ |
846 | rs_rate_scale_perform(priv, dev, hdr, sta); | 979 | rs_rate_scale_perform(priv, dev, hdr, sta); |
847 | sta_info_put(sta); | 980 | out: |
981 | rcu_read_unlock(); | ||
848 | return; | 982 | return; |
849 | } | 983 | } |
850 | 984 | ||
@@ -948,7 +1082,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | |||
948 | * to decrease to match "active" throughput. When moving from MIMO to SISO, | 1082 | * to decrease to match "active" throughput. When moving from MIMO to SISO, |
949 | * bit rate will typically need to increase, but not if performance was bad. | 1083 | * bit rate will typically need to increase, but not if performance was bad. |
950 | */ | 1084 | */ |
951 | static s32 rs_get_best_rate(struct iwl4965_priv *priv, | 1085 | static s32 rs_get_best_rate(struct iwl_priv *priv, |
952 | struct iwl4965_lq_sta *lq_sta, | 1086 | struct iwl4965_lq_sta *lq_sta, |
953 | struct iwl4965_scale_tbl_info *tbl, /* "search" */ | 1087 | struct iwl4965_scale_tbl_info *tbl, /* "search" */ |
954 | u16 rate_mask, s8 index, s8 rate) | 1088 | u16 rate_mask, s8 index, s8 rate) |
@@ -1046,7 +1180,7 @@ static inline u8 rs_is_both_ant_supp(u8 valid_antenna) | |||
1046 | /* | 1180 | /* |
1047 | * Set up search table for MIMO | 1181 | * Set up search table for MIMO |
1048 | */ | 1182 | */ |
1049 | static int rs_switch_to_mimo(struct iwl4965_priv *priv, | 1183 | static int rs_switch_to_mimo(struct iwl_priv *priv, |
1050 | struct iwl4965_lq_sta *lq_sta, | 1184 | struct iwl4965_lq_sta *lq_sta, |
1051 | struct ieee80211_conf *conf, | 1185 | struct ieee80211_conf *conf, |
1052 | struct sta_info *sta, | 1186 | struct sta_info *sta, |
@@ -1105,13 +1239,13 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv, | |||
1105 | return 0; | 1239 | return 0; |
1106 | #else | 1240 | #else |
1107 | return -1; | 1241 | return -1; |
1108 | #endif /*CONFIG_IWL4965_HT */ | 1242 | #endif /*CONFIG_IWL4965_HT */ |
1109 | } | 1243 | } |
1110 | 1244 | ||
1111 | /* | 1245 | /* |
1112 | * Set up search table for SISO | 1246 | * Set up search table for SISO |
1113 | */ | 1247 | */ |
1114 | static int rs_switch_to_siso(struct iwl4965_priv *priv, | 1248 | static int rs_switch_to_siso(struct iwl_priv *priv, |
1115 | struct iwl4965_lq_sta *lq_sta, | 1249 | struct iwl4965_lq_sta *lq_sta, |
1116 | struct ieee80211_conf *conf, | 1250 | struct ieee80211_conf *conf, |
1117 | struct sta_info *sta, | 1251 | struct sta_info *sta, |
@@ -1168,13 +1302,13 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv, | |||
1168 | #else | 1302 | #else |
1169 | return -1; | 1303 | return -1; |
1170 | 1304 | ||
1171 | #endif /*CONFIG_IWL4965_HT */ | 1305 | #endif /*CONFIG_IWL4965_HT */ |
1172 | } | 1306 | } |
1173 | 1307 | ||
1174 | /* | 1308 | /* |
1175 | * Try to switch to new modulation mode from legacy | 1309 | * Try to switch to new modulation mode from legacy |
1176 | */ | 1310 | */ |
1177 | static int rs_move_legacy_other(struct iwl4965_priv *priv, | 1311 | static int rs_move_legacy_other(struct iwl_priv *priv, |
1178 | struct iwl4965_lq_sta *lq_sta, | 1312 | struct iwl4965_lq_sta *lq_sta, |
1179 | struct ieee80211_conf *conf, | 1313 | struct ieee80211_conf *conf, |
1180 | struct sta_info *sta, | 1314 | struct sta_info *sta, |
@@ -1272,7 +1406,7 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv, | |||
1272 | /* | 1406 | /* |
1273 | * Try to switch to new modulation mode from SISO | 1407 | * Try to switch to new modulation mode from SISO |
1274 | */ | 1408 | */ |
1275 | static int rs_move_siso_to_other(struct iwl4965_priv *priv, | 1409 | static int rs_move_siso_to_other(struct iwl_priv *priv, |
1276 | struct iwl4965_lq_sta *lq_sta, | 1410 | struct iwl4965_lq_sta *lq_sta, |
1277 | struct ieee80211_conf *conf, | 1411 | struct ieee80211_conf *conf, |
1278 | struct sta_info *sta, | 1412 | struct sta_info *sta, |
@@ -1325,6 +1459,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1325 | break; | 1459 | break; |
1326 | case IWL_SISO_SWITCH_GI: | 1460 | case IWL_SISO_SWITCH_GI: |
1327 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1461 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); |
1462 | |||
1328 | memcpy(search_tbl, tbl, sz); | 1463 | memcpy(search_tbl, tbl, sz); |
1329 | search_tbl->action = 0; | 1464 | search_tbl->action = 0; |
1330 | if (search_tbl->is_SGI) | 1465 | if (search_tbl->is_SGI) |
@@ -1367,7 +1502,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1367 | /* | 1502 | /* |
1368 | * Try to switch to new modulation mode from MIMO | 1503 | * Try to switch to new modulation mode from MIMO |
1369 | */ | 1504 | */ |
1370 | static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | 1505 | static int rs_move_mimo_to_other(struct iwl_priv *priv, |
1371 | struct iwl4965_lq_sta *lq_sta, | 1506 | struct iwl4965_lq_sta *lq_sta, |
1372 | struct ieee80211_conf *conf, | 1507 | struct ieee80211_conf *conf, |
1373 | struct sta_info *sta, | 1508 | struct sta_info *sta, |
@@ -1390,6 +1525,7 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | |||
1390 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1525 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1391 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1526 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); |
1392 | 1527 | ||
1528 | |||
1393 | /* Set up new search table for SISO */ | 1529 | /* Set up new search table for SISO */ |
1394 | memcpy(search_tbl, tbl, sz); | 1530 | memcpy(search_tbl, tbl, sz); |
1395 | search_tbl->lq_type = LQ_SISO; | 1531 | search_tbl->lq_type = LQ_SISO; |
@@ -1546,7 +1682,7 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) | |||
1546 | /* | 1682 | /* |
1547 | * Do rate scaling and search for new modulation mode. | 1683 | * Do rate scaling and search for new modulation mode. |
1548 | */ | 1684 | */ |
1549 | static void rs_rate_scale_perform(struct iwl4965_priv *priv, | 1685 | static void rs_rate_scale_perform(struct iwl_priv *priv, |
1550 | struct net_device *dev, | 1686 | struct net_device *dev, |
1551 | struct ieee80211_hdr *hdr, | 1687 | struct ieee80211_hdr *hdr, |
1552 | struct sta_info *sta) | 1688 | struct sta_info *sta) |
@@ -1574,6 +1710,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1574 | u8 active_tbl = 0; | 1710 | u8 active_tbl = 0; |
1575 | u8 done_search = 0; | 1711 | u8 done_search = 0; |
1576 | u16 high_low; | 1712 | u16 high_low; |
1713 | #ifdef CONFIG_IWL4965_HT | ||
1714 | u8 tid = MAX_TID_COUNT; | ||
1715 | __le16 *qc; | ||
1716 | #endif | ||
1577 | 1717 | ||
1578 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1718 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1579 | 1719 | ||
@@ -1594,6 +1734,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1594 | } | 1734 | } |
1595 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1735 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1596 | 1736 | ||
1737 | #ifdef CONFIG_IWL4965_HT | ||
1738 | qc = ieee80211_get_qos_ctrl(hdr); | ||
1739 | if (qc) { | ||
1740 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1741 | rs_tl_add_packet(lq_sta, tid); | ||
1742 | } | ||
1743 | #endif | ||
1597 | /* | 1744 | /* |
1598 | * Select rate-scale / modulation-mode table to work with in | 1745 | * Select rate-scale / modulation-mode table to work with in |
1599 | * the rest of this function: "search" if searching for better | 1746 | * the rest of this function: "search" if searching for better |
@@ -1608,7 +1755,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1608 | is_green = lq_sta->is_green; | 1755 | is_green = lq_sta->is_green; |
1609 | 1756 | ||
1610 | /* current tx rate */ | 1757 | /* current tx rate */ |
1611 | index = sta->last_txrate; | 1758 | index = sta->last_txrate_idx; |
1612 | 1759 | ||
1613 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, | 1760 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, |
1614 | tbl->lq_type); | 1761 | tbl->lq_type); |
@@ -1621,7 +1768,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1621 | 1768 | ||
1622 | /* mask with station rate restriction */ | 1769 | /* mask with station rate restriction */ |
1623 | if (is_legacy(tbl->lq_type)) { | 1770 | if (is_legacy(tbl->lq_type)) { |
1624 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 1771 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1625 | /* supp_rates has no CCK bits in A mode */ | 1772 | /* supp_rates has no CCK bits in A mode */ |
1626 | rate_scale_index_msk = (u16) (rate_mask & | 1773 | rate_scale_index_msk = (u16) (rate_mask & |
1627 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 1774 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
@@ -1685,7 +1832,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1685 | if (update_lq) { | 1832 | if (update_lq) { |
1686 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | 1833 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); |
1687 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 1834 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
1688 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 1835 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
1689 | } | 1836 | } |
1690 | goto out; | 1837 | goto out; |
1691 | 1838 | ||
@@ -1727,7 +1874,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1727 | tbl = &(lq_sta->lq_info[active_tbl]); | 1874 | tbl = &(lq_sta->lq_info[active_tbl]); |
1728 | 1875 | ||
1729 | /* Revert to "active" rate and throughput info */ | 1876 | /* Revert to "active" rate and throughput info */ |
1730 | index = iwl4965_rate_index_from_plcp( | 1877 | index = iwl4965_hwrate_to_plcp_idx( |
1731 | tbl->current_rate.rate_n_flags); | 1878 | tbl->current_rate.rate_n_flags); |
1732 | current_tpt = lq_sta->last_tpt; | 1879 | current_tpt = lq_sta->last_tpt; |
1733 | 1880 | ||
@@ -1850,7 +1997,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1850 | if (update_lq) { | 1997 | if (update_lq) { |
1851 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | 1998 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); |
1852 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 1999 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
1853 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2000 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
1854 | } | 2001 | } |
1855 | 2002 | ||
1856 | /* Should we stay with this modulation mode, or search for a new one? */ | 2003 | /* Should we stay with this modulation mode, or search for a new one? */ |
@@ -1883,14 +2030,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1883 | rs_rate_scale_clear_window(&(tbl->win[i])); | 2030 | rs_rate_scale_clear_window(&(tbl->win[i])); |
1884 | 2031 | ||
1885 | /* Use new "search" start rate */ | 2032 | /* Use new "search" start rate */ |
1886 | index = iwl4965_rate_index_from_plcp( | 2033 | index = iwl4965_hwrate_to_plcp_idx( |
1887 | tbl->current_rate.rate_n_flags); | 2034 | tbl->current_rate.rate_n_flags); |
1888 | 2035 | ||
1889 | IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", | 2036 | IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", |
1890 | tbl->current_rate.rate_n_flags, index); | 2037 | tbl->current_rate.rate_n_flags, index); |
1891 | rs_fill_link_cmd(lq_sta, &tbl->current_rate, | 2038 | rs_fill_link_cmd(lq_sta, &tbl->current_rate, |
1892 | &lq_sta->lq); | 2039 | &lq_sta->lq); |
1893 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2040 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
1894 | } | 2041 | } |
1895 | 2042 | ||
1896 | /* If the "active" (non-search) mode was legacy, | 2043 | /* If the "active" (non-search) mode was legacy, |
@@ -1914,15 +2061,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1914 | * mode for a while before next round of mode comparisons. */ | 2061 | * mode for a while before next round of mode comparisons. */ |
1915 | if (lq_sta->enable_counter && | 2062 | if (lq_sta->enable_counter && |
1916 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2063 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
1917 | #ifdef CONFIG_IWL4965_HT_AGG | 2064 | #ifdef CONFIG_IWL4965_HT |
1918 | /* If appropriate, set up aggregation! */ | 2065 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
1919 | if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) && | 2066 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
1920 | (priv->lq_mngr.agg_ctrl.auto_agg)) { | 2067 | (tid != MAX_TID_COUNT)) { |
1921 | priv->lq_mngr.agg_ctrl.tid_retry = | 2068 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); |
1922 | TID_ALL_SPECIFIED; | 2069 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
1923 | schedule_work(&priv->agg_work); | ||
1924 | } | 2070 | } |
1925 | #endif /*CONFIG_IWL4965_HT_AGG */ | 2071 | #endif /*CONFIG_IWL4965_HT */ |
1926 | lq_sta->action_counter = 0; | 2072 | lq_sta->action_counter = 0; |
1927 | rs_set_stay_in_table(0, lq_sta); | 2073 | rs_set_stay_in_table(0, lq_sta); |
1928 | } | 2074 | } |
@@ -1942,21 +2088,21 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1942 | out: | 2088 | out: |
1943 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); | 2089 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); |
1944 | i = index; | 2090 | i = index; |
1945 | sta->last_txrate = i; | 2091 | sta->last_txrate_idx = i; |
1946 | 2092 | ||
1947 | /* sta->txrate is an index to A mode rates which start | 2093 | /* sta->txrate_idx is an index to A mode rates which start |
1948 | * at IWL_FIRST_OFDM_RATE | 2094 | * at IWL_FIRST_OFDM_RATE |
1949 | */ | 2095 | */ |
1950 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2096 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1951 | sta->txrate = i - IWL_FIRST_OFDM_RATE; | 2097 | sta->txrate_idx = i - IWL_FIRST_OFDM_RATE; |
1952 | else | 2098 | else |
1953 | sta->txrate = i; | 2099 | sta->txrate_idx = i; |
1954 | 2100 | ||
1955 | return; | 2101 | return; |
1956 | } | 2102 | } |
1957 | 2103 | ||
1958 | 2104 | ||
1959 | static void rs_initialize_lq(struct iwl4965_priv *priv, | 2105 | static void rs_initialize_lq(struct iwl_priv *priv, |
1960 | struct ieee80211_conf *conf, | 2106 | struct ieee80211_conf *conf, |
1961 | struct sta_info *sta) | 2107 | struct sta_info *sta) |
1962 | { | 2108 | { |
@@ -1972,7 +2118,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1972 | goto out; | 2118 | goto out; |
1973 | 2119 | ||
1974 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2120 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1975 | i = sta->last_txrate; | 2121 | i = sta->last_txrate_idx; |
1976 | 2122 | ||
1977 | if ((lq_sta->lq.sta_id == 0xff) && | 2123 | if ((lq_sta->lq.sta_id == 0xff) && |
1978 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 2124 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) |
@@ -1996,7 +2142,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1996 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; | 2142 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; |
1997 | 2143 | ||
1998 | tbl->antenna_type = ANT_AUX; | 2144 | tbl->antenna_type = ANT_AUX; |
1999 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx); | 2145 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); |
2000 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) | 2146 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) |
2001 | rs_toggle_antenna(&mcs_rate, tbl); | 2147 | rs_toggle_antenna(&mcs_rate, tbl); |
2002 | 2148 | ||
@@ -2004,13 +2150,14 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
2004 | tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; | 2150 | tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; |
2005 | rs_get_expected_tpt_table(lq_sta, tbl); | 2151 | rs_get_expected_tpt_table(lq_sta, tbl); |
2006 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 2152 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
2007 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2153 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2008 | out: | 2154 | out: |
2009 | return; | 2155 | return; |
2010 | } | 2156 | } |
2011 | 2157 | ||
2012 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 2158 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
2013 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 2159 | struct ieee80211_supported_band *sband, |
2160 | struct sk_buff *skb, | ||
2014 | struct rate_selection *sel) | 2161 | struct rate_selection *sel) |
2015 | { | 2162 | { |
2016 | 2163 | ||
@@ -2020,11 +2167,13 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2020 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2167 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2021 | struct sta_info *sta; | 2168 | struct sta_info *sta; |
2022 | u16 fc; | 2169 | u16 fc; |
2023 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 2170 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
2024 | struct iwl4965_lq_sta *lq_sta; | 2171 | struct iwl4965_lq_sta *lq_sta; |
2025 | 2172 | ||
2026 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); | 2173 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); |
2027 | 2174 | ||
2175 | rcu_read_lock(); | ||
2176 | |||
2028 | sta = sta_info_get(local, hdr->addr1); | 2177 | sta = sta_info_get(local, hdr->addr1); |
2029 | 2178 | ||
2030 | /* Send management frames and broadcast/multicast data using lowest | 2179 | /* Send management frames and broadcast/multicast data using lowest |
@@ -2032,14 +2181,12 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2032 | fc = le16_to_cpu(hdr->frame_control); | 2181 | fc = le16_to_cpu(hdr->frame_control); |
2033 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2182 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2034 | !sta || !sta->rate_ctrl_priv) { | 2183 | !sta || !sta->rate_ctrl_priv) { |
2035 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2184 | sel->rate = rate_lowest(local, sband, sta); |
2036 | if (sta) | 2185 | goto out; |
2037 | sta_info_put(sta); | ||
2038 | return; | ||
2039 | } | 2186 | } |
2040 | 2187 | ||
2041 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2188 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
2042 | i = sta->last_txrate; | 2189 | i = sta->last_txrate_idx; |
2043 | 2190 | ||
2044 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2191 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
2045 | !lq_sta->ibss_sta_added) { | 2192 | !lq_sta->ibss_sta_added) { |
@@ -2062,14 +2209,15 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2062 | goto done; | 2209 | goto done; |
2063 | } | 2210 | } |
2064 | 2211 | ||
2065 | done: | 2212 | done: |
2066 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2213 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2067 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2214 | sel->rate = rate_lowest(local, sband, sta); |
2068 | return; | 2215 | goto out; |
2069 | } | 2216 | } |
2070 | sta_info_put(sta); | ||
2071 | 2217 | ||
2072 | sel->rate = &priv->ieee_rates[i]; | 2218 | sel->rate = &priv->ieee_rates[i]; |
2219 | out: | ||
2220 | rcu_read_unlock(); | ||
2073 | } | 2221 | } |
2074 | 2222 | ||
2075 | static void *rs_alloc_sta(void *priv, gfp_t gfp) | 2223 | static void *rs_alloc_sta(void *priv, gfp_t gfp) |
@@ -2099,13 +2247,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2099 | { | 2247 | { |
2100 | int i, j; | 2248 | int i, j; |
2101 | struct ieee80211_conf *conf = &local->hw.conf; | 2249 | struct ieee80211_conf *conf = &local->hw.conf; |
2102 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; | 2250 | struct ieee80211_supported_band *sband; |
2103 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 2251 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
2104 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2252 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2105 | 2253 | ||
2254 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2255 | |||
2106 | lq_sta->flush_timer = 0; | 2256 | lq_sta->flush_timer = 0; |
2107 | lq_sta->supp_rates = sta->supp_rates; | 2257 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
2108 | sta->txrate = 3; | 2258 | sta->txrate_idx = 3; |
2109 | for (j = 0; j < LQ_SIZE; j++) | 2259 | for (j = 0; j < LQ_SIZE; j++) |
2110 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2260 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2111 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); | 2261 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); |
@@ -2140,15 +2290,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2140 | } | 2290 | } |
2141 | 2291 | ||
2142 | /* Find highest tx rate supported by hardware and destination station */ | 2292 | /* Find highest tx rate supported by hardware and destination station */ |
2143 | for (i = 0; i < mode->num_rates; i++) { | 2293 | for (i = 0; i < sband->n_bitrates; i++) |
2144 | if ((sta->supp_rates & BIT(i)) && | 2294 | if (sta->supp_rates[sband->band] & BIT(i)) |
2145 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) | 2295 | sta->txrate_idx = i; |
2146 | sta->txrate = i; | 2296 | |
2147 | } | 2297 | sta->last_txrate_idx = sta->txrate_idx; |
2148 | sta->last_txrate = sta->txrate; | 2298 | /* WTF is with this bogus comment? A doesn't have cck rates */ |
2149 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ | 2299 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ |
2150 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 2300 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
2151 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 2301 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2152 | 2302 | ||
2153 | lq_sta->is_dup = 0; | 2303 | lq_sta->is_dup = 0; |
2154 | lq_sta->valid_antenna = priv->valid_antenna; | 2304 | lq_sta->valid_antenna = priv->valid_antenna; |
@@ -2157,7 +2307,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2157 | lq_sta->active_rate = priv->active_rate; | 2307 | lq_sta->active_rate = priv->active_rate; |
2158 | lq_sta->active_rate &= ~(0x1000); | 2308 | lq_sta->active_rate &= ~(0x1000); |
2159 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2309 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2160 | lq_sta->phymode = priv->phymode; | 2310 | lq_sta->band = priv->band; |
2161 | #ifdef CONFIG_IWL4965_HT | 2311 | #ifdef CONFIG_IWL4965_HT |
2162 | /* | 2312 | /* |
2163 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2313 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
@@ -2180,6 +2330,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2180 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2330 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", |
2181 | lq_sta->active_siso_rate, | 2331 | lq_sta->active_siso_rate, |
2182 | lq_sta->active_mimo_rate); | 2332 | lq_sta->active_mimo_rate); |
2333 | /* as default allow aggregation for all tids */ | ||
2334 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | ||
2183 | #endif /*CONFIG_IWL4965_HT*/ | 2335 | #endif /*CONFIG_IWL4965_HT*/ |
2184 | #ifdef CONFIG_MAC80211_DEBUGFS | 2336 | #ifdef CONFIG_MAC80211_DEBUGFS |
2185 | lq_sta->drv = priv; | 2337 | lq_sta->drv = priv; |
@@ -2193,7 +2345,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2193 | 2345 | ||
2194 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 2346 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, |
2195 | struct iwl4965_rate *tx_mcs, | 2347 | struct iwl4965_rate *tx_mcs, |
2196 | struct iwl4965_link_quality_cmd *lq_cmd) | 2348 | struct iwl_link_quality_cmd *lq_cmd) |
2197 | { | 2349 | { |
2198 | int index = 0; | 2350 | int index = 0; |
2199 | int rate_idx; | 2351 | int rate_idx; |
@@ -2207,7 +2359,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2207 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); | 2359 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); |
2208 | 2360 | ||
2209 | /* Interpret rate_n_flags */ | 2361 | /* Interpret rate_n_flags */ |
2210 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode, | 2362 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, |
2211 | &tbl_type, &rate_idx); | 2363 | &tbl_type, &rate_idx); |
2212 | 2364 | ||
2213 | /* How many times should we repeat the initial rate? */ | 2365 | /* How many times should we repeat the initial rate? */ |
@@ -2261,7 +2413,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2261 | index++; | 2413 | index++; |
2262 | } | 2414 | } |
2263 | 2415 | ||
2264 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type, | 2416 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, |
2265 | &rate_idx); | 2417 | &rate_idx); |
2266 | 2418 | ||
2267 | /* Indicate to uCode which entries might be MIMO. | 2419 | /* Indicate to uCode which entries might be MIMO. |
@@ -2318,17 +2470,11 @@ static void rs_free(void *priv_rate) | |||
2318 | 2470 | ||
2319 | static void rs_clear(void *priv_rate) | 2471 | static void rs_clear(void *priv_rate) |
2320 | { | 2472 | { |
2321 | struct iwl4965_priv *priv = (struct iwl4965_priv *) priv_rate; | 2473 | struct iwl_priv *priv = (struct iwl_priv *) priv_rate; |
2322 | 2474 | ||
2323 | IWL_DEBUG_RATE("enter\n"); | 2475 | IWL_DEBUG_RATE("enter\n"); |
2324 | 2476 | ||
2325 | priv->lq_mngr.lq_ready = 0; | 2477 | priv->lq_mngr.lq_ready = 0; |
2326 | #ifdef CONFIG_IWL4965_HT | ||
2327 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2328 | if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
2329 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); | ||
2330 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
2331 | #endif /* CONFIG_IWL4965_HT */ | ||
2332 | 2478 | ||
2333 | IWL_DEBUG_RATE("leave\n"); | 2479 | IWL_DEBUG_RATE("leave\n"); |
2334 | } | 2480 | } |
@@ -2354,7 +2500,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | |||
2354 | { | 2500 | { |
2355 | u32 base_rate; | 2501 | u32 base_rate; |
2356 | 2502 | ||
2357 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2503 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
2358 | base_rate = 0x800D; | 2504 | base_rate = 0x800D; |
2359 | else | 2505 | else |
2360 | base_rate = 0x820A; | 2506 | base_rate = 0x820A; |
@@ -2398,7 +2544,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | |||
2398 | 2544 | ||
2399 | if (lq_sta->dbg_fixed.rate_n_flags) { | 2545 | if (lq_sta->dbg_fixed.rate_n_flags) { |
2400 | rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); | 2546 | rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); |
2401 | rs_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); | 2547 | iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); |
2402 | } | 2548 | } |
2403 | 2549 | ||
2404 | return count; | 2550 | return count; |
@@ -2495,6 +2641,12 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2495 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2641 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2496 | debugfs_create_file("rate_stats_table", 0600, dir, | 2642 | debugfs_create_file("rate_stats_table", 0600, dir, |
2497 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2643 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2644 | #ifdef CONFIG_IWL4965_HT | ||
2645 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | ||
2646 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | ||
2647 | &lq_sta->tx_agg_tid_en); | ||
2648 | #endif | ||
2649 | |||
2498 | } | 2650 | } |
2499 | 2651 | ||
2500 | static void rs_remove_debugfs(void *priv, void *priv_sta) | 2652 | static void rs_remove_debugfs(void *priv, void *priv_sta) |
@@ -2502,6 +2654,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2502 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2654 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2503 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2655 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2504 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2656 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2657 | #ifdef CONFIG_IWL4965_HT | ||
2658 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | ||
2659 | #endif | ||
2505 | } | 2660 | } |
2506 | #endif | 2661 | #endif |
2507 | 2662 | ||
@@ -2525,7 +2680,7 @@ static struct rate_control_ops rs_ops = { | |||
2525 | int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | 2680 | int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) |
2526 | { | 2681 | { |
2527 | struct ieee80211_local *local = hw_to_local(hw); | 2682 | struct ieee80211_local *local = hw_to_local(hw); |
2528 | struct iwl4965_priv *priv = hw->priv; | 2683 | struct iwl_priv *priv = hw->priv; |
2529 | struct iwl4965_lq_sta *lq_sta; | 2684 | struct iwl4965_lq_sta *lq_sta; |
2530 | struct sta_info *sta; | 2685 | struct sta_info *sta; |
2531 | int cnt = 0, i; | 2686 | int cnt = 0, i; |
@@ -2534,13 +2689,15 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2534 | u32 max_time = 0; | 2689 | u32 max_time = 0; |
2535 | u8 lq_type, antenna; | 2690 | u8 lq_type, antenna; |
2536 | 2691 | ||
2692 | rcu_read_lock(); | ||
2693 | |||
2537 | sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); | 2694 | sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); |
2538 | if (!sta || !sta->rate_ctrl_priv) { | 2695 | if (!sta || !sta->rate_ctrl_priv) { |
2539 | if (sta) { | 2696 | if (sta) |
2540 | sta_info_put(sta); | ||
2541 | IWL_DEBUG_RATE("leave - no private rate data!\n"); | 2697 | IWL_DEBUG_RATE("leave - no private rate data!\n"); |
2542 | } else | 2698 | else |
2543 | IWL_DEBUG_RATE("leave - no station!\n"); | 2699 | IWL_DEBUG_RATE("leave - no station!\n"); |
2700 | rcu_read_unlock(); | ||
2544 | return sprintf(buf, "station %d not found\n", sta_id); | 2701 | return sprintf(buf, "station %d not found\n", sta_id); |
2545 | } | 2702 | } |
2546 | 2703 | ||
@@ -2605,25 +2762,25 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2605 | 2762 | ||
2606 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " | 2763 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " |
2607 | "active_search %d rate index %d\n", lq_type, antenna, | 2764 | "active_search %d rate index %d\n", lq_type, antenna, |
2608 | lq_sta->search_better_tbl, sta->last_txrate); | 2765 | lq_sta->search_better_tbl, sta->last_txrate_idx); |
2609 | 2766 | ||
2610 | sta_info_put(sta); | 2767 | rcu_read_unlock(); |
2611 | return cnt; | 2768 | return cnt; |
2612 | } | 2769 | } |
2613 | 2770 | ||
2614 | void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | 2771 | void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) |
2615 | { | 2772 | { |
2616 | struct iwl4965_priv *priv = hw->priv; | 2773 | struct iwl_priv *priv = hw->priv; |
2617 | 2774 | ||
2618 | priv->lq_mngr.lq_ready = 1; | 2775 | priv->lq_mngr.lq_ready = 1; |
2619 | } | 2776 | } |
2620 | 2777 | ||
2621 | void iwl4965_rate_control_register(struct ieee80211_hw *hw) | 2778 | int iwl4965_rate_control_register(void) |
2622 | { | 2779 | { |
2623 | ieee80211_rate_control_register(&rs_ops); | 2780 | return ieee80211_rate_control_register(&rs_ops); |
2624 | } | 2781 | } |
2625 | 2782 | ||
2626 | void iwl4965_rate_control_unregister(struct ieee80211_hw *hw) | 2783 | void iwl4965_rate_control_unregister(void) |
2627 | { | 2784 | { |
2628 | ieee80211_rate_control_unregister(&rs_ops); | 2785 | ieee80211_rate_control_unregister(&rs_ops); |
2629 | } | 2786 | } |