aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:09 -0400
commit2e92e6f2c50b4baf85cca968f0e6f1b5c0df7d39 (patch)
treee845c2f3af6d29c807c540366b97b1d886b92c91
parent36d6825b91bc492b65b6333c369cd96a2fc8c903 (diff)
mac80211: use rate index in TX control
This patch modifies struct ieee80211_tx_control to give band info and the rate index (instead of rate pointers) to drivers. This mostly serves to reduce the TX control structure size to make it fit into skb->cb so that the fragmentation code can put it there and we can think about passing it to drivers that way in the future. The rt2x00 driver update was done by Ivo, thanks. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/adm8211.c6
-rw-r--r--drivers/net/wireless/ath5k/base.c8
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c13
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c2
-rw-r--r--drivers/net/wireless/p54/p54common.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c9
-rw-r--r--drivers/net/wireless/rtl8180_dev.c19
-rw-r--r--drivers/net/wireless/rtl8187_dev.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c7
-rw-r--r--include/net/mac80211.h51
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/mlme.c6
-rw-r--r--net/mac80211/rate.c12
-rw-r--r--net/mac80211/rate.h25
-rw-r--r--net/mac80211/rc80211_pid_algo.c6
-rw-r--r--net/mac80211/tx.c104
-rw-r--r--net/mac80211/util.c10
25 files changed, 205 insertions, 151 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 79dfca546c89..22db664a58d9 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1693,10 +1693,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
1693 size_t payload_len, hdrlen; 1693 size_t payload_len, hdrlen;
1694 int plcp, dur, len, plcp_signal, short_preamble; 1694 int plcp, dur, len, plcp_signal, short_preamble;
1695 struct ieee80211_hdr *hdr; 1695 struct ieee80211_hdr *hdr;
1696 struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, control);
1696 1697
1697 short_preamble = !!(control->tx_rate->flags & 1698 short_preamble = !!(txrate->flags & IEEE80211_TXCTL_SHORT_PREAMBLE);
1698 IEEE80211_TXCTL_SHORT_PREAMBLE); 1699 plcp_signal = txrate->bitrate;
1699 plcp_signal = control->tx_rate->bitrate;
1700 1700
1701 hdr = (struct ieee80211_hdr *)skb->data; 1701 hdr = (struct ieee80211_hdr *)skb->data;
1702 fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; 1702 fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 3f16ad66bdb5..32ee351a7650 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1323,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1323 1323
1324 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1324 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1325 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1325 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1326 (sc->power_level * 2), ctl->tx_rate->hw_value, 1326 (sc->power_level * 2),
1327 ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
1327 ctl->retry_limit, keyidx, 0, flags, 0, 0); 1328 ctl->retry_limit, keyidx, 0, flags, 0, 0);
1328 if (ret) 1329 if (ret)
1329 goto err_unmap; 1330 goto err_unmap;
@@ -2046,7 +2047,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
2046 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2047 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2047 ieee80211_get_hdrlen_from_skb(skb), 2048 ieee80211_get_hdrlen_from_skb(skb),
2048 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2049 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2049 ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID, 2050 ieee80211_get_tx_rate(sc->hw, ctl)->hw_value,
2051 1, AR5K_TXKEYIX_INVALID,
2050 antenna, flags, 0, 0); 2052 antenna, flags, 0, 0);
2051 if (ret) 2053 if (ret)
2052 goto err_unmap; 2054 goto err_unmap;
@@ -2654,7 +2656,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
2654 memmove(skb->data, skb->data+pad, hdrlen); 2656 memmove(skb->data, skb->data+pad, hdrlen);
2655 } 2657 }
2656 2658
2657 sc->led_txrate = ctl->tx_rate->hw_value; 2659 sc->led_txrate = ieee80211_get_tx_rate(hw, ctl)->hw_value;
2658 2660
2659 spin_lock_irqsave(&sc->txbuflock, flags); 2661 spin_lock_irqsave(&sc->txbuflock, flags);
2660 if (list_empty(&sc->txbuf)) { 2662 if (list_empty(&sc->txbuf)) {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9445a604a966..e428645352b4 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1372,7 +1372,7 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1372 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); 1372 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
1373 len = min((size_t) dev->wl->current_beacon->len, 1373 len = min((size_t) dev->wl->current_beacon->len,
1374 0x200 - sizeof(struct b43_plcp_hdr6)); 1374 0x200 - sizeof(struct b43_plcp_hdr6));
1375 rate = dev->wl->beacon_txctl.tx_rate->hw_value; 1375 rate = ieee80211_get_tx_rate(dev->wl->hw, &dev->wl->beacon_txctl)->hw_value;
1376 1376
1377 b43_write_template_common(dev, (const u8 *)bcn, 1377 b43_write_template_common(dev, (const u8 *)bcn,
1378 len, ram_offset, shm_size_offset, rate); 1378 len, ram_offset, shm_size_offset, rate);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index afce9338d83a..9b682a3cf5e4 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -201,13 +201,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
201 u32 mac_ctl = 0; 201 u32 mac_ctl = 0;
202 u16 phy_ctl = 0; 202 u16 phy_ctl = 0;
203 u8 extra_ft = 0; 203 u8 extra_ft = 0;
204 struct ieee80211_rate *txrate;
204 205
205 memset(txhdr, 0, sizeof(*txhdr)); 206 memset(txhdr, 0, sizeof(*txhdr));
206 207
207 WARN_ON(!txctl->tx_rate); 208 txrate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
208 rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB; 209 rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
209 rate_ofdm = b43_is_ofdm_rate(rate); 210 rate_ofdm = b43_is_ofdm_rate(rate);
210 fbrate = txctl->alt_retry_rate ? : txctl->tx_rate; 211 fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : txrate;
211 rate_fb = fbrate->hw_value; 212 rate_fb = fbrate->hw_value;
212 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); 213 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
213 214
@@ -336,9 +337,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
336 int rts_rate, rts_rate_fb; 337 int rts_rate, rts_rate_fb;
337 int rts_rate_ofdm, rts_rate_fb_ofdm; 338 int rts_rate_ofdm, rts_rate_fb_ofdm;
338 struct b43_plcp_hdr6 *plcp; 339 struct b43_plcp_hdr6 *plcp;
340 struct ieee80211_rate *rts_cts_rate;
339 341
340 WARN_ON(!txctl->rts_cts_rate); 342 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl);
341 rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB; 343
344 rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
342 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); 345 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
343 rts_rate_fb = b43_calc_fallback_rate(rts_rate); 346 rts_rate_fb = b43_calc_fallback_rate(rts_rate);
344 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 347 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index bed9e041d6c5..55dc251bf510 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -201,15 +201,18 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
201 unsigned int plcp_fragment_len; 201 unsigned int plcp_fragment_len;
202 u32 mac_ctl = 0; 202 u32 mac_ctl = 0;
203 u16 phy_ctl = 0; 203 u16 phy_ctl = 0;
204 struct ieee80211_rate *tx_rate;
204 205
205 wlhdr = (const struct ieee80211_hdr *)fragment_data; 206 wlhdr = (const struct ieee80211_hdr *)fragment_data;
206 fctl = le16_to_cpu(wlhdr->frame_control); 207 fctl = le16_to_cpu(wlhdr->frame_control);
207 208
208 memset(txhdr, 0, sizeof(*txhdr)); 209 memset(txhdr, 0, sizeof(*txhdr));
209 210
210 rate = txctl->tx_rate->hw_value; 211 tx_rate = ieee80211_get_tx_rate(dev->wl->hw, txctl);
212
213 rate = tx_rate->hw_value;
211 rate_ofdm = b43legacy_is_ofdm_rate(rate); 214 rate_ofdm = b43legacy_is_ofdm_rate(rate);
212 rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate; 215 rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, txctl) ? : tx_rate;
213 rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); 216 rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
214 217
215 txhdr->mac_frame_ctl = wlhdr->frame_control; 218 txhdr->mac_frame_ctl = wlhdr->frame_control;
@@ -312,7 +315,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
312 int rts_rate_ofdm; 315 int rts_rate_ofdm;
313 int rts_rate_fb_ofdm; 316 int rts_rate_fb_ofdm;
314 317
315 rts_rate = txctl->rts_cts_rate->hw_value; 318 rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, txctl)->hw_value;
316 rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); 319 rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
317 rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); 320 rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
318 rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); 321 rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index e51eeeff6992..f3ca02fe9619 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -464,7 +464,7 @@ static void rs_tx_status(void *priv_rate,
464 464
465 465
466 retries = tx_resp->retry_count; 466 retries = tx_resp->retry_count;
467 first_index = tx_resp->control.tx_rate->hw_value; 467 first_index = sband->bitrates[tx_resp->control.tx_rate_idx].hw_value;
468 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { 468 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
469 IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); 469 IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
470 return; 470 return;
@@ -669,7 +669,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
669 is_multicast_ether_addr(hdr->addr1) || 669 is_multicast_ether_addr(hdr->addr1) ||
670 !sta || !sta->rate_ctrl_priv) { 670 !sta || !sta->rate_ctrl_priv) {
671 IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); 671 IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
672 sel->rate = rate_lowest(local, sband, sta); 672 sel->rate_idx = rate_lowest_index(local, sband, sta);
673 rcu_read_unlock(); 673 rcu_read_unlock();
674 return; 674 return;
675 } 675 }
@@ -813,7 +813,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
813 813
814 IWL_DEBUG_RATE("leave: %d\n", index); 814 IWL_DEBUG_RATE("leave: %d\n", index);
815 815
816 sel->rate = &sband->bitrates[sta->txrate_idx]; 816 sel->rate_idx = sta->txrate_idx;
817} 817}
818 818
819static struct rate_control_ops rs_ops = { 819static struct rate_control_ops rs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index ad4e7b74ca24..f8e691f88ab3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -331,7 +331,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
331 tx_resp->rate, tx_resp->failure_frame); 331 tx_resp->rate, tx_resp->failure_frame);
332 332
333 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); 333 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
334 tx_status->control.tx_rate = &priv->ieee_rates[rate_idx]; 334 if (tx_status->control.band == IEEE80211_BAND_5GHZ)
335 rate_idx -= IWL_FIRST_OFDM_RATE;
336 tx_status->control.tx_rate_idx = rate_idx;
335 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); 337 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
336 iwl3945_tx_queue_reclaim(priv, txq_id, index); 338 iwl3945_tx_queue_reclaim(priv, txq_id, index);
337 339
@@ -962,7 +964,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
962 struct ieee80211_hdr *hdr, int sta_id, int tx_id) 964 struct ieee80211_hdr *hdr, int sta_id, int tx_id)
963{ 965{
964 unsigned long flags; 966 unsigned long flags;
965 u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); 967 u16 hw_value = ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value;
968 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
966 u16 rate_mask; 969 u16 rate_mask;
967 int rate; 970 int rate;
968 u8 rts_retry_limit; 971 u8 rts_retry_limit;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 2adc2281c77c..7993a1d83025 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -862,7 +862,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
862 if (priv->band == IEEE80211_BAND_5GHZ) 862 if (priv->band == IEEE80211_BAND_5GHZ)
863 rs_index -= IWL_FIRST_OFDM_RATE; 863 rs_index -= IWL_FIRST_OFDM_RATE;
864 864
865 if ((tx_resp->control.tx_rate == NULL) || 865 if ((tx_resp->control.tx_rate_idx < 0) ||
866 (tbl_type.is_SGI ^ 866 (tbl_type.is_SGI ^
867 !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) || 867 !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) ||
868 (tbl_type.is_fat ^ 868 (tbl_type.is_fat ^
@@ -875,7 +875,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
875 (!!(tx_rate & RATE_MCS_GF_MSK) ^ 875 (!!(tx_rate & RATE_MCS_GF_MSK) ^
876 !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || 876 !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
877 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != 877 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
878 tx_resp->control.tx_rate->bitrate)) { 878 hw->wiphy->bands[tx_resp->control.band]->bitrates[tx_resp->control.tx_rate_idx].bitrate)) {
879 IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate); 879 IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
880 goto out; 880 goto out;
881 } 881 }
@@ -2154,7 +2154,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2154 fc = le16_to_cpu(hdr->frame_control); 2154 fc = le16_to_cpu(hdr->frame_control);
2155 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || 2155 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
2156 !sta || !sta->rate_ctrl_priv) { 2156 !sta || !sta->rate_ctrl_priv) {
2157 sel->rate = rate_lowest(local, sband, sta); 2157 sel->rate_idx = rate_lowest_index(local, sband, sta);
2158 goto out; 2158 goto out;
2159 } 2159 }
2160 2160
@@ -2184,11 +2184,13 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2184 2184
2185done: 2185done:
2186 if ((i < 0) || (i > IWL_RATE_COUNT)) { 2186 if ((i < 0) || (i > IWL_RATE_COUNT)) {
2187 sel->rate = rate_lowest(local, sband, sta); 2187 sel->rate_idx = rate_lowest_index(local, sband, sta);
2188 goto out; 2188 goto out;
2189 } 2189 }
2190 2190
2191 sel->rate = &priv->ieee_rates[i]; 2191 if (sband->band == IEEE80211_BAND_5GHZ)
2192 i -= IWL_FIRST_OFDM_RATE;
2193 sel->rate_idx = i;
2192out: 2194out:
2193 rcu_read_unlock(); 2195 rcu_read_unlock();
2194} 2196}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index f848a5b0f622..fb670b5cfebb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -373,14 +373,10 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
373 control->flags |= IEEE80211_TXCTL_DUP_DATA; 373 control->flags |= IEEE80211_TXCTL_DUP_DATA;
374 if (rate_n_flags & RATE_MCS_SGI_MSK) 374 if (rate_n_flags & RATE_MCS_SGI_MSK)
375 control->flags |= IEEE80211_TXCTL_SHORT_GI; 375 control->flags |= IEEE80211_TXCTL_SHORT_GI;
376 /* since iwl4965_hwrate_to_plcp_idx is band indifferent, we always use
377 * IEEE80211_BAND_2GHZ band as it contains all the rates */
378 rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags); 376 rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
379 if (rate_index == -1) 377 if (control->band == IEEE80211_BAND_5GHZ)
380 control->tx_rate = NULL; 378 rate_index -= IWL_FIRST_OFDM_RATE;
381 else 379 control->tx_rate_idx = rate_index;
382 control->tx_rate =
383 &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index];
384} 380}
385 381
386int iwl4965_hw_rxq_stop(struct iwl_priv *priv) 382int iwl4965_hw_rxq_stop(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index f32cddabdf64..4b5149c8c32e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -578,7 +578,10 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
578 u8 data_retry_limit = 0; 578 u8 data_retry_limit = 0;
579 u8 rate_plcp; 579 u8 rate_plcp;
580 u16 rate_flags = 0; 580 u16 rate_flags = 0;
581 int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); 581 int rate_idx;
582
583 rate_idx = min(ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value & 0xffff,
584 IWL_RATE_COUNT - 1);
582 585
583 rate_plcp = iwl_rates[rate_idx].plcp; 586 rate_plcp = iwl_rates[rate_idx].plcp;
584 587
@@ -723,7 +726,8 @@ int iwl_tx_skb(struct iwl_priv *priv,
723 goto drop_unlock; 726 goto drop_unlock;
724 } 727 }
725 728
726 if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { 729 if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) ==
730 IWL_INVALID_RATE) {
727 IWL_ERROR("ERROR: No TX rate available.\n"); 731 IWL_ERROR("ERROR: No TX rate available.\n");
728 goto drop_unlock; 732 goto drop_unlock;
729 } 733 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 54cde8a7b5fa..a28b4c9f6524 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2581,7 +2581,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
2581 goto drop_unlock; 2581 goto drop_unlock;
2582 } 2582 }
2583 2583
2584 if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { 2584 if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) == IWL_INVALID_RATE) {
2585 IWL_ERROR("ERROR: No TX rate available.\n"); 2585 IWL_ERROR("ERROR: No TX rate available.\n");
2586 goto drop_unlock; 2586 goto drop_unlock;
2587 } 2587 }
@@ -6694,7 +6694,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
6694 } 6694 }
6695 6695
6696 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, 6696 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
6697 ctl->tx_rate->bitrate); 6697 ieee80211_get_tx_rate(hw, ctl)->bitrate);
6698 6698
6699 if (iwl3945_tx_skb(priv, skb, ctl)) 6699 if (iwl3945_tx_skb(priv, skb, ctl))
6700 dev_kfree_skb_any(skb); 6700 dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index db4f606bad50..1fad6227aa51 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -4281,7 +4281,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
4281 } 4281 }
4282 4282
4283 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, 4283 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
4284 ctl->tx_rate->bitrate); 4284 ieee80211_get_tx_rate(hw, ctl)->bitrate);
4285 4285
4286 if (iwl_tx_skb(priv, skb, ctl)) 4286 if (iwl_tx_skb(priv, skb, ctl))
4287 dev_kfree_skb_any(skb); 4287 dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 3d35fe6a8f5f..3ca9386561ff 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -592,7 +592,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
592 txhdr->padding2 = 0; 592 txhdr->padding2 = 0;
593 593
594 /* TODO: add support for alternate retry TX rates */ 594 /* TODO: add support for alternate retry TX rates */
595 rate = control->tx_rate->hw_value; 595 rate = ieee80211_get_tx_rate(dev, control)->hw_value;
596 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) 596 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
597 rate |= 0x10; 597 rate |= 0x10;
598 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) 598 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 19c10629c767..5cf4c2f59260 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -33,8 +33,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
33 struct txentry_desc *txdesc, 33 struct txentry_desc *txdesc,
34 struct ieee80211_tx_control *control) 34 struct ieee80211_tx_control *control)
35{ 35{
36 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
36 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 37 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
37 struct ieee80211_rate *rate = control->tx_rate; 38 struct ieee80211_rate *rate =
39 ieee80211_get_tx_rate(rt2x00dev->hw, control);
38 const struct rt2x00_rate *hwrate; 40 const struct rt2x00_rate *hwrate;
39 unsigned int data_length; 41 unsigned int data_length;
40 unsigned int duration; 42 unsigned int duration;
@@ -77,8 +79,9 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
77 __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); 79 __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
78 __clear_bit(ENTRY_TXD_ACK, &txdesc->flags); 80 __clear_bit(ENTRY_TXD_ACK, &txdesc->flags);
79 } 81 }
80 if (control->rts_cts_rate) 82 if (control->rts_cts_rate_idx >= 0)
81 rate = control->rts_cts_rate; 83 rate =
84 ieee80211_get_rts_cts_rate(rt2x00dev->hw, control);
82 } 85 }
83 86
84 /* 87 /*
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index c220998cee65..6263209b889e 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -257,24 +257,21 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
257 mapping = pci_map_single(priv->pdev, skb->data, 257 mapping = pci_map_single(priv->pdev, skb->data,
258 skb->len, PCI_DMA_TODEVICE); 258 skb->len, PCI_DMA_TODEVICE);
259 259
260 BUG_ON(!control->tx_rate);
261
262 tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | 260 tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
263 RTL8180_TX_DESC_FLAG_LS | 261 RTL8180_TX_DESC_FLAG_LS |
264 (control->tx_rate->hw_value << 24) | skb->len; 262 (ieee80211_get_tx_rate(dev, control)->hw_value << 24) |
263 skb->len;
265 264
266 if (priv->r8185) 265 if (priv->r8185)
267 tx_flags |= RTL8180_TX_DESC_FLAG_DMA | 266 tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
268 RTL8180_TX_DESC_FLAG_NO_ENC; 267 RTL8180_TX_DESC_FLAG_NO_ENC;
269 268
270 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { 269 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
271 BUG_ON(!control->rts_cts_rate);
272 tx_flags |= RTL8180_TX_DESC_FLAG_RTS; 270 tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
273 tx_flags |= control->rts_cts_rate->hw_value << 19; 271 tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
274 } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { 272 } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
275 BUG_ON(!control->rts_cts_rate);
276 tx_flags |= RTL8180_TX_DESC_FLAG_CTS; 273 tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
277 tx_flags |= control->rts_cts_rate->hw_value << 19; 274 tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
278 } 275 }
279 276
280 *((struct ieee80211_tx_control **) skb->cb) = 277 *((struct ieee80211_tx_control **) skb->cb) =
@@ -288,9 +285,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
288 unsigned int remainder; 285 unsigned int remainder;
289 286
290 plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), 287 plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
291 (control->tx_rate->bitrate * 2) / 10); 288 (ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
292 remainder = (16 * (skb->len + 4)) % 289 remainder = (16 * (skb->len + 4)) %
293 ((control->tx_rate->bitrate * 2) / 10); 290 ((ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10);
294 if (remainder > 0 && remainder <= 6) 291 if (remainder > 0 && remainder <= 6)
295 plcp_len |= 1 << 15; 292 plcp_len |= 1 << 15;
296 } 293 }
@@ -303,8 +300,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
303 entry->plcp_len = cpu_to_le16(plcp_len); 300 entry->plcp_len = cpu_to_le16(plcp_len);
304 entry->tx_buf = cpu_to_le32(mapping); 301 entry->tx_buf = cpu_to_le32(mapping);
305 entry->frame_len = cpu_to_le32(skb->len); 302 entry->frame_len = cpu_to_le32(skb->len);
306 entry->flags2 = control->alt_retry_rate != NULL ? 303 entry->flags2 = control->alt_retry_rate_idx >= 0 ?
307 control->alt_retry_rate->bitrate << 4 : 0; 304 ieee80211_get_alt_retry_rate(dev, control)->bitrate << 4 : 0;
308 entry->retry_limit = control->retry_limit; 305 entry->retry_limit = control->retry_limit;
309 entry->flags = cpu_to_le32(tx_flags); 306 entry->flags = cpu_to_le32(tx_flags);
310 __skb_queue_tail(&ring->queue, skb); 307 __skb_queue_tail(&ring->queue, skb);
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e14c84248686..86a09b49681c 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -179,21 +179,17 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
179 flags = skb->len; 179 flags = skb->len;
180 flags |= RTL8187_TX_FLAG_NO_ENCRYPT; 180 flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
181 181
182 BUG_ON(!control->tx_rate); 182 flags |= ieee80211_get_tx_rate(dev, control)->hw_value << 24;
183
184 flags |= control->tx_rate->hw_value << 24;
185 if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) 183 if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
186 flags |= RTL8187_TX_FLAG_MORE_FRAG; 184 flags |= RTL8187_TX_FLAG_MORE_FRAG;
187 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { 185 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
188 BUG_ON(!control->rts_cts_rate);
189 flags |= RTL8187_TX_FLAG_RTS; 186 flags |= RTL8187_TX_FLAG_RTS;
190 flags |= control->rts_cts_rate->hw_value << 19; 187 flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
191 rts_dur = ieee80211_rts_duration(dev, priv->vif, 188 rts_dur = ieee80211_rts_duration(dev, priv->vif,
192 skb->len, control); 189 skb->len, control);
193 } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { 190 } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
194 BUG_ON(!control->rts_cts_rate);
195 flags |= RTL8187_TX_FLAG_CTS; 191 flags |= RTL8187_TX_FLAG_CTS;
196 flags |= control->rts_cts_rate->hw_value << 19; 192 flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19;
197 } 193 }
198 194
199 hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); 195 hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 0c736735e217..99c508c09e5b 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -523,14 +523,17 @@ static int fill_ctrlset(struct zd_mac *mac,
523 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 523 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
524 unsigned int frag_len = skb->len + FCS_LEN; 524 unsigned int frag_len = skb->len + FCS_LEN;
525 unsigned int packet_length; 525 unsigned int packet_length;
526 struct ieee80211_rate *txrate;
526 struct zd_ctrlset *cs = (struct zd_ctrlset *) 527 struct zd_ctrlset *cs = (struct zd_ctrlset *)
527 skb_push(skb, sizeof(struct zd_ctrlset)); 528 skb_push(skb, sizeof(struct zd_ctrlset));
528 529
529 ZD_ASSERT(frag_len <= 0xffff); 530 ZD_ASSERT(frag_len <= 0xffff);
530 531
531 cs->modulation = control->tx_rate->hw_value; 532 txrate = ieee80211_get_tx_rate(mac->hw, control);
533
534 cs->modulation = txrate->hw_value;
532 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) 535 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
533 cs->modulation = control->tx_rate->hw_value_short; 536 cs->modulation = txrate->hw_value_short;
534 537
535 cs->tx_length = cpu_to_le16(frag_len); 538 cs->tx_length = cpu_to_le16(frag_len);
536 539
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f00fc76a7344..0df91bea6c1f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -266,27 +266,26 @@ enum mac80211_tx_control_flags {
266 * ieee80211_ops->remove_interface() callback funtion. 266 * ieee80211_ops->remove_interface() callback funtion.
267 * The hw_key pointer is valid until it has been removed with the 267 * The hw_key pointer is valid until it has been removed with the
268 * ieee80211_ops->set_key() callback function. 268 * ieee80211_ops->set_key() callback function.
269 * The tx_rate and alt_retry_rate pointers are valid until the phy is
270 * deregistered.
271 */ 269 */
272struct ieee80211_tx_control { 270struct ieee80211_tx_control {
273 struct ieee80211_vif *vif; 271 u32 flags; /* tx control flags defined above */
274 struct ieee80211_rate *tx_rate; 272
273 s8 tx_rate_idx, /* Transmit rate (indexes registered rates) */
274 rts_cts_rate_idx, /* Transmit rate for RTS/CTS frame */
275 alt_retry_rate_idx; /* retry rate for the last retries */
275 276
276 /* Transmit rate for RTS/CTS frame */ 277 s8 retry_limit; /* 1 = only first attempt, 2 = one retry, ..
277 struct ieee80211_rate *rts_cts_rate; 278 * This could be used when set_retry_limit
279 * is not implemented by the driver */
278 280
279 /* retry rate for the last retries */ 281 struct ieee80211_vif *vif;
280 struct ieee80211_rate *alt_retry_rate;
281 282
282 /* Key used for hardware encryption 283 /* Key used for hardware encryption
283 * NULL if IEEE80211_TXCTL_DO_NOT_ENCRYPT is set */ 284 * NULL if IEEE80211_TXCTL_DO_NOT_ENCRYPT is set */
284 struct ieee80211_key_conf *hw_key; 285 struct ieee80211_key_conf *hw_key;
285 286
286 u32 flags; /* tx control flags defined above */ 287 enum ieee80211_band band;
287 u8 retry_limit; /* 1 = only first attempt, 2 = one retry, .. 288
288 * This could be used when set_retry_limit
289 * is not implemented by the driver */
290 u8 antenna_sel_tx; /* 0 = default/diversity, otherwise bit 289 u8 antenna_sel_tx; /* 0 = default/diversity, otherwise bit
291 * position represents antenna number used */ 290 * position represents antenna number used */
292 u8 icv_len; /* length of the ICV/MIC field in octets */ 291 u8 icv_len; /* length of the ICV/MIC field in octets */
@@ -298,6 +297,7 @@ struct ieee80211_tx_control {
298}; 297};
299 298
300 299
300
301/** 301/**
302 * enum mac80211_rx_flags - receive flags 302 * enum mac80211_rx_flags - receive flags
303 * 303 *
@@ -823,6 +823,33 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
823 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN); 823 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
824} 824}
825 825
826static inline struct ieee80211_rate *
827ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
828 const struct ieee80211_tx_control *c)
829{
830 if (WARN_ON(c->tx_rate_idx < 0))
831 return NULL;
832 return &hw->wiphy->bands[c->band]->bitrates[c->tx_rate_idx];
833}
834
835static inline struct ieee80211_rate *
836ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
837 const struct ieee80211_tx_control *c)
838{
839 if (c->rts_cts_rate_idx < 0)
840 return NULL;
841 return &hw->wiphy->bands[c->band]->bitrates[c->rts_cts_rate_idx];
842}
843
844static inline struct ieee80211_rate *
845ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
846 const struct ieee80211_tx_control *c)
847{
848 if (c->alt_retry_rate_idx < 0)
849 return NULL;
850 return &hw->wiphy->bands[c->band]->bitrates[c->alt_retry_rate_idx];
851}
852
826/** 853/**
827 * DOC: Hardware crypto acceleration 854 * DOC: Hardware crypto acceleration
828 * 855 *
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ed0d9b35ae6f..a4cccd1b7d53 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -159,11 +159,11 @@ struct ieee80211_tx_data {
159 159
160 struct ieee80211_tx_control *control; 160 struct ieee80211_tx_control *control;
161 struct ieee80211_channel *channel; 161 struct ieee80211_channel *channel;
162 struct ieee80211_rate *rate; 162 s8 rate_idx;
163 /* use this rate (if set) for last fragment; rate can 163 /* use this rate (if set) for last fragment; rate can
164 * be set to lower rate for the first fragments, e.g., 164 * be set to lower rate for the first fragments, e.g.,
165 * when using CTS protection with IEEE 802.11g. */ 165 * when using CTS protection with IEEE 802.11g. */
166 struct ieee80211_rate *last_frag_rate; 166 s8 last_frag_rate_idx;
167 167
168 /* Extra fragments (in addition to the first fragment 168 /* Extra fragments (in addition to the first fragment
169 * in skb) */ 169 * in skb) */
@@ -225,9 +225,9 @@ struct ieee80211_tx_stored_packet {
225 struct ieee80211_tx_control control; 225 struct ieee80211_tx_control control;
226 struct sk_buff *skb; 226 struct sk_buff *skb;
227 struct sk_buff **extra_frag; 227 struct sk_buff **extra_frag;
228 struct ieee80211_rate *last_frag_rate; 228 s8 last_frag_rate_idx;
229 int num_extra_frag; 229 int num_extra_frag;
230 unsigned int last_frag_rate_ctrl_probe; 230 bool last_frag_rate_ctrl_probe;
231}; 231};
232 232
233struct beacon_data { 233struct beacon_data {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7877d3b3f4cb..604149369dc9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2406,15 +2406,15 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2406 2406
2407 memset(&control, 0, sizeof(control)); 2407 memset(&control, 0, sizeof(control));
2408 rate_control_get_rate(dev, sband, skb, &ratesel); 2408 rate_control_get_rate(dev, sband, skb, &ratesel);
2409 if (!ratesel.rate) { 2409 if (ratesel.rate_idx < 0) {
2410 printk(KERN_DEBUG "%s: Failed to determine TX rate " 2410 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2411 "for IBSS beacon\n", dev->name); 2411 "for IBSS beacon\n", dev->name);
2412 break; 2412 break;
2413 } 2413 }
2414 control.vif = &sdata->vif; 2414 control.vif = &sdata->vif;
2415 control.tx_rate = ratesel.rate; 2415 control.tx_rate_idx = ratesel.rate_idx;
2416 if (sdata->bss_conf.use_short_preamble && 2416 if (sdata->bss_conf.use_short_preamble &&
2417 ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 2417 sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
2418 control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 2418 control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
2419 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2419 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2420 control.flags |= IEEE80211_TXCTL_NO_ACK; 2420 control.flags |= IEEE80211_TXCTL_NO_ACK;
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 841df93807fc..0388c090dfe9 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev,
176 rcu_read_lock(); 176 rcu_read_lock();
177 sta = sta_info_get(local, hdr->addr1); 177 sta = sta_info_get(local, hdr->addr1);
178 178
179 memset(sel, 0, sizeof(struct rate_selection)); 179 sel->rate_idx = -1;
180 sel->nonerp_idx = -1;
181 sel->probe_idx = -1;
180 182
181 ref->ops->get_rate(ref->priv, dev, sband, skb, sel); 183 ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
182 184
185 BUG_ON(sel->rate_idx < 0);
186
183 /* Select a non-ERP backup rate. */ 187 /* Select a non-ERP backup rate. */
184 if (!sel->nonerp) { 188 if (sel->nonerp_idx < 0) {
185 for (i = 0; i < sband->n_bitrates; i++) { 189 for (i = 0; i < sband->n_bitrates; i++) {
186 struct ieee80211_rate *rate = &sband->bitrates[i]; 190 struct ieee80211_rate *rate = &sband->bitrates[i];
187 if (sel->rate->bitrate < rate->bitrate) 191 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
188 break; 192 break;
189 193
190 if (rate_supported(sta, sband->band, i) && 194 if (rate_supported(sta, sband->band, i) &&
191 !(rate->flags & IEEE80211_RATE_ERP_G)) 195 !(rate->flags & IEEE80211_RATE_ERP_G))
192 sel->nonerp = rate; 196 sel->nonerp_idx = i;
193 } 197 }
194 } 198 }
195 199
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 5b45f33cb766..a29148dcca99 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -19,14 +19,15 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "sta_info.h" 20#include "sta_info.h"
21 21
22/* TODO: kdoc */ 22/**
23 * struct rate_selection - rate selection for rate control algos
24 * @rate: selected transmission rate index
25 * @nonerp: Non-ERP rate to use instead if ERP cannot be used
26 * @probe: rate for probing (or -1)
27 *
28 */
23struct rate_selection { 29struct rate_selection {
24 /* Selected transmission rate */ 30 s8 rate_idx, nonerp_idx, probe_idx;
25 struct ieee80211_rate *rate;
26 /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
27 struct ieee80211_rate *nonerp;
28 /* probe with this rate, or NULL for no probing */
29 struct ieee80211_rate *probe;
30}; 31};
31 32
32struct rate_control_ops { 33struct rate_control_ops {
@@ -138,7 +139,7 @@ static inline int rate_supported(struct sta_info *sta,
138 return (sta == NULL || sta->supp_rates[band] & BIT(index)); 139 return (sta == NULL || sta->supp_rates[band] & BIT(index));
139} 140}
140 141
141static inline int 142static inline s8
142rate_lowest_index(struct ieee80211_local *local, 143rate_lowest_index(struct ieee80211_local *local,
143 struct ieee80211_supported_band *sband, 144 struct ieee80211_supported_band *sband,
144 struct sta_info *sta) 145 struct sta_info *sta)
@@ -155,14 +156,6 @@ rate_lowest_index(struct ieee80211_local *local,
155 return 0; 156 return 0;
156} 157}
157 158
158static inline struct ieee80211_rate *
159rate_lowest(struct ieee80211_local *local,
160 struct ieee80211_supported_band *sband,
161 struct sta_info *sta)
162{
163 return &sband->bitrates[rate_lowest_index(local, sband, sta)];
164}
165
166 159
167/* functions for rate control related to a device */ 160/* functions for rate control related to a device */
168int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 161int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a849b745bdb5..14cde36f5070 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -266,7 +266,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
266 266
267 /* Ignore all frames that were sent with a different rate than the rate 267 /* Ignore all frames that were sent with a different rate than the rate
268 * we currently advise mac80211 to use. */ 268 * we currently advise mac80211 to use. */
269 if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) 269 if (status->control.tx_rate_idx != sta->txrate_idx)
270 goto unlock; 270 goto unlock;
271 271
272 spinfo = sta->rate_ctrl_priv; 272 spinfo = sta->rate_ctrl_priv;
@@ -330,7 +330,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
330 fc = le16_to_cpu(hdr->frame_control); 330 fc = le16_to_cpu(hdr->frame_control);
331 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 331 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
332 is_multicast_ether_addr(hdr->addr1) || !sta) { 332 is_multicast_ether_addr(hdr->addr1) || !sta) {
333 sel->rate = rate_lowest(local, sband, sta); 333 sel->rate_idx = rate_lowest_index(local, sband, sta);
334 rcu_read_unlock(); 334 rcu_read_unlock();
335 return; 335 return;
336 } 336 }
@@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
349 349
350 rcu_read_unlock(); 350 rcu_read_unlock();
351 351
352 sel->rate = &sband->bitrates[rateidx]; 352 sel->rate_idx = rateidx;
353 353
354#ifdef CONFIG_MAC80211_DEBUGFS 354#ifdef CONFIG_MAC80211_DEBUGFS
355 rate_control_pid_event_tx_rate( 355 rate_control_pid_event_tx_rate(
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index aecec2a72b08..99c3860bc0e2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -91,11 +91,12 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
91 int next_frag_len) 91 int next_frag_len)
92{ 92{
93 int rate, mrate, erp, dur, i; 93 int rate, mrate, erp, dur, i;
94 struct ieee80211_rate *txrate = tx->rate; 94 struct ieee80211_rate *txrate;
95 struct ieee80211_local *local = tx->local; 95 struct ieee80211_local *local = tx->local;
96 struct ieee80211_supported_band *sband; 96 struct ieee80211_supported_band *sband;
97 97
98 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 98 sband = local->hw.wiphy->bands[tx->channel->band];
99 txrate = &sband->bitrates[tx->rate_idx];
99 100
100 erp = 0; 101 erp = 0;
101 if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 102 if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -610,40 +611,40 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
610 struct rate_selection rsel; 611 struct rate_selection rsel;
611 struct ieee80211_supported_band *sband; 612 struct ieee80211_supported_band *sband;
612 613
613 sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; 614 sband = tx->local->hw.wiphy->bands[tx->channel->band];
614 615
615 if (likely(!tx->rate)) { 616 if (likely(tx->rate_idx < 0)) {
616 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); 617 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
617 tx->rate = rsel.rate; 618 tx->rate_idx = rsel.rate_idx;
618 if (unlikely(rsel.probe)) { 619 if (unlikely(rsel.probe_idx >= 0)) {
619 tx->control->flags |= 620 tx->control->flags |=
620 IEEE80211_TXCTL_RATE_CTRL_PROBE; 621 IEEE80211_TXCTL_RATE_CTRL_PROBE;
621 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; 622 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
622 tx->control->alt_retry_rate = tx->rate; 623 tx->control->alt_retry_rate_idx = tx->rate_idx;
623 tx->rate = rsel.probe; 624 tx->rate_idx = rsel.probe_idx;
624 } else 625 } else
625 tx->control->alt_retry_rate = NULL; 626 tx->control->alt_retry_rate_idx = -1;
626 627
627 if (!tx->rate) 628 if (unlikely(tx->rate_idx < 0))
628 return TX_DROP; 629 return TX_DROP;
629 } else 630 } else
630 tx->control->alt_retry_rate = NULL; 631 tx->control->alt_retry_rate_idx = -1;
631 632
632 if (tx->sdata->bss_conf.use_cts_prot && 633 if (tx->sdata->bss_conf.use_cts_prot &&
633 (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) { 634 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
634 tx->last_frag_rate = tx->rate; 635 tx->last_frag_rate_idx = tx->rate_idx;
635 if (rsel.probe) 636 if (rsel.probe_idx >= 0)
636 tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; 637 tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG;
637 else 638 else
638 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; 639 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
639 tx->rate = rsel.nonerp; 640 tx->rate_idx = rsel.nonerp_idx;
640 tx->control->tx_rate = rsel.nonerp; 641 tx->control->tx_rate_idx = rsel.nonerp_idx;
641 tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; 642 tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
642 } else { 643 } else {
643 tx->last_frag_rate = tx->rate; 644 tx->last_frag_rate_idx = tx->rate_idx;
644 tx->control->tx_rate = tx->rate; 645 tx->control->tx_rate_idx = tx->rate_idx;
645 } 646 }
646 tx->control->tx_rate = tx->rate; 647 tx->control->tx_rate_idx = tx->rate_idx;
647 648
648 return TX_CONTINUE; 649 return TX_CONTINUE;
649} 650}
@@ -655,6 +656,9 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
655 u16 fc = le16_to_cpu(hdr->frame_control); 656 u16 fc = le16_to_cpu(hdr->frame_control);
656 u16 dur; 657 u16 dur;
657 struct ieee80211_tx_control *control = tx->control; 658 struct ieee80211_tx_control *control = tx->control;
659 struct ieee80211_supported_band *sband;
660
661 sband = tx->local->hw.wiphy->bands[tx->channel->band];
658 662
659 if (!control->retry_limit) { 663 if (!control->retry_limit) {
660 if (!is_multicast_ether_addr(hdr->addr1)) { 664 if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -681,14 +685,14 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
681 * frames. 685 * frames.
682 * TODO: The last fragment could still use multiple retry 686 * TODO: The last fragment could still use multiple retry
683 * rates. */ 687 * rates. */
684 control->alt_retry_rate = NULL; 688 control->alt_retry_rate_idx = -1;
685 } 689 }
686 690
687 /* Use CTS protection for unicast frames sent using extended rates if 691 /* Use CTS protection for unicast frames sent using extended rates if
688 * there are associated non-ERP stations and RTS/CTS is not configured 692 * there are associated non-ERP stations and RTS/CTS is not configured
689 * for the frame. */ 693 * for the frame. */
690 if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && 694 if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
691 (tx->rate->flags & IEEE80211_RATE_ERP_G) && 695 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) &&
692 (tx->flags & IEEE80211_TX_UNICAST) && 696 (tx->flags & IEEE80211_TX_UNICAST) &&
693 tx->sdata->bss_conf.use_cts_prot && 697 tx->sdata->bss_conf.use_cts_prot &&
694 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) 698 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
@@ -698,7 +702,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
698 * short preambles at the selected rate and short preambles are 702 * short preambles at the selected rate and short preambles are
699 * available on the network at the current point in time. */ 703 * available on the network at the current point in time. */
700 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 704 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
701 (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && 705 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
702 tx->sdata->bss_conf.use_short_preamble && 706 tx->sdata->bss_conf.use_short_preamble &&
703 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { 707 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
704 tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 708 tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
@@ -715,32 +719,32 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
715 if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || 719 if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
716 (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { 720 (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
717 struct ieee80211_supported_band *sband; 721 struct ieee80211_supported_band *sband;
718 struct ieee80211_rate *rate, *baserate; 722 struct ieee80211_rate *rate;
723 s8 baserate = -1;
719 int idx; 724 int idx;
720 725
721 sband = tx->local->hw.wiphy->bands[ 726 sband = tx->local->hw.wiphy->bands[tx->channel->band];
722 tx->local->hw.conf.channel->band];
723 727
724 /* Do not use multiple retry rates when using RTS/CTS */ 728 /* Do not use multiple retry rates when using RTS/CTS */
725 control->alt_retry_rate = NULL; 729 control->alt_retry_rate_idx = -1;
726 730
727 /* Use min(data rate, max base rate) as CTS/RTS rate */ 731 /* Use min(data rate, max base rate) as CTS/RTS rate */
728 rate = tx->rate; 732 rate = &sband->bitrates[tx->rate_idx];
729 baserate = NULL;
730 733
731 for (idx = 0; idx < sband->n_bitrates; idx++) { 734 for (idx = 0; idx < sband->n_bitrates; idx++) {
732 if (sband->bitrates[idx].bitrate > rate->bitrate) 735 if (sband->bitrates[idx].bitrate > rate->bitrate)
733 continue; 736 continue;
734 if (tx->sdata->basic_rates & BIT(idx) && 737 if (tx->sdata->basic_rates & BIT(idx) &&
735 (!baserate || 738 (baserate < 0 ||
736 (baserate->bitrate < sband->bitrates[idx].bitrate))) 739 (sband->bitrates[baserate].bitrate
737 baserate = &sband->bitrates[idx]; 740 < sband->bitrates[idx].bitrate)))
741 baserate = idx;
738 } 742 }
739 743
740 if (baserate) 744 if (baserate >= 0)
741 control->rts_cts_rate = baserate; 745 control->rts_cts_rate_idx = baserate;
742 else 746 else
743 control->rts_cts_rate = &sband->bitrates[0]; 747 control->rts_cts_rate_idx = 0;
744 } 748 }
745 749
746 if (tx->sta) { 750 if (tx->sta) {
@@ -768,7 +772,11 @@ ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx)
768 struct sk_buff *skb = tx->skb; 772 struct sk_buff *skb = tx->skb;
769 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 773 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
770 u32 load = 0, hdrtime; 774 u32 load = 0, hdrtime;
771 struct ieee80211_rate *rate = tx->rate; 775 struct ieee80211_rate *rate;
776 struct ieee80211_supported_band *sband;
777
778 sband = tx->local->hw.wiphy->bands[tx->channel->band];
779 rate = &sband->bitrates[tx->rate_idx];
772 780
773 /* TODO: this could be part of tx_status handling, so that the number 781 /* TODO: this could be part of tx_status handling, so that the number
774 * of retries would be known; TX rate should in that case be stored 782 * of retries would be known; TX rate should in that case be stored
@@ -803,7 +811,7 @@ ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx)
803 for (i = 0; i < tx->num_extra_frag; i++) { 811 for (i = 0; i < tx->num_extra_frag; i++) {
804 load += 2 * hdrtime; 812 load += 2 * hdrtime;
805 load += tx->extra_frag[i]->len * 813 load += tx->extra_frag[i]->len *
806 tx->rate->bitrate; 814 rate->bitrate;
807 } 815 }
808 } 816 }
809 817
@@ -859,7 +867,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
859 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); 867 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
860 struct ieee80211_tx_control *control = tx->control; 868 struct ieee80211_tx_control *control = tx->control;
861 869
862 sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; 870 sband = tx->local->hw.wiphy->bands[tx->channel->band];
863 871
864 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; 872 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
865 tx->flags |= IEEE80211_TX_INJECTED; 873 tx->flags |= IEEE80211_TX_INJECTED;
@@ -899,7 +907,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
899 r = &sband->bitrates[i]; 907 r = &sband->bitrates[i];
900 908
901 if (r->bitrate == target_rate) { 909 if (r->bitrate == target_rate) {
902 tx->rate = r; 910 tx->rate_idx = i;
903 break; 911 break;
904 } 912 }
905 } 913 }
@@ -1097,7 +1105,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1097 if (__ieee80211_queue_stopped(local, control->queue)) 1105 if (__ieee80211_queue_stopped(local, control->queue))
1098 return IEEE80211_TX_FRAG_AGAIN; 1106 return IEEE80211_TX_FRAG_AGAIN;
1099 if (i == tx->num_extra_frag) { 1107 if (i == tx->num_extra_frag) {
1100 control->tx_rate = tx->last_frag_rate; 1108 control->tx_rate_idx = tx->last_frag_rate_idx;
1101 1109
1102 if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) 1110 if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG)
1103 control->flags |= 1111 control->flags |=
@@ -1155,6 +1163,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1155 1163
1156 sta = tx.sta; 1164 sta = tx.sta;
1157 tx.channel = local->hw.conf.channel; 1165 tx.channel = local->hw.conf.channel;
1166 control->band = tx.channel->band;
1158 1167
1159 for (handler = ieee80211_tx_handlers; *handler != NULL; 1168 for (handler = ieee80211_tx_handlers; *handler != NULL;
1160 handler++) { 1169 handler++) {
@@ -1187,7 +1196,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1187 next_len = tx.extra_frag[i + 1]->len; 1196 next_len = tx.extra_frag[i + 1]->len;
1188 } else { 1197 } else {
1189 next_len = 0; 1198 next_len = 0;
1190 tx.rate = tx.last_frag_rate; 1199 tx.rate_idx = tx.last_frag_rate_idx;
1191 } 1200 }
1192 dur = ieee80211_duration(&tx, 0, next_len); 1201 dur = ieee80211_duration(&tx, 0, next_len);
1193 hdr->duration_id = cpu_to_le16(dur); 1202 hdr->duration_id = cpu_to_le16(dur);
@@ -1224,7 +1233,7 @@ retry:
1224 store->skb = skb; 1233 store->skb = skb;
1225 store->extra_frag = tx.extra_frag; 1234 store->extra_frag = tx.extra_frag;
1226 store->num_extra_frag = tx.num_extra_frag; 1235 store->num_extra_frag = tx.num_extra_frag;
1227 store->last_frag_rate = tx.last_frag_rate; 1236 store->last_frag_rate_idx = tx.last_frag_rate_idx;
1228 store->last_frag_rate_ctrl_probe = 1237 store->last_frag_rate_ctrl_probe =
1229 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); 1238 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG);
1230 } 1239 }
@@ -1685,7 +1694,7 @@ void ieee80211_tx_pending(unsigned long data)
1685 tx.control = &store->control; 1694 tx.control = &store->control;
1686 tx.extra_frag = store->extra_frag; 1695 tx.extra_frag = store->extra_frag;
1687 tx.num_extra_frag = store->num_extra_frag; 1696 tx.num_extra_frag = store->num_extra_frag;
1688 tx.last_frag_rate = store->last_frag_rate; 1697 tx.last_frag_rate_idx = store->last_frag_rate_idx;
1689 tx.flags = 0; 1698 tx.flags = 0;
1690 if (store->last_frag_rate_ctrl_probe) 1699 if (store->last_frag_rate_ctrl_probe)
1691 tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; 1700 tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG;
@@ -1789,9 +1798,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1789 struct ieee80211_mgmt *mgmt; 1798 struct ieee80211_mgmt *mgmt;
1790 int *num_beacons; 1799 int *num_beacons;
1791 bool err = true; 1800 bool err = true;
1801 enum ieee80211_band band = local->hw.conf.channel->band;
1792 u8 *pos; 1802 u8 *pos;
1793 1803
1794 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1804 sband = local->hw.wiphy->bands[band];
1795 1805
1796 rcu_read_lock(); 1806 rcu_read_lock();
1797 1807
@@ -1885,8 +1895,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1885 } 1895 }
1886 1896
1887 if (control) { 1897 if (control) {
1898 control->band = band;
1888 rate_control_get_rate(local->mdev, sband, skb, &rsel); 1899 rate_control_get_rate(local->mdev, sband, skb, &rsel);
1889 if (!rsel.rate) { 1900 if (unlikely(rsel.rate_idx < 0)) {
1890 if (net_ratelimit()) { 1901 if (net_ratelimit()) {
1891 printk(KERN_DEBUG "%s: ieee80211_beacon_get: " 1902 printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
1892 "no rate found\n", 1903 "no rate found\n",
@@ -1898,9 +1909,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1898 } 1909 }
1899 1910
1900 control->vif = vif; 1911 control->vif = vif;
1901 control->tx_rate = rsel.rate; 1912 control->tx_rate_idx = rsel.rate_idx;
1902 if (sdata->bss_conf.use_short_preamble && 1913 if (sdata->bss_conf.use_short_preamble &&
1903 rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 1914 sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
1904 control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 1915 control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
1905 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1916 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1906 control->flags |= IEEE80211_TXCTL_NO_ACK; 1917 control->flags |= IEEE80211_TXCTL_NO_ACK;
@@ -2006,6 +2017,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2006 sta = tx.sta; 2017 sta = tx.sta;
2007 tx.flags |= IEEE80211_TX_PS_BUFFERED; 2018 tx.flags |= IEEE80211_TX_PS_BUFFERED;
2008 tx.channel = local->hw.conf.channel; 2019 tx.channel = local->hw.conf.channel;
2020 control->band = tx.channel->band;
2009 2021
2010 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { 2022 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
2011 res = (*handler)(&tx); 2023 res = (*handler)(&tx);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 800c15aff6e7..65a34fddeb00 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -266,10 +266,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
266 bool short_preamble; 266 bool short_preamble;
267 int erp; 267 int erp;
268 u16 dur; 268 u16 dur;
269 struct ieee80211_supported_band *sband;
270
271 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
269 272
270 short_preamble = sdata->bss_conf.use_short_preamble; 273 short_preamble = sdata->bss_conf.use_short_preamble;
271 274
272 rate = frame_txctl->rts_cts_rate; 275 rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
273 276
274 erp = 0; 277 erp = 0;
275 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 278 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -300,10 +303,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
300 bool short_preamble; 303 bool short_preamble;
301 int erp; 304 int erp;
302 u16 dur; 305 u16 dur;
306 struct ieee80211_supported_band *sband;
307
308 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
303 309
304 short_preamble = sdata->bss_conf.use_short_preamble; 310 short_preamble = sdata->bss_conf.use_short_preamble;
305 311
306 rate = frame_txctl->rts_cts_rate; 312 rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx];
307 erp = 0; 313 erp = 0;
308 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 314 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
309 erp = rate->flags & IEEE80211_RATE_ERP_G; 315 erp = rate->flags & IEEE80211_RATE_ERP_G;