aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/rc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/rc.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c317
1 files changed, 186 insertions, 131 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index e49be733d546..ba7f36ab0a74 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc. 2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2009 Atheros Communications, Inc. 3 * Copyright (c) 2004-2011 Atheros Communications, Inc.
4 * 4 *
5 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
302 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 302 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
303 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ 303 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
304 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, 304 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
305 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ 305 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
306 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 306 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
307 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ 307 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
308 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, 308 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
@@ -378,39 +378,9 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
378 0, /* Phy rates allowed initially */ 378 0, /* Phy rates allowed initially */
379}; 379};
380 380
381static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
382 [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
383 [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
384 [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
385 [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
386 [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
387 [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
388 [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
389 [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
390};
391
392static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, 381static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
393 struct ieee80211_tx_rate *rate); 382 struct ieee80211_tx_rate *rate);
394 383
395static inline int8_t median(int8_t a, int8_t b, int8_t c)
396{
397 if (a >= b) {
398 if (b >= c)
399 return b;
400 else if (a > c)
401 return c;
402 else
403 return a;
404 } else {
405 if (a >= c)
406 return a;
407 else if (b >= c)
408 return c;
409 else
410 return b;
411 }
412}
413
414static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, 384static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
415 struct ath_rate_priv *ath_rc_priv) 385 struct ath_rate_priv *ath_rc_priv)
416{ 386{
@@ -430,7 +400,7 @@ static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
430 } 400 }
431} 401}
432 402
433static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) 403static void ath_rc_init_valid_rate_idx(struct ath_rate_priv *ath_rc_priv)
434{ 404{
435 u8 i; 405 u8 i;
436 406
@@ -438,7 +408,7 @@ static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
438 ath_rc_priv->valid_rate_index[i] = 0; 408 ath_rc_priv->valid_rate_index[i] = 0;
439} 409}
440 410
441static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, 411static inline void ath_rc_set_valid_rate_idx(struct ath_rate_priv *ath_rc_priv,
442 u8 index, int valid_tx_rate) 412 u8 index, int valid_tx_rate)
443{ 413{
444 BUG_ON(index > ath_rc_priv->rate_table_size); 414 BUG_ON(index > ath_rc_priv->rate_table_size);
@@ -519,7 +489,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
519 489
520 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; 490 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
521 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 491 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
522 ath_rc_set_valid_txmask(ath_rc_priv, i, 1); 492 ath_rc_set_valid_rate_idx(ath_rc_priv, i, 1);
523 hi = i; 493 hi = i;
524 } 494 }
525 } 495 }
@@ -538,7 +508,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
538 for (i = 0; i < rateset->rs_nrates; i++) { 508 for (i = 0; i < rateset->rs_nrates; i++) {
539 for (j = 0; j < rate_table->rate_cnt; j++) { 509 for (j = 0; j < rate_table->rate_cnt; j++) {
540 u32 phy = rate_table->info[j].phy; 510 u32 phy = rate_table->info[j].phy;
541 u16 rate_flags = rate_table->info[i].rate_flags; 511 u16 rate_flags = rate_table->info[j].rate_flags;
542 u8 rate = rateset->rs_rates[i]; 512 u8 rate = rateset->rs_rates[i];
543 u8 dot11rate = rate_table->info[j].dot11rate; 513 u8 dot11rate = rate_table->info[j].dot11rate;
544 514
@@ -562,7 +532,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
562 ath_rc_priv->valid_phy_rateidx[phy] 532 ath_rc_priv->valid_phy_rateidx[phy]
563 [valid_rate_count] = j; 533 [valid_rate_count] = j;
564 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 534 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
565 ath_rc_set_valid_txmask(ath_rc_priv, j, 1); 535 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
566 hi = A_MAX(hi, j); 536 hi = A_MAX(hi, j);
567 } 537 }
568 } 538 }
@@ -598,7 +568,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
598 ath_rc_priv->valid_phy_rateidx[phy] 568 ath_rc_priv->valid_phy_rateidx[phy]
599 [ath_rc_priv->valid_phy_ratecnt[phy]] = j; 569 [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
600 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 570 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
601 ath_rc_set_valid_txmask(ath_rc_priv, j, 1); 571 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
602 hi = A_MAX(hi, j); 572 hi = A_MAX(hi, j);
603 } 573 }
604 } 574 }
@@ -719,7 +689,8 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
719 689
720 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { 690 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
721 rate->flags |= IEEE80211_TX_RC_MCS; 691 rate->flags |= IEEE80211_TX_RC_MCS;
722 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 692 if (WLAN_RC_PHY_40(rate_table->info[rix].phy) &&
693 conf_is_ht40(&txrc->hw->conf))
723 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 694 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
724 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) 695 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
725 rate->flags |= IEEE80211_TX_RC_SHORT_GI; 696 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
@@ -791,7 +762,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
791 */ 762 */
792 try_per_rate = 4; 763 try_per_rate = 4;
793 764
794 rate_table = sc->cur_rate_table; 765 rate_table = ath_rc_priv->rate_table;
795 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 766 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
796 767
797 /* 768 /*
@@ -822,7 +793,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
822 793
823 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 794 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
824 } else { 795 } else {
825 /* Set the choosen rate. No RTS for first series entry. */ 796 /* Set the chosen rate. No RTS for first series entry. */
826 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 797 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
827 try_per_rate, rix, 0); 798 try_per_rate, rix, 0);
828 } 799 }
@@ -884,17 +855,16 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
884 ath_rc_rate_set_rtscts(sc, rate_table, tx_info); 855 ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
885} 856}
886 857
887static bool ath_rc_update_per(struct ath_softc *sc, 858static void ath_rc_update_per(struct ath_softc *sc,
888 const struct ath_rate_table *rate_table, 859 const struct ath_rate_table *rate_table,
889 struct ath_rate_priv *ath_rc_priv, 860 struct ath_rate_priv *ath_rc_priv,
890 struct ieee80211_tx_info *tx_info, 861 struct ieee80211_tx_info *tx_info,
891 int tx_rate, int xretries, int retries, 862 int tx_rate, int xretries, int retries,
892 u32 now_msec) 863 u32 now_msec)
893{ 864{
894 bool state_change = false;
895 int count, n_bad_frames; 865 int count, n_bad_frames;
896 u8 last_per; 866 u8 last_per;
897 static u32 nretry_to_per_lookup[10] = { 867 static const u32 nretry_to_per_lookup[10] = {
898 100 * 0 / 1, 868 100 * 0 / 1,
899 100 * 1 / 4, 869 100 * 1 / 4,
900 100 * 1 / 2, 870 100 * 1 / 2,
@@ -1022,8 +992,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1022 992
1023 } 993 }
1024 } 994 }
995}
1025 996
1026 return state_change; 997static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
998 int xretries, int retries, u8 per)
999{
1000 struct ath_rc_stats *stats = &rc->rcstats[rix];
1001
1002 stats->xretries += xretries;
1003 stats->retries += retries;
1004 stats->per = per;
1027} 1005}
1028 1006
1029/* Update PER, RSSI and whatever else that the code thinks it is doing. 1007/* Update PER, RSSI and whatever else that the code thinks it is doing.
@@ -1037,8 +1015,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1037 u32 now_msec = jiffies_to_msecs(jiffies); 1015 u32 now_msec = jiffies_to_msecs(jiffies);
1038 int rate; 1016 int rate;
1039 u8 last_per; 1017 u8 last_per;
1040 bool state_change = false; 1018 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
1041 const struct ath_rate_table *rate_table = sc->cur_rate_table;
1042 int size = ath_rc_priv->rate_table_size; 1019 int size = ath_rc_priv->rate_table_size;
1043 1020
1044 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) 1021 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1047,9 +1024,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1047 last_per = ath_rc_priv->per[tx_rate]; 1024 last_per = ath_rc_priv->per[tx_rate];
1048 1025
1049 /* Update PER first */ 1026 /* Update PER first */
1050 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, 1027 ath_rc_update_per(sc, rate_table, ath_rc_priv,
1051 tx_info, tx_rate, xretries, 1028 tx_info, tx_rate, xretries,
1052 retries, now_msec); 1029 retries, now_msec);
1053 1030
1054 /* 1031 /*
1055 * If this rate looks bad (high PER) then stop using it for 1032 * If this rate looks bad (high PER) then stop using it for
@@ -1098,7 +1075,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1098 ath_rc_priv->per_down_time = now_msec; 1075 ath_rc_priv->per_down_time = now_msec;
1099 } 1076 }
1100 1077
1101 ath_debug_stat_retries(sc, tx_rate, xretries, retries, 1078 ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
1102 ath_rc_priv->per[tx_rate]); 1079 ath_rc_priv->per[tx_rate]);
1103 1080
1104} 1081}
@@ -1107,13 +1084,12 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
1107 struct ieee80211_tx_rate *rate) 1084 struct ieee80211_tx_rate *rate)
1108{ 1085{
1109 int rix = 0, i = 0; 1086 int rix = 0, i = 0;
1110 int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; 1087 static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
1111 1088
1112 if (!(rate->flags & IEEE80211_TX_RC_MCS)) 1089 if (!(rate->flags & IEEE80211_TX_RC_MCS))
1113 return rate->idx; 1090 return rate->idx;
1114 1091
1115 while (rate->idx > mcs_rix_off[i] && 1092 while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
1116 i < sizeof(mcs_rix_off)/sizeof(int)) {
1117 rix++; i++; 1093 rix++; i++;
1118 } 1094 }
1119 1095
@@ -1140,7 +1116,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1140 u8 flags; 1116 u8 flags;
1141 u32 i = 0, rix; 1117 u32 i = 0, rix;
1142 1118
1143 rate_table = sc->cur_rate_table; 1119 rate_table = ath_rc_priv->rate_table;
1144 1120
1145 /* 1121 /*
1146 * If the first rate is not the final index, there 1122 * If the first rate is not the final index, there
@@ -1190,39 +1166,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1190static const 1166static const
1191struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, 1167struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1192 enum ieee80211_band band, 1168 enum ieee80211_band band,
1193 bool is_ht, 1169 bool is_ht)
1194 bool is_cw_40)
1195{ 1170{
1196 int mode = 0;
1197 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1171 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1198 1172
1199 switch(band) { 1173 switch(band) {
1200 case IEEE80211_BAND_2GHZ: 1174 case IEEE80211_BAND_2GHZ:
1201 mode = ATH9K_MODE_11G;
1202 if (is_ht) 1175 if (is_ht)
1203 mode = ATH9K_MODE_11NG_HT20; 1176 return &ar5416_11ng_ratetable;
1204 if (is_cw_40) 1177 return &ar5416_11g_ratetable;
1205 mode = ATH9K_MODE_11NG_HT40PLUS;
1206 break;
1207 case IEEE80211_BAND_5GHZ: 1178 case IEEE80211_BAND_5GHZ:
1208 mode = ATH9K_MODE_11A;
1209 if (is_ht) 1179 if (is_ht)
1210 mode = ATH9K_MODE_11NA_HT20; 1180 return &ar5416_11na_ratetable;
1211 if (is_cw_40) 1181 return &ar5416_11a_ratetable;
1212 mode = ATH9K_MODE_11NA_HT40PLUS;
1213 break;
1214 default: 1182 default:
1215 ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); 1183 ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n");
1216 return NULL; 1184 return NULL;
1217 } 1185 }
1218
1219 BUG_ON(mode >= ATH9K_MODE_MAX);
1220
1221 ath_print(common, ATH_DBG_CONFIG,
1222 "Choosing rate table for mode: %d\n", mode);
1223
1224 sc->cur_rate_mode = mode;
1225 return hw_rate_table[mode];
1226} 1186}
1227 1187
1228static void ath_rc_init(struct ath_softc *sc, 1188static void ath_rc_init(struct ath_softc *sc,
@@ -1246,7 +1206,7 @@ static void ath_rc_init(struct ath_softc *sc,
1246 } 1206 }
1247 1207
1248 /* Determine the valid rates */ 1208 /* Determine the valid rates */
1249 ath_rc_init_valid_txmask(ath_rc_priv); 1209 ath_rc_init_valid_rate_idx(ath_rc_priv);
1250 1210
1251 for (i = 0; i < WLAN_RC_PHY_MAX; i++) { 1211 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1252 for (j = 0; j < MAX_TX_RATE_PHY; j++) 1212 for (j = 0; j < MAX_TX_RATE_PHY; j++)
@@ -1293,11 +1253,11 @@ static void ath_rc_init(struct ath_softc *sc,
1293 ath_rc_priv->max_valid_rate = k; 1253 ath_rc_priv->max_valid_rate = k;
1294 ath_rc_sort_validrates(rate_table, ath_rc_priv); 1254 ath_rc_sort_validrates(rate_table, ath_rc_priv);
1295 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1255 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
1296 sc->cur_rate_table = rate_table; 1256 ath_rc_priv->rate_table = rate_table;
1297 1257
1298 ath_print(common, ATH_DBG_CONFIG, 1258 ath_dbg(common, ATH_DBG_CONFIG,
1299 "RC Initialized with capabilities: 0x%x\n", 1259 "RC Initialized with capabilities: 0x%x\n",
1300 ath_rc_priv->ht_cap); 1260 ath_rc_priv->ht_cap);
1301} 1261}
1302 1262
1303static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, 1263static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1320,10 +1280,35 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
1320 return caps; 1280 return caps;
1321} 1281}
1322 1282
1283static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
1284 u8 tidno)
1285{
1286 struct ath_atx_tid *txtid;
1287
1288 if (!(sc->sc_flags & SC_OP_TXAGGR))
1289 return false;
1290
1291 txtid = ATH_AN_2_TID(an, tidno);
1292
1293 if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
1294 return true;
1295 return false;
1296}
1297
1298
1323/***********************************/ 1299/***********************************/
1324/* mac80211 Rate Control callbacks */ 1300/* mac80211 Rate Control callbacks */
1325/***********************************/ 1301/***********************************/
1326 1302
1303static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1304{
1305 struct ath_rc_stats *stats;
1306
1307 stats = &rc->rcstats[final_rate];
1308 stats->success++;
1309}
1310
1311
1327static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, 1312static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1328 struct ieee80211_sta *sta, void *priv_sta, 1313 struct ieee80211_sta *sta, void *priv_sta,
1329 struct sk_buff *skb) 1314 struct sk_buff *skb)
@@ -1332,14 +1317,14 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1332 struct ath_rate_priv *ath_rc_priv = priv_sta; 1317 struct ath_rate_priv *ath_rc_priv = priv_sta;
1333 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1318 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1334 struct ieee80211_hdr *hdr; 1319 struct ieee80211_hdr *hdr;
1335 int final_ts_idx = 0, tx_status = 0, is_underrun = 0; 1320 int final_ts_idx = 0, tx_status = 0;
1336 int long_retry = 0; 1321 int long_retry = 0;
1337 __le16 fc; 1322 __le16 fc;
1338 int i; 1323 int i;
1339 1324
1340 hdr = (struct ieee80211_hdr *)skb->data; 1325 hdr = (struct ieee80211_hdr *)skb->data;
1341 fc = hdr->frame_control; 1326 fc = hdr->frame_control;
1342 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 1327 for (i = 0; i < sc->hw->max_rates; i++) {
1343 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; 1328 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
1344 if (!rate->count) 1329 if (!rate->count)
1345 break; 1330 break;
@@ -1359,32 +1344,23 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1359 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1344 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
1360 return; 1345 return;
1361 1346
1362 /* 1347 if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
1363 * If an underrun error is seen assume it as an excessive retry only 1348 tx_info->status.ampdu_ack_len =
1364 * if max frame trigger level has been reached (2 KB for singel stream, 1349 (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
1365 * and 4 KB for dual stream). Adjust the long retry as if the frame was 1350 tx_info->status.ampdu_len = 1;
1366 * tried hw->max_rate_tries times to affect how ratectrl updates PER for
1367 * the failed rate. In case of congestion on the bus penalizing these
1368 * type of underruns should help hardware actually transmit new frames
1369 * successfully by eventually preferring slower rates. This itself
1370 * should also alleviate congestion on the bus.
1371 */
1372 if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
1373 (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
1374 tx_status = 1;
1375 is_underrun = 1;
1376 } 1351 }
1377 1352
1378 if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) 1353 if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
1379 tx_status = 1; 1354 tx_status = 1;
1380 1355
1381 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, 1356 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1382 (is_underrun) ? sc->hw->max_rate_tries : long_retry); 1357 long_retry);
1383 1358
1384 /* Check if aggregation has to be enabled for this tid */ 1359 /* Check if aggregation has to be enabled for this tid */
1385 if (conf_is_ht(&sc->hw->conf) && 1360 if (conf_is_ht(&sc->hw->conf) &&
1386 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { 1361 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
1387 if (ieee80211_is_data_qos(fc)) { 1362 if (ieee80211_is_data_qos(fc) &&
1363 skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
1388 u8 *qc, tid; 1364 u8 *qc, tid;
1389 struct ath_node *an; 1365 struct ath_node *an;
1390 1366
@@ -1393,12 +1369,13 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1393 an = (struct ath_node *)sta->drv_priv; 1369 an = (struct ath_node *)sta->drv_priv;
1394 1370
1395 if(ath_tx_aggr_check(sc, an, tid)) 1371 if(ath_tx_aggr_check(sc, an, tid))
1396 ieee80211_start_tx_ba_session(sta, tid); 1372 ieee80211_start_tx_ba_session(sta, tid, 0);
1397 } 1373 }
1398 } 1374 }
1399 1375
1400 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table, 1376 ath_debug_stat_rc(ath_rc_priv,
1401 &tx_info->status.rates[final_ts_idx])); 1377 ath_rc_get_rateindex(ath_rc_priv->rate_table,
1378 &tx_info->status.rates[final_ts_idx]));
1402} 1379}
1403 1380
1404static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1381static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1429,23 +1406,17 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1429 ath_rc_priv->neg_ht_rates.rs_nrates = j; 1406 ath_rc_priv->neg_ht_rates.rs_nrates = j;
1430 } 1407 }
1431 1408
1432 is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1409 is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
1433 1410
1434 if (is_cw40) 1411 if (is_cw40)
1435 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; 1412 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
1436 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) 1413 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
1437 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; 1414 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
1438 1415
1439 /* Choose rate table first */ 1416 /* Choose rate table first */
1440 1417
1441 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || 1418 rate_table = ath_choose_rate_table(sc, sband->band,
1442 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || 1419 sta->ht_cap.ht_supported);
1443 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1444 rate_table = ath_choose_rate_table(sc, sband->band,
1445 sta->ht_cap.ht_supported, is_cw40);
1446 } else {
1447 rate_table = hw_rate_table[sc->cur_rate_mode];
1448 }
1449 1420
1450 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); 1421 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
1451 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1422 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1459,10 +1430,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1459 struct ath_rate_priv *ath_rc_priv = priv_sta; 1430 struct ath_rate_priv *ath_rc_priv = priv_sta;
1460 const struct ath_rate_table *rate_table = NULL; 1431 const struct ath_rate_table *rate_table = NULL;
1461 bool oper_cw40 = false, oper_sgi; 1432 bool oper_cw40 = false, oper_sgi;
1462 bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? 1433 bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
1463 true : false; 1434 bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG);
1464 bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
1465 true : false;
1466 1435
1467 /* FIXME: Handle AP mode later when we support CWM */ 1436 /* FIXME: Handle AP mode later when we support CWM */
1468 1437
@@ -1485,24 +1454,109 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1485 1454
1486 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) { 1455 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
1487 rate_table = ath_choose_rate_table(sc, sband->band, 1456 rate_table = ath_choose_rate_table(sc, sband->band,
1488 sta->ht_cap.ht_supported, 1457 sta->ht_cap.ht_supported);
1489 oper_cw40);
1490 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, 1458 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1491 oper_cw40, oper_sgi); 1459 oper_cw40, oper_sgi);
1492 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1460 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1493 1461
1494 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, 1462 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
1495 "Operating HT Bandwidth changed to: %d\n", 1463 "Operating HT Bandwidth changed to: %d\n",
1496 sc->hw->conf.channel_type); 1464 sc->hw->conf.channel_type);
1497 sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode]; 1465 }
1466 }
1467}
1468
1469#ifdef CONFIG_ATH9K_DEBUGFS
1470
1471static int ath9k_debugfs_open(struct inode *inode, struct file *file)
1472{
1473 file->private_data = inode->i_private;
1474 return 0;
1475}
1476
1477static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1478 size_t count, loff_t *ppos)
1479{
1480 struct ath_rate_priv *rc = file->private_data;
1481 char *buf;
1482 unsigned int len = 0, max;
1483 int i = 0;
1484 ssize_t retval;
1485
1486 if (rc->rate_table == NULL)
1487 return 0;
1488
1489 max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
1490 buf = kmalloc(max, GFP_KERNEL);
1491 if (buf == NULL)
1492 return -ENOMEM;
1493
1494 len += sprintf(buf, "%6s %6s %6s "
1495 "%10s %10s %10s %10s\n",
1496 "HT", "MCS", "Rate",
1497 "Success", "Retries", "XRetries", "PER");
1498
1499 for (i = 0; i < rc->rate_table->rate_cnt; i++) {
1500 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1501 struct ath_rc_stats *stats = &rc->rcstats[i];
1502 char mcs[5];
1503 char htmode[5];
1504 int used_mcs = 0, used_htmode = 0;
1505
1506 if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
1507 used_mcs = snprintf(mcs, 5, "%d",
1508 rc->rate_table->info[i].ratecode);
1509
1510 if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
1511 used_htmode = snprintf(htmode, 5, "HT40");
1512 else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
1513 used_htmode = snprintf(htmode, 5, "HT20");
1514 else
1515 used_htmode = snprintf(htmode, 5, "????");
1498 } 1516 }
1517
1518 mcs[used_mcs] = '\0';
1519 htmode[used_htmode] = '\0';
1520
1521 len += snprintf(buf + len, max - len,
1522 "%6s %6s %3u.%d: "
1523 "%10u %10u %10u %10u\n",
1524 htmode,
1525 mcs,
1526 ratekbps / 1000,
1527 (ratekbps % 1000) / 100,
1528 stats->success,
1529 stats->retries,
1530 stats->xretries,
1531 stats->per);
1499 } 1532 }
1533
1534 if (len > max)
1535 len = max;
1536
1537 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1538 kfree(buf);
1539 return retval;
1500} 1540}
1501 1541
1542static const struct file_operations fops_rcstat = {
1543 .read = read_file_rcstat,
1544 .open = ath9k_debugfs_open,
1545 .owner = THIS_MODULE
1546};
1547
1548static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
1549 struct dentry *dir)
1550{
1551 struct ath_rate_priv *rc = priv_sta;
1552 debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
1553}
1554
1555#endif /* CONFIG_ATH9K_DEBUGFS */
1556
1502static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 1557static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1503{ 1558{
1504 struct ath_wiphy *aphy = hw->priv; 1559 return hw->priv;
1505 return aphy->sc;
1506} 1560}
1507 1561
1508static void ath_rate_free(void *priv) 1562static void ath_rate_free(void *priv)
@@ -1517,13 +1571,11 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
1517 1571
1518 rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); 1572 rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1519 if (!rate_priv) { 1573 if (!rate_priv) {
1520 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 1574 ath_err(ath9k_hw_common(sc->sc_ah),
1521 "Unable to allocate private rc structure\n"); 1575 "Unable to allocate private rc structure\n");
1522 return NULL; 1576 return NULL;
1523 } 1577 }
1524 1578
1525 rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
1526
1527 return rate_priv; 1579 return rate_priv;
1528} 1580}
1529 1581
@@ -1545,6 +1597,9 @@ static struct rate_control_ops ath_rate_ops = {
1545 .free = ath_rate_free, 1597 .free = ath_rate_free,
1546 .alloc_sta = ath_rate_alloc_sta, 1598 .alloc_sta = ath_rate_alloc_sta,
1547 .free_sta = ath_rate_free_sta, 1599 .free_sta = ath_rate_free_sta,
1600#ifdef CONFIG_ATH9K_DEBUGFS
1601 .add_sta_debugfs = ath_rate_add_sta_debugfs,
1602#endif
1548}; 1603};
1549 1604
1550int ath_rate_control_register(void) 1605int ath_rate_control_register(void)