diff options
-rw-r--r-- | drivers/net/wireless/ath9k/ath9k.h | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/beacon.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 190 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/recv.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/xmit.c | 163 |
10 files changed, 132 insertions, 374 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 6be2b947307c..c4012c88d82b 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -401,22 +401,6 @@ enum ath9k_int { | |||
401 | ATH9K_INT_NOCARD = 0xffffffff | 401 | ATH9K_INT_NOCARD = 0xffffffff |
402 | }; | 402 | }; |
403 | 403 | ||
404 | struct ath9k_rate_table { | ||
405 | int rateCount; | ||
406 | u8 rateCodeToIndex[256]; | ||
407 | struct { | ||
408 | u8 valid; | ||
409 | u8 phy; | ||
410 | u32 rateKbps; | ||
411 | u8 rateCode; | ||
412 | u8 shortPreamble; | ||
413 | u8 dot11Rate; | ||
414 | u8 controlRate; | ||
415 | u16 lpAckDuration; | ||
416 | u16 spAckDuration; | ||
417 | } info[32]; | ||
418 | }; | ||
419 | |||
420 | #define ATH9K_RATESERIES_RTS_CTS 0x0001 | 404 | #define ATH9K_RATESERIES_RTS_CTS 0x0001 |
421 | #define ATH9K_RATESERIES_2040 0x0002 | 405 | #define ATH9K_RATESERIES_2040 0x0002 |
422 | #define ATH9K_RATESERIES_HALFGI 0x0004 | 406 | #define ATH9K_RATESERIES_HALFGI 0x0004 |
@@ -828,6 +812,8 @@ struct chan_centers { | |||
828 | u16 ext_center; | 812 | u16 ext_center; |
829 | }; | 813 | }; |
830 | 814 | ||
815 | struct ath_rate_table; | ||
816 | |||
831 | /* Helpers */ | 817 | /* Helpers */ |
832 | 818 | ||
833 | enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah, | 819 | enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah, |
@@ -838,7 +824,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah, | |||
838 | u16 flags, u16 *low, | 824 | u16 flags, u16 *low, |
839 | u16 *high); | 825 | u16 *high); |
840 | u16 ath9k_hw_computetxtime(struct ath_hal *ah, | 826 | u16 ath9k_hw_computetxtime(struct ath_hal *ah, |
841 | const struct ath9k_rate_table *rates, | 827 | struct ath_rate_table *rates, |
842 | u32 frameLen, u16 rateix, | 828 | u32 frameLen, u16 rateix, |
843 | bool shortPreamble); | 829 | bool shortPreamble); |
844 | u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); | 830 | u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); |
@@ -883,12 +869,6 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore); | |||
883 | void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period); | 869 | void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period); |
884 | void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, | 870 | void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, |
885 | const struct ath9k_beacon_state *bs); | 871 | const struct ath9k_beacon_state *bs); |
886 | |||
887 | /* Rate table */ | ||
888 | |||
889 | const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah, | ||
890 | u32 mode); | ||
891 | |||
892 | /* HW Capabilities */ | 872 | /* HW Capabilities */ |
893 | 873 | ||
894 | bool ath9k_hw_fill_cap_info(struct ath_hal *ah); | 874 | bool ath9k_hw_fill_cap_info(struct ath_hal *ah); |
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index d186cd41c235..dcf23834194c 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c | |||
@@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, | |||
68 | struct ath_hal *ah = sc->sc_ah; | 68 | struct ath_hal *ah = sc->sc_ah; |
69 | struct ath_desc *ds; | 69 | struct ath_desc *ds; |
70 | struct ath9k_11n_rate_series series[4]; | 70 | struct ath9k_11n_rate_series series[4]; |
71 | const struct ath9k_rate_table *rt; | 71 | struct ath_rate_table *rt; |
72 | int flags, antenna; | 72 | int flags, antenna; |
73 | u8 rix, rate; | 73 | u8 rix, rate; |
74 | int ctsrate = 0; | 74 | int ctsrate = 0; |
@@ -106,10 +106,10 @@ static void ath_beacon_setup(struct ath_softc *sc, | |||
106 | * XXX everything at min xmit rate | 106 | * XXX everything at min xmit rate |
107 | */ | 107 | */ |
108 | rix = 0; | 108 | rix = 0; |
109 | rt = sc->sc_currates; | 109 | rt = sc->hw_rate_table[sc->sc_curmode]; |
110 | rate = rt->info[rix].rateCode; | 110 | rate = rt->info[rix].ratecode; |
111 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 111 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
112 | rate |= rt->info[rix].shortPreamble; | 112 | rate |= rt->info[rix].short_preamble; |
113 | 113 | ||
114 | ath9k_hw_set11n_txdesc(ah, ds, | 114 | ath9k_hw_set11n_txdesc(ah, ds, |
115 | skb->len + FCS_LEN, /* frame length */ | 115 | skb->len + FCS_LEN, /* frame length */ |
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 6c872e704b93..fb6a013f3f31 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c | |||
@@ -80,38 +80,9 @@ static u8 parse_mpdudensity(u8 mpdudensity) | |||
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Set current operating mode | 82 | * Set current operating mode |
83 | * | ||
84 | * This function initializes and fills the rate table in the ATH object based | ||
85 | * on the operating mode. | ||
86 | */ | 83 | */ |
87 | static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) | 84 | static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) |
88 | { | 85 | { |
89 | const struct ath9k_rate_table *rt; | ||
90 | int i; | ||
91 | |||
92 | rt = ath9k_hw_getratetable(sc->sc_ah, mode); | ||
93 | BUG_ON(!rt); | ||
94 | |||
95 | memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap)); | ||
96 | for (i = 0; i < 256; i++) { | ||
97 | u8 ix = rt->rateCodeToIndex[i]; | ||
98 | |||
99 | if (ix == 0xff) | ||
100 | continue; | ||
101 | |||
102 | sc->sc_hwmap[i].ieeerate = | ||
103 | rt->info[ix].dot11Rate & IEEE80211_RATE_VAL; | ||
104 | sc->sc_hwmap[i].rateKbps = rt->info[ix].rateKbps; | ||
105 | |||
106 | if (rt->info[ix].shortPreamble || | ||
107 | rt->info[ix].phy == PHY_OFDM) { | ||
108 | /* XXX: Handle this */ | ||
109 | } | ||
110 | |||
111 | /* NB: this uses the last entry if the rate isn't found */ | ||
112 | /* XXX beware of overlow */ | ||
113 | } | ||
114 | sc->sc_currates = rt; | ||
115 | sc->sc_curmode = mode; | 86 | sc->sc_curmode = mode; |
116 | /* | 87 | /* |
117 | * All protection frames are transmited at 2Mb/s for | 88 | * All protection frames are transmited at 2Mb/s for |
@@ -126,37 +97,36 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) | |||
126 | */ | 97 | */ |
127 | static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | 98 | static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) |
128 | { | 99 | { |
129 | struct ath_hal *ah = sc->sc_ah; | 100 | struct ath_rate_table *rate_table = NULL; |
130 | const struct ath9k_rate_table *rt = NULL; | ||
131 | struct ieee80211_supported_band *sband; | 101 | struct ieee80211_supported_band *sband; |
132 | struct ieee80211_rate *rate; | 102 | struct ieee80211_rate *rate; |
133 | int i, maxrates; | 103 | int i, maxrates; |
134 | 104 | ||
135 | switch (band) { | 105 | switch (band) { |
136 | case IEEE80211_BAND_2GHZ: | 106 | case IEEE80211_BAND_2GHZ: |
137 | rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11G); | 107 | rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; |
138 | break; | 108 | break; |
139 | case IEEE80211_BAND_5GHZ: | 109 | case IEEE80211_BAND_5GHZ: |
140 | rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11A); | 110 | rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; |
141 | break; | 111 | break; |
142 | default: | 112 | default: |
143 | break; | 113 | break; |
144 | } | 114 | } |
145 | 115 | ||
146 | if (rt == NULL) | 116 | if (rate_table == NULL) |
147 | return; | 117 | return; |
148 | 118 | ||
149 | sband = &sc->sbands[band]; | 119 | sband = &sc->sbands[band]; |
150 | rate = sc->rates[band]; | 120 | rate = sc->rates[band]; |
151 | 121 | ||
152 | if (rt->rateCount > ATH_RATE_MAX) | 122 | if (rate_table->rate_cnt > ATH_RATE_MAX) |
153 | maxrates = ATH_RATE_MAX; | 123 | maxrates = ATH_RATE_MAX; |
154 | else | 124 | else |
155 | maxrates = rt->rateCount; | 125 | maxrates = rate_table->rate_cnt; |
156 | 126 | ||
157 | for (i = 0; i < maxrates; i++) { | 127 | for (i = 0; i < maxrates; i++) { |
158 | rate[i].bitrate = rt->info[i].rateKbps / 100; | 128 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; |
159 | rate[i].hw_value = rt->info[i].rateCode; | 129 | rate[i].hw_value = rate_table->info[i].ratecode; |
160 | sband->n_bitrates++; | 130 | sband->n_bitrates++; |
161 | DPRINTF(sc, ATH_DBG_CONFIG, | 131 | DPRINTF(sc, ATH_DBG_CONFIG, |
162 | "%s: Rate: %2dMbps, ratecode: %2d\n", | 132 | "%s: Rate: %2dMbps, ratecode: %2d\n", |
@@ -1000,12 +970,10 @@ int ath_init(u16 devid, struct ath_softc *sc) | |||
1000 | 970 | ||
1001 | /* Setup rate tables */ | 971 | /* Setup rate tables */ |
1002 | 972 | ||
973 | ath_rate_attach(sc); | ||
1003 | ath_setup_rates(sc, IEEE80211_BAND_2GHZ); | 974 | ath_setup_rates(sc, IEEE80211_BAND_2GHZ); |
1004 | ath_setup_rates(sc, IEEE80211_BAND_5GHZ); | 975 | ath_setup_rates(sc, IEEE80211_BAND_5GHZ); |
1005 | 976 | ||
1006 | /* NB: setup here so ath_rate_update is happy */ | ||
1007 | ath_setcurmode(sc, ATH9K_MODE_11A); | ||
1008 | |||
1009 | /* | 977 | /* |
1010 | * Allocate hardware transmit queues: one queue for | 978 | * Allocate hardware transmit queues: one queue for |
1011 | * beacon frames and one data queue for each QoS | 979 | * beacon frames and one data queue for each QoS |
@@ -1071,8 +1039,6 @@ int ath_init(u16 devid, struct ath_softc *sc) | |||
1071 | sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; | 1039 | sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; |
1072 | setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); | 1040 | setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); |
1073 | 1041 | ||
1074 | ath_rate_attach(sc); | ||
1075 | |||
1076 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 1042 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, |
1077 | ATH9K_CIPHER_TKIP, NULL)) { | 1043 | ATH9K_CIPHER_TKIP, NULL)) { |
1078 | /* | 1044 | /* |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 255f860b2719..0c348209f39c 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -858,12 +858,7 @@ struct ath_softc { | |||
858 | /* Rate */ | 858 | /* Rate */ |
859 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; | 859 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; |
860 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; | 860 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; |
861 | const struct ath9k_rate_table *sc_currates; | ||
862 | u8 sc_protrix; /* protection rate index */ | 861 | u8 sc_protrix; /* protection rate index */ |
863 | struct { | ||
864 | u32 rateKbps; /* transfer rate in kbs */ | ||
865 | u8 ieeerate; /* IEEE rate */ | ||
866 | } sc_hwmap[256]; /* h/w rate ix mappings */ | ||
867 | 862 | ||
868 | /* Channel, Band */ | 863 | /* Channel, Band */ |
869 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; | 864 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 82c2a4259ce4..a26867c56a82 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -142,14 +142,14 @@ bool ath9k_get_channel_edges(struct ath_hal *ah, | |||
142 | } | 142 | } |
143 | 143 | ||
144 | u16 ath9k_hw_computetxtime(struct ath_hal *ah, | 144 | u16 ath9k_hw_computetxtime(struct ath_hal *ah, |
145 | const struct ath9k_rate_table *rates, | 145 | struct ath_rate_table *rates, |
146 | u32 frameLen, u16 rateix, | 146 | u32 frameLen, u16 rateix, |
147 | bool shortPreamble) | 147 | bool shortPreamble) |
148 | { | 148 | { |
149 | u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; | 149 | u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; |
150 | u32 kbps; | 150 | u32 kbps; |
151 | 151 | ||
152 | kbps = rates->info[rateix].rateKbps; | 152 | kbps = rates->info[rateix].ratekbps; |
153 | 153 | ||
154 | if (kbps == 0) | 154 | if (kbps == 0) |
155 | return 0; | 155 | return 0; |
@@ -157,7 +157,7 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, | |||
157 | switch (rates->info[rateix].phy) { | 157 | switch (rates->info[rateix].phy) { |
158 | case PHY_CCK: | 158 | case PHY_CCK: |
159 | phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; | 159 | phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; |
160 | if (shortPreamble && rates->info[rateix].shortPreamble) | 160 | if (shortPreamble && rates->info[rateix].short_preamble) |
161 | phyTime >>= 1; | 161 | phyTime >>= 1; |
162 | numBits = frameLen << 3; | 162 | numBits = frameLen << 3; |
163 | txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); | 163 | txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); |
@@ -3190,190 +3190,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, | |||
3190 | 3190 | ||
3191 | } | 3191 | } |
3192 | 3192 | ||
3193 | /***************/ | ||
3194 | /* Rate tables */ | ||
3195 | /***************/ | ||
3196 | |||
3197 | static struct ath9k_rate_table ar5416_11a_table = { | ||
3198 | 8, | ||
3199 | {0}, | ||
3200 | { | ||
3201 | {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0}, | ||
3202 | {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0}, | ||
3203 | {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2}, | ||
3204 | {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2}, | ||
3205 | {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4}, | ||
3206 | {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4}, | ||
3207 | {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4}, | ||
3208 | {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4} | ||
3209 | }, | ||
3210 | }; | ||
3211 | |||
3212 | static struct ath9k_rate_table ar5416_11b_table = { | ||
3213 | 4, | ||
3214 | {0}, | ||
3215 | { | ||
3216 | {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, | ||
3217 | {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, | ||
3218 | {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1}, | ||
3219 | {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1} | ||
3220 | }, | ||
3221 | }; | ||
3222 | |||
3223 | static struct ath9k_rate_table ar5416_11g_table = { | ||
3224 | 12, | ||
3225 | {0}, | ||
3226 | { | ||
3227 | {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, | ||
3228 | {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, | ||
3229 | {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2}, | ||
3230 | {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3}, | ||
3231 | |||
3232 | {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4}, | ||
3233 | {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4}, | ||
3234 | {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6}, | ||
3235 | {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6}, | ||
3236 | {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8}, | ||
3237 | {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8}, | ||
3238 | {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8}, | ||
3239 | {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8} | ||
3240 | }, | ||
3241 | }; | ||
3242 | |||
3243 | static struct ath9k_rate_table ar5416_11ng_table = { | ||
3244 | 28, | ||
3245 | {0}, | ||
3246 | { | ||
3247 | {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, | ||
3248 | {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, | ||
3249 | {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2}, | ||
3250 | {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3}, | ||
3251 | |||
3252 | {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4}, | ||
3253 | {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4}, | ||
3254 | {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6}, | ||
3255 | {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6}, | ||
3256 | {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8}, | ||
3257 | {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8}, | ||
3258 | {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8}, | ||
3259 | {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}, | ||
3260 | {true, PHY_HT, 6500, 0x80, 0x00, 0, 4}, | ||
3261 | {true, PHY_HT, 13000, 0x81, 0x00, 1, 6}, | ||
3262 | {true, PHY_HT, 19500, 0x82, 0x00, 2, 6}, | ||
3263 | {true, PHY_HT, 26000, 0x83, 0x00, 3, 8}, | ||
3264 | {true, PHY_HT, 39000, 0x84, 0x00, 4, 8}, | ||
3265 | {true, PHY_HT, 52000, 0x85, 0x00, 5, 8}, | ||
3266 | {true, PHY_HT, 58500, 0x86, 0x00, 6, 8}, | ||
3267 | {true, PHY_HT, 65000, 0x87, 0x00, 7, 8}, | ||
3268 | {true, PHY_HT, 13000, 0x88, 0x00, 8, 4}, | ||
3269 | {true, PHY_HT, 26000, 0x89, 0x00, 9, 6}, | ||
3270 | {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6}, | ||
3271 | {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8}, | ||
3272 | {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8}, | ||
3273 | {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8}, | ||
3274 | {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8}, | ||
3275 | {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8}, | ||
3276 | }, | ||
3277 | }; | ||
3278 | |||
3279 | static struct ath9k_rate_table ar5416_11na_table = { | ||
3280 | 24, | ||
3281 | {0}, | ||
3282 | { | ||
3283 | {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0}, | ||
3284 | {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0}, | ||
3285 | {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2}, | ||
3286 | {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2}, | ||
3287 | {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4}, | ||
3288 | {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4}, | ||
3289 | {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4}, | ||
3290 | {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}, | ||
3291 | {true, PHY_HT, 6500, 0x80, 0x00, 0, 0}, | ||
3292 | {true, PHY_HT, 13000, 0x81, 0x00, 1, 2}, | ||
3293 | {true, PHY_HT, 19500, 0x82, 0x00, 2, 2}, | ||
3294 | {true, PHY_HT, 26000, 0x83, 0x00, 3, 4}, | ||
3295 | {true, PHY_HT, 39000, 0x84, 0x00, 4, 4}, | ||
3296 | {true, PHY_HT, 52000, 0x85, 0x00, 5, 4}, | ||
3297 | {true, PHY_HT, 58500, 0x86, 0x00, 6, 4}, | ||
3298 | {true, PHY_HT, 65000, 0x87, 0x00, 7, 4}, | ||
3299 | {true, PHY_HT, 13000, 0x88, 0x00, 8, 0}, | ||
3300 | {true, PHY_HT, 26000, 0x89, 0x00, 9, 2}, | ||
3301 | {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2}, | ||
3302 | {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4}, | ||
3303 | {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4}, | ||
3304 | {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4}, | ||
3305 | {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4}, | ||
3306 | {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4}, | ||
3307 | }, | ||
3308 | }; | ||
3309 | |||
3310 | static void ath9k_hw_setup_rate_table(struct ath_hal *ah, | ||
3311 | struct ath9k_rate_table *rt) | ||
3312 | { | ||
3313 | int i; | ||
3314 | |||
3315 | if (rt->rateCodeToIndex[0] != 0) | ||
3316 | return; | ||
3317 | |||
3318 | for (i = 0; i < 256; i++) | ||
3319 | rt->rateCodeToIndex[i] = (u8) -1; | ||
3320 | |||
3321 | for (i = 0; i < rt->rateCount; i++) { | ||
3322 | u8 code = rt->info[i].rateCode; | ||
3323 | u8 cix = rt->info[i].controlRate; | ||
3324 | |||
3325 | rt->rateCodeToIndex[code] = i; | ||
3326 | rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; | ||
3327 | |||
3328 | rt->info[i].lpAckDuration = | ||
3329 | ath9k_hw_computetxtime(ah, rt, | ||
3330 | WLAN_CTRL_FRAME_SIZE, | ||
3331 | cix, | ||
3332 | false); | ||
3333 | rt->info[i].spAckDuration = | ||
3334 | ath9k_hw_computetxtime(ah, rt, | ||
3335 | WLAN_CTRL_FRAME_SIZE, | ||
3336 | cix, | ||
3337 | true); | ||
3338 | } | ||
3339 | } | ||
3340 | |||
3341 | const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah, | ||
3342 | u32 mode) | ||
3343 | { | ||
3344 | struct ath9k_rate_table *rt; | ||
3345 | |||
3346 | switch (mode) { | ||
3347 | case ATH9K_MODE_11A: | ||
3348 | rt = &ar5416_11a_table; | ||
3349 | break; | ||
3350 | case ATH9K_MODE_11B: | ||
3351 | rt = &ar5416_11b_table; | ||
3352 | break; | ||
3353 | case ATH9K_MODE_11G: | ||
3354 | rt = &ar5416_11g_table; | ||
3355 | break; | ||
3356 | case ATH9K_MODE_11NG_HT20: | ||
3357 | case ATH9K_MODE_11NG_HT40PLUS: | ||
3358 | case ATH9K_MODE_11NG_HT40MINUS: | ||
3359 | rt = &ar5416_11ng_table; | ||
3360 | break; | ||
3361 | case ATH9K_MODE_11NA_HT20: | ||
3362 | case ATH9K_MODE_11NA_HT40PLUS: | ||
3363 | case ATH9K_MODE_11NA_HT40MINUS: | ||
3364 | rt = &ar5416_11na_table; | ||
3365 | break; | ||
3366 | default: | ||
3367 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n", | ||
3368 | __func__, mode); | ||
3369 | return NULL; | ||
3370 | } | ||
3371 | |||
3372 | ath9k_hw_setup_rate_table(ah, rt); | ||
3373 | |||
3374 | return rt; | ||
3375 | } | ||
3376 | |||
3377 | /*******************/ | 3193 | /*******************/ |
3378 | /* HW Capabilities */ | 3194 | /* HW Capabilities */ |
3379 | /*******************/ | 3195 | /*******************/ |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 11d7bee2fda0..e86bcd284148 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -780,6 +780,8 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
780 | BIT(NL80211_IFTYPE_ADHOC); | 780 | BIT(NL80211_IFTYPE_ADHOC); |
781 | 781 | ||
782 | hw->queues = 4; | 782 | hw->queues = 4; |
783 | hw->max_rates = 4; | ||
784 | hw->max_rate_tries = ATH_11N_TXMAXTRY; | ||
783 | hw->sta_data_size = sizeof(struct ath_node); | 785 | hw->sta_data_size = sizeof(struct ath_node); |
784 | hw->vif_data_size = sizeof(struct ath_vap); | 786 | hw->vif_data_size = sizeof(struct ath_vap); |
785 | 787 | ||
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 156b245ab9e4..bf637aa7ddab 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | static struct ath_rate_table ar5416_11na_ratetable = { | 26 | static struct ath_rate_table ar5416_11na_ratetable = { |
27 | 42, | 27 | 42, |
28 | {0}, | ||
28 | { | 29 | { |
29 | { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ | 30 | { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ |
30 | 5400, 0x0b, 0x00, 12, | 31 | 5400, 0x0b, 0x00, 12, |
@@ -168,6 +169,7 @@ static struct ath_rate_table ar5416_11na_ratetable = { | |||
168 | 169 | ||
169 | static struct ath_rate_table ar5416_11ng_ratetable = { | 170 | static struct ath_rate_table ar5416_11ng_ratetable = { |
170 | 46, | 171 | 46, |
172 | {0}, | ||
171 | { | 173 | { |
172 | { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 1000, /* 1 Mb */ | 174 | { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 1000, /* 1 Mb */ |
173 | 900, 0x1b, 0x00, 2, | 175 | 900, 0x1b, 0x00, 2, |
@@ -315,6 +317,7 @@ static struct ath_rate_table ar5416_11ng_ratetable = { | |||
315 | 317 | ||
316 | static struct ath_rate_table ar5416_11a_ratetable = { | 318 | static struct ath_rate_table ar5416_11a_ratetable = { |
317 | 8, | 319 | 8, |
320 | {0}, | ||
318 | { | 321 | { |
319 | { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ | 322 | { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ |
320 | 5400, 0x0b, 0x00, (0x80|12), | 323 | 5400, 0x0b, 0x00, (0x80|12), |
@@ -348,6 +351,7 @@ static struct ath_rate_table ar5416_11a_ratetable = { | |||
348 | 351 | ||
349 | static struct ath_rate_table ar5416_11g_ratetable = { | 352 | static struct ath_rate_table ar5416_11g_ratetable = { |
350 | 12, | 353 | 12, |
354 | {0}, | ||
351 | { | 355 | { |
352 | { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ | 356 | { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ |
353 | 900, 0x1b, 0x00, 2, | 357 | 900, 0x1b, 0x00, 2, |
@@ -393,6 +397,7 @@ static struct ath_rate_table ar5416_11g_ratetable = { | |||
393 | 397 | ||
394 | static struct ath_rate_table ar5416_11b_ratetable = { | 398 | static struct ath_rate_table ar5416_11b_ratetable = { |
395 | 4, | 399 | 4, |
400 | {0}, | ||
396 | { | 401 | { |
397 | { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ | 402 | { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ |
398 | 900, 0x1b, 0x00, (0x80|2), | 403 | 900, 0x1b, 0x00, (0x80|2), |
@@ -1302,14 +1307,14 @@ static void ath_rc_update(struct ath_softc *sc, | |||
1302 | if (final_ts_idx != 0) { | 1307 | if (final_ts_idx != 0) { |
1303 | /* Process intermediate rates that failed.*/ | 1308 | /* Process intermediate rates that failed.*/ |
1304 | for (series = 0; series < final_ts_idx ; series++) { | 1309 | for (series = 0; series < final_ts_idx ; series++) { |
1305 | if (rates[series].count != 0) { | 1310 | if (rates[series].count != 0 && (rates[series].idx >= 0)) { |
1306 | flags = rates[series].flags; | 1311 | flags = rates[series].flags; |
1307 | /* If HT40 and we have switched mode from | 1312 | /* If HT40 and we have switched mode from |
1308 | * 40 to 20 => don't update */ | 1313 | * 40 to 20 => don't update */ |
1309 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | 1314 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1310 | (ath_rc_priv->rc_phy_mode != | 1315 | (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) |
1311 | (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) | ||
1312 | return; | 1316 | return; |
1317 | |||
1313 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | 1318 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1314 | (flags & IEEE80211_TX_RC_SHORT_GI)) | 1319 | (flags & IEEE80211_TX_RC_SHORT_GI)) |
1315 | rix = rate_table->info[ | 1320 | rix = rate_table->info[ |
@@ -1343,8 +1348,9 @@ static void ath_rc_update(struct ath_softc *sc, | |||
1343 | flags = rates[series].flags; | 1348 | flags = rates[series].flags; |
1344 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ | 1349 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ |
1345 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | 1350 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && |
1346 | (ath_rc_priv->rc_phy_mode != (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) | 1351 | (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { |
1347 | return; | 1352 | return; |
1353 | } | ||
1348 | 1354 | ||
1349 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) | 1355 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) |
1350 | rix = rate_table->info[rates[series].idx].ht_index; | 1356 | rix = rate_table->info[rates[series].idx].ht_index; |
@@ -1628,7 +1634,6 @@ static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, | |||
1628 | void *priv_sta) | 1634 | void *priv_sta) |
1629 | { | 1635 | { |
1630 | struct ath_rate_node *rate_priv = priv_sta; | 1636 | struct ath_rate_node *rate_priv = priv_sta; |
1631 | |||
1632 | kfree(rate_priv); | 1637 | kfree(rate_priv); |
1633 | } | 1638 | } |
1634 | 1639 | ||
@@ -1644,6 +1649,35 @@ static struct rate_control_ops ath_rate_ops = { | |||
1644 | .free_sta = ath_rate_free_sta, | 1649 | .free_sta = ath_rate_free_sta, |
1645 | }; | 1650 | }; |
1646 | 1651 | ||
1652 | static void ath_setup_rate_table(struct ath_softc *sc, | ||
1653 | struct ath_rate_table *rate_table) | ||
1654 | { | ||
1655 | int i; | ||
1656 | |||
1657 | for (i = 0; i < 256; i++) | ||
1658 | rate_table->rateCodeToIndex[i] = (u8)-1; | ||
1659 | |||
1660 | for (i = 0; i < rate_table->rate_cnt; i++) { | ||
1661 | u8 code = rate_table->info[i].ratecode; | ||
1662 | u8 cix = rate_table->info[i].ctrl_rate; | ||
1663 | u8 sh = rate_table->info[i].short_preamble; | ||
1664 | |||
1665 | rate_table->rateCodeToIndex[code] = i; | ||
1666 | rate_table->rateCodeToIndex[code | sh] = i; | ||
1667 | |||
1668 | rate_table->info[i].lpAckDuration = | ||
1669 | ath9k_hw_computetxtime(sc->sc_ah, rate_table, | ||
1670 | WLAN_CTRL_FRAME_SIZE, | ||
1671 | cix, | ||
1672 | false); | ||
1673 | rate_table->info[i].spAckDuration = | ||
1674 | ath9k_hw_computetxtime(sc->sc_ah, rate_table, | ||
1675 | WLAN_CTRL_FRAME_SIZE, | ||
1676 | cix, | ||
1677 | true); | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1647 | void ath_rate_attach(struct ath_softc *sc) | 1681 | void ath_rate_attach(struct ath_softc *sc) |
1648 | { | 1682 | { |
1649 | sc->hw_rate_table[ATH9K_MODE_11B] = | 1683 | sc->hw_rate_table[ATH9K_MODE_11B] = |
@@ -1664,6 +1698,12 @@ void ath_rate_attach(struct ath_softc *sc) | |||
1664 | &ar5416_11ng_ratetable; | 1698 | &ar5416_11ng_ratetable; |
1665 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = | 1699 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = |
1666 | &ar5416_11ng_ratetable; | 1700 | &ar5416_11ng_ratetable; |
1701 | |||
1702 | ath_setup_rate_table(sc, &ar5416_11b_ratetable); | ||
1703 | ath_setup_rate_table(sc, &ar5416_11a_ratetable); | ||
1704 | ath_setup_rate_table(sc, &ar5416_11g_ratetable); | ||
1705 | ath_setup_rate_table(sc, &ar5416_11na_ratetable); | ||
1706 | ath_setup_rate_table(sc, &ar5416_11ng_ratetable); | ||
1667 | } | 1707 | } |
1668 | 1708 | ||
1669 | int ath_rate_control_register(void) | 1709 | int ath_rate_control_register(void) |
@@ -1675,4 +1715,3 @@ void ath_rate_control_unregister(void) | |||
1675 | { | 1715 | { |
1676 | ieee80211_rate_control_unregister(&ath_rate_ops); | 1716 | ieee80211_rate_control_unregister(&ath_rate_ops); |
1677 | } | 1717 | } |
1678 | |||
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 3324bed3f0ac..c1e370c7c681 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h | |||
@@ -143,6 +143,7 @@ enum { | |||
143 | */ | 143 | */ |
144 | struct ath_rate_table { | 144 | struct ath_rate_table { |
145 | int rate_cnt; | 145 | int rate_cnt; |
146 | u8 rateCodeToIndex[256]; | ||
146 | struct { | 147 | struct { |
147 | int valid; | 148 | int valid; |
148 | int valid_single_stream; | 149 | int valid_single_stream; |
@@ -160,6 +161,8 @@ struct ath_rate_table { | |||
160 | u8 sgi_index; | 161 | u8 sgi_index; |
161 | u8 ht_index; | 162 | u8 ht_index; |
162 | u32 max_4ms_framelen; | 163 | u32 max_4ms_framelen; |
164 | u16 lpAckDuration; | ||
165 | u16 spAckDuration; | ||
163 | } info[RATE_TABLE_SIZE]; | 166 | } info[RATE_TABLE_SIZE]; |
164 | u32 probe_interval; | 167 | u32 probe_interval; |
165 | u32 rssi_reduce_interval; | 168 | u32 rssi_reduce_interval; |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 000e189e104a..20f83779278a 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -140,8 +140,9 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | |||
140 | struct ieee80211_rx_status *rx_status, bool *decrypt_error, | 140 | struct ieee80211_rx_status *rx_status, bool *decrypt_error, |
141 | struct ath_softc *sc) | 141 | struct ath_softc *sc) |
142 | { | 142 | { |
143 | struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; | ||
143 | struct ieee80211_hdr *hdr; | 144 | struct ieee80211_hdr *hdr; |
144 | int ratekbps; | 145 | int ratekbps, rix; |
145 | u8 ratecode; | 146 | u8 ratecode; |
146 | __le16 fc; | 147 | __le16 fc; |
147 | 148 | ||
@@ -196,7 +197,8 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | |||
196 | } | 197 | } |
197 | 198 | ||
198 | ratecode = ds->ds_rxstat.rs_rate; | 199 | ratecode = ds->ds_rxstat.rs_rate; |
199 | ratekbps = sc->sc_hwmap[ratecode].rateKbps; | 200 | rix = rate_table->rateCodeToIndex[ratecode]; |
201 | ratekbps = rate_table->info[rix].ratekbps; | ||
200 | 202 | ||
201 | /* HT rate */ | 203 | /* HT rate */ |
202 | if (ratecode & 0x80) { | 204 | if (ratecode & 0x80) { |
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index baf5cb9d967e..b2d0cca6f4a6 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -176,25 +176,6 @@ static int get_hw_crypto_keytype(struct sk_buff *skb) | |||
176 | return ATH9K_KEY_TYPE_CLEAR; | 176 | return ATH9K_KEY_TYPE_CLEAR; |
177 | } | 177 | } |
178 | 178 | ||
179 | static void setup_rate_retries(struct ath_softc *sc, struct sk_buff *skb) | ||
180 | { | ||
181 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
182 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
183 | struct ieee80211_hdr *hdr; | ||
184 | __le16 fc; | ||
185 | |||
186 | hdr = (struct ieee80211_hdr *)skb->data; | ||
187 | fc = hdr->frame_control; | ||
188 | |||
189 | if (ieee80211_has_morefrags(fc) || | ||
190 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { | ||
191 | rates[1].count = rates[2].count = rates[3].count = 0; | ||
192 | rates[1].idx = rates[2].idx = rates[3].idx = 0; | ||
193 | /* reset tries but keep rate index */ | ||
194 | rates[0].count = ATH_TXMAXTRY; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /* Called only when tx aggregation is enabled and HT is supported */ | 179 | /* Called only when tx aggregation is enabled and HT is supported */ |
199 | 180 | ||
200 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | 181 | static void assign_aggr_tid_seqno(struct sk_buff *skb, |
@@ -468,27 +449,23 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
468 | * width - 0 for 20 MHz, 1 for 40 MHz | 449 | * width - 0 for 20 MHz, 1 for 40 MHz |
469 | * half_gi - to use 4us v/s 3.6 us for symbol time | 450 | * half_gi - to use 4us v/s 3.6 us for symbol time |
470 | */ | 451 | */ |
471 | |||
472 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | 452 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, |
473 | int width, int half_gi, bool shortPreamble) | 453 | int width, int half_gi, bool shortPreamble) |
474 | { | 454 | { |
475 | const struct ath9k_rate_table *rt = sc->sc_currates; | 455 | struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; |
476 | u32 nbits, nsymbits, duration, nsymbols; | 456 | u32 nbits, nsymbits, duration, nsymbols; |
477 | u8 rc; | 457 | u8 rc; |
478 | int streams, pktlen; | 458 | int streams, pktlen; |
479 | 459 | ||
480 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; | 460 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; |
481 | rc = rt->info[rix].rateCode; | 461 | rc = rate_table->info[rix].ratecode; |
482 | 462 | ||
483 | /* | 463 | /* for legacy rates, use old function to compute packet duration */ |
484 | * for legacy rates, use old function to compute packet duration | ||
485 | */ | ||
486 | if (!IS_HT_RATE(rc)) | 464 | if (!IS_HT_RATE(rc)) |
487 | return ath9k_hw_computetxtime(sc->sc_ah, rt, pktlen, rix, | 465 | return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen, |
488 | shortPreamble); | 466 | rix, shortPreamble); |
489 | /* | 467 | |
490 | * find number of symbols: PLCP + data | 468 | /* find number of symbols: PLCP + data */ |
491 | */ | ||
492 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; | 469 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; |
493 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | 470 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; |
494 | nsymbols = (nbits + nsymbits - 1) / nsymbits; | 471 | nsymbols = (nbits + nsymbits - 1) / nsymbits; |
@@ -498,9 +475,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | |||
498 | else | 475 | else |
499 | duration = SYMBOL_TIME_HALFGI(nsymbols); | 476 | duration = SYMBOL_TIME_HALFGI(nsymbols); |
500 | 477 | ||
501 | /* | 478 | /* addup duration for legacy/ht training and signal fields */ |
502 | * addup duration for legacy/ht training and signal fields | ||
503 | */ | ||
504 | streams = HT_RC_2_STREAMS(rc); | 479 | streams = HT_RC_2_STREAMS(rc); |
505 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | 480 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); |
506 | 481 | ||
@@ -512,114 +487,104 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | |||
512 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | 487 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) |
513 | { | 488 | { |
514 | struct ath_hal *ah = sc->sc_ah; | 489 | struct ath_hal *ah = sc->sc_ah; |
515 | const struct ath9k_rate_table *rt; | 490 | struct ath_rate_table *rt; |
516 | struct ath_desc *ds = bf->bf_desc; | 491 | struct ath_desc *ds = bf->bf_desc; |
517 | struct ath_desc *lastds = bf->bf_lastbf->bf_desc; | 492 | struct ath_desc *lastds = bf->bf_lastbf->bf_desc; |
518 | struct ath9k_11n_rate_series series[4]; | 493 | struct ath9k_11n_rate_series series[4]; |
519 | int i, flags, rtsctsena = 0; | ||
520 | u32 ctsduration = 0; | ||
521 | u8 rix = 0, cix, ctsrate = 0; | ||
522 | struct ath_node *an = NULL; | 494 | struct ath_node *an = NULL; |
523 | struct sk_buff *skb; | 495 | struct sk_buff *skb; |
524 | struct ieee80211_tx_info *tx_info; | 496 | struct ieee80211_tx_info *tx_info; |
525 | struct ieee80211_tx_rate *rates; | 497 | struct ieee80211_tx_rate *rates; |
498 | struct ieee80211_hdr *hdr; | ||
499 | int i, flags, rtsctsena = 0; | ||
500 | u32 ctsduration = 0; | ||
501 | u8 rix = 0, cix, ctsrate = 0; | ||
502 | __le16 fc; | ||
503 | |||
504 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | ||
526 | 505 | ||
527 | skb = (struct sk_buff *)bf->bf_mpdu; | 506 | skb = (struct sk_buff *)bf->bf_mpdu; |
507 | hdr = (struct ieee80211_hdr *)skb->data; | ||
508 | fc = hdr->frame_control; | ||
528 | tx_info = IEEE80211_SKB_CB(skb); | 509 | tx_info = IEEE80211_SKB_CB(skb); |
529 | rates = tx_info->rate_driver_data[0]; | 510 | rates = tx_info->control.rates; |
530 | 511 | ||
531 | if (tx_info->control.sta) | 512 | if (tx_info->control.sta) |
532 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | 513 | an = (struct ath_node *)tx_info->control.sta->drv_priv; |
533 | 514 | ||
534 | /* | 515 | if (ieee80211_has_morefrags(fc) || |
535 | * get the cix for the lowest valid rix. | 516 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { |
536 | */ | 517 | rates[1].count = rates[2].count = rates[3].count = 0; |
537 | rt = sc->sc_currates; | 518 | rates[1].idx = rates[2].idx = rates[3].idx = 0; |
519 | rates[0].count = ATH_TXMAXTRY; | ||
520 | } | ||
521 | |||
522 | /* get the cix for the lowest valid rix */ | ||
523 | rt = sc->hw_rate_table[sc->sc_curmode]; | ||
538 | for (i = 3; i >= 0; i--) { | 524 | for (i = 3; i >= 0; i--) { |
539 | if (rates[i].count) { | 525 | if (rates[i].count && (rates[i].idx >= 0)) { |
540 | rix = rates[i].idx; | 526 | rix = rates[i].idx; |
541 | break; | 527 | break; |
542 | } | 528 | } |
543 | } | 529 | } |
530 | |||
544 | flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)); | 531 | flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)); |
545 | cix = rt->info[rix].controlRate; | 532 | cix = rt->info[rix].ctrl_rate; |
546 | 533 | ||
547 | /* | 534 | /* |
548 | * If 802.11g protection is enabled, determine whether | 535 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or |
549 | * to use RTS/CTS or just CTS. Note that this is only | 536 | * just CTS. Note that this is only done for OFDM/HT unicast frames. |
550 | * done for OFDM/HT unicast frames. | ||
551 | */ | 537 | */ |
552 | if (sc->sc_protmode != PROT_M_NONE && | 538 | if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK) |
553 | (rt->info[rix].phy == PHY_OFDM || | 539 | && (rt->info[rix].phy == WLAN_PHY_OFDM || |
554 | rt->info[rix].phy == PHY_HT) && | 540 | WLAN_RC_PHY_HT(rt->info[rix].phy))) { |
555 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { | ||
556 | if (sc->sc_protmode == PROT_M_RTSCTS) | 541 | if (sc->sc_protmode == PROT_M_RTSCTS) |
557 | flags = ATH9K_TXDESC_RTSENA; | 542 | flags = ATH9K_TXDESC_RTSENA; |
558 | else if (sc->sc_protmode == PROT_M_CTSONLY) | 543 | else if (sc->sc_protmode == PROT_M_CTSONLY) |
559 | flags = ATH9K_TXDESC_CTSENA; | 544 | flags = ATH9K_TXDESC_CTSENA; |
560 | 545 | ||
561 | cix = rt->info[sc->sc_protrix].controlRate; | 546 | cix = rt->info[sc->sc_protrix].ctrl_rate; |
562 | rtsctsena = 1; | 547 | rtsctsena = 1; |
563 | } | 548 | } |
564 | 549 | ||
565 | /* For 11n, the default behavior is to enable RTS for | 550 | /* For 11n, the default behavior is to enable RTS for hw retried frames. |
566 | * hw retried frames. We enable the global flag here and | 551 | * We enable the global flag here and let rate series flags determine |
567 | * let rate series flags determine which rates will actually | 552 | * which rates will actually use RTS. |
568 | * use RTS. | ||
569 | */ | 553 | */ |
570 | if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { | 554 | if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { |
571 | /* | 555 | /* 802.11g protection not needed, use our default behavior */ |
572 | * 802.11g protection not needed, use our default behavior | ||
573 | */ | ||
574 | if (!rtsctsena) | 556 | if (!rtsctsena) |
575 | flags = ATH9K_TXDESC_RTSENA; | 557 | flags = ATH9K_TXDESC_RTSENA; |
576 | } | 558 | } |
577 | 559 | ||
578 | /* | 560 | /* Set protection if aggregate protection on */ |
579 | * Set protection if aggregate protection on | ||
580 | */ | ||
581 | if (sc->sc_config.ath_aggr_prot && | 561 | if (sc->sc_config.ath_aggr_prot && |
582 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { | 562 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { |
583 | flags = ATH9K_TXDESC_RTSENA; | 563 | flags = ATH9K_TXDESC_RTSENA; |
584 | cix = rt->info[sc->sc_protrix].controlRate; | 564 | cix = rt->info[sc->sc_protrix].ctrl_rate; |
585 | rtsctsena = 1; | 565 | rtsctsena = 1; |
586 | } | 566 | } |
587 | 567 | ||
588 | /* | 568 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ |
589 | * For AR5416 - RTS cannot be followed by a frame larger than 8K. | 569 | if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) |
590 | */ | ||
591 | if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) { | ||
592 | /* | ||
593 | * Ensure that in the case of SM Dynamic power save | ||
594 | * while we are bursting the second aggregate the | ||
595 | * RTS is cleared. | ||
596 | */ | ||
597 | flags &= ~(ATH9K_TXDESC_RTSENA); | 570 | flags &= ~(ATH9K_TXDESC_RTSENA); |
598 | } | ||
599 | |||
600 | /* | ||
601 | * CTS transmit rate is derived from the transmit rate | ||
602 | * by looking in the h/w rate table. We must also factor | ||
603 | * in whether or not a short preamble is to be used. | ||
604 | * NB: cix is set above where RTS/CTS is enabled | ||
605 | */ | ||
606 | BUG_ON(cix == 0xff); | ||
607 | ctsrate = rt->info[cix].rateCode | | ||
608 | (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0); | ||
609 | 571 | ||
610 | /* | 572 | /* |
611 | * Setup HAL rate series | 573 | * CTS transmit rate is derived from the transmit rate by looking in the |
574 | * h/w rate table. We must also factor in whether or not a short | ||
575 | * preamble is to be used. NB: cix is set above where RTS/CTS is enabled | ||
612 | */ | 576 | */ |
613 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | 577 | ctsrate = rt->info[cix].ratecode | |
578 | (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0); | ||
614 | 579 | ||
615 | for (i = 0; i < 4; i++) { | 580 | for (i = 0; i < 4; i++) { |
616 | if (!rates[i].count) | 581 | if (!rates[i].count || (rates[i].idx < 0)) |
617 | continue; | 582 | continue; |
618 | 583 | ||
619 | rix = rates[i].idx; | 584 | rix = rates[i].idx; |
620 | 585 | ||
621 | series[i].Rate = rt->info[rix].rateCode | | 586 | series[i].Rate = rt->info[rix].ratecode | |
622 | (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0); | 587 | (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0); |
623 | 588 | ||
624 | series[i].Tries = rates[i].count; | 589 | series[i].Tries = rates[i].count; |
625 | 590 | ||
@@ -645,13 +610,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
645 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 610 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; |
646 | } | 611 | } |
647 | 612 | ||
648 | /* | 613 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ |
649 | * set dur_update_en for l-sig computation except for PS-Poll frames | 614 | ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf), |
650 | */ | 615 | ctsrate, ctsduration, |
651 | ath9k_hw_set11n_ratescenario(ah, ds, lastds, | ||
652 | !bf_ispspoll(bf), | ||
653 | ctsrate, | ||
654 | ctsduration, | ||
655 | series, 4, flags); | 616 | series, 4, flags); |
656 | 617 | ||
657 | if (sc->sc_config.ath_aggr_prot && flags) | 618 | if (sc->sc_config.ath_aggr_prot && flags) |
@@ -662,7 +623,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
662 | * Function to send a normal HT (non-AMPDU) frame | 623 | * Function to send a normal HT (non-AMPDU) frame |
663 | * NB: must be called with txq lock held | 624 | * NB: must be called with txq lock held |
664 | */ | 625 | */ |
665 | |||
666 | static int ath_tx_send_normal(struct ath_softc *sc, | 626 | static int ath_tx_send_normal(struct ath_softc *sc, |
667 | struct ath_txq *txq, | 627 | struct ath_txq *txq, |
668 | struct ath_atx_tid *tid, | 628 | struct ath_atx_tid *tid, |
@@ -1256,7 +1216,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1256 | struct ath_atx_tid *tid) | 1216 | struct ath_atx_tid *tid) |
1257 | { | 1217 | { |
1258 | struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; | 1218 | struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; |
1259 | const struct ath9k_rate_table *rt = sc->sc_currates; | ||
1260 | struct sk_buff *skb; | 1219 | struct sk_buff *skb; |
1261 | struct ieee80211_tx_info *tx_info; | 1220 | struct ieee80211_tx_info *tx_info; |
1262 | struct ieee80211_tx_rate *rates; | 1221 | struct ieee80211_tx_rate *rates; |
@@ -1280,7 +1239,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1280 | 1239 | ||
1281 | for (i = 0; i < 4; i++) { | 1240 | for (i = 0; i < 4; i++) { |
1282 | if (rates[i].count) { | 1241 | if (rates[i].count) { |
1283 | if (rt->info[rates[i].idx].phy != PHY_HT) { | 1242 | if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) { |
1284 | legacy = 1; | 1243 | legacy = 1; |
1285 | break; | 1244 | break; |
1286 | } | 1245 | } |
@@ -1325,7 +1284,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1325 | struct ath_buf *bf, | 1284 | struct ath_buf *bf, |
1326 | u16 frmlen) | 1285 | u16 frmlen) |
1327 | { | 1286 | { |
1328 | const struct ath9k_rate_table *rt = sc->sc_currates; | 1287 | struct ath_rate_table *rt = sc->hw_rate_table[sc->sc_curmode]; |
1329 | struct sk_buff *skb = bf->bf_mpdu; | 1288 | struct sk_buff *skb = bf->bf_mpdu; |
1330 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1289 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1331 | u32 nsymbits, nsymbols, mpdudensity; | 1290 | u32 nsymbits, nsymbols, mpdudensity; |
@@ -1362,7 +1321,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1362 | 1321 | ||
1363 | rix = tx_info->control.rates[0].idx; | 1322 | rix = tx_info->control.rates[0].idx; |
1364 | flags = tx_info->control.rates[0].flags; | 1323 | flags = tx_info->control.rates[0].flags; |
1365 | rc = rt->info[rix].rateCode; | 1324 | rc = rt->info[rix].ratecode; |
1366 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; | 1325 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; |
1367 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; | 1326 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; |
1368 | 1327 | ||
@@ -1713,10 +1672,6 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | |||
1713 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | 1672 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; |
1714 | } | 1673 | } |
1715 | 1674 | ||
1716 | /* Rate series */ | ||
1717 | |||
1718 | setup_rate_retries(sc, skb); | ||
1719 | |||
1720 | /* Assign seqno, tidno */ | 1675 | /* Assign seqno, tidno */ |
1721 | 1676 | ||
1722 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) | 1677 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) |