diff options
25 files changed, 205 insertions, 151 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 79dfca546c8..22db664a58d 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 3f16ad66bdb..32ee351a765 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 9445a604a96..e428645352b 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 afce9338d83..9b682a3cf5e 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 bed9e041d6c..55dc251bf51 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 e51eeeff699..f3ca02fe961 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 | ||
819 | static struct rate_control_ops rs_ops = { | 819 | static 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 ad4e7b74ca2..f8e691f88ab 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 2adc2281c77..7993a1d8302 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 | ||
2185 | done: | 2185 | done: |
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; | ||
2192 | out: | 2194 | out: |
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 f848a5b0f62..fb670b5cfeb 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 | ||
386 | int iwl4965_hw_rxq_stop(struct iwl_priv *priv) | 382 | int 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 f32cddabdf6..4b5149c8c32 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 54cde8a7b5f..a28b4c9f652 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 db4f606bad5..1fad6227aa5 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 3d35fe6a8f5..3ca9386561f 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 19c10629c76..5cf4c2f5926 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 c220998cee6..6263209b889 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 e14c8424868..86a09b49681 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 0c736735e21..99c508c09e5 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 f00fc76a734..0df91bea6c1 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 | */ |
272 | struct ieee80211_tx_control { | 270 | struct 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 | ||
826 | static inline struct ieee80211_rate * | ||
827 | ieee80211_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 | |||
835 | static inline struct ieee80211_rate * | ||
836 | ieee80211_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 | |||
844 | static inline struct ieee80211_rate * | ||
845 | ieee80211_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 ed0d9b35ae6..a4cccd1b7d5 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 | ||
233 | struct beacon_data { | 233 | struct beacon_data { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7877d3b3f4c..604149369dc 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 841df93807f..0388c090dfe 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 5b45f33cb76..a29148dcca9 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 | */ | ||
23 | struct rate_selection { | 29 | struct 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 | ||
32 | struct rate_control_ops { | 33 | struct 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 | ||
141 | static inline int | 142 | static inline s8 |
142 | rate_lowest_index(struct ieee80211_local *local, | 143 | rate_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 | ||
158 | static inline struct ieee80211_rate * | ||
159 | rate_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 */ |
168 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | 161 | int 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 a849b745bdb..14cde36f507 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 aecec2a72b0..99c3860bc0e 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 800c15aff6e..65a34fddeb0 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; |