diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 204 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 396 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 54 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 20 |
5 files changed, 199 insertions, 487 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index f4f2497646bd..660671f17a3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -83,7 +83,7 @@ struct iwl4965_rate_scale_data { | |||
83 | /** | 83 | /** |
84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates | 84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates |
85 | * | 85 | * |
86 | * There are two of these in struct iwl_rate_scale_priv, | 86 | * There are two of these in struct iwl4965_lq_sta, |
87 | * one for "active", and one for "search". | 87 | * one for "active", and one for "search". |
88 | */ | 88 | */ |
89 | struct iwl4965_scale_tbl_info { | 89 | struct iwl4965_scale_tbl_info { |
@@ -98,8 +98,23 @@ struct iwl4965_scale_tbl_info { | |||
98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | #ifdef CONFIG_IWL4965_HT | ||
102 | |||
103 | struct iwl4965_traffic_load { | ||
104 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
105 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
106 | * slice */ | ||
107 | u32 total; /* total num of packets during the | ||
108 | * last TID_MAX_TIME_DIFF */ | ||
109 | u8 queue_count; /* number of queues that has | ||
110 | * been used since the last cleanup */ | ||
111 | u8 head; /* start of the circular buffer */ | ||
112 | }; | ||
113 | |||
114 | #endif /* CONFIG_IWL4965_HT */ | ||
115 | |||
101 | /** | 116 | /** |
102 | * struct iwl_rate_scale_priv -- driver's rate scaling private structure | 117 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
103 | * | 118 | * |
104 | * Pointer to this gets passed back and forth between driver and mac80211. | 119 | * Pointer to this gets passed back and forth between driver and mac80211. |
105 | */ | 120 | */ |
@@ -136,9 +151,16 @@ struct iwl4965_lq_sta { | |||
136 | 151 | ||
137 | struct iwl4965_link_quality_cmd lq; | 152 | struct iwl4965_link_quality_cmd lq; |
138 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 153 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
154 | #ifdef CONFIG_IWL4965_HT | ||
155 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
156 | u8 tx_agg_tid_en; | ||
157 | #endif | ||
139 | #ifdef CONFIG_MAC80211_DEBUGFS | 158 | #ifdef CONFIG_MAC80211_DEBUGFS |
140 | struct dentry *rs_sta_dbgfs_scale_table_file; | 159 | struct dentry *rs_sta_dbgfs_scale_table_file; |
141 | struct dentry *rs_sta_dbgfs_stats_table_file; | 160 | struct dentry *rs_sta_dbgfs_stats_table_file; |
161 | #ifdef CONFIG_IWL4965_HT | ||
162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
163 | #endif | ||
142 | struct iwl4965_rate dbg_fixed; | 164 | struct iwl4965_rate dbg_fixed; |
143 | struct iwl4965_priv *drv; | 165 | struct iwl4965_priv *drv; |
144 | #endif | 166 | #endif |
@@ -269,6 +291,135 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
269 | window->stamp = 0; | 291 | window->stamp = 0; |
270 | } | 292 | } |
271 | 293 | ||
294 | #ifdef CONFIG_IWL4965_HT | ||
295 | /* | ||
296 | * removes the old data from the statistics. All data that is older than | ||
297 | * TID_MAX_TIME_DIFF, will be deleted. | ||
298 | */ | ||
299 | static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | ||
300 | { | ||
301 | /* The oldest age we want to keep */ | ||
302 | u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; | ||
303 | |||
304 | while (tl->queue_count && | ||
305 | (tl->time_stamp < oldest_time)) { | ||
306 | tl->total -= tl->packet_count[tl->head]; | ||
307 | tl->packet_count[tl->head] = 0; | ||
308 | tl->time_stamp += TID_QUEUE_CELL_SPACING; | ||
309 | tl->queue_count--; | ||
310 | tl->head++; | ||
311 | if (tl->head >= TID_QUEUE_MAX_SIZE) | ||
312 | tl->head = 0; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * increment traffic load value for tid and also remove | ||
318 | * any old values if passed the certain time period | ||
319 | */ | ||
320 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
321 | { | ||
322 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
323 | u32 time_diff; | ||
324 | s32 index; | ||
325 | struct iwl4965_traffic_load *tl = NULL; | ||
326 | |||
327 | if (tid >= TID_MAX_LOAD_COUNT) | ||
328 | return; | ||
329 | |||
330 | tl = &lq_data->load[tid]; | ||
331 | |||
332 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
333 | |||
334 | /* Happens only for the first packet. Initialize the data */ | ||
335 | if (!(tl->queue_count)) { | ||
336 | tl->total = 1; | ||
337 | tl->time_stamp = curr_time; | ||
338 | tl->queue_count = 1; | ||
339 | tl->head = 0; | ||
340 | tl->packet_count[0] = 1; | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
345 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
346 | |||
347 | /* The history is too long: remove data that is older than */ | ||
348 | /* TID_MAX_TIME_DIFF */ | ||
349 | if (index >= TID_QUEUE_MAX_SIZE) | ||
350 | rs_tl_rm_old_stats(tl, curr_time); | ||
351 | |||
352 | index = (tl->head + index) % TID_QUEUE_MAX_SIZE; | ||
353 | tl->packet_count[index] = tl->packet_count[index] + 1; | ||
354 | tl->total = tl->total + 1; | ||
355 | |||
356 | if ((index + 1) > tl->queue_count) | ||
357 | tl->queue_count = index + 1; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | get the traffic load value for tid | ||
362 | */ | ||
363 | static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
364 | { | ||
365 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
366 | u32 time_diff; | ||
367 | s32 index; | ||
368 | struct iwl4965_traffic_load *tl = NULL; | ||
369 | |||
370 | if (tid >= TID_MAX_LOAD_COUNT) | ||
371 | return 0; | ||
372 | |||
373 | tl = &(lq_data->load[tid]); | ||
374 | |||
375 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
376 | |||
377 | if (!(tl->queue_count)) | ||
378 | return 0; | ||
379 | |||
380 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
381 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
382 | |||
383 | /* The history is too long: remove data that is older than */ | ||
384 | /* TID_MAX_TIME_DIFF */ | ||
385 | if (index >= TID_QUEUE_MAX_SIZE) | ||
386 | rs_tl_rm_old_stats(tl, curr_time); | ||
387 | |||
388 | return tl->total; | ||
389 | } | ||
390 | |||
391 | static void rs_tl_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
392 | struct iwl4965_lq_sta *lq_data, u8 tid, | ||
393 | struct sta_info *sta) | ||
394 | { | ||
395 | unsigned long state; | ||
396 | DECLARE_MAC_BUF(mac); | ||
397 | |||
398 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
399 | state = sta->ampdu_mlme.tid_tx[tid].state; | ||
400 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
401 | |||
402 | if (state == HT_AGG_STATE_IDLE && | ||
403 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | ||
404 | IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", | ||
405 | print_mac(mac, sta->addr), tid); | ||
406 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void rs_tl_turn_on_agg(struct iwl4965_priv *priv, u8 tid, | ||
411 | struct iwl4965_lq_sta *lq_data, | ||
412 | struct sta_info *sta) | ||
413 | { | ||
414 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
415 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
416 | else if (tid == IWL_AGG_ALL_TID) | ||
417 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
418 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
419 | } | ||
420 | |||
421 | #endif /* CONFIG_IWLWIFI_HT */ | ||
422 | |||
272 | /** | 423 | /** |
273 | * rs_collect_tx_data - Update the success/failure sliding window | 424 | * rs_collect_tx_data - Update the success/failure sliding window |
274 | * | 425 | * |
@@ -1134,7 +1285,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv, | |||
1134 | return 0; | 1285 | return 0; |
1135 | #else | 1286 | #else |
1136 | return -1; | 1287 | return -1; |
1137 | #endif /*CONFIG_IWL4965_HT */ | 1288 | #endif /*CONFIG_IWL4965_HT */ |
1138 | } | 1289 | } |
1139 | 1290 | ||
1140 | /* | 1291 | /* |
@@ -1197,7 +1348,7 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv, | |||
1197 | #else | 1348 | #else |
1198 | return -1; | 1349 | return -1; |
1199 | 1350 | ||
1200 | #endif /*CONFIG_IWL4965_HT */ | 1351 | #endif /*CONFIG_IWL4965_HT */ |
1201 | } | 1352 | } |
1202 | 1353 | ||
1203 | /* | 1354 | /* |
@@ -1354,6 +1505,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1354 | break; | 1505 | break; |
1355 | case IWL_SISO_SWITCH_GI: | 1506 | case IWL_SISO_SWITCH_GI: |
1356 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1507 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); |
1508 | |||
1357 | memcpy(search_tbl, tbl, sz); | 1509 | memcpy(search_tbl, tbl, sz); |
1358 | search_tbl->action = 0; | 1510 | search_tbl->action = 0; |
1359 | if (search_tbl->is_SGI) | 1511 | if (search_tbl->is_SGI) |
@@ -1419,6 +1571,7 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | |||
1419 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1571 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1420 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1572 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); |
1421 | 1573 | ||
1574 | |||
1422 | /* Set up new search table for SISO */ | 1575 | /* Set up new search table for SISO */ |
1423 | memcpy(search_tbl, tbl, sz); | 1576 | memcpy(search_tbl, tbl, sz); |
1424 | search_tbl->lq_type = LQ_SISO; | 1577 | search_tbl->lq_type = LQ_SISO; |
@@ -1603,6 +1756,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1603 | u8 active_tbl = 0; | 1756 | u8 active_tbl = 0; |
1604 | u8 done_search = 0; | 1757 | u8 done_search = 0; |
1605 | u16 high_low; | 1758 | u16 high_low; |
1759 | #ifdef CONFIG_IWL4965_HT | ||
1760 | u8 tid = MAX_TID_COUNT; | ||
1761 | __le16 *qc; | ||
1762 | #endif | ||
1606 | 1763 | ||
1607 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1764 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1608 | 1765 | ||
@@ -1623,6 +1780,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1623 | } | 1780 | } |
1624 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1781 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1625 | 1782 | ||
1783 | #ifdef CONFIG_IWL4965_HT | ||
1784 | qc = ieee80211_get_qos_ctrl(hdr); | ||
1785 | if (qc) { | ||
1786 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1787 | rs_tl_add_packet(lq_sta, tid); | ||
1788 | } | ||
1789 | #endif | ||
1626 | /* | 1790 | /* |
1627 | * Select rate-scale / modulation-mode table to work with in | 1791 | * Select rate-scale / modulation-mode table to work with in |
1628 | * the rest of this function: "search" if searching for better | 1792 | * the rest of this function: "search" if searching for better |
@@ -1943,15 +2107,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1943 | * mode for a while before next round of mode comparisons. */ | 2107 | * mode for a while before next round of mode comparisons. */ |
1944 | if (lq_sta->enable_counter && | 2108 | if (lq_sta->enable_counter && |
1945 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2109 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
1946 | #ifdef CONFIG_IWL4965_HT_AGG | 2110 | #ifdef CONFIG_IWL4965_HT |
1947 | /* If appropriate, set up aggregation! */ | 2111 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
1948 | if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) && | 2112 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
1949 | (priv->lq_mngr.agg_ctrl.auto_agg)) { | 2113 | (tid != MAX_TID_COUNT)) { |
1950 | priv->lq_mngr.agg_ctrl.tid_retry = | 2114 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); |
1951 | TID_ALL_SPECIFIED; | 2115 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
1952 | schedule_work(&priv->agg_work); | ||
1953 | } | 2116 | } |
1954 | #endif /*CONFIG_IWL4965_HT_AGG */ | 2117 | #endif /*CONFIG_IWL4965_HT */ |
1955 | lq_sta->action_counter = 0; | 2118 | lq_sta->action_counter = 0; |
1956 | rs_set_stay_in_table(0, lq_sta); | 2119 | rs_set_stay_in_table(0, lq_sta); |
1957 | } | 2120 | } |
@@ -2209,6 +2372,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2209 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2372 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", |
2210 | lq_sta->active_siso_rate, | 2373 | lq_sta->active_siso_rate, |
2211 | lq_sta->active_mimo_rate); | 2374 | lq_sta->active_mimo_rate); |
2375 | /* as default allow aggregation for all tids */ | ||
2376 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | ||
2212 | #endif /*CONFIG_IWL4965_HT*/ | 2377 | #endif /*CONFIG_IWL4965_HT*/ |
2213 | #ifdef CONFIG_MAC80211_DEBUGFS | 2378 | #ifdef CONFIG_MAC80211_DEBUGFS |
2214 | lq_sta->drv = priv; | 2379 | lq_sta->drv = priv; |
@@ -2352,12 +2517,6 @@ static void rs_clear(void *priv_rate) | |||
2352 | IWL_DEBUG_RATE("enter\n"); | 2517 | IWL_DEBUG_RATE("enter\n"); |
2353 | 2518 | ||
2354 | priv->lq_mngr.lq_ready = 0; | 2519 | priv->lq_mngr.lq_ready = 0; |
2355 | #ifdef CONFIG_IWL4965_HT | ||
2356 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2357 | if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
2358 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); | ||
2359 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
2360 | #endif /* CONFIG_IWL4965_HT */ | ||
2361 | 2520 | ||
2362 | IWL_DEBUG_RATE("leave\n"); | 2521 | IWL_DEBUG_RATE("leave\n"); |
2363 | } | 2522 | } |
@@ -2524,6 +2683,12 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2524 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2683 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2525 | debugfs_create_file("rate_stats_table", 0600, dir, | 2684 | debugfs_create_file("rate_stats_table", 0600, dir, |
2526 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2685 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2686 | #ifdef CONFIG_IWL4965_HT | ||
2687 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | ||
2688 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | ||
2689 | &lq_sta->tx_agg_tid_en); | ||
2690 | #endif | ||
2691 | |||
2527 | } | 2692 | } |
2528 | 2693 | ||
2529 | static void rs_remove_debugfs(void *priv, void *priv_sta) | 2694 | static void rs_remove_debugfs(void *priv, void *priv_sta) |
@@ -2531,6 +2696,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2531 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2696 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2532 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2697 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2533 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2698 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2699 | #ifdef CONFIG_IWL4965_HT | ||
2700 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | ||
2701 | #endif | ||
2534 | } | 2702 | } |
2535 | #endif | 2703 | #endif |
2536 | 2704 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index 55f707382787..13b6c72eeb73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h | |||
@@ -212,6 +212,18 @@ enum { | |||
212 | 212 | ||
213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ | 213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ |
214 | 214 | ||
215 | /* load per tid defines for A-MPDU activation */ | ||
216 | #define IWL_AGG_TPT_THREHOLD 0 | ||
217 | #define IWL_AGG_LOAD_THRESHOLD 10 | ||
218 | #define IWL_AGG_ALL_TID 0xff | ||
219 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
220 | #define TID_QUEUE_MAX_SIZE 20 | ||
221 | #define TID_ROUND_VALUE 5 /* mS */ | ||
222 | #define TID_MAX_LOAD_COUNT 8 | ||
223 | |||
224 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
225 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
226 | |||
215 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; | 227 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; |
216 | 228 | ||
217 | enum iwl4965_table_type { | 229 | enum iwl4965_table_type { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 89aff4aae45f..e81120cc45f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2946,378 +2946,6 @@ void iwl4965_set_rxon_chain(struct iwl4965_priv *priv) | |||
2946 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | 2946 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); |
2947 | } | 2947 | } |
2948 | 2948 | ||
2949 | #ifdef CONFIG_IWL4965_HT | ||
2950 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2951 | /* | ||
2952 | get the traffic load value for tid | ||
2953 | */ | ||
2954 | static u32 iwl4965_tl_get_load(struct iwl4965_priv *priv, u8 tid) | ||
2955 | { | ||
2956 | u32 load = 0; | ||
2957 | u32 current_time = jiffies_to_msecs(jiffies); | ||
2958 | u32 time_diff; | ||
2959 | s32 index; | ||
2960 | unsigned long flags; | ||
2961 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
2962 | |||
2963 | if (tid >= TID_MAX_LOAD_COUNT) | ||
2964 | return 0; | ||
2965 | |||
2966 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
2967 | |||
2968 | current_time -= current_time % TID_ROUND_VALUE; | ||
2969 | |||
2970 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
2971 | if (!(tid_ptr->queue_count)) | ||
2972 | goto out; | ||
2973 | |||
2974 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
2975 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
2976 | |||
2977 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
2978 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
2979 | |||
2980 | while (tid_ptr->queue_count && | ||
2981 | (tid_ptr->time_stamp < oldest_time)) { | ||
2982 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
2983 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
2984 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
2985 | tid_ptr->queue_count--; | ||
2986 | tid_ptr->head++; | ||
2987 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
2988 | tid_ptr->head = 0; | ||
2989 | } | ||
2990 | } | ||
2991 | load = tid_ptr->total; | ||
2992 | |||
2993 | out: | ||
2994 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
2995 | return load; | ||
2996 | } | ||
2997 | |||
2998 | /* | ||
2999 | increment traffic load value for tid and also remove | ||
3000 | any old values if passed the certian time period | ||
3001 | */ | ||
3002 | static void iwl4965_tl_add_packet(struct iwl4965_priv *priv, u8 tid) | ||
3003 | { | ||
3004 | u32 current_time = jiffies_to_msecs(jiffies); | ||
3005 | u32 time_diff; | ||
3006 | s32 index; | ||
3007 | unsigned long flags; | ||
3008 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
3009 | |||
3010 | if (tid >= TID_MAX_LOAD_COUNT) | ||
3011 | return; | ||
3012 | |||
3013 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
3014 | |||
3015 | current_time -= current_time % TID_ROUND_VALUE; | ||
3016 | |||
3017 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3018 | if (!(tid_ptr->queue_count)) { | ||
3019 | tid_ptr->total = 1; | ||
3020 | tid_ptr->time_stamp = current_time; | ||
3021 | tid_ptr->queue_count = 1; | ||
3022 | tid_ptr->head = 0; | ||
3023 | tid_ptr->packet_count[0] = 1; | ||
3024 | goto out; | ||
3025 | } | ||
3026 | |||
3027 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
3028 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
3029 | |||
3030 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
3031 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
3032 | |||
3033 | while (tid_ptr->queue_count && | ||
3034 | (tid_ptr->time_stamp < oldest_time)) { | ||
3035 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
3036 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
3037 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
3038 | tid_ptr->queue_count--; | ||
3039 | tid_ptr->head++; | ||
3040 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
3041 | tid_ptr->head = 0; | ||
3042 | } | ||
3043 | } | ||
3044 | |||
3045 | index = (tid_ptr->head + index) % TID_QUEUE_MAX_SIZE; | ||
3046 | tid_ptr->packet_count[index] = tid_ptr->packet_count[index] + 1; | ||
3047 | tid_ptr->total = tid_ptr->total + 1; | ||
3048 | |||
3049 | if ((index + 1) > tid_ptr->queue_count) | ||
3050 | tid_ptr->queue_count = index + 1; | ||
3051 | out: | ||
3052 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3053 | |||
3054 | } | ||
3055 | |||
3056 | #define MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS 7 | ||
3057 | enum HT_STATUS { | ||
3058 | BA_STATUS_FAILURE = 0, | ||
3059 | BA_STATUS_INITIATOR_DELBA, | ||
3060 | BA_STATUS_RECIPIENT_DELBA, | ||
3061 | BA_STATUS_RENEW_ADDBA_REQUEST, | ||
3062 | BA_STATUS_ACTIVE, | ||
3063 | }; | ||
3064 | |||
3065 | /** | ||
3066 | * iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available | ||
3067 | */ | ||
3068 | static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv) | ||
3069 | { | ||
3070 | int i; | ||
3071 | struct iwl4965_lq_mngr *lq; | ||
3072 | u8 count = 0; | ||
3073 | u16 msk; | ||
3074 | |||
3075 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3076 | |||
3077 | /* Find out how many agg queues are in use */ | ||
3078 | for (i = 0; i < TID_MAX_LOAD_COUNT ; i++) { | ||
3079 | msk = 1 << i; | ||
3080 | if ((lq->agg_ctrl.granted_ba & msk) || | ||
3081 | (lq->agg_ctrl.wait_for_agg_status & msk)) | ||
3082 | count++; | ||
3083 | } | ||
3084 | |||
3085 | if (count < MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS) | ||
3086 | return 1; | ||
3087 | |||
3088 | return 0; | ||
3089 | } | ||
3090 | |||
3091 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3092 | u8 tid, enum HT_STATUS status); | ||
3093 | |||
3094 | static int iwl4965_perform_addba(struct iwl4965_priv *priv, u8 tid, u32 length, | ||
3095 | u32 ba_timeout) | ||
3096 | { | ||
3097 | int rc; | ||
3098 | |||
3099 | rc = ieee80211_start_BA_session(priv->hw, priv->bssid, tid); | ||
3100 | if (rc) | ||
3101 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3102 | |||
3103 | return rc; | ||
3104 | } | ||
3105 | |||
3106 | static int iwl4965_perform_delba(struct iwl4965_priv *priv, u8 tid) | ||
3107 | { | ||
3108 | int rc; | ||
3109 | |||
3110 | rc = ieee80211_stop_BA_session(priv->hw, priv->bssid, tid); | ||
3111 | if (rc) | ||
3112 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3113 | |||
3114 | return rc; | ||
3115 | } | ||
3116 | |||
3117 | static void iwl4965_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
3118 | struct iwl4965_lq_mngr *lq, | ||
3119 | u8 auto_agg, u8 tid) | ||
3120 | { | ||
3121 | u32 tid_msk = (1 << tid); | ||
3122 | unsigned long flags; | ||
3123 | |||
3124 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3125 | /* | ||
3126 | if ((auto_agg) && (!lq->enable_counter)){ | ||
3127 | lq->agg_ctrl.next_retry = 0; | ||
3128 | lq->agg_ctrl.tid_retry = 0; | ||
3129 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3130 | return; | ||
3131 | } | ||
3132 | */ | ||
3133 | if (!(lq->agg_ctrl.granted_ba & tid_msk) && | ||
3134 | (lq->agg_ctrl.requested_ba & tid_msk)) { | ||
3135 | u8 available_queues; | ||
3136 | u32 load; | ||
3137 | |||
3138 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3139 | available_queues = iwl4964_tl_ba_avail(priv); | ||
3140 | load = iwl4965_tl_get_load(priv, tid); | ||
3141 | |||
3142 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3143 | if (!available_queues) { | ||
3144 | if (auto_agg) | ||
3145 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3146 | else { | ||
3147 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3148 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3149 | } | ||
3150 | } else if ((auto_agg) && | ||
3151 | ((load <= lq->agg_ctrl.tid_traffic_load_threshold) || | ||
3152 | ((lq->agg_ctrl.wait_for_agg_status & tid_msk)))) | ||
3153 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3154 | else { | ||
3155 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3156 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3157 | iwl4965_perform_addba(priv, tid, 0x40, | ||
3158 | lq->agg_ctrl.ba_timeout); | ||
3159 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3160 | } | ||
3161 | } | ||
3162 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3163 | } | ||
3164 | |||
3165 | static void iwl4965_turn_on_agg(struct iwl4965_priv *priv, u8 tid) | ||
3166 | { | ||
3167 | struct iwl4965_lq_mngr *lq; | ||
3168 | unsigned long flags; | ||
3169 | |||
3170 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3171 | |||
3172 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
3173 | iwl4965_turn_on_agg_for_tid(priv, lq, lq->agg_ctrl.auto_agg, | ||
3174 | tid); | ||
3175 | else if (tid == TID_ALL_SPECIFIED) { | ||
3176 | if (lq->agg_ctrl.requested_ba) { | ||
3177 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
3178 | iwl4965_turn_on_agg_for_tid(priv, lq, | ||
3179 | lq->agg_ctrl.auto_agg, tid); | ||
3180 | } else { | ||
3181 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3182 | lq->agg_ctrl.tid_retry = 0; | ||
3183 | lq->agg_ctrl.next_retry = 0; | ||
3184 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3185 | } | ||
3186 | } | ||
3187 | |||
3188 | } | ||
3189 | |||
3190 | void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid) | ||
3191 | { | ||
3192 | u32 tid_msk; | ||
3193 | struct iwl4965_lq_mngr *lq; | ||
3194 | unsigned long flags; | ||
3195 | |||
3196 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3197 | |||
3198 | if ((tid < TID_MAX_LOAD_COUNT)) { | ||
3199 | tid_msk = 1 << tid; | ||
3200 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3201 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3202 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3203 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3204 | iwl4965_perform_delba(priv, tid); | ||
3205 | } else if (tid == TID_ALL_SPECIFIED) { | ||
3206 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3207 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3208 | tid_msk = 1 << tid; | ||
3209 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3210 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3211 | iwl4965_perform_delba(priv, tid); | ||
3212 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3213 | } | ||
3214 | lq->agg_ctrl.requested_ba = 0; | ||
3215 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3216 | } | ||
3217 | } | ||
3218 | |||
3219 | /** | ||
3220 | * iwl4965_ba_status - Update driver's link quality mgr with tid's HT status | ||
3221 | */ | ||
3222 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3223 | u8 tid, enum HT_STATUS status) | ||
3224 | { | ||
3225 | struct iwl4965_lq_mngr *lq; | ||
3226 | u32 tid_msk = (1 << tid); | ||
3227 | unsigned long flags; | ||
3228 | |||
3229 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3230 | |||
3231 | if ((tid >= TID_MAX_LOAD_COUNT)) | ||
3232 | goto out; | ||
3233 | |||
3234 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3235 | switch (status) { | ||
3236 | case BA_STATUS_ACTIVE: | ||
3237 | if (!(lq->agg_ctrl.granted_ba & tid_msk)) | ||
3238 | lq->agg_ctrl.granted_ba |= tid_msk; | ||
3239 | break; | ||
3240 | default: | ||
3241 | if ((lq->agg_ctrl.granted_ba & tid_msk)) | ||
3242 | lq->agg_ctrl.granted_ba &= ~tid_msk; | ||
3243 | break; | ||
3244 | } | ||
3245 | |||
3246 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3247 | if (status != BA_STATUS_ACTIVE) { | ||
3248 | if (lq->agg_ctrl.auto_agg) { | ||
3249 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3250 | lq->agg_ctrl.next_retry = | ||
3251 | jiffies + msecs_to_jiffies(500); | ||
3252 | } else | ||
3253 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3254 | } | ||
3255 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3256 | out: | ||
3257 | return; | ||
3258 | } | ||
3259 | |||
3260 | static void iwl4965_bg_agg_work(struct work_struct *work) | ||
3261 | { | ||
3262 | struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, | ||
3263 | agg_work); | ||
3264 | |||
3265 | u32 tid; | ||
3266 | u32 retry_tid; | ||
3267 | u32 tid_msk; | ||
3268 | unsigned long flags; | ||
3269 | struct iwl4965_lq_mngr *lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3270 | |||
3271 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3272 | retry_tid = lq->agg_ctrl.tid_retry; | ||
3273 | lq->agg_ctrl.tid_retry = 0; | ||
3274 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3275 | |||
3276 | if (retry_tid == TID_ALL_SPECIFIED) | ||
3277 | iwl4965_turn_on_agg(priv, TID_ALL_SPECIFIED); | ||
3278 | else { | ||
3279 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3280 | tid_msk = (1 << tid); | ||
3281 | if (retry_tid & tid_msk) | ||
3282 | iwl4965_turn_on_agg(priv, tid); | ||
3283 | } | ||
3284 | } | ||
3285 | |||
3286 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3287 | if (lq->agg_ctrl.tid_retry) | ||
3288 | lq->agg_ctrl.next_retry = jiffies + msecs_to_jiffies(500); | ||
3289 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3290 | return; | ||
3291 | } | ||
3292 | |||
3293 | /* TODO: move this functionality to rate scaling */ | ||
3294 | void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
3295 | struct ieee80211_hdr *hdr) | ||
3296 | { | ||
3297 | __le16 *qc = ieee80211_get_qos_ctrl(hdr); | ||
3298 | |||
3299 | if (qc && | ||
3300 | (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) { | ||
3301 | u8 tid = 0; | ||
3302 | tid = (u8) (le16_to_cpu(*qc) & 0xF); | ||
3303 | if (tid < TID_MAX_LOAD_COUNT) | ||
3304 | iwl4965_tl_add_packet(priv, tid); | ||
3305 | } | ||
3306 | |||
3307 | if (priv->lq_mngr.agg_ctrl.next_retry && | ||
3308 | (time_after(priv->lq_mngr.agg_ctrl.next_retry, jiffies))) { | ||
3309 | unsigned long flags; | ||
3310 | |||
3311 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3312 | priv->lq_mngr.agg_ctrl.next_retry = 0; | ||
3313 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3314 | schedule_work(&priv->agg_work); | ||
3315 | } | ||
3316 | } | ||
3317 | |||
3318 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
3319 | #endif /* CONFIG_IWL4965_HT */ | ||
3320 | |||
3321 | /** | 2949 | /** |
3322 | * sign_extend - Sign extend a value using specified bit as sign-bit | 2950 | * sign_extend - Sign extend a value using specified bit as sign-bit |
3323 | * | 2951 | * |
@@ -4191,25 +3819,6 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv, | |||
4191 | } | 3819 | } |
4192 | 3820 | ||
4193 | #ifdef CONFIG_IWL4965_HT | 3821 | #ifdef CONFIG_IWL4965_HT |
4194 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4195 | |||
4196 | /** | ||
4197 | * iwl4965_set_tx_status - Update driver's record of one Tx frame's status | ||
4198 | * | ||
4199 | * This will get sent to mac80211. | ||
4200 | */ | ||
4201 | static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx, | ||
4202 | u32 status, u32 retry_count, u32 rate) | ||
4203 | { | ||
4204 | struct ieee80211_tx_status *tx_status = | ||
4205 | &(priv->txq[txq_id].txb[idx].status); | ||
4206 | |||
4207 | tx_status->flags = status ? IEEE80211_TX_STATUS_ACK : 0; | ||
4208 | tx_status->retry_count += retry_count; | ||
4209 | tx_status->control.tx_rate = rate; | ||
4210 | } | ||
4211 | |||
4212 | #endif/* CONFIG_IWL4965_HT_AGG */ | ||
4213 | 3822 | ||
4214 | /** | 3823 | /** |
4215 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table | 3824 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table |
@@ -4984,11 +4593,6 @@ void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv) | |||
4984 | #ifdef CONFIG_IWL4965_SENSITIVITY | 4593 | #ifdef CONFIG_IWL4965_SENSITIVITY |
4985 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); | 4594 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); |
4986 | #endif | 4595 | #endif |
4987 | #ifdef CONFIG_IWL4965_HT | ||
4988 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4989 | INIT_WORK(&priv->agg_work, iwl4965_bg_agg_work); | ||
4990 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4991 | #endif /* CONFIG_IWL4965_HT */ | ||
4992 | init_timer(&priv->statistics_periodic); | 4596 | init_timer(&priv->statistics_periodic); |
4993 | priv->statistics_periodic.data = (unsigned long)priv; | 4597 | priv->statistics_periodic.data = (unsigned long)priv; |
4994 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | 4598 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 47c7f3ffe369..de5c1bf8fc42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -782,11 +782,6 @@ extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
782 | const u8 *addr, u16 tid, u16 *ssn); | 782 | const u8 *addr, u16 tid, u16 *ssn); |
783 | extern int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, | 783 | extern int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, |
784 | u8 tid, int txq_id); | 784 | u8 tid, int txq_id); |
785 | #ifdef CONFIG_IWL4965_HT_AGG | ||
786 | extern void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid); | ||
787 | extern void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
788 | struct ieee80211_hdr *hdr); | ||
789 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
790 | #endif /*CONFIG_IWL4965_HT */ | 785 | #endif /*CONFIG_IWL4965_HT */ |
791 | /* Structures, enum, and defines specific to the 4965 */ | 786 | /* Structures, enum, and defines specific to the 4965 */ |
792 | 787 | ||
@@ -798,18 +793,6 @@ struct iwl4965_kw { | |||
798 | size_t size; | 793 | size_t size; |
799 | }; | 794 | }; |
800 | 795 | ||
801 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
802 | #define TID_QUEUE_MAX_SIZE 20 | ||
803 | #define TID_ROUND_VALUE 5 /* mS */ | ||
804 | #define TID_MAX_LOAD_COUNT 8 | ||
805 | |||
806 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
807 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
808 | |||
809 | #define TID_ALL_ENABLED 0x7f | ||
810 | #define TID_ALL_SPECIFIED 0xff | ||
811 | #define TID_AGG_TPT_THREHOLD 0x0 | ||
812 | |||
813 | #define IWL_CHANNEL_WIDTH_20MHZ 0 | 796 | #define IWL_CHANNEL_WIDTH_20MHZ 0 |
814 | #define IWL_CHANNEL_WIDTH_40MHZ 1 | 797 | #define IWL_CHANNEL_WIDTH_40MHZ 1 |
815 | 798 | ||
@@ -834,37 +817,7 @@ struct iwl4965_kw { | |||
834 | 817 | ||
835 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 | 818 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 |
836 | 819 | ||
837 | struct iwl4965_traffic_load { | ||
838 | unsigned long time_stamp; | ||
839 | u32 packet_count[TID_QUEUE_MAX_SIZE]; | ||
840 | u8 queue_count; | ||
841 | u8 head; | ||
842 | u32 total; | ||
843 | }; | ||
844 | |||
845 | #ifdef CONFIG_IWL4965_HT_AGG | ||
846 | /** | ||
847 | * struct iwl4965_agg_control | ||
848 | * @requested_ba: bit map of tids requesting aggregation/block-ack | ||
849 | * @granted_ba: bit map of tids granted aggregation/block-ack | ||
850 | */ | ||
851 | struct iwl4965_agg_control { | ||
852 | unsigned long next_retry; | ||
853 | u32 wait_for_agg_status; | ||
854 | u32 tid_retry; | ||
855 | u32 requested_ba; | ||
856 | u32 granted_ba; | ||
857 | u8 auto_agg; | ||
858 | u32 tid_traffic_load_threshold; | ||
859 | u32 ba_timeout; | ||
860 | struct iwl4965_traffic_load traffic_load[TID_MAX_LOAD_COUNT]; | ||
861 | }; | ||
862 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
863 | |||
864 | struct iwl4965_lq_mngr { | 820 | struct iwl4965_lq_mngr { |
865 | #ifdef CONFIG_IWL4965_HT_AGG | ||
866 | struct iwl4965_agg_control agg_ctrl; | ||
867 | #endif | ||
868 | spinlock_t lock; | 821 | spinlock_t lock; |
869 | s32 max_window_size; | 822 | s32 max_window_size; |
870 | s32 *expected_tpt; | 823 | s32 *expected_tpt; |
@@ -877,7 +830,6 @@ struct iwl4965_lq_mngr { | |||
877 | u8 lq_ready; | 830 | u8 lq_ready; |
878 | }; | 831 | }; |
879 | 832 | ||
880 | |||
881 | /* Sensitivity and chain noise calibration */ | 833 | /* Sensitivity and chain noise calibration */ |
882 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) | 834 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) |
883 | #define INITIALIZATION_VALUE 0xFFFF | 835 | #define INITIALIZATION_VALUE 0xFFFF |
@@ -1265,11 +1217,7 @@ struct iwl4965_priv { | |||
1265 | #endif | 1217 | #endif |
1266 | struct work_struct statistics_work; | 1218 | struct work_struct statistics_work; |
1267 | struct timer_list statistics_periodic; | 1219 | struct timer_list statistics_periodic; |
1268 | 1220 | }; /*iwl4965_priv */ | |
1269 | #ifdef CONFIG_IWL4965_HT_AGG | ||
1270 | struct work_struct agg_work; | ||
1271 | #endif | ||
1272 | }; /*iwl4965_priv */ | ||
1273 | 1221 | ||
1274 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) | 1222 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) |
1275 | { | 1223 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 16cb990e06fa..5f38fc585eda 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -3075,14 +3075,6 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
3075 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); | 3075 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); |
3076 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); | 3076 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); |
3077 | 3077 | ||
3078 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3079 | #ifdef CONFIG_IWL4965_HT | ||
3080 | /* TODO: move this functionality to rate scaling */ | ||
3081 | iwl4965_tl_get_stats(priv, hdr); | ||
3082 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3083 | #endif /*CONFIG_IWL4965_HT */ | ||
3084 | |||
3085 | |||
3086 | if (!ieee80211_get_morefrag(hdr)) { | 3078 | if (!ieee80211_get_morefrag(hdr)) { |
3087 | txq->need_update = 1; | 3079 | txq->need_update = 1; |
3088 | if (qc) { | 3080 | if (qc) { |
@@ -8102,18 +8094,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
8102 | spin_lock_irqsave(&priv->lock, flags); | 8094 | spin_lock_irqsave(&priv->lock, flags); |
8103 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 8095 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
8104 | spin_unlock_irqrestore(&priv->lock, flags); | 8096 | spin_unlock_irqrestore(&priv->lock, flags); |
8105 | #ifdef CONFIG_IWL4965_HT_AGG | ||
8106 | /* if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
8107 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/ | ||
8108 | |||
8109 | memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control)); | ||
8110 | priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10; | ||
8111 | priv->lq_mngr.agg_ctrl.ba_timeout = 5000; | ||
8112 | priv->lq_mngr.agg_ctrl.auto_agg = 1; | ||
8113 | |||
8114 | if (priv->lq_mngr.agg_ctrl.auto_agg) | ||
8115 | priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED; | ||
8116 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
8117 | #endif /* CONFIG_IWL4965_HT */ | 8097 | #endif /* CONFIG_IWL4965_HT */ |
8118 | 8098 | ||
8119 | #ifdef CONFIG_IWL4965_QOS | 8099 | #ifdef CONFIG_IWL4965_QOS |