diff options
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 145 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.h | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/xmit.c | 162 |
5 files changed, 108 insertions, 226 deletions
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index cf2d9410b3dd..255f860b2719 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -203,7 +203,6 @@ struct ath_buf_state { | |||
203 | int bfs_seqno; /* sequence number */ | 203 | int bfs_seqno; /* sequence number */ |
204 | int bfs_tidno; /* tid of this frame */ | 204 | int bfs_tidno; /* tid of this frame */ |
205 | int bfs_retries; /* current retries */ | 205 | int bfs_retries; /* current retries */ |
206 | struct ath_rc_series bfs_rcs[4]; /* rate series */ | ||
207 | u32 bf_type; /* BUF_* (enum buffer_type) */ | 206 | u32 bf_type; /* BUF_* (enum buffer_type) */ |
208 | /* key type use to encrypt this frame */ | 207 | /* key type use to encrypt this frame */ |
209 | u32 bfs_keyix; | 208 | u32 bfs_keyix; |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index ca7809836c33..11d7bee2fda0 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -350,13 +350,12 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
350 | DPRINTF(sc, ATH_DBG_XMIT, | 350 | DPRINTF(sc, ATH_DBG_XMIT, |
351 | "%s: TX complete: skb: %p\n", __func__, skb); | 351 | "%s: TX complete: skb: %p\n", __func__, skb); |
352 | 352 | ||
353 | ieee80211_tx_info_clear_status(tx_info); | ||
354 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | 353 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || |
355 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | 354 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
356 | /* free driver's private data area of tx_info, XXX: HACK! */ | 355 | if (tx_info->rate_driver_data[0] != NULL) { |
357 | if (tx_info->control.vif != NULL) | 356 | kfree(tx_info->rate_driver_data[0]); |
358 | kfree(tx_info->control.vif); | 357 | tx_info->rate_driver_data[0] = NULL; |
359 | tx_info->control.vif = NULL; | 358 | } |
360 | } | 359 | } |
361 | 360 | ||
362 | if (tx_status->flags & ATH_TX_BAR) { | 361 | if (tx_status->flags & ATH_TX_BAR) { |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 59c146cdd0db..156b245ab9e4 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -805,22 +805,22 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc, | |||
805 | } | 805 | } |
806 | 806 | ||
807 | static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , | 807 | static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , |
808 | struct ath_rc_series *series, | 808 | struct ieee80211_tx_rate *rate, |
809 | u8 tries, | 809 | u8 tries, |
810 | u8 rix, | 810 | u8 rix, |
811 | int rtsctsenable) | 811 | int rtsctsenable) |
812 | { | 812 | { |
813 | series->tries = tries; | 813 | rate->count = tries; |
814 | series->flags = (rtsctsenable ? ATH_RC_RTSCTS_FLAG : 0) | | 814 | rate->idx = rix; |
815 | (WLAN_RC_PHY_DS(rate_table->info[rix].phy) ? | 815 | |
816 | ATH_RC_DS_FLAG : 0) | | 816 | if (rtsctsenable) |
817 | (WLAN_RC_PHY_40(rate_table->info[rix].phy) ? | 817 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; |
818 | ATH_RC_CW40_FLAG : 0) | | 818 | if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) |
819 | (WLAN_RC_PHY_SGI(rate_table->info[rix].phy) ? | 819 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
820 | ATH_RC_SGI_FLAG : 0); | 820 | if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) |
821 | 821 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | |
822 | series->rix = rate_table->info[rix].base_index; | 822 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) |
823 | series->max_4ms_framelen = rate_table->info[rix].max_4ms_framelen; | 823 | rate->flags |= IEEE80211_TX_RC_MCS; |
824 | } | 824 | } |
825 | 825 | ||
826 | static u8 ath_rc_rate_getidx(struct ath_softc *sc, | 826 | static u8 ath_rc_rate_getidx(struct ath_softc *sc, |
@@ -855,11 +855,12 @@ static u8 ath_rc_rate_getidx(struct ath_softc *sc, | |||
855 | static void ath_rc_ratefind(struct ath_softc *sc, | 855 | static void ath_rc_ratefind(struct ath_softc *sc, |
856 | struct ath_rate_node *ath_rc_priv, | 856 | struct ath_rate_node *ath_rc_priv, |
857 | int num_tries, int num_rates, unsigned int rcflag, | 857 | int num_tries, int num_rates, unsigned int rcflag, |
858 | struct ath_rc_series series[], int *is_probe, | 858 | struct ieee80211_tx_info *tx_info, int *is_probe, |
859 | int is_retry) | 859 | int is_retry) |
860 | { | 860 | { |
861 | u8 try_per_rate = 0, i = 0, rix, nrix; | 861 | u8 try_per_rate = 0, i = 0, rix, nrix; |
862 | struct ath_rate_table *rate_table; | 862 | struct ath_rate_table *rate_table; |
863 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
863 | 864 | ||
864 | rate_table = sc->hw_rate_table[sc->sc_curmode]; | 865 | rate_table = sc->hw_rate_table[sc->sc_curmode]; |
865 | rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, | 866 | rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, |
@@ -871,7 +872,7 @@ static void ath_rc_ratefind(struct ath_softc *sc, | |||
871 | /* set one try for probe rates. For the | 872 | /* set one try for probe rates. For the |
872 | * probes don't enable rts */ | 873 | * probes don't enable rts */ |
873 | ath_rc_rate_set_series(rate_table, | 874 | ath_rc_rate_set_series(rate_table, |
874 | &series[i++], 1, nrix, FALSE); | 875 | &rates[i++], 1, nrix, FALSE); |
875 | 876 | ||
876 | try_per_rate = (num_tries/num_rates); | 877 | try_per_rate = (num_tries/num_rates); |
877 | /* Get the next tried/allowed rate. No RTS for the next series | 878 | /* Get the next tried/allowed rate. No RTS for the next series |
@@ -880,12 +881,12 @@ static void ath_rc_ratefind(struct ath_softc *sc, | |||
880 | nrix = ath_rc_rate_getidx(sc, | 881 | nrix = ath_rc_rate_getidx(sc, |
881 | ath_rc_priv, rate_table, nrix, 1, FALSE); | 882 | ath_rc_priv, rate_table, nrix, 1, FALSE); |
882 | ath_rc_rate_set_series(rate_table, | 883 | ath_rc_rate_set_series(rate_table, |
883 | &series[i++], try_per_rate, nrix, 0); | 884 | &rates[i++], try_per_rate, nrix, 0); |
884 | } else { | 885 | } else { |
885 | try_per_rate = (num_tries/num_rates); | 886 | try_per_rate = (num_tries/num_rates); |
886 | /* Set the choosen rate. No RTS for first series entry. */ | 887 | /* Set the choosen rate. No RTS for first series entry. */ |
887 | ath_rc_rate_set_series(rate_table, | 888 | ath_rc_rate_set_series(rate_table, |
888 | &series[i++], try_per_rate, nrix, FALSE); | 889 | &rates[i++], try_per_rate, nrix, FALSE); |
889 | } | 890 | } |
890 | 891 | ||
891 | /* Fill in the other rates for multirate retry */ | 892 | /* Fill in the other rates for multirate retry */ |
@@ -902,7 +903,7 @@ static void ath_rc_ratefind(struct ath_softc *sc, | |||
902 | rate_table, nrix, 1, min_rate); | 903 | rate_table, nrix, 1, min_rate); |
903 | /* All other rates in the series have RTS enabled */ | 904 | /* All other rates in the series have RTS enabled */ |
904 | ath_rc_rate_set_series(rate_table, | 905 | ath_rc_rate_set_series(rate_table, |
905 | &series[i], try_num, nrix, TRUE); | 906 | &rates[i], try_num, nrix, TRUE); |
906 | } | 907 | } |
907 | 908 | ||
908 | /* | 909 | /* |
@@ -928,9 +929,8 @@ static void ath_rc_ratefind(struct ath_softc *sc, | |||
928 | if (i == 4 && | 929 | if (i == 4 && |
929 | ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || | 930 | ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || |
930 | (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { | 931 | (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { |
931 | series[3].rix = series[2].rix; | 932 | rates[3].idx = rates[2].idx; |
932 | series[3].flags = series[2].flags; | 933 | rates[3].flags = rates[2].flags; |
933 | series[3].max_4ms_framelen = series[2].max_4ms_framelen; | ||
934 | } | 934 | } |
935 | } | 935 | } |
936 | } | 936 | } |
@@ -943,7 +943,7 @@ static void ath_rate_findrate(struct ath_softc *sc, | |||
943 | int num_tries, | 943 | int num_tries, |
944 | int num_rates, | 944 | int num_rates, |
945 | unsigned int rcflag, | 945 | unsigned int rcflag, |
946 | struct ath_rc_series series[], | 946 | struct ieee80211_tx_info *tx_info, |
947 | int *is_probe, | 947 | int *is_probe, |
948 | int is_retry) | 948 | int is_retry) |
949 | { | 949 | { |
@@ -951,7 +951,7 @@ static void ath_rate_findrate(struct ath_softc *sc, | |||
951 | return; | 951 | return; |
952 | 952 | ||
953 | ath_rc_ratefind(sc, ath_rc_priv, num_tries, num_rates, | 953 | ath_rc_ratefind(sc, ath_rc_priv, num_tries, num_rates, |
954 | rcflag, series, is_probe, is_retry); | 954 | rcflag, tx_info, is_probe, is_retry); |
955 | } | 955 | } |
956 | 956 | ||
957 | static void ath_rc_update_ht(struct ath_softc *sc, | 957 | static void ath_rc_update_ht(struct ath_softc *sc, |
@@ -1283,17 +1283,17 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1283 | */ | 1283 | */ |
1284 | static void ath_rc_update(struct ath_softc *sc, | 1284 | static void ath_rc_update(struct ath_softc *sc, |
1285 | struct ath_rate_node *ath_rc_priv, | 1285 | struct ath_rate_node *ath_rc_priv, |
1286 | struct ath_tx_info_priv *info_priv, int final_ts_idx, | 1286 | struct ieee80211_tx_info *tx_info, int final_ts_idx, |
1287 | int xretries, int long_retry) | 1287 | int xretries, int long_retry) |
1288 | { | 1288 | { |
1289 | struct ath_tx_info_priv *info_priv = | ||
1290 | (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
1289 | struct ath_rate_table *rate_table; | 1291 | struct ath_rate_table *rate_table; |
1290 | struct ath_rc_series rcs[4]; | 1292 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
1291 | u8 flags; | 1293 | u8 flags; |
1292 | u32 series = 0, rix; | 1294 | u32 series = 0, rix; |
1293 | 1295 | ||
1294 | memcpy(rcs, info_priv->rcs, 4 * sizeof(rcs[0])); | ||
1295 | rate_table = sc->hw_rate_table[sc->sc_curmode]; | 1296 | rate_table = sc->hw_rate_table[sc->sc_curmode]; |
1296 | ASSERT(rcs[0].tries != 0); | ||
1297 | 1297 | ||
1298 | /* | 1298 | /* |
1299 | * If the first rate is not the final index, there | 1299 | * If the first rate is not the final index, there |
@@ -1302,31 +1302,31 @@ static void ath_rc_update(struct ath_softc *sc, | |||
1302 | if (final_ts_idx != 0) { | 1302 | if (final_ts_idx != 0) { |
1303 | /* Process intermediate rates that failed.*/ | 1303 | /* Process intermediate rates that failed.*/ |
1304 | for (series = 0; series < final_ts_idx ; series++) { | 1304 | for (series = 0; series < final_ts_idx ; series++) { |
1305 | if (rcs[series].tries != 0) { | 1305 | if (rates[series].count != 0) { |
1306 | flags = rcs[series].flags; | 1306 | flags = rates[series].flags; |
1307 | /* If HT40 and we have switched mode from | 1307 | /* If HT40 and we have switched mode from |
1308 | * 40 to 20 => don't update */ | 1308 | * 40 to 20 => don't update */ |
1309 | if ((flags & ATH_RC_CW40_FLAG) && | 1309 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1310 | (ath_rc_priv->rc_phy_mode != | 1310 | (ath_rc_priv->rc_phy_mode != |
1311 | (flags & ATH_RC_CW40_FLAG))) | 1311 | (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) |
1312 | return; | 1312 | return; |
1313 | if ((flags & ATH_RC_CW40_FLAG) && | 1313 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1314 | (flags & ATH_RC_SGI_FLAG)) | 1314 | (flags & IEEE80211_TX_RC_SHORT_GI)) |
1315 | rix = rate_table->info[ | 1315 | rix = rate_table->info[ |
1316 | rcs[series].rix].ht_index; | 1316 | rates[series].idx].ht_index; |
1317 | else if (flags & ATH_RC_SGI_FLAG) | 1317 | else if (flags & IEEE80211_TX_RC_SHORT_GI) |
1318 | rix = rate_table->info[ | 1318 | rix = rate_table->info[ |
1319 | rcs[series].rix].sgi_index; | 1319 | rates[series].idx].sgi_index; |
1320 | else if (flags & ATH_RC_CW40_FLAG) | 1320 | else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
1321 | rix = rate_table->info[ | 1321 | rix = rate_table->info[ |
1322 | rcs[series].rix].cw40index; | 1322 | rates[series].idx].cw40index; |
1323 | else | 1323 | else |
1324 | rix = rate_table->info[ | 1324 | rix = rate_table->info[ |
1325 | rcs[series].rix].base_index; | 1325 | rates[series].idx].base_index; |
1326 | ath_rc_update_ht(sc, ath_rc_priv, | 1326 | ath_rc_update_ht(sc, ath_rc_priv, |
1327 | info_priv, rix, | 1327 | info_priv, rix, |
1328 | xretries ? 1 : 2, | 1328 | xretries ? 1 : 2, |
1329 | rcs[series].tries); | 1329 | rates[series].count); |
1330 | } | 1330 | } |
1331 | } | 1331 | } |
1332 | } else { | 1332 | } else { |
@@ -1336,24 +1336,24 @@ static void ath_rc_update(struct ath_softc *sc, | |||
1336 | * Treating it as an excessive retry penalizes the rate | 1336 | * Treating it as an excessive retry penalizes the rate |
1337 | * inordinately. | 1337 | * inordinately. |
1338 | */ | 1338 | */ |
1339 | if (rcs[0].tries == 1 && xretries == 1) | 1339 | if (rates[0].count == 1 && xretries == 1) |
1340 | xretries = 2; | 1340 | xretries = 2; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | flags = rcs[series].flags; | 1343 | flags = rates[series].flags; |
1344 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ | 1344 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ |
1345 | if ((flags & ATH_RC_CW40_FLAG) && | 1345 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1346 | (ath_rc_priv->rc_phy_mode != (flags & ATH_RC_CW40_FLAG))) | 1346 | (ath_rc_priv->rc_phy_mode != (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) |
1347 | return; | 1347 | return; |
1348 | 1348 | ||
1349 | if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_SGI_FLAG)) | 1349 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) |
1350 | rix = rate_table->info[rcs[series].rix].ht_index; | 1350 | rix = rate_table->info[rates[series].idx].ht_index; |
1351 | else if (flags & ATH_RC_SGI_FLAG) | 1351 | else if (flags & IEEE80211_TX_RC_SHORT_GI) |
1352 | rix = rate_table->info[rcs[series].rix].sgi_index; | 1352 | rix = rate_table->info[rates[series].idx].sgi_index; |
1353 | else if (flags & ATH_RC_CW40_FLAG) | 1353 | else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
1354 | rix = rate_table->info[rcs[series].rix].cw40index; | 1354 | rix = rate_table->info[rates[series].idx].cw40index; |
1355 | else | 1355 | else |
1356 | rix = rate_table->info[rcs[series].rix].base_index; | 1356 | rix = rate_table->info[rates[series].idx].base_index; |
1357 | 1357 | ||
1358 | ath_rc_update_ht(sc, ath_rc_priv, info_priv, rix, | 1358 | ath_rc_update_ht(sc, ath_rc_priv, info_priv, rix, |
1359 | xretries, long_retry); | 1359 | xretries, long_retry); |
@@ -1365,8 +1365,10 @@ static void ath_rc_update(struct ath_softc *sc, | |||
1365 | static void ath_rate_tx_complete(struct ath_softc *sc, | 1365 | static void ath_rate_tx_complete(struct ath_softc *sc, |
1366 | struct ath_node *an, | 1366 | struct ath_node *an, |
1367 | struct ath_rate_node *rc_priv, | 1367 | struct ath_rate_node *rc_priv, |
1368 | struct ath_tx_info_priv *info_priv) | 1368 | struct ieee80211_tx_info *tx_info) |
1369 | { | 1369 | { |
1370 | struct ath_tx_info_priv *info_priv = | ||
1371 | (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
1370 | int final_ts_idx = info_priv->tx.ts_rateindex; | 1372 | int final_ts_idx = info_priv->tx.ts_rateindex; |
1371 | int tx_status = 0, is_underrun = 0; | 1373 | int tx_status = 0, is_underrun = 0; |
1372 | 1374 | ||
@@ -1395,7 +1397,7 @@ static void ath_rate_tx_complete(struct ath_softc *sc, | |||
1395 | (info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) | 1397 | (info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) |
1396 | tx_status = 1; | 1398 | tx_status = 1; |
1397 | 1399 | ||
1398 | ath_rc_update(sc, rc_priv, info_priv, final_ts_idx, tx_status, | 1400 | ath_rc_update(sc, rc_priv, tx_info, final_ts_idx, tx_status, |
1399 | (is_underrun) ? ATH_11N_TXMAXTRY : | 1401 | (is_underrun) ? ATH_11N_TXMAXTRY : |
1400 | info_priv->tx.ts_longretry); | 1402 | info_priv->tx.ts_longretry); |
1401 | } | 1403 | } |
@@ -1507,8 +1509,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1507 | 1509 | ||
1508 | hdr = (struct ieee80211_hdr *)skb->data; | 1510 | hdr = (struct ieee80211_hdr *)skb->data; |
1509 | fc = hdr->frame_control; | 1511 | fc = hdr->frame_control; |
1510 | /* XXX: UGLY HACK!! */ | 1512 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; |
1511 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1512 | 1513 | ||
1513 | an = (struct ath_node *)sta->drv_priv; | 1514 | an = (struct ath_node *)sta->drv_priv; |
1514 | 1515 | ||
@@ -1516,10 +1517,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1516 | return; | 1517 | return; |
1517 | 1518 | ||
1518 | if (an && priv_sta && ieee80211_is_data(fc)) | 1519 | if (an && priv_sta && ieee80211_is_data(fc)) |
1519 | ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv); | 1520 | ath_rate_tx_complete(sc, an, priv_sta, tx_info); |
1520 | 1521 | ||
1521 | kfree(tx_info_priv); | 1522 | kfree(tx_info_priv); |
1522 | tx_info->control.vif = NULL; | ||
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | 1525 | static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, |
@@ -1530,28 +1530,18 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
1530 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1530 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1531 | struct ath_softc *sc = priv; | 1531 | struct ath_softc *sc = priv; |
1532 | struct ieee80211_hw *hw = sc->hw; | 1532 | struct ieee80211_hw *hw = sc->hw; |
1533 | struct ath_tx_info_priv *tx_info_priv; | ||
1534 | struct ath_rate_node *ath_rc_priv = priv_sta; | 1533 | struct ath_rate_node *ath_rc_priv = priv_sta; |
1535 | struct ath_node *an; | 1534 | struct ath_node *an; |
1536 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1535 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1537 | int is_probe = FALSE; | 1536 | int is_probe = FALSE; |
1538 | s8 lowest_idx; | ||
1539 | __le16 fc = hdr->frame_control; | 1537 | __le16 fc = hdr->frame_control; |
1540 | u8 *qc, tid; | 1538 | u8 *qc, tid; |
1541 | 1539 | ||
1542 | DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); | ||
1543 | |||
1544 | /* allocate driver private area of tx_info, XXX: UGLY HACK! */ | ||
1545 | tx_info->control.vif = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | ||
1546 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1547 | ASSERT(tx_info_priv != NULL); | ||
1548 | |||
1549 | lowest_idx = rate_lowest_index(sband, sta); | ||
1550 | tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; | ||
1551 | /* lowest rate for management and multicast/broadcast frames */ | 1540 | /* lowest rate for management and multicast/broadcast frames */ |
1552 | if (!ieee80211_is_data(fc) || | 1541 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { |
1553 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 1542 | tx_info->control.rates[0].idx = rate_lowest_index(sband, sta); |
1554 | tx_info->control.rates[0].idx = lowest_idx; | 1543 | tx_info->control.rates[0].count = |
1544 | is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY; | ||
1555 | return; | 1545 | return; |
1556 | } | 1546 | } |
1557 | 1547 | ||
@@ -1559,24 +1549,11 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
1559 | ath_rate_findrate(sc, ath_rc_priv, | 1549 | ath_rate_findrate(sc, ath_rc_priv, |
1560 | ATH_11N_TXMAXTRY, 4, | 1550 | ATH_11N_TXMAXTRY, 4, |
1561 | ATH_RC_PROBE_ALLOWED, | 1551 | ATH_RC_PROBE_ALLOWED, |
1562 | tx_info_priv->rcs, | 1552 | tx_info, |
1563 | &is_probe, | 1553 | &is_probe, |
1564 | false); | 1554 | false); |
1565 | #if 0 | ||
1566 | if (is_probe) | ||
1567 | sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate; | ||
1568 | #endif | ||
1569 | |||
1570 | /* Ratecontrol sometimes returns invalid rate index */ | ||
1571 | if (tx_info_priv->rcs[0].rix != 0xff) | ||
1572 | ath_rc_priv->prev_data_rix = tx_info_priv->rcs[0].rix; | ||
1573 | else | ||
1574 | tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix; | ||
1575 | |||
1576 | tx_info->control.rates[0].idx = tx_info_priv->rcs[0].rix; | ||
1577 | 1555 | ||
1578 | /* Check if aggregation has to be enabled for this tid */ | 1556 | /* Check if aggregation has to be enabled for this tid */ |
1579 | |||
1580 | if (hw->conf.ht.enabled) { | 1557 | if (hw->conf.ht.enabled) { |
1581 | if (ieee80211_is_data_qos(fc)) { | 1558 | if (ieee80211_is_data_qos(fc)) { |
1582 | qc = ieee80211_get_qos_ctl(hdr); | 1559 | qc = ieee80211_get_qos_ctl(hdr); |
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 30248de5b2b6..3324bed3f0ac 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h | |||
@@ -169,20 +169,6 @@ struct ath_rate_table { | |||
169 | #define ATH_RC_PROBE_ALLOWED 0x00000001 | 169 | #define ATH_RC_PROBE_ALLOWED 0x00000001 |
170 | #define ATH_RC_MINRATE_LASTRATE 0x00000002 | 170 | #define ATH_RC_MINRATE_LASTRATE 0x00000002 |
171 | 171 | ||
172 | struct ath_rc_series { | ||
173 | u8 rix; | ||
174 | u8 tries; | ||
175 | u8 flags; | ||
176 | u32 max_4ms_framelen; | ||
177 | }; | ||
178 | |||
179 | /* rcs_flags definition */ | ||
180 | #define ATH_RC_DS_FLAG 0x01 | ||
181 | #define ATH_RC_CW40_FLAG 0x02 /* CW 40 */ | ||
182 | #define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */ | ||
183 | #define ATH_RC_HT_FLAG 0x08 /* HT */ | ||
184 | #define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */ | ||
185 | |||
186 | /* | 172 | /* |
187 | * State structures for new rate adaptation code | 173 | * State structures for new rate adaptation code |
188 | */ | 174 | */ |
@@ -259,13 +245,10 @@ struct ath_rate_node { | |||
259 | struct ath_rate_softc *asc; | 245 | struct ath_rate_softc *asc; |
260 | }; | 246 | }; |
261 | 247 | ||
262 | /* Driver data of ieee80211_tx_info */ | ||
263 | struct ath_tx_info_priv { | 248 | struct ath_tx_info_priv { |
264 | struct ath_rc_series rcs[4]; | ||
265 | struct ath_tx_status tx; | 249 | struct ath_tx_status tx; |
266 | int n_frames; | 250 | int n_frames; |
267 | int n_bad_frames; | 251 | int n_bad_frames; |
268 | u8 min_rate; | ||
269 | }; | 252 | }; |
270 | 253 | ||
271 | void ath_rate_attach(struct ath_softc *sc); | 254 | void ath_rate_attach(struct ath_softc *sc); |
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 44735b6d9f04..baf5cb9d967e 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -102,23 +102,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
102 | ath9k_hw_txstart(ah, txq->axq_qnum); | 102 | ath9k_hw_txstart(ah, txq->axq_qnum); |
103 | } | 103 | } |
104 | 104 | ||
105 | /* Get transmit rate index using rate in Kbps */ | ||
106 | |||
107 | static int ath_tx_findindex(const struct ath9k_rate_table *rt, int rate) | ||
108 | { | ||
109 | int i; | ||
110 | int ndx = 0; | ||
111 | |||
112 | for (i = 0; i < rt->rateCount; i++) { | ||
113 | if (rt->info[i].rateKbps == rate) { | ||
114 | ndx = i; | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return ndx; | ||
120 | } | ||
121 | |||
122 | /* Check if it's okay to send out aggregates */ | 105 | /* Check if it's okay to send out aggregates */ |
123 | 106 | ||
124 | static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) | 107 | static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) |
@@ -158,26 +141,23 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
158 | return htype; | 141 | return htype; |
159 | } | 142 | } |
160 | 143 | ||
161 | static bool check_min_rate(struct sk_buff *skb) | 144 | static bool is_pae(struct sk_buff *skb) |
162 | { | 145 | { |
163 | struct ieee80211_hdr *hdr; | 146 | struct ieee80211_hdr *hdr; |
164 | bool use_minrate = false; | ||
165 | __le16 fc; | 147 | __le16 fc; |
166 | 148 | ||
167 | hdr = (struct ieee80211_hdr *)skb->data; | 149 | hdr = (struct ieee80211_hdr *)skb->data; |
168 | fc = hdr->frame_control; | 150 | fc = hdr->frame_control; |
169 | 151 | ||
170 | if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) { | 152 | if (ieee80211_is_data(fc)) { |
171 | use_minrate = true; | ||
172 | } else if (ieee80211_is_data(fc)) { | ||
173 | if (ieee80211_is_nullfunc(fc) || | 153 | if (ieee80211_is_nullfunc(fc) || |
174 | /* Port Access Entity (IEEE 802.1X) */ | 154 | /* Port Access Entity (IEEE 802.1X) */ |
175 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 155 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
176 | use_minrate = true; | 156 | return true; |
177 | } | 157 | } |
178 | } | 158 | } |
179 | 159 | ||
180 | return use_minrate; | 160 | return false; |
181 | } | 161 | } |
182 | 162 | ||
183 | static int get_hw_crypto_keytype(struct sk_buff *skb) | 163 | static int get_hw_crypto_keytype(struct sk_buff *skb) |
@@ -199,50 +179,19 @@ static int get_hw_crypto_keytype(struct sk_buff *skb) | |||
199 | static void setup_rate_retries(struct ath_softc *sc, struct sk_buff *skb) | 179 | static void setup_rate_retries(struct ath_softc *sc, struct sk_buff *skb) |
200 | { | 180 | { |
201 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 181 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
202 | struct ath_tx_info_priv *tx_info_priv; | 182 | struct ieee80211_tx_rate *rates = tx_info->control.rates; |
203 | struct ath_rc_series *rcs; | ||
204 | struct ieee80211_hdr *hdr; | 183 | struct ieee80211_hdr *hdr; |
205 | const struct ath9k_rate_table *rt; | ||
206 | bool use_minrate; | ||
207 | __le16 fc; | 184 | __le16 fc; |
208 | u8 rix; | ||
209 | |||
210 | rt = sc->sc_currates; | ||
211 | BUG_ON(!rt); | ||
212 | 185 | ||
213 | hdr = (struct ieee80211_hdr *)skb->data; | 186 | hdr = (struct ieee80211_hdr *)skb->data; |
214 | fc = hdr->frame_control; | 187 | fc = hdr->frame_control; |
215 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; /* HACK */ | ||
216 | rcs = tx_info_priv->rcs; | ||
217 | |||
218 | /* Check if min rates have to be used */ | ||
219 | use_minrate = check_min_rate(skb); | ||
220 | |||
221 | if (ieee80211_is_data(fc) && !use_minrate) { | ||
222 | if (is_multicast_ether_addr(hdr->addr1)) { | ||
223 | rcs[0].rix = | ||
224 | ath_tx_findindex(rt, tx_info_priv->min_rate); | ||
225 | /* mcast packets are not re-tried */ | ||
226 | rcs[0].tries = 1; | ||
227 | } | ||
228 | } else { | ||
229 | /* for management and control frames, | ||
230 | or for NULL and EAPOL frames */ | ||
231 | if (use_minrate) | ||
232 | rcs[0].rix = ath_rate_findrateix(sc, tx_info_priv->min_rate); | ||
233 | else | ||
234 | rcs[0].rix = 0; | ||
235 | rcs[0].tries = ATH_MGT_TXMAXTRY; | ||
236 | } | ||
237 | |||
238 | rix = rcs[0].rix; | ||
239 | 188 | ||
240 | if (ieee80211_has_morefrags(fc) || | 189 | if (ieee80211_has_morefrags(fc) || |
241 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { | 190 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { |
242 | rcs[1].tries = rcs[2].tries = rcs[3].tries = 0; | 191 | rates[1].count = rates[2].count = rates[3].count = 0; |
243 | rcs[1].rix = rcs[2].rix = rcs[3].rix = 0; | 192 | rates[1].idx = rates[2].idx = rates[3].idx = 0; |
244 | /* reset tries but keep rate index */ | 193 | /* reset tries but keep rate index */ |
245 | rcs[0].tries = ATH_TXMAXTRY; | 194 | rates[0].count = ATH_TXMAXTRY; |
246 | } | 195 | } |
247 | } | 196 | } |
248 | 197 | ||
@@ -274,7 +223,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, | |||
274 | 223 | ||
275 | /* Get seqno */ | 224 | /* Get seqno */ |
276 | 225 | ||
277 | if (ieee80211_is_data(fc) && !check_min_rate(skb)) { | 226 | if (ieee80211_is_data(fc) && !is_pae(skb)) { |
278 | /* For HT capable stations, we save tidno for later use. | 227 | /* For HT capable stations, we save tidno for later use. |
279 | * We also override seqno set by upper layer with the one | 228 | * We also override seqno set by upper layer with the one |
280 | * in tx aggregation state. | 229 | * in tx aggregation state. |
@@ -573,9 +522,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
573 | struct ath_node *an = NULL; | 522 | struct ath_node *an = NULL; |
574 | struct sk_buff *skb; | 523 | struct sk_buff *skb; |
575 | struct ieee80211_tx_info *tx_info; | 524 | struct ieee80211_tx_info *tx_info; |
525 | struct ieee80211_tx_rate *rates; | ||
576 | 526 | ||
577 | skb = (struct sk_buff *)bf->bf_mpdu; | 527 | skb = (struct sk_buff *)bf->bf_mpdu; |
578 | tx_info = IEEE80211_SKB_CB(skb); | 528 | tx_info = IEEE80211_SKB_CB(skb); |
529 | rates = tx_info->rate_driver_data[0]; | ||
579 | 530 | ||
580 | if (tx_info->control.sta) | 531 | if (tx_info->control.sta) |
581 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | 532 | an = (struct ath_node *)tx_info->control.sta->drv_priv; |
@@ -584,9 +535,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
584 | * get the cix for the lowest valid rix. | 535 | * get the cix for the lowest valid rix. |
585 | */ | 536 | */ |
586 | rt = sc->sc_currates; | 537 | rt = sc->sc_currates; |
587 | for (i = 4; i--;) { | 538 | for (i = 3; i >= 0; i--) { |
588 | if (bf->bf_rcs[i].tries) { | 539 | if (rates[i].count) { |
589 | rix = bf->bf_rcs[i].rix; | 540 | rix = rates[i].idx; |
590 | break; | 541 | break; |
591 | } | 542 | } |
592 | } | 543 | } |
@@ -662,27 +613,27 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
662 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | 613 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); |
663 | 614 | ||
664 | for (i = 0; i < 4; i++) { | 615 | for (i = 0; i < 4; i++) { |
665 | if (!bf->bf_rcs[i].tries) | 616 | if (!rates[i].count) |
666 | continue; | 617 | continue; |
667 | 618 | ||
668 | rix = bf->bf_rcs[i].rix; | 619 | rix = rates[i].idx; |
669 | 620 | ||
670 | series[i].Rate = rt->info[rix].rateCode | | 621 | series[i].Rate = rt->info[rix].rateCode | |
671 | (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0); | 622 | (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0); |
672 | 623 | ||
673 | series[i].Tries = bf->bf_rcs[i].tries; | 624 | series[i].Tries = rates[i].count; |
674 | 625 | ||
675 | series[i].RateFlags = ( | 626 | series[i].RateFlags = ( |
676 | (bf->bf_rcs[i].flags & ATH_RC_RTSCTS_FLAG) ? | 627 | (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ? |
677 | ATH9K_RATESERIES_RTS_CTS : 0) | | 628 | ATH9K_RATESERIES_RTS_CTS : 0) | |
678 | ((bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) ? | 629 | ((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? |
679 | ATH9K_RATESERIES_2040 : 0) | | 630 | ATH9K_RATESERIES_2040 : 0) | |
680 | ((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ? | 631 | ((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ? |
681 | ATH9K_RATESERIES_HALFGI : 0); | 632 | ATH9K_RATESERIES_HALFGI : 0); |
682 | 633 | ||
683 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | 634 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, |
684 | (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0, | 635 | (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0, |
685 | (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG), | 636 | (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), |
686 | bf_isshpreamble(bf)); | 637 | bf_isshpreamble(bf)); |
687 | 638 | ||
688 | if (bf_isht(bf) && an) | 639 | if (bf_isht(bf) && an) |
@@ -718,22 +669,12 @@ static int ath_tx_send_normal(struct ath_softc *sc, | |||
718 | struct list_head *bf_head) | 669 | struct list_head *bf_head) |
719 | { | 670 | { |
720 | struct ath_buf *bf; | 671 | struct ath_buf *bf; |
721 | struct sk_buff *skb; | ||
722 | struct ieee80211_tx_info *tx_info; | ||
723 | struct ath_tx_info_priv *tx_info_priv; | ||
724 | 672 | ||
725 | BUG_ON(list_empty(bf_head)); | 673 | BUG_ON(list_empty(bf_head)); |
726 | 674 | ||
727 | bf = list_first_entry(bf_head, struct ath_buf, list); | 675 | bf = list_first_entry(bf_head, struct ath_buf, list); |
728 | bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */ | 676 | bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */ |
729 | 677 | ||
730 | skb = (struct sk_buff *)bf->bf_mpdu; | ||
731 | tx_info = IEEE80211_SKB_CB(skb); | ||
732 | |||
733 | /* XXX: HACK! */ | ||
734 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
735 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | ||
736 | |||
737 | /* update starting sequence number for subsequent ADDBA request */ | 678 | /* update starting sequence number for subsequent ADDBA request */ |
738 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | 679 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); |
739 | 680 | ||
@@ -1124,8 +1065,8 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1124 | skb = bf->bf_mpdu; | 1065 | skb = bf->bf_mpdu; |
1125 | tx_info = IEEE80211_SKB_CB(skb); | 1066 | tx_info = IEEE80211_SKB_CB(skb); |
1126 | 1067 | ||
1127 | /* XXX: HACK! */ | 1068 | tx_info_priv = |
1128 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->control.vif; | 1069 | (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; |
1129 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1070 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1130 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1071 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1131 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1072 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
@@ -1268,9 +1209,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, | |||
1268 | struct ath_tx_control *txctl) | 1209 | struct ath_tx_control *txctl) |
1269 | { | 1210 | { |
1270 | struct ath_buf *bf; | 1211 | struct ath_buf *bf; |
1271 | struct sk_buff *skb; | ||
1272 | struct ieee80211_tx_info *tx_info; | ||
1273 | struct ath_tx_info_priv *tx_info_priv; | ||
1274 | 1212 | ||
1275 | BUG_ON(list_empty(bf_head)); | 1213 | BUG_ON(list_empty(bf_head)); |
1276 | 1214 | ||
@@ -1296,12 +1234,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, | |||
1296 | return 0; | 1234 | return 0; |
1297 | } | 1235 | } |
1298 | 1236 | ||
1299 | skb = (struct sk_buff *)bf->bf_mpdu; | ||
1300 | tx_info = IEEE80211_SKB_CB(skb); | ||
1301 | /* XXX: HACK! */ | ||
1302 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1303 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | ||
1304 | |||
1305 | /* Add sub-frame to BAW */ | 1237 | /* Add sub-frame to BAW */ |
1306 | ath_tx_addto_baw(sc, tid, bf); | 1238 | ath_tx_addto_baw(sc, tid, bf); |
1307 | 1239 | ||
@@ -1323,9 +1255,11 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1323 | struct ath_buf *bf, | 1255 | struct ath_buf *bf, |
1324 | struct ath_atx_tid *tid) | 1256 | struct ath_atx_tid *tid) |
1325 | { | 1257 | { |
1258 | struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; | ||
1326 | const struct ath9k_rate_table *rt = sc->sc_currates; | 1259 | const struct ath9k_rate_table *rt = sc->sc_currates; |
1327 | struct sk_buff *skb; | 1260 | struct sk_buff *skb; |
1328 | struct ieee80211_tx_info *tx_info; | 1261 | struct ieee80211_tx_info *tx_info; |
1262 | struct ieee80211_tx_rate *rates; | ||
1329 | struct ath_tx_info_priv *tx_info_priv; | 1263 | struct ath_tx_info_priv *tx_info_priv; |
1330 | u32 max_4ms_framelen, frame_length; | 1264 | u32 max_4ms_framelen, frame_length; |
1331 | u16 aggr_limit, legacy = 0, maxampdu; | 1265 | u16 aggr_limit, legacy = 0, maxampdu; |
@@ -1333,10 +1267,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1333 | 1267 | ||
1334 | skb = (struct sk_buff *)bf->bf_mpdu; | 1268 | skb = (struct sk_buff *)bf->bf_mpdu; |
1335 | tx_info = IEEE80211_SKB_CB(skb); | 1269 | tx_info = IEEE80211_SKB_CB(skb); |
1336 | tx_info_priv = (struct ath_tx_info_priv *) | 1270 | rates = tx_info->control.rates; |
1337 | tx_info->control.vif; /* XXX: HACK! */ | 1271 | tx_info_priv = |
1338 | memcpy(bf->bf_rcs, | 1272 | (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; |
1339 | tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | ||
1340 | 1273 | ||
1341 | /* | 1274 | /* |
1342 | * Find the lowest frame length among the rate series that will have a | 1275 | * Find the lowest frame length among the rate series that will have a |
@@ -1346,14 +1279,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1346 | max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; | 1279 | max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; |
1347 | 1280 | ||
1348 | for (i = 0; i < 4; i++) { | 1281 | for (i = 0; i < 4; i++) { |
1349 | if (bf->bf_rcs[i].tries) { | 1282 | if (rates[i].count) { |
1350 | frame_length = bf->bf_rcs[i].max_4ms_framelen; | 1283 | if (rt->info[rates[i].idx].phy != PHY_HT) { |
1351 | |||
1352 | if (rt->info[bf->bf_rcs[i].rix].phy != PHY_HT) { | ||
1353 | legacy = 1; | 1284 | legacy = 1; |
1354 | break; | 1285 | break; |
1355 | } | 1286 | } |
1356 | 1287 | ||
1288 | frame_length = | ||
1289 | rate_table->info[rates[i].idx].max_4ms_framelen; | ||
1357 | max_4ms_framelen = min(max_4ms_framelen, frame_length); | 1290 | max_4ms_framelen = min(max_4ms_framelen, frame_length); |
1358 | } | 1291 | } |
1359 | } | 1292 | } |
@@ -1393,6 +1326,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1393 | u16 frmlen) | 1326 | u16 frmlen) |
1394 | { | 1327 | { |
1395 | const struct ath9k_rate_table *rt = sc->sc_currates; | 1328 | const struct ath9k_rate_table *rt = sc->sc_currates; |
1329 | struct sk_buff *skb = bf->bf_mpdu; | ||
1330 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1396 | u32 nsymbits, nsymbols, mpdudensity; | 1331 | u32 nsymbits, nsymbols, mpdudensity; |
1397 | u16 minlen; | 1332 | u16 minlen; |
1398 | u8 rc, flags, rix; | 1333 | u8 rc, flags, rix; |
@@ -1425,11 +1360,11 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1425 | if (mpdudensity == 0) | 1360 | if (mpdudensity == 0) |
1426 | return ndelim; | 1361 | return ndelim; |
1427 | 1362 | ||
1428 | rix = bf->bf_rcs[0].rix; | 1363 | rix = tx_info->control.rates[0].idx; |
1429 | flags = bf->bf_rcs[0].flags; | 1364 | flags = tx_info->control.rates[0].flags; |
1430 | rc = rt->info[rix].rateCode; | 1365 | rc = rt->info[rix].rateCode; |
1431 | width = (flags & ATH_RC_CW40_FLAG) ? 1 : 0; | 1366 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; |
1432 | half_gi = (flags & ATH_RC_SGI_FLAG) ? 1 : 0; | 1367 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; |
1433 | 1368 | ||
1434 | if (half_gi) | 1369 | if (half_gi) |
1435 | nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity); | 1370 | nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity); |
@@ -1471,7 +1406,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1471 | u16 aggr_limit = 0, al = 0, bpad = 0, | 1406 | u16 aggr_limit = 0, al = 0, bpad = 0, |
1472 | al_delta, h_baw = tid->baw_size / 2; | 1407 | al_delta, h_baw = tid->baw_size / 2; |
1473 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; | 1408 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; |
1474 | int prev_al = 0, is_ds_rate = 0; | 1409 | int prev_al = 0; |
1475 | INIT_LIST_HEAD(&bf_head); | 1410 | INIT_LIST_HEAD(&bf_head); |
1476 | 1411 | ||
1477 | BUG_ON(list_empty(&tid->buf_q)); | 1412 | BUG_ON(list_empty(&tid->buf_q)); |
@@ -1492,11 +1427,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1492 | if (!rl) { | 1427 | if (!rl) { |
1493 | aggr_limit = ath_lookup_rate(sc, bf, tid); | 1428 | aggr_limit = ath_lookup_rate(sc, bf, tid); |
1494 | rl = 1; | 1429 | rl = 1; |
1495 | /* | ||
1496 | * Is rate dual stream | ||
1497 | */ | ||
1498 | is_ds_rate = | ||
1499 | (bf->bf_rcs[0].flags & ATH_RC_DS_FLAG) ? 1 : 0; | ||
1500 | } | 1430 | } |
1501 | 1431 | ||
1502 | /* | 1432 | /* |
@@ -1739,14 +1669,13 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1739 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1669 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1740 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1670 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1741 | struct ath_tx_info_priv *tx_info_priv; | 1671 | struct ath_tx_info_priv *tx_info_priv; |
1742 | struct ath_rc_series *rcs; | ||
1743 | int hdrlen; | 1672 | int hdrlen; |
1744 | __le16 fc; | 1673 | __le16 fc; |
1745 | 1674 | ||
1746 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | 1675 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_KERNEL); |
1676 | tx_info->rate_driver_data[0] = tx_info_priv; | ||
1747 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1677 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1748 | fc = hdr->frame_control; | 1678 | fc = hdr->frame_control; |
1749 | rcs = tx_info_priv->rcs; | ||
1750 | 1679 | ||
1751 | ATH_TXBUF_RESET(bf); | 1680 | ATH_TXBUF_RESET(bf); |
1752 | 1681 | ||
@@ -1766,7 +1695,7 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1766 | (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? | 1695 | (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? |
1767 | (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) : | 1696 | (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) : |
1768 | (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE); | 1697 | (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE); |
1769 | (sc->hw->conf.ht.enabled && | 1698 | (sc->hw->conf.ht.enabled && !is_pae(skb) && |
1770 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ? | 1699 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ? |
1771 | (bf->bf_state.bf_type |= BUF_HT) : | 1700 | (bf->bf_state.bf_type |= BUF_HT) : |
1772 | (bf->bf_state.bf_type &= ~BUF_HT); | 1701 | (bf->bf_state.bf_type &= ~BUF_HT); |
@@ -1788,11 +1717,6 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1788 | 1717 | ||
1789 | setup_rate_retries(sc, skb); | 1718 | setup_rate_retries(sc, skb); |
1790 | 1719 | ||
1791 | bf->bf_rcs[0] = rcs[0]; | ||
1792 | bf->bf_rcs[1] = rcs[1]; | ||
1793 | bf->bf_rcs[2] = rcs[2]; | ||
1794 | bf->bf_rcs[3] = rcs[3]; | ||
1795 | |||
1796 | /* Assign seqno, tidno */ | 1720 | /* Assign seqno, tidno */ |
1797 | 1721 | ||
1798 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) | 1722 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) |