diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/rc.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 80 |
1 files changed, 21 insertions, 59 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 89978d71617f..896d12986b1e 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -381,25 +381,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = { | |||
381 | static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | 381 | static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, |
382 | struct ieee80211_tx_rate *rate); | 382 | struct ieee80211_tx_rate *rate); |
383 | 383 | ||
384 | static inline int8_t median(int8_t a, int8_t b, int8_t c) | ||
385 | { | ||
386 | if (a >= b) { | ||
387 | if (b >= c) | ||
388 | return b; | ||
389 | else if (a > c) | ||
390 | return c; | ||
391 | else | ||
392 | return a; | ||
393 | } else { | ||
394 | if (a >= c) | ||
395 | return a; | ||
396 | else if (b >= c) | ||
397 | return c; | ||
398 | else | ||
399 | return b; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, | 384 | static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, |
404 | struct ath_rate_priv *ath_rc_priv) | 385 | struct ath_rate_priv *ath_rc_priv) |
405 | { | 386 | { |
@@ -883,7 +864,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
883 | bool state_change = false; | 864 | bool state_change = false; |
884 | int count, n_bad_frames; | 865 | int count, n_bad_frames; |
885 | u8 last_per; | 866 | u8 last_per; |
886 | static u32 nretry_to_per_lookup[10] = { | 867 | static const u32 nretry_to_per_lookup[10] = { |
887 | 100 * 0 / 1, | 868 | 100 * 0 / 1, |
888 | 100 * 1 / 4, | 869 | 100 * 1 / 4, |
889 | 100 * 1 / 2, | 870 | 100 * 1 / 2, |
@@ -1106,13 +1087,13 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | |||
1106 | struct ieee80211_tx_rate *rate) | 1087 | struct ieee80211_tx_rate *rate) |
1107 | { | 1088 | { |
1108 | int rix = 0, i = 0; | 1089 | int rix = 0, i = 0; |
1109 | int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; | 1090 | static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; |
1110 | 1091 | ||
1111 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) | 1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) |
1112 | return rate->idx; | 1093 | return rate->idx; |
1113 | 1094 | ||
1114 | while (rate->idx > mcs_rix_off[i] && | 1095 | while (rate->idx > mcs_rix_off[i] && |
1115 | i < sizeof(mcs_rix_off)/sizeof(int)) { | 1096 | i < ARRAY_SIZE(mcs_rix_off)) { |
1116 | rix++; i++; | 1097 | rix++; i++; |
1117 | } | 1098 | } |
1118 | 1099 | ||
@@ -1203,7 +1184,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, | |||
1203 | return &ar5416_11na_ratetable; | 1184 | return &ar5416_11na_ratetable; |
1204 | return &ar5416_11a_ratetable; | 1185 | return &ar5416_11a_ratetable; |
1205 | default: | 1186 | default: |
1206 | ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); | 1187 | ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n"); |
1207 | return NULL; | 1188 | return NULL; |
1208 | } | 1189 | } |
1209 | } | 1190 | } |
@@ -1278,9 +1259,9 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1278 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; | 1259 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; |
1279 | ath_rc_priv->rate_table = rate_table; | 1260 | ath_rc_priv->rate_table = rate_table; |
1280 | 1261 | ||
1281 | ath_print(common, ATH_DBG_CONFIG, | 1262 | ath_dbg(common, ATH_DBG_CONFIG, |
1282 | "RC Initialized with capabilities: 0x%x\n", | 1263 | "RC Initialized with capabilities: 0x%x\n", |
1283 | ath_rc_priv->ht_cap); | 1264 | ath_rc_priv->ht_cap); |
1284 | } | 1265 | } |
1285 | 1266 | ||
1286 | static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, | 1267 | static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, |
@@ -1373,23 +1354,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1373 | tx_info->status.ampdu_len = 1; | 1354 | tx_info->status.ampdu_len = 1; |
1374 | } | 1355 | } |
1375 | 1356 | ||
1376 | /* | 1357 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) |
1377 | * If an underrun error is seen assume it as an excessive retry only | ||
1378 | * if max frame trigger level has been reached (2 KB for singel stream, | ||
1379 | * and 4 KB for dual stream). Adjust the long retry as if the frame was | ||
1380 | * tried hw->max_rate_tries times to affect how ratectrl updates PER for | ||
1381 | * the failed rate. In case of congestion on the bus penalizing these | ||
1382 | * type of underruns should help hardware actually transmit new frames | ||
1383 | * successfully by eventually preferring slower rates. This itself | ||
1384 | * should also alleviate congestion on the bus. | ||
1385 | */ | ||
1386 | if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && | ||
1387 | (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { | ||
1388 | tx_status = 1; | ||
1389 | is_underrun = 1; | ||
1390 | } | ||
1391 | |||
1392 | if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) | ||
1393 | tx_status = 1; | 1358 | tx_status = 1; |
1394 | 1359 | ||
1395 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, | 1360 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, |
@@ -1398,7 +1363,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1398 | /* Check if aggregation has to be enabled for this tid */ | 1363 | /* Check if aggregation has to be enabled for this tid */ |
1399 | if (conf_is_ht(&sc->hw->conf) && | 1364 | if (conf_is_ht(&sc->hw->conf) && |
1400 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 1365 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
1401 | if (ieee80211_is_data_qos(fc)) { | 1366 | if (ieee80211_is_data_qos(fc) && |
1367 | skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { | ||
1402 | u8 *qc, tid; | 1368 | u8 *qc, tid; |
1403 | struct ath_node *an; | 1369 | struct ath_node *an; |
1404 | 1370 | ||
@@ -1407,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1407 | an = (struct ath_node *)sta->drv_priv; | 1373 | an = (struct ath_node *)sta->drv_priv; |
1408 | 1374 | ||
1409 | if(ath_tx_aggr_check(sc, an, tid)) | 1375 | if(ath_tx_aggr_check(sc, an, tid)) |
1410 | ieee80211_start_tx_ba_session(sta, tid); | 1376 | ieee80211_start_tx_ba_session(sta, tid, 0); |
1411 | } | 1377 | } |
1412 | } | 1378 | } |
1413 | 1379 | ||
@@ -1444,12 +1410,12 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
1444 | ath_rc_priv->neg_ht_rates.rs_nrates = j; | 1410 | ath_rc_priv->neg_ht_rates.rs_nrates = j; |
1445 | } | 1411 | } |
1446 | 1412 | ||
1447 | is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 1413 | is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); |
1448 | 1414 | ||
1449 | if (is_cw40) | 1415 | if (is_cw40) |
1450 | is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; | 1416 | is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); |
1451 | else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) | 1417 | else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) |
1452 | is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; | 1418 | is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); |
1453 | 1419 | ||
1454 | /* Choose rate table first */ | 1420 | /* Choose rate table first */ |
1455 | 1421 | ||
@@ -1468,10 +1434,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1468 | struct ath_rate_priv *ath_rc_priv = priv_sta; | 1434 | struct ath_rate_priv *ath_rc_priv = priv_sta; |
1469 | const struct ath_rate_table *rate_table = NULL; | 1435 | const struct ath_rate_table *rate_table = NULL; |
1470 | bool oper_cw40 = false, oper_sgi; | 1436 | bool oper_cw40 = false, oper_sgi; |
1471 | bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? | 1437 | bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG); |
1472 | true : false; | 1438 | bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG); |
1473 | bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? | ||
1474 | true : false; | ||
1475 | 1439 | ||
1476 | /* FIXME: Handle AP mode later when we support CWM */ | 1440 | /* FIXME: Handle AP mode later when we support CWM */ |
1477 | 1441 | ||
@@ -1499,9 +1463,9 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1499 | oper_cw40, oper_sgi); | 1463 | oper_cw40, oper_sgi); |
1500 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); | 1464 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); |
1501 | 1465 | ||
1502 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | 1466 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, |
1503 | "Operating HT Bandwidth changed to: %d\n", | 1467 | "Operating HT Bandwidth changed to: %d\n", |
1504 | sc->hw->conf.channel_type); | 1468 | sc->hw->conf.channel_type); |
1505 | } | 1469 | } |
1506 | } | 1470 | } |
1507 | } | 1471 | } |
@@ -1612,13 +1576,11 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp | |||
1612 | 1576 | ||
1613 | rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); | 1577 | rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); |
1614 | if (!rate_priv) { | 1578 | if (!rate_priv) { |
1615 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1579 | ath_err(ath9k_hw_common(sc->sc_ah), |
1616 | "Unable to allocate private rc structure\n"); | 1580 | "Unable to allocate private rc structure\n"); |
1617 | return NULL; | 1581 | return NULL; |
1618 | } | 1582 | } |
1619 | 1583 | ||
1620 | rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max; | ||
1621 | |||
1622 | return rate_priv; | 1584 | return rate_priv; |
1623 | } | 1585 | } |
1624 | 1586 | ||